Skip to content

Commit

Permalink
ok to pass nil headers, test, don't retry 404 (#5)
Browse files Browse the repository at this point in the history
  • Loading branch information
JamesReate committed Apr 14, 2022
1 parent 0ff2e47 commit 1e7d293
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 6 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.18

require (
github.com/avast/retry-go/v4 v4.0.3
github.com/jarcoal/httpmock v1.1.0
github.com/pkg/errors v0.9.1
github.com/stretchr/testify v1.7.0
google.golang.org/grpc v1.45.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/jarcoal/httpmock v1.1.0 h1:F47ChZj1Y2zFsCXxNkBPwNNKnAyOATcdQibk0qEdVCE=
github.com/jarcoal/httpmock v1.1.0/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik=
github.com/pierrre/gotestcover v0.0.0-20160517101806-924dca7d15f0/go.mod h1:4xpMLz7RBWyB+ElzHu8Llua96TRCB3YwX+l5EP1wmHk=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down
13 changes: 7 additions & 6 deletions http_client_wrapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ type httpClientWrapper struct {
}

func NewHTTPClientWrapper(baseURL, torProxyURL string, timeoutSeconds time.Duration, headers map[string]string, addJSONHeaders bool) (HTTPClientWrapper, error) {
if headers == nil {
headers = map[string]string{}
}
if addJSONHeaders {
headers["Accept"] = "application/json"
headers["Content-Type"] = "application/json"
Expand Down Expand Up @@ -54,10 +57,8 @@ func (h httpClientWrapper) ExecuteRequest(path, method string, body []byte) (*ht
return nil, err
}

if len(h.headers) > 0 {
for hk, hv := range h.headers {
req.Header.Set(hk, hv)
}
for hk, hv := range h.headers {
req.Header.Set(hk, hv)
}
res := new(http.Response)

Expand All @@ -71,8 +72,8 @@ func (h httpClientWrapper) ExecuteRequest(path, method string, body []byte) (*ht
return errors.Wrapf(err, "error reading failed request body")
}
errResp := errors.Errorf("received non success status code %d with body: %s", res.StatusCode, string(body))
if res.StatusCode == 400 || res.StatusCode == 401 {
// unrecoverable since probably bad payload
if res.StatusCode == 400 || res.StatusCode == 401 || res.StatusCode == 404 {
// unrecoverable since probably bad payload or n
return retry.Unrecoverable(errResp)
}
return errResp
Expand Down
77 changes: 77 additions & 0 deletions http_client_wrapper_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package shared

import (
"github.com/jarcoal/httpmock"
"github.com/stretchr/testify/assert"
"net/http"
"testing"
)

func Test_httpClientWrapper_ExecuteRequest_failsTooManyRetries(t *testing.T) {
const baseURL = "http://test.com"
hcw, _ := NewHTTPClientWrapper(baseURL, "", 1, nil, true)
httpmock.Activate()
defer httpmock.DeactivateAndReset()
path := "/api/vehicle/v2/makes"
httpmock.RegisterResponder(http.MethodGet, baseURL+path, httpmock.NewStringResponder(409, "error: too many requests"))
response, err := hcw.ExecuteRequest(path, "GET", nil)
countInfo := httpmock.GetCallCountInfo()
c := countInfo["GET "+baseURL+path]

assert.Equal(t, 5, c, "expected five retries")
assert.Error(t, err, "expected error")
assert.Contains(t, err.Error(), "All attempts fail")
assert.Equal(t, 409, response.StatusCode)
}

func Test_httpClientWrapper_ExecuteRequest_doesNotRetryCertainStatusCodes(t *testing.T) {
const baseURL = "http://test.com"
hcw, _ := NewHTTPClientWrapper(baseURL, "", 1, nil, true)

tests := []struct {
name string
statusCode int
}{
{
name: "don't retry 400",
statusCode: 400,
},
{
name: "don't retry 401",
statusCode: 401,
},
{
name: "don't retry 404",
statusCode: 404,
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
httpmock.Activate()
defer httpmock.DeactivateAndReset()
path := "/api/vehicle/v2/makes"
httpmock.RegisterResponder(http.MethodGet, baseURL+path, httpmock.NewStringResponder(test.statusCode, "error: whatever"))
response, err := hcw.ExecuteRequest(path, "GET", nil)
countInfo := httpmock.GetCallCountInfo()
c := countInfo["GET "+baseURL+path]

assert.Equal(t, 1, c, "expected single call")
assert.Equal(t, test.statusCode, response.StatusCode)
assert.Error(t, err, "expected error")
})
}
}

func Test(t *testing.T) {
tests := []struct {
name string
}{
// TODO: test cases
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {

})
}
}

0 comments on commit 1e7d293

Please sign in to comment.