func testServer(t *testing.T) (cancel, step func(), resp <-chan *http.Response) { var ( ctx, cancelfn = context.WithCancel(context.Background()) stepch = make(chan bool) endpoint = func(context.Context, interface{}) (interface{}, error) { <-stepch; return struct{}{}, nil } response = make(chan *http.Response) handler = httptransport.Server{ Context: ctx, Endpoint: endpoint, DecodeRequestFunc: func(*http.Request) (interface{}, error) { return struct{}{}, nil }, EncodeResponseFunc: func(http.ResponseWriter, interface{}) error { return nil }, Before: []httptransport.RequestFunc{func(ctx context.Context, r *http.Request) context.Context { return ctx }}, After: []httptransport.ResponseFunc{func(ctx context.Context, w http.ResponseWriter) { return }}, Logger: log.NewNopLogger(), } ) go func() { server := httptest.NewServer(handler) defer server.Close() resp, err := http.Get(server.URL) if err != nil { t.Error(err) return } response <- resp }() return cancelfn, func() { stepch <- true }, response }
func TestNoTimeout(t *testing.T) { ctx := context.Background() resp, err := doRequest(ctx) if resp == nil || err != nil { t.Fatalf("error received from client: %v %v", err, resp) } }
func TestSetContentType(t *testing.T) { const contentType = "application/json" r := httptest.NewRecorder() httptransport.SetContentType(contentType)(context.Background(), r) if want, have := contentType, r.Header().Get("Content-Type"); want != have { t.Errorf("want %q, have %q", want, have) } }
func TestSetHeader(t *testing.T) { const ( key = "X-Foo" val = "12345" ) r := httptest.NewRecorder() httptransport.SetResponseHeader(key, val)(context.Background(), r) if want, have := val, r.Header().Get(key); want != have { t.Errorf("want %q, have %q", want, have) } }
func ExampleWithTimeout() { // Pass a context with a timeout to tell a blocking function that it // should abandon its work after the timeout elapses. ctx, _ := context.WithTimeout(context.Background(), 100*time.Millisecond) select { case <-time.After(200 * time.Millisecond): fmt.Println("overslept") case <-ctx.Done(): fmt.Println(ctx.Err()) // prints "context deadline exceeded" } // Output: // context deadline exceeded }
func TestCancelAfterRequest(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) resp, err := doRequest(ctx) // Cancel before reading the body. // Request.Body should still be readable after the context is canceled. cancel() b, err := ioutil.ReadAll(resp.Body) if err != nil || string(b) != requestBody { t.Fatalf("could not read body: %q %v", b, err) } }
func TestServerBadEncode(t *testing.T) { handler := httptransport.Server{ Context: context.Background(), Endpoint: func(context.Context, interface{}) (interface{}, error) { return struct{}{}, nil }, DecodeRequestFunc: func(*http.Request) (interface{}, error) { return struct{}{}, nil }, EncodeResponseFunc: func(http.ResponseWriter, interface{}) error { return errors.New("dang") }, Logger: log.NewNopLogger(), } server := httptest.NewServer(handler) defer server.Close() resp, _ := http.Get(server.URL) if want, have := http.StatusInternalServerError, resp.StatusCode; want != have { t.Errorf("want %d, have %d", want, have) } }
func TestCancel(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) go func() { time.Sleep(requestDuration / 2) cancel() }() resp, err := doRequest(ctx) if resp != nil || err == nil { t.Fatalf("expected error, didn't get one. resp: %v", resp) } if err != ctx.Err() { t.Fatalf("expected error from context but got: %v", err) } }
func TestServerErrorEncoder(t *testing.T) { errTeapot := errors.New("teapot") code := func(err error) int { if err == errTeapot { return http.StatusTeapot } return http.StatusInternalServerError } handler := httptransport.Server{ Context: context.Background(), Endpoint: func(context.Context, interface{}) (interface{}, error) { return struct{}{}, errTeapot }, DecodeRequestFunc: func(*http.Request) (interface{}, error) { return struct{}{}, nil }, EncodeResponseFunc: func(http.ResponseWriter, interface{}) error { return nil }, ErrorEncoder: func(w http.ResponseWriter, err error) { w.WriteHeader(code(err)) }, Logger: log.NewNopLogger(), } server := httptest.NewServer(handler) defer server.Close() resp, _ := http.Get(server.URL) if want, have := http.StatusTeapot, resp.StatusCode; want != have { t.Errorf("want %d, have %d", want, have) } }
func TestHTTPClient(t *testing.T) { var ( encode = func(*http.Request, interface{}) error { return nil } decode = func(*http.Response) (interface{}, error) { return struct{}{}, nil } headers = make(chan string, 1) headerKey = "X-Foo" headerVal = "abcde" ) server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { headers <- r.Header.Get(headerKey) w.WriteHeader(http.StatusOK) })) client := httptransport.Client{ Method: "GET", URL: mustParse(server.URL), EncodeRequestFunc: encode, DecodeResponseFunc: decode, Before: []httptransport.RequestFunc{httptransport.SetRequestHeader(headerKey, headerVal)}, } _, err := client.Endpoint()(context.Background(), struct{}{}) if err != nil { t.Fatal(err) } var have string select { case have = <-headers: case <-time.After(time.Millisecond): t.Fatalf("timeout waiting for %s", headerKey) } if want := headerVal; want != have { t.Errorf("want %q, have %q", want, have) } }
if _, err := e(ctx, req); err != nil { panic(err) } // Output: // first pre // second pre // third pre // my endpoint! // third post // second post // first post } var ( ctx = context.Background() req = struct{}{} ) func annotate(s string) endpoint.Middleware { return func(next endpoint.Endpoint) endpoint.Endpoint { return func(ctx context.Context, request interface{}) (interface{}, error) { fmt.Println(s, "pre") defer fmt.Println(s, "post") return next(ctx, request) } } } func myEndpoint(context.Context, interface{}) (interface{}, error) { fmt.Println("my endpoint!")