github.com/loggregator/cli@v6.33.1-0.20180224010324-82334f081791+incompatible/api/cloudcontroller/wrapper/retry_request_test.go (about) 1 package wrapper_test 2 3 import ( 4 "errors" 5 "io/ioutil" 6 "net/http" 7 "strings" 8 9 "code.cloudfoundry.org/cli/api/cloudcontroller" 10 "code.cloudfoundry.org/cli/api/cloudcontroller/ccerror" 11 "code.cloudfoundry.org/cli/api/cloudcontroller/cloudcontrollerfakes" 12 . "code.cloudfoundry.org/cli/api/cloudcontroller/wrapper" 13 . "github.com/onsi/ginkgo" 14 . "github.com/onsi/ginkgo/extensions/table" 15 . "github.com/onsi/gomega" 16 ) 17 18 var _ = Describe("Retry Request", func() { 19 DescribeTable("number of retries", 20 func(requestMethod string, responseStatusCode int, expectedNumberOfRetries int) { 21 rawRequestBody := "banana pants" 22 body := strings.NewReader(rawRequestBody) 23 24 req, err := http.NewRequest(requestMethod, "https://foo.bar.com/banana", body) 25 Expect(err).NotTo(HaveOccurred()) 26 request := cloudcontroller.NewRequest(req, body) 27 28 response := &cloudcontroller.Response{ 29 HTTPResponse: &http.Response{ 30 StatusCode: responseStatusCode, 31 }, 32 } 33 34 fakeConnection := new(cloudcontrollerfakes.FakeConnection) 35 expectedErr := ccerror.RawHTTPStatusError{ 36 StatusCode: responseStatusCode, 37 } 38 fakeConnection.MakeStub = func(req *cloudcontroller.Request, passedResponse *cloudcontroller.Response) error { 39 defer req.Body.Close() 40 body, readErr := ioutil.ReadAll(request.Body) 41 Expect(readErr).ToNot(HaveOccurred()) 42 Expect(string(body)).To(Equal(rawRequestBody)) 43 return expectedErr 44 } 45 46 wrapper := NewRetryRequest(2).Wrap(fakeConnection) 47 err = wrapper.Make(request, response) 48 Expect(err).To(MatchError(expectedErr)) 49 Expect(fakeConnection.MakeCallCount()).To(Equal(expectedNumberOfRetries)) 50 }, 51 52 Entry("maxRetries for Non-Post (500) Internal Server Error", http.MethodGet, http.StatusInternalServerError, 3), 53 Entry("maxRetries for Non-Post (502) Bad Gateway", http.MethodGet, http.StatusBadGateway, 3), 54 Entry("maxRetries for Non-Post (503) Service Unavailable", http.MethodGet, http.StatusServiceUnavailable, 3), 55 Entry("maxRetries for Non-Post (504) Gateway Timeout", http.MethodGet, http.StatusGatewayTimeout, 3), 56 57 Entry("1 for Post (500) Internal Server Error", http.MethodPost, http.StatusInternalServerError, 1), 58 Entry("1 for Post (502) Bad Gateway", http.MethodPost, http.StatusBadGateway, 1), 59 Entry("1 for Post (503) Service Unavailable", http.MethodPost, http.StatusServiceUnavailable, 1), 60 Entry("1 for Post (504) Gateway Timeout", http.MethodPost, http.StatusGatewayTimeout, 1), 61 62 Entry("1 for Get 4XX Errors", http.MethodGet, http.StatusNotFound, 1), 63 ) 64 65 It("does not retry on success", func() { 66 req, err := http.NewRequest(http.MethodGet, "https://foo.bar.com/banana", nil) 67 Expect(err).NotTo(HaveOccurred()) 68 request := cloudcontroller.NewRequest(req, nil) 69 response := &cloudcontroller.Response{ 70 HTTPResponse: &http.Response{ 71 StatusCode: http.StatusOK, 72 }, 73 } 74 75 fakeConnection := new(cloudcontrollerfakes.FakeConnection) 76 wrapper := NewRetryRequest(2).Wrap(fakeConnection) 77 78 err = wrapper.Make(request, response) 79 Expect(err).ToNot(HaveOccurred()) 80 Expect(fakeConnection.MakeCallCount()).To(Equal(1)) 81 }) 82 83 Context("when a PipeSeekError is returned from ResetBody", func() { 84 var ( 85 expectedErr error 86 request *cloudcontroller.Request 87 response *cloudcontroller.Response 88 89 fakeConnection *cloudcontrollerfakes.FakeConnection 90 wrapper cloudcontroller.Connection 91 ) 92 93 BeforeEach(func() { 94 body, _ := cloudcontroller.NewPipeBomb() 95 req, err := http.NewRequest(http.MethodGet, "https://foo.bar.com/banana", body) 96 Expect(err).NotTo(HaveOccurred()) 97 request = cloudcontroller.NewRequest(req, body) 98 response = &cloudcontroller.Response{ 99 HTTPResponse: &http.Response{ 100 StatusCode: http.StatusInternalServerError, 101 }, 102 } 103 104 fakeConnection = new(cloudcontrollerfakes.FakeConnection) 105 expectedErr = errors.New("oh noes") 106 fakeConnection.MakeReturns(expectedErr) 107 108 wrapper = NewRetryRequest(2).Wrap(fakeConnection) 109 }) 110 111 It("sets the err on PipeSeekError", func() { 112 err := wrapper.Make(request, response) 113 Expect(err).To(MatchError(ccerror.PipeSeekError{Err: expectedErr})) 114 Expect(fakeConnection.MakeCallCount()).To(Equal(1)) 115 }) 116 }) 117 })