// +build go1.7 // Copyright (c) 2015-2019 Jeevanandam M (jeeva@myjeeva.com) // 2016 Andrew Grigorev (https://github.com/ei-grad) // All rights reserved. // resty source code and usage is governed by a MIT style // license that can be found in the LICENSE file. package resty import ( "context" "net/http" "strings" "sync/atomic" "testing" "time" ) func TestSetContext(t *testing.T) { ts := createGetServer(t) defer ts.Close() resp, err := R(). SetContext(context.Background()). Get(ts.URL + "/") assertError(t, err) assertEqual(t, http.StatusOK, resp.StatusCode()) assertEqual(t, "200 OK", resp.Status()) assertEqual(t, true, resp.Body() != nil) assertEqual(t, "TestGet: text response", resp.String()) logResponse(t, resp) } func TestSetContextWithError(t *testing.T) { ts := createGetServer(t) defer ts.Close() resp, err := dcr(). SetContext(context.Background()). Get(ts.URL + "/mypage") assertError(t, err) assertEqual(t, http.StatusBadRequest, resp.StatusCode()) assertEqual(t, "", resp.String()) logResponse(t, resp) } func TestSetContextCancel(t *testing.T) { ch := make(chan struct{}) ts := createTestServer(func(w http.ResponseWriter, r *http.Request) { defer func() { ch <- struct{}{} // tell test request is finished }() t.Logf("Server: %v %v", r.Method, r.URL.Path) ch <- struct{}{} <-ch // wait for client to finish request n, err := w.Write([]byte("TestSetContextCancel: response")) // FIXME? test server doesn't handle request cancellation t.Logf("Server: wrote %d bytes", n) t.Logf("Server: err is %v ", err) }) defer ts.Close() ctx, cancel := context.WithCancel(context.Background()) go func() { <-ch // wait for server to start request handling cancel() }() _, err := R(). SetContext(ctx). Get(ts.URL + "/") ch <- struct{}{} // tell server to continue request handling <-ch // wait for server to finish request handling t.Logf("Error: %v", err) if !errIsContextCanceled(err) { t.Errorf("Got unexpected error: %v", err) } } func TestSetContextCancelRetry(t *testing.T) { reqCount := 0 ch := make(chan struct{}) ts := createTestServer(func(w http.ResponseWriter, r *http.Request) { reqCount++ defer func() { ch <- struct{}{} // tell test request is finished }() t.Logf("Server: %v %v", r.Method, r.URL.Path) ch <- struct{}{} <-ch // wait for client to finish request n, err := w.Write([]byte("TestSetContextCancel: response")) // FIXME? test server doesn't handle request cancellation t.Logf("Server: wrote %d bytes", n) t.Logf("Server: err is %v ", err) }) defer ts.Close() ctx, cancel := context.WithCancel(context.Background()) go func() { <-ch // wait for server to start request handling cancel() }() c := dc() c.SetHTTPMode(). SetTimeout(time.Second * 3). SetRetryCount(3) _, err := c.R(). SetContext(ctx). Get(ts.URL + "/") ch <- struct{}{} // tell server to continue request handling <-ch // wait for server to finish request handling t.Logf("Error: %v", err) if !errIsContextCanceled(err) { t.Errorf("Got unexpected error: %v", err) } if reqCount != 1 { t.Errorf("Request was retried %d times instead of 1", reqCount) } } func TestSetContextCancelWithError(t *testing.T) { ch := make(chan struct{}) ts := createTestServer(func(w http.ResponseWriter, r *http.Request) { defer func() { ch <- struct{}{} // tell test request is finished }() t.Logf("Server: %v %v", r.Method, r.URL.Path) t.Log("Server: sending StatusBadRequest response") w.WriteHeader(http.StatusBadRequest) ch <- struct{}{} <-ch // wait for client to finish request n, err := w.Write([]byte("TestSetContextCancelWithError: response")) // FIXME? test server doesn't handle request cancellation t.Logf("Server: wrote %d bytes", n) t.Logf("Server: err is %v ", err) }) defer ts.Close() ctx, cancel := context.WithCancel(context.Background()) go func() { <-ch // wait for server to start request handling cancel() }() _, err := R(). SetContext(ctx). Get(ts.URL + "/") ch <- struct{}{} // tell server to continue request handling <-ch // wait for server to finish request handling t.Logf("Error: %v", err) if !errIsContextCanceled(err) { t.Errorf("Got unexpected error: %v", err) } } func TestClientRetryWithSetContext(t *testing.T) { var attemptctx int32 ts := createTestServer(func(w http.ResponseWriter, r *http.Request) { t.Logf("Method: %v", r.Method) t.Logf("Path: %v", r.URL.Path) attp := atomic.AddInt32(&attemptctx, 1) if attp <= 3 { time.Sleep(time.Second * 2) } _, _ = w.Write([]byte("TestClientRetry page")) }) defer ts.Close() c := dc() c.SetHTTPMode(). SetTimeout(time.Second * 1). SetRetryCount(3) _, err := c.R(). SetContext(context.Background()). Get(ts.URL + "/") assertEqual(t, true, strings.HasPrefix(err.Error(), "Get "+ts.URL+"/")) }