commit fe3356a54dccebe5d474d67068f817ef69f5c099
Author: Cecylia Bocovich <cohosh(a)torproject.org>
Date: Wed Jun 12 10:14:21 2019 -0400
Unit tests for metrics code
Added unit tests for metrics logging. Refactored the logMetrics()
function to allow for easier testing
---
broker/metrics.go | 33 ++++++----
broker/snowflake-broker_test.go | 129 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 149 insertions(+), 13 deletions(-)
diff --git a/broker/metrics.go b/broker/metrics.go
index b03c6db..5ac4192 100644
--- a/broker/metrics.go
+++ b/broker/metrics.go
@@ -116,25 +116,32 @@ func NewMetrics(metricsLogger *log.Logger) (*Metrics, error) {
return m, nil
}
+// Logs metrics in intervals specified by metricsResolution
func (m *Metrics) logMetrics() {
-
heartbeat := time.Tick(metricsResolution)
for range heartbeat {
- m.logger.Println("snowflake-stats-end", time.Now().UTC().Format("2006-01-02 15:04:05"), "(", int(metricsResolution.Seconds()), "s)")
- m.logger.Println("snowflake-ips", m.countryStats.Display())
- m.logger.Println("snowflake-idle-count", binCount(m.proxyIdleCount))
- m.logger.Println("client-denied-count", binCount(m.clientDeniedCount))
- m.logger.Println("client-snowflake-match-count", binCount(m.clientProxyMatchCount))
-
- //restore all metrics to original values
- m.proxyIdleCount = 0
- m.clientDeniedCount = 0
- m.clientProxyMatchCount = 0
- m.countryStats.counts = make(map[string]int)
- m.countryStats.ips = make(map[string]bool)
+ m.printMetrics()
+ m.zeroMetrics()
}
}
+func (m *Metrics) printMetrics() {
+ m.logger.Println("snowflake-stats-end", time.Now().UTC().Format("2006-01-02 15:04:05"), "(", int(metricsResolution.Seconds()), "s)")
+ m.logger.Println("snowflake-ips", m.countryStats.Display())
+ m.logger.Println("snowflake-idle-count", binCount(m.proxyIdleCount))
+ m.logger.Println("client-denied-count", binCount(m.clientDeniedCount))
+ m.logger.Println("client-snowflake-match-count", binCount(m.clientProxyMatchCount))
+}
+
+// Restores all metrics to original values
+func (m *Metrics) zeroMetrics() {
+ m.proxyIdleCount = 0
+ m.clientDeniedCount = 0
+ m.clientProxyMatchCount = 0
+ m.countryStats.counts = make(map[string]int)
+ m.countryStats.ips = make(map[string]bool)
+}
+
// Rounds up a count to the nearest multiple of 8.
func binCount(count int) int {
return int((math.Ceil(float64(count) / 8)) * 8)
diff --git a/broker/snowflake-broker_test.go b/broker/snowflake-broker_test.go
index 03aa2b4..021122e 100644
--- a/broker/snowflake-broker_test.go
+++ b/broker/snowflake-broker_test.go
@@ -11,6 +11,7 @@ import (
"net/http/httptest"
"os"
"testing"
+ "time"
)
func NullLogger() *log.Logger {
@@ -390,3 +391,131 @@ func TestGeoip(t *testing.T) {
})
}
+
+func TestMetrics(t *testing.T) {
+
+ Convey("Test metrics...", t, func() {
+ done := make(chan bool)
+ buf := new(bytes.Buffer)
+ ctx := NewBrokerContext(log.New(buf, "", 0))
+
+ err := ctx.metrics.LoadGeoipDatabases("test_geoip", "test_geoip6")
+ So(err, ShouldEqual, nil)
+
+ //Test addition of proxy polls
+ Convey("for proxy polls", func() {
+ w := httptest.NewRecorder()
+ data := bytes.NewReader([]byte("test"))
+ r, err := http.NewRequest("POST", "snowflake.broker/proxy", data)
+ r.Header.Set("X-Session-ID", "test")
+ r.RemoteAddr = "129.97.208.23:8888" //CA geoip
+ So(err, ShouldBeNil)
+ go func(ctx *BrokerContext) {
+ proxyPolls(ctx, w, r)
+ done <- true
+ }(ctx)
+ p := <-ctx.proxyPolls //manually unblock poll
+ p.offerChannel <- nil
+ <-done
+
+ ctx.metrics.printMetrics()
+ So(buf.String(), ShouldResemble, "snowflake-stats-end "+time.Now().UTC().Format("2006-01-02 15:04:05")+" ( 86400 s)\nsnowflake-ips CA=1,\nsnowflake-idle-count 8\nclient-denied-count 0\nclient-snowflake-match-count 0\n")
+ })
+
+ //Test addition of client failures
+ Convey("for no proxies available", func() {
+ w := httptest.NewRecorder()
+ data := bytes.NewReader([]byte("test"))
+ r, err := http.NewRequest("POST", "snowflake.broker/client", data)
+ So(err, ShouldBeNil)
+
+ clientOffers(ctx, w, r)
+
+ ctx.metrics.printMetrics()
+ So(buf.String(), ShouldResemble, "snowflake-stats-end "+time.Now().UTC().Format("2006-01-02 15:04:05")+" ( 86400 s)\nsnowflake-ips \nsnowflake-idle-count 0\nclient-denied-count 8\nclient-snowflake-match-count 0\n")
+
+ // Test reset
+ buf.Reset()
+ ctx.metrics.zeroMetrics()
+ ctx.metrics.printMetrics()
+ So(buf.String(), ShouldResemble, "snowflake-stats-end "+time.Now().UTC().Format("2006-01-02 15:04:05")+" ( 86400 s)\nsnowflake-ips \nsnowflake-idle-count 0\nclient-denied-count 0\nclient-snowflake-match-count 0\n")
+ })
+ //Test addition of client matches
+ Convey("for client-proxy match", func() {
+ w := httptest.NewRecorder()
+ data := bytes.NewReader([]byte("test"))
+ r, err := http.NewRequest("POST", "snowflake.broker/client", data)
+ So(err, ShouldBeNil)
+
+ // Prepare a fake proxy to respond with.
+ snowflake := ctx.AddSnowflake("fake")
+ go func() {
+ clientOffers(ctx, w, r)
+ done <- true
+ }()
+ offer := <-snowflake.offerChannel
+ So(offer, ShouldResemble, []byte("test"))
+ snowflake.answerChannel <- []byte("fake answer")
+ <-done
+
+ ctx.metrics.printMetrics()
+ So(buf.String(), ShouldResemble, "snowflake-stats-end "+time.Now().UTC().Format("2006-01-02 15:04:05")+" ( 86400 s)\nsnowflake-ips \nsnowflake-idle-count 0\nclient-denied-count 0\nclient-snowflake-match-count 8\n")
+ })
+ //Test rounding boundary
+ Convey("binning boundary", func() {
+ w := httptest.NewRecorder()
+ data := bytes.NewReader([]byte("test"))
+ r, err := http.NewRequest("POST", "snowflake.broker/client", data)
+ So(err, ShouldBeNil)
+
+ clientOffers(ctx, w, r)
+ clientOffers(ctx, w, r)
+ clientOffers(ctx, w, r)
+ clientOffers(ctx, w, r)
+ clientOffers(ctx, w, r)
+ clientOffers(ctx, w, r)
+ clientOffers(ctx, w, r)
+ clientOffers(ctx, w, r)
+
+ ctx.metrics.printMetrics()
+ So(buf.String(), ShouldResemble, "snowflake-stats-end "+time.Now().UTC().Format("2006-01-02 15:04:05")+" ( 86400 s)\nsnowflake-ips \nsnowflake-idle-count 0\nclient-denied-count 8\nclient-snowflake-match-count 0\n")
+
+ clientOffers(ctx, w, r)
+ buf.Reset()
+ ctx.metrics.printMetrics()
+ So(buf.String(), ShouldResemble, "snowflake-stats-end "+time.Now().UTC().Format("2006-01-02 15:04:05")+" ( 86400 s)\nsnowflake-ips \nsnowflake-idle-count 0\nclient-denied-count 16\nclient-snowflake-match-count 0\n")
+ })
+
+ //Test unique ip
+ Convey("proxy counts by unique ip", func() {
+ w := httptest.NewRecorder()
+ data := bytes.NewReader([]byte("test"))
+ r, err := http.NewRequest("POST", "snowflake.broker/proxy", data)
+ r.Header.Set("X-Session-ID", "test")
+ r.RemoteAddr = "129.97.208.23:8888" //CA geoip
+ So(err, ShouldBeNil)
+ go func(ctx *BrokerContext) {
+ proxyPolls(ctx, w, r)
+ done <- true
+ }(ctx)
+ p := <-ctx.proxyPolls //manually unblock poll
+ p.offerChannel <- nil
+ <-done
+
+ data = bytes.NewReader([]byte("test"))
+ r, err = http.NewRequest("POST", "snowflake.broker/proxy", data)
+ r.Header.Set("X-Session-ID", "test")
+ r.RemoteAddr = "129.97.208.23:8888" //CA geoip
+ go func(ctx *BrokerContext) {
+ proxyPolls(ctx, w, r)
+ done <- true
+ }(ctx)
+ p = <-ctx.proxyPolls //manually unblock poll
+ p.offerChannel <- nil
+ <-done
+
+ ctx.metrics.printMetrics()
+ So(buf.String(), ShouldResemble, "snowflake-stats-end "+time.Now().UTC().Format("2006-01-02 15:04:05")+" ( 86400 s)\nsnowflake-ips CA=1,\nsnowflake-idle-count 8\nclient-denied-count 0\nclient-snowflake-match-count 0\n")
+ })
+ })
+}