github.com/mponton/terratest@v0.44.0/modules/http-helper/http_helper_test.go (about) 1 package http_helper 2 3 import ( 4 "bytes" 5 "fmt" 6 "io/ioutil" 7 "net/http" 8 "net/http/httptest" 9 "regexp" 10 "strings" 11 "testing" 12 "time" 13 14 "github.com/stretchr/testify/require" 15 ) 16 17 func getTestServerForFunction(handler func(w http.ResponseWriter, 18 r *http.Request)) *httptest.Server { 19 return httptest.NewServer(http.HandlerFunc(handler)) 20 } 21 22 func TestOkBody(t *testing.T) { 23 t.Parallel() 24 ts := getTestServerForFunction(bodyCopyHandler) 25 defer ts.Close() 26 url := ts.URL 27 expectedBody := "Hello, Terratest!" 28 body := bytes.NewReader([]byte(expectedBody)) 29 statusCode, respBody := HTTPDo(t, "POST", url, body, nil, nil) 30 31 expectedCode := 200 32 if statusCode != expectedCode { 33 t.Errorf("handler returned wrong status code: got %v want %v", statusCode, expectedCode) 34 } 35 if respBody != expectedBody { 36 t.Errorf("handler returned wrong body: got %v want %v", respBody, expectedBody) 37 } 38 } 39 40 func TestHTTPDoWithValidation(t *testing.T) { 41 t.Parallel() 42 ts := getTestServerForFunction(bodyCopyHandler) 43 defer ts.Close() 44 url := ts.URL 45 expectedBody := "Hello, Terratest!" 46 body := bytes.NewReader([]byte(expectedBody)) 47 HTTPDoWithValidation(t, "POST", url, body, nil, 200, expectedBody, nil) 48 } 49 50 func TestHTTPDoWithCustomValidation(t *testing.T) { 51 t.Parallel() 52 ts := getTestServerForFunction(bodyCopyHandler) 53 defer ts.Close() 54 url := ts.URL 55 expectedBody := "Hello, Terratest!" 56 body := bytes.NewReader([]byte(expectedBody)) 57 58 customValidation := func(statusCode int, response string) bool { 59 return statusCode == 200 && response == expectedBody 60 } 61 62 HTTPDoWithCustomValidation(t, "POST", url, body, nil, customValidation, nil) 63 } 64 65 func TestOkHeaders(t *testing.T) { 66 t.Parallel() 67 ts := getTestServerForFunction(headersCopyHandler) 68 defer ts.Close() 69 url := ts.URL 70 headers := map[string]string{"Authorization": "Bearer 1a2b3c99ff"} 71 statusCode, respBody := HTTPDo(t, "POST", url, nil, headers, nil) 72 73 expectedCode := 200 74 if statusCode != expectedCode { 75 t.Errorf("handler returned wrong status code: got %v want %v", statusCode, expectedCode) 76 } 77 expectedLine := "Authorization: Bearer 1a2b3c99ff" 78 if !strings.Contains(respBody, expectedLine) { 79 t.Errorf("handler returned wrong body: got %v want %v", respBody, expectedLine) 80 } 81 } 82 83 func TestWrongStatus(t *testing.T) { 84 t.Parallel() 85 ts := getTestServerForFunction(wrongStatusHandler) 86 defer ts.Close() 87 url := ts.URL 88 statusCode, _ := HTTPDo(t, "POST", url, nil, nil, nil) 89 90 expectedCode := 500 91 if statusCode != expectedCode { 92 t.Errorf("handler returned wrong status code: got %v want %v", statusCode, expectedCode) 93 } 94 } 95 96 func TestRequestTimeout(t *testing.T) { 97 t.Parallel() 98 ts := getTestServerForFunction(sleepingHandler) 99 defer ts.Close() 100 url := ts.URL 101 _, _, err := HTTPDoE(t, "DELETE", url, nil, nil, nil) 102 103 if err == nil { 104 t.Error("handler didn't return a timeout error") 105 } 106 if !strings.Contains(err.Error(), "Client.Timeout") { 107 t.Errorf("handler didn't return an expected error, got %q", err) 108 } 109 } 110 111 func TestOkWithRetry(t *testing.T) { 112 t.Parallel() 113 ts := getTestServerForFunction(retryHandler) 114 defer ts.Close() 115 body := "TEST_CONTENT" 116 bodyBytes := []byte(body) 117 url := ts.URL 118 counter = 3 119 response := HTTPDoWithRetry(t, "POST", url, bodyBytes, nil, 200, 10, time.Second, nil) 120 require.Equal(t, body, response) 121 } 122 123 func TestErrorWithRetry(t *testing.T) { 124 t.Parallel() 125 ts := getTestServerForFunction(failRetryHandler) 126 defer ts.Close() 127 failCounter = 3 128 url := ts.URL 129 _, err := HTTPDoWithRetryE(t, "POST", url, nil, nil, 200, 2, time.Second, nil) 130 131 if err == nil { 132 t.Error("handler didn't return a retry error") 133 } 134 135 pattern := `unsuccessful after \d+ retries` 136 match, _ := regexp.MatchString(pattern, err.Error()) 137 if !match { 138 t.Errorf("handler didn't return an expected error, got %q", err) 139 } 140 } 141 142 func bodyCopyHandler(w http.ResponseWriter, r *http.Request) { 143 w.WriteHeader(http.StatusOK) 144 body, _ := ioutil.ReadAll(r.Body) 145 w.Write(body) 146 } 147 148 func headersCopyHandler(w http.ResponseWriter, r *http.Request) { 149 w.WriteHeader(http.StatusOK) 150 var buffer bytes.Buffer 151 for key, values := range r.Header { 152 buffer.WriteString(fmt.Sprintf("%s: %s\n", key, strings.Join(values, ","))) 153 } 154 w.Write(buffer.Bytes()) 155 } 156 157 func wrongStatusHandler(w http.ResponseWriter, r *http.Request) { 158 w.WriteHeader(http.StatusInternalServerError) 159 } 160 161 func sleepingHandler(w http.ResponseWriter, r *http.Request) { 162 time.Sleep(time.Second * 15) 163 } 164 165 var counter int 166 167 func retryHandler(w http.ResponseWriter, r *http.Request) { 168 if counter > 0 { 169 counter-- 170 w.WriteHeader(http.StatusServiceUnavailable) 171 ioutil.ReadAll(r.Body) 172 } else { 173 w.WriteHeader(http.StatusOK) 174 bytes, _ := ioutil.ReadAll(r.Body) 175 w.Write(bytes) 176 } 177 } 178 179 var failCounter int 180 181 func failRetryHandler(w http.ResponseWriter, r *http.Request) { 182 if failCounter > 0 { 183 failCounter-- 184 w.WriteHeader(http.StatusServiceUnavailable) 185 ioutil.ReadAll(r.Body) 186 } else { 187 w.WriteHeader(http.StatusOK) 188 bytes, _ := ioutil.ReadAll(r.Body) 189 w.Write(bytes) 190 } 191 }