From f777a93b29c5e36dca7fcb176e9572052bd66c63 Mon Sep 17 00:00:00 2001 From: Cecylia Bocovich Date: Thu, 14 Aug 2025 08:39:29 -0400 Subject: [PATCH] Add failing concurrency test This test fails when run with go test -v -race due to data races in calls to prometheus update functions. --- broker/snowflake-broker_test.go | 65 +++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/broker/snowflake-broker_test.go b/broker/snowflake-broker_test.go index 605ea37..3eb4ba5 100644 --- a/broker/snowflake-broker_test.go +++ b/broker/snowflake-broker_test.go @@ -3,6 +3,8 @@ package main import ( "bytes" "container/heap" + "crypto/rand" + "encoding/base64" "encoding/hex" "fmt" "io" @@ -10,6 +12,7 @@ import ( "net/http" "net/http/httptest" "os" + "strings" "sync" "testing" "time" @@ -1069,3 +1072,65 @@ snowflake-ips-nat-unknown 0 }) }) } + +func TestConcurrency(t *testing.T) { + Convey("Test concurency with", t, func() { + ctx := NewBrokerContext(NullLogger(), "snowflake.torproject.net") + i := &IPC{ctx} + Convey("multiple simultaneous polls", func(c C) { + go ctx.Broker() + + var proxies sync.WaitGroup + var wg sync.WaitGroup + + proxies.Add(1000) + // Multiple proxy polls + for x := 0; x < 1000; x++ { + wp := httptest.NewRecorder() + buf := make([]byte, 16) + _, err := rand.Read(buf) + id := strings.TrimRight(base64.StdEncoding.EncodeToString(buf), "=") + + datap := bytes.NewReader([]byte(fmt.Sprintf("{\"Sid\": \"%s\",\"Version\":\"1.0\",\"AcceptedRelayPattern\":\"snowflake.torproject.net\"}", id))) + rp, err := http.NewRequest("POST", "snowflake.broker/proxy", datap) + So(err, ShouldBeNil) + + go func() { + proxies.Done() + proxyPolls(i, wp, rp) + c.So(wp.Code, ShouldEqual, http.StatusOK) + + // Proxy answers + wp = httptest.NewRecorder() + datap, err = createProxyAnswer(sdp, id) + c.So(err, ShouldBeNil) + rp, err = http.NewRequest("POST", "snowflake.broker/answer", datap) + c.So(err, ShouldBeNil) + go func() { + proxyAnswers(i, wp, rp) + }() + }() + } + // Wait for all proxies to poll before sending client offers + proxies.Wait() + + // Multiple client offers + for x := 0; x < 500; x++ { + wg.Add(1) + wc := httptest.NewRecorder() + datac, err := createClientOffer(sdp, NATUnrestricted, "") + So(err, ShouldBeNil) + rc, err := http.NewRequest("POST", "snowflake.broker/client", datac) + So(err, ShouldBeNil) + + go func() { + clientOffers(i, wc, rc) + c.So(wc.Code, ShouldEqual, http.StatusOK) + c.So(wc.Body.String(), ShouldContainSubstring, "8.8.8.8") + wg.Done() + }() + } + wg.Wait() + }) + }) +}