mercredi 18 décembre 2019

Golang: how to test for context cancellation from upstream

Suppose I'm working with a function like this:

func Handle(req *http.Request) {

   // do some stuff

   timeout, _ := time.ParseDuration(req.FormValue("timeout"))
   ctx, cancel := context.WithTimeout(req.Context(), timeout)
   req = req.WithContext(ctx)
   defer cancel()

   // do some other stuff

}

and I want to write a test like this:

func TestContextIsCancelled(t *testing.T) {

   req := httptest.NewRequest("GET", "http://example.com", nil)
   q := req.URL.Query()
   q.Set("timeout", "1s")  // short timeout
   req.URL.RawQuery = q.Encode()
   go Handle(req)
   time.Sleep(2 * time.Second)  // request should be timed out after this

   // verify request was cancelled
   err := req.Context().Err()
   if err != context.Canceled {
      t.Error("Request hasn't been cancelled")
   }

}

This doesn't work, because the upstream request/context isn't cancelled when the downstream one times out. Is there a way to make this test do what I want it to without changing the signature of Handle?

Aucun commentaire:

Enregistrer un commentaire