[tor-commits] [snowflake/master] Unit tests for metrics code

cohosh at torproject.org cohosh at torproject.org
Fri Jun 28 21:32:20 UTC 2019


commit fe3356a54dccebe5d474d67068f817ef69f5c099
Author: Cecylia Bocovich <cohosh at 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")
+		})
+	})
+}





More information about the tor-commits mailing list