[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [snowflake/master] Add tests to check for data race in broker
commit 42e16021c49b59433450c8f5b5a54e449f9dc522
Author: Cecylia Bocovich <cohosh@xxxxxxxxxxxxxx>
Date: Mon Nov 25 14:00:54 2019 -0500
Add tests to check for data race in broker
We had some data races in the broker that occur when proxies and clients
modify the heap/snowflake map at the same time. This test has a client
and proxy access the broker simultaneously to check for data races.
---
broker/snowflake-broker_test.go | 144 +++++++++++++++++++++++++++-------------
1 file changed, 97 insertions(+), 47 deletions(-)
diff --git a/broker/snowflake-broker_test.go b/broker/snowflake-broker_test.go
index b23e688..18b83dd 100644
--- a/broker/snowflake-broker_test.go
+++ b/broker/snowflake-broker_test.go
@@ -191,58 +191,108 @@ func TestBroker(t *testing.T) {
})
})
+
})
Convey("End-To-End", t, func() {
- done := make(chan bool)
- polled := make(chan bool)
ctx := NewBrokerContext(NullLogger())
- // Proxy polls with its ID first...
- dataP := bytes.NewReader([]byte(`{"Sid":"ymbcCMto7KHNGYlp","Version":"1.0"}`))
- wP := httptest.NewRecorder()
- rP, err := http.NewRequest("POST", "snowflake.broker/proxy", dataP)
- So(err, ShouldBeNil)
- go func() {
- proxyPolls(ctx, wP, rP)
- polled <- true
- }()
-
- // Manually do the Broker goroutine action here for full control.
- p := <-ctx.proxyPolls
- So(p.id, ShouldEqual, "ymbcCMto7KHNGYlp")
- s := ctx.AddSnowflake(p.id, "")
- go func() {
- offer := <-s.offerChannel
- p.offerChannel <- offer
- }()
- So(ctx.idToSnowflake["ymbcCMto7KHNGYlp"], ShouldNotBeNil)
-
- // Client request blocks until proxy answer arrives.
- dataC := bytes.NewReader([]byte("fake offer"))
- wC := httptest.NewRecorder()
- rC, err := http.NewRequest("POST", "snowflake.broker/client", dataC)
- So(err, ShouldBeNil)
- go func() {
- clientOffers(ctx, wC, rC)
- done <- true
- }()
-
- <-polled
- So(wP.Code, ShouldEqual, http.StatusOK)
- So(wP.Body.String(), ShouldResemble, `{"Status":"client match","Offer":"fake offer"}`)
- So(ctx.idToSnowflake["ymbcCMto7KHNGYlp"], ShouldNotBeNil)
- // Follow up with the answer request afterwards
- wA := httptest.NewRecorder()
- dataA := bytes.NewReader([]byte(`{"Version":"1.0","Sid":"ymbcCMto7KHNGYlp","Answer":"test"}`))
- rA, err := http.NewRequest("POST", "snowflake.broker/answer", dataA)
- So(err, ShouldBeNil)
- proxyAnswers(ctx, wA, rA)
- So(wA.Code, ShouldEqual, http.StatusOK)
-
- <-done
- So(wC.Code, ShouldEqual, http.StatusOK)
- So(wC.Body.String(), ShouldEqual, "test")
+ Convey("Check for client/proxy data race", func() {
+ proxy_done := make(chan bool)
+ client_done := make(chan bool)
+
+ go ctx.Broker()
+
+ // Make proxy poll
+ wp := httptest.NewRecorder()
+ datap := bytes.NewReader([]byte(`{"Sid":"ymbcCMto7KHNGYlp","Version":"1.0"}`))
+ rp, err := http.NewRequest("POST", "snowflake.broker/proxy", datap)
+ So(err, ShouldBeNil)
+
+ go func(ctx *BrokerContext) {
+ proxyPolls(ctx, wp, rp)
+ proxy_done <- true
+ }(ctx)
+
+ // Client offer
+ wc := httptest.NewRecorder()
+ datac := bytes.NewReader([]byte("test"))
+ rc, err := http.NewRequest("POST", "snowflake.broker/client", datac)
+ So(err, ShouldBeNil)
+
+ go func() {
+ clientOffers(ctx, wc, rc)
+ client_done <- true
+ }()
+
+ <-proxy_done
+ So(wp.Code, ShouldEqual, http.StatusOK)
+
+ // Proxy answers
+ wp = httptest.NewRecorder()
+ datap = bytes.NewReader([]byte(`{"Version":"1.0","Sid":"ymbcCMto7KHNGYlp","Answer":"test"}`))
+ rp, err = http.NewRequest("POST", "snowflake.broker/answer", datap)
+ So(err, ShouldBeNil)
+ go func(ctx *BrokerContext) {
+ proxyAnswers(ctx, wp, rp)
+ proxy_done <- true
+ }(ctx)
+
+ <-proxy_done
+ <-client_done
+
+ })
+
+ Convey("Ensure correct snowflake brokering", func() {
+ done := make(chan bool)
+ polled := make(chan bool)
+
+ // Proxy polls with its ID first...
+ dataP := bytes.NewReader([]byte(`{"Sid":"ymbcCMto7KHNGYlp","Version":"1.0"}`))
+ wP := httptest.NewRecorder()
+ rP, err := http.NewRequest("POST", "snowflake.broker/proxy", dataP)
+ So(err, ShouldBeNil)
+ go func() {
+ proxyPolls(ctx, wP, rP)
+ polled <- true
+ }()
+
+ // Manually do the Broker goroutine action here for full control.
+ p := <-ctx.proxyPolls
+ So(p.id, ShouldEqual, "ymbcCMto7KHNGYlp")
+ s := ctx.AddSnowflake(p.id, "")
+ go func() {
+ offer := <-s.offerChannel
+ p.offerChannel <- offer
+ }()
+ So(ctx.idToSnowflake["ymbcCMto7KHNGYlp"], ShouldNotBeNil)
+
+ // Client request blocks until proxy answer arrives.
+ dataC := bytes.NewReader([]byte("fake offer"))
+ wC := httptest.NewRecorder()
+ rC, err := http.NewRequest("POST", "snowflake.broker/client", dataC)
+ So(err, ShouldBeNil)
+ go func() {
+ clientOffers(ctx, wC, rC)
+ done <- true
+ }()
+
+ <-polled
+ So(wP.Code, ShouldEqual, http.StatusOK)
+ So(wP.Body.String(), ShouldResemble, `{"Status":"client match","Offer":"fake offer"}`)
+ So(ctx.idToSnowflake["ymbcCMto7KHNGYlp"], ShouldNotBeNil)
+ // Follow up with the answer request afterwards
+ wA := httptest.NewRecorder()
+ dataA := bytes.NewReader([]byte(`{"Version":"1.0","Sid":"ymbcCMto7KHNGYlp","Answer":"test"}`))
+ rA, err := http.NewRequest("POST", "snowflake.broker/answer", dataA)
+ So(err, ShouldBeNil)
+ proxyAnswers(ctx, wA, rA)
+ So(wA.Code, ShouldEqual, http.StatusOK)
+
+ <-done
+ So(wC.Code, ShouldEqual, http.StatusOK)
+ So(wC.Body.String(), ShouldEqual, "test")
+ })
})
}
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits