// +build go1.7
// Copyright (c) 2015-2016 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.Duration(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.Duration(time.Second * 1)).
SetRetryCount(3)
_, err := c.R().
SetContext(context.Background()).
Get(ts.URL + "/")
assertEqual(t, true, strings.HasPrefix(err.Error(), "Get "+ts.URL+"/"))
}