From 9da06344c240d3cd7ce53ee0261722ee2198654a Mon Sep 17 00:00:00 2001 From: Aleksandr Nogikh Date: Thu, 26 Jan 2023 12:22:38 +0100 Subject: dashboard: use context variables for mocking Currently we use context.Context values themselves, but that limits the ability to derive contexts during the request processing. Also, the race detector is reporting a data race during the `reflect.DeepEqual` comparison. --- dashboard/app/util_test.go | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/dashboard/app/util_test.go b/dashboard/app/util_test.go index a008015a0..af9bbc2e3 100644 --- a/dashboard/app/util_test.go +++ b/dashboard/app/util_test.go @@ -25,7 +25,6 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/syzkaller/dashboard/dashapi" "golang.org/x/net/context" - "google.golang.org/appengine/v2" "google.golang.org/appengine/v2/aetest" db "google.golang.org/appengine/v2/datastore" "google.golang.org/appengine/v2/log" @@ -70,14 +69,14 @@ func NewCtx(t *testing.T) *Ctx { c := &Ctx{ t: t, inst: inst, - ctx: appengine.NewContext(r), mockedTime: time.Date(2000, 1, 1, 0, 0, 0, 0, time.UTC), emailSink: make(chan *aemail.Message, 100), } c.client = c.makeClient(client1, password1, true) c.client2 = c.makeClient(client2, password2, true) c.publicClient = c.makeClient(clientPublicEmail, keyPublicEmail, true) - registerContext(r, c) + c.ctx = registerRequest(r, c).Context() + return c } @@ -246,7 +245,7 @@ func (c *Ctx) httpRequest(method, url, body string, access AccessLevel) (*httpte if err != nil { c.t.Fatal(err) } - registerContext(r, c) + r = registerRequest(r, c) if access == AccessAdmin || access == AccessUser { user := &user.User{ Email: "user@syzkaller.com", @@ -374,7 +373,7 @@ type apiClient struct { func (c *Ctx) makeClient(client, key string, failOnErrors bool) *apiClient { doer := func(r *http.Request) (*http.Response, error) { - registerContext(r, c) + r = registerRequest(r, c) w := httptest.NewRecorder() http.DefaultServeMux.ServeHTTP(w, r) res := &http.Response{ @@ -549,26 +548,33 @@ func initMocks() { // Machinery to associate mocked time with requests. type RequestMapping struct { - c context.Context + id int ctx *Ctx } var ( requestMu sync.Mutex + requestNum int requestContexts []RequestMapping ) -func registerContext(r *http.Request, c *Ctx) { +func registerRequest(r *http.Request, c *Ctx) *http.Request { requestMu.Lock() defer requestMu.Unlock() - requestContexts = append(requestContexts, RequestMapping{appengine.NewContext(r), c}) + + requestNum++ + newContext := context.WithValue(r.Context(), requestIDKey, requestNum) + newRequest := r.WithContext(newContext) + requestContexts = append(requestContexts, RequestMapping{requestNum, c}) + return newRequest } func getRequestContext(c context.Context) *Ctx { requestMu.Lock() defer requestMu.Unlock() + reqID := getRequestID(c) for _, m := range requestContexts { - if reflect.DeepEqual(c, m.c) { + if m.id == reqID { return m.ctx } } @@ -588,3 +594,13 @@ func unregisterContext(c *Ctx) { } requestContexts = requestContexts[:n] } + +const requestIDKey = "test_request_id" + +func getRequestID(c context.Context) int { + val, ok := c.Value(requestIDKey).(int) + if !ok { + panic("the context did not come from a test") + } + return val +} -- cgit mrf-deployment