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 }