13 httptransport "github.com/go-kit/kit/transport/http"
16 type TestResponse struct {
21 func TestHTTPClient(t *testing.T) {
24 encode = func(context.Context, *http.Request, interface{}) error { return nil }
25 decode = func(_ context.Context, r *http.Response) (interface{}, error) {
26 buffer := make([]byte, len(testbody))
28 return TestResponse{r.Body, string(buffer)}, nil
30 headers = make(chan string, 1)
33 afterHeaderKey = "X-The-Dude"
34 afterHeaderVal = "Abides"
36 afterFunc = func(ctx context.Context, r *http.Response) context.Context {
37 afterVal = r.Header.Get(afterHeaderKey)
42 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
43 headers <- r.Header.Get(headerKey)
44 w.Header().Set(afterHeaderKey, afterHeaderVal)
45 w.WriteHeader(http.StatusOK)
46 w.Write([]byte(testbody))
49 client := httptransport.NewClient(
51 mustParse(server.URL),
54 httptransport.ClientBefore(httptransport.SetRequestHeader(headerKey, headerVal)),
55 httptransport.ClientAfter(afterFunc),
58 res, err := client.Endpoint()(context.Background(), struct{}{})
65 case have = <-headers:
66 case <-time.After(time.Millisecond):
67 t.Fatalf("timeout waiting for %s", headerKey)
69 // Check that Request Header was successfully received
70 if want := headerVal; want != have {
71 t.Errorf("want %q, have %q", want, have)
74 // Check that Response header set from server was received in SetClientAfter
75 if want, have := afterVal, afterHeaderVal; want != have {
76 t.Errorf("want %q, have %q", want, have)
79 // Check that the response was successfully decoded
80 response, ok := res.(TestResponse)
82 t.Fatal("response should be TestResponse")
84 if want, have := testbody, response.String; want != have {
85 t.Errorf("want %q, have %q", want, have)
88 // Check that response body was closed
90 _, err = response.Body.Read(b)
92 t.Fatal("wanted error, got none")
94 if doNotWant, have := io.EOF, err; doNotWant == have {
95 t.Errorf("do not want %q, have %q", doNotWant, have)
99 func TestHTTPClientBufferedStream(t *testing.T) {
101 testbody = "testbody"
102 encode = func(context.Context, *http.Request, interface{}) error { return nil }
103 decode = func(_ context.Context, r *http.Response) (interface{}, error) {
104 return TestResponse{r.Body, ""}, nil
108 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
109 w.WriteHeader(http.StatusOK)
110 w.Write([]byte(testbody))
113 client := httptransport.NewClient(
115 mustParse(server.URL),
118 httptransport.BufferedStream(true),
121 res, err := client.Endpoint()(context.Background(), struct{}{})
126 // Check that the response was successfully decoded
127 response, ok := res.(TestResponse)
129 t.Fatal("response should be TestResponse")
132 // Check that response body was NOT closed
133 b := make([]byte, len(testbody))
134 _, err = response.Body.Read(b)
135 if want, have := io.EOF, err; have != want {
136 t.Fatalf("want %q, have %q", want, have)
138 if want, have := testbody, string(b); want != have {
139 t.Errorf("want %q, have %q", want, have)
143 func TestClientFinalizer(t *testing.T) {
145 headerKey = "X-Henlo-Lizer"
146 headerVal = "Helllo you stinky lizard"
147 responseBody = "go eat a fly ugly\n"
148 done = make(chan struct{})
149 encode = func(context.Context, *http.Request, interface{}) error { return nil }
150 decode = func(_ context.Context, r *http.Response) (interface{}, error) {
151 return TestResponse{r.Body, ""}, nil
155 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
156 w.Header().Set(headerKey, headerVal)
157 w.Write([]byte(responseBody))
161 client := httptransport.NewClient(
163 mustParse(server.URL),
166 httptransport.ClientFinalizer(func(ctx context.Context, err error) {
167 responseHeader := ctx.Value(httptransport.ContextKeyResponseHeaders).(http.Header)
168 if want, have := headerVal, responseHeader.Get(headerKey); want != have {
169 t.Errorf("%s: want %q, have %q", headerKey, want, have)
172 responseSize := ctx.Value(httptransport.ContextKeyResponseSize).(int64)
173 if want, have := int64(len(responseBody)), responseSize; want != have {
174 t.Errorf("response size: want %d, have %d", want, have)
181 _, err := client.Endpoint()(context.Background(), struct{}{})
188 case <-time.After(time.Second):
189 t.Fatal("timeout waiting for finalizer")
193 func TestEncodeJSONRequest(t *testing.T) {
194 var header http.Header
197 server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
198 b, err := ioutil.ReadAll(r.Body)
199 if err != nil && err != io.EOF {
208 serverURL, err := url.Parse(server.URL)
214 client := httptransport.NewClient(
217 httptransport.EncodeJSONRequest,
218 func(context.Context, *http.Response) (interface{}, error) { return nil, nil },
221 for _, test := range []struct {
229 {"test", "\"test\"\n"},
230 {enhancedRequest{Foo: "foo"}, "{\"foo\":\"foo\"}\n"},
232 if _, err := client(context.Background(), test.value); err != nil {
237 if body != test.body {
238 t.Errorf("%v: actual %#v, expected %#v", test.value, body, test.body)
242 if _, err := client(context.Background(), enhancedRequest{Foo: "foo"}); err != nil {
246 if _, ok := header["X-Edward"]; !ok {
247 t.Fatalf("X-Edward value: actual %v, expected %v", nil, []string{"Snowden"})
250 if v := header.Get("X-Edward"); v != "Snowden" {
251 t.Errorf("X-Edward string: actual %v, expected %v", v, "Snowden")
255 func mustParse(s string) *url.URL {
256 u, err := url.Parse(s)
263 type enhancedRequest struct {
264 Foo string `json:"foo"`
267 func (e enhancedRequest) Headers() http.Header { return http.Header{"X-Edward": []string{"Snowden"}} }