github.com/hugorut/terraform@v1.1.3/src/backend/remote-state/http/client_test.go (about)

     1  package http
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"net/url"
    10  	"reflect"
    11  	"testing"
    12  
    13  	"github.com/hashicorp/go-retryablehttp"
    14  	"github.com/hugorut/terraform/src/states/remote"
    15  )
    16  
    17  func TestHTTPClient_impl(t *testing.T) {
    18  	var _ remote.Client = new(httpClient)
    19  	var _ remote.ClientLocker = new(httpClient)
    20  }
    21  
    22  func TestHTTPClient(t *testing.T) {
    23  	handler := new(testHTTPHandler)
    24  	ts := httptest.NewServer(http.HandlerFunc(handler.Handle))
    25  	defer ts.Close()
    26  
    27  	url, err := url.Parse(ts.URL)
    28  	if err != nil {
    29  		t.Fatalf("Parse: %s", err)
    30  	}
    31  
    32  	// Test basic get/update
    33  	client := &httpClient{URL: url, Client: retryablehttp.NewClient()}
    34  	remote.TestClient(t, client)
    35  
    36  	// test just a single PUT
    37  	p := &httpClient{
    38  		URL:          url,
    39  		UpdateMethod: "PUT",
    40  		Client:       retryablehttp.NewClient(),
    41  	}
    42  	remote.TestClient(t, p)
    43  
    44  	// Test locking and alternative UpdateMethod
    45  	a := &httpClient{
    46  		URL:          url,
    47  		UpdateMethod: "PUT",
    48  		LockURL:      url,
    49  		LockMethod:   "LOCK",
    50  		UnlockURL:    url,
    51  		UnlockMethod: "UNLOCK",
    52  		Client:       retryablehttp.NewClient(),
    53  	}
    54  	b := &httpClient{
    55  		URL:          url,
    56  		UpdateMethod: "PUT",
    57  		LockURL:      url,
    58  		LockMethod:   "LOCK",
    59  		UnlockURL:    url,
    60  		UnlockMethod: "UNLOCK",
    61  		Client:       retryablehttp.NewClient(),
    62  	}
    63  	remote.TestRemoteLocks(t, a, b)
    64  
    65  	// test a WebDAV-ish backend
    66  	davhandler := new(testHTTPHandler)
    67  	ts = httptest.NewServer(http.HandlerFunc(davhandler.HandleWebDAV))
    68  	defer ts.Close()
    69  
    70  	url, err = url.Parse(ts.URL)
    71  	client = &httpClient{
    72  		URL:          url,
    73  		UpdateMethod: "PUT",
    74  		Client:       retryablehttp.NewClient(),
    75  	}
    76  	if err != nil {
    77  		t.Fatalf("Parse: %s", err)
    78  	}
    79  
    80  	remote.TestClient(t, client) // first time through: 201
    81  	remote.TestClient(t, client) // second time, with identical data: 204
    82  
    83  	// test a broken backend
    84  	brokenHandler := new(testBrokenHTTPHandler)
    85  	brokenHandler.handler = new(testHTTPHandler)
    86  	ts = httptest.NewServer(http.HandlerFunc(brokenHandler.Handle))
    87  	defer ts.Close()
    88  
    89  	url, err = url.Parse(ts.URL)
    90  	if err != nil {
    91  		t.Fatalf("Parse: %s", err)
    92  	}
    93  	client = &httpClient{URL: url, Client: retryablehttp.NewClient()}
    94  	remote.TestClient(t, client)
    95  }
    96  
    97  type testHTTPHandler struct {
    98  	Data   []byte
    99  	Locked bool
   100  }
   101  
   102  func (h *testHTTPHandler) Handle(w http.ResponseWriter, r *http.Request) {
   103  	switch r.Method {
   104  	case "GET":
   105  		w.Write(h.Data)
   106  	case "PUT":
   107  		buf := new(bytes.Buffer)
   108  		if _, err := io.Copy(buf, r.Body); err != nil {
   109  			w.WriteHeader(500)
   110  		}
   111  		w.WriteHeader(201)
   112  		h.Data = buf.Bytes()
   113  	case "POST":
   114  		buf := new(bytes.Buffer)
   115  		if _, err := io.Copy(buf, r.Body); err != nil {
   116  			w.WriteHeader(500)
   117  		}
   118  		h.Data = buf.Bytes()
   119  	case "LOCK":
   120  		if h.Locked {
   121  			w.WriteHeader(423)
   122  		} else {
   123  			h.Locked = true
   124  		}
   125  	case "UNLOCK":
   126  		h.Locked = false
   127  	case "DELETE":
   128  		h.Data = nil
   129  		w.WriteHeader(200)
   130  	default:
   131  		w.WriteHeader(500)
   132  		w.Write([]byte(fmt.Sprintf("Unknown method: %s", r.Method)))
   133  	}
   134  }
   135  
   136  // mod_dav-ish behavior
   137  func (h *testHTTPHandler) HandleWebDAV(w http.ResponseWriter, r *http.Request) {
   138  	switch r.Method {
   139  	case "GET":
   140  		w.Write(h.Data)
   141  	case "PUT":
   142  		buf := new(bytes.Buffer)
   143  		if _, err := io.Copy(buf, r.Body); err != nil {
   144  			w.WriteHeader(500)
   145  		}
   146  		if reflect.DeepEqual(h.Data, buf.Bytes()) {
   147  			h.Data = buf.Bytes()
   148  			w.WriteHeader(204)
   149  		} else {
   150  			h.Data = buf.Bytes()
   151  			w.WriteHeader(201)
   152  		}
   153  	case "DELETE":
   154  		h.Data = nil
   155  		w.WriteHeader(200)
   156  	default:
   157  		w.WriteHeader(500)
   158  		w.Write([]byte(fmt.Sprintf("Unknown method: %s", r.Method)))
   159  	}
   160  }
   161  
   162  type testBrokenHTTPHandler struct {
   163  	lastRequestWasBroken bool
   164  	handler              *testHTTPHandler
   165  }
   166  
   167  func (h *testBrokenHTTPHandler) Handle(w http.ResponseWriter, r *http.Request) {
   168  	if h.lastRequestWasBroken {
   169  		h.lastRequestWasBroken = false
   170  		h.handler.Handle(w, r)
   171  	} else {
   172  		h.lastRequestWasBroken = true
   173  		w.WriteHeader(500)
   174  	}
   175  }