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  }