github.com/sl1pm4t/terraform@v0.6.4-0.20170725213156-870617d22df3/plugin/discovery/get_test.go (about) 1 package discovery 2 3 import ( 4 "archive/zip" 5 "fmt" 6 "io" 7 "io/ioutil" 8 "net/http" 9 "net/http/httptest" 10 "os" 11 "path/filepath" 12 "reflect" 13 "regexp" 14 "strings" 15 "testing" 16 ) 17 18 const testProviderFile = "test provider binary" 19 20 // return the directory listing for the "test" provider 21 func testListingHandler(w http.ResponseWriter, r *http.Request) { 22 w.Write([]byte(versionList)) 23 } 24 25 func testChecksumHandler(w http.ResponseWriter, r *http.Request) { 26 // this exact plugin has a signnature and checksum file 27 if r.URL.Path == "/terraform-provider-template/0.1.0/terraform-provider-template_0.1.0_SHA256SUMS" { 28 http.ServeFile(w, r, "testdata/terraform-provider-template_0.1.0_SHA256SUMS") 29 return 30 } 31 if r.URL.Path == "/terraform-provider-template/0.1.0/terraform-provider-template_0.1.0_SHA256SUMS.sig" { 32 http.ServeFile(w, r, "testdata/terraform-provider-template_0.1.0_SHA256SUMS.sig") 33 return 34 } 35 36 // this this checksum file is corrupt and doesn't match the sig 37 if r.URL.Path == "/terraform-provider-badsig/0.1.0/terraform-provider-badsig_0.1.0_SHA256SUMS" { 38 http.ServeFile(w, r, "testdata/terraform-provider-badsig_0.1.0_SHA256SUMS") 39 return 40 } 41 if r.URL.Path == "/terraform-provider-badsig/0.1.0/terraform-provider-badsig_0.1.0_SHA256SUMS.sig" { 42 http.ServeFile(w, r, "testdata/terraform-provider-badsig_0.1.0_SHA256SUMS.sig") 43 return 44 } 45 46 http.Error(w, "signtaure files not found", http.StatusNotFound) 47 } 48 49 // returns a 200 for a valid provider url, using the patch number for the 50 // plugin protocol version. 51 func testHandler(w http.ResponseWriter, r *http.Request) { 52 if r.URL.Path == "/terraform-provider-test/" { 53 testListingHandler(w, r) 54 return 55 } 56 57 parts := strings.Split(r.URL.Path, "/") 58 if len(parts) != 4 { 59 http.Error(w, "not found", http.StatusNotFound) 60 return 61 } 62 63 filename := parts[3] 64 65 reg := regexp.MustCompile(`(terraform-provider-test)_(\d).(\d).(\d)_([^_]+)_([^._]+).zip`) 66 67 fileParts := reg.FindStringSubmatch(filename) 68 if len(fileParts) != 7 { 69 http.Error(w, "invalid provider: "+filename, http.StatusNotFound) 70 return 71 } 72 73 w.Header().Set(protocolVersionHeader, fileParts[4]) 74 75 // write a dummy file 76 z := zip.NewWriter(w) 77 fn := fmt.Sprintf("%s_v%s.%s.%s_x%s", fileParts[1], fileParts[2], fileParts[3], fileParts[4], fileParts[4]) 78 f, err := z.Create(fn) 79 if err != nil { 80 panic(err) 81 } 82 io.WriteString(f, testProviderFile) 83 z.Close() 84 } 85 86 func testReleaseServer() *httptest.Server { 87 handler := http.NewServeMux() 88 handler.HandleFunc("/terraform-provider-test/", testHandler) 89 handler.HandleFunc("/terraform-provider-template/", testChecksumHandler) 90 handler.HandleFunc("/terraform-provider-badsig/", testChecksumHandler) 91 92 return httptest.NewServer(handler) 93 } 94 95 func TestMain(m *testing.M) { 96 server := testReleaseServer() 97 releaseHost = server.URL 98 99 os.Exit(m.Run()) 100 } 101 102 func TestVersionListing(t *testing.T) { 103 i := &ProviderInstaller{} 104 versions, err := i.listProviderVersions("test") 105 if err != nil { 106 t.Fatal(err) 107 } 108 109 Versions(versions).Sort() 110 111 expected := []string{ 112 "1.2.4", 113 "1.2.3", 114 "1.2.1", 115 } 116 117 if len(versions) != len(expected) { 118 t.Fatalf("Received wrong number of versions. expected: %q, got: %q", expected, versions) 119 } 120 121 for i, v := range versions { 122 if v.String() != expected[i] { 123 t.Fatalf("incorrect version: %q, expected %q", v, expected[i]) 124 } 125 } 126 } 127 128 func TestCheckProtocolVersions(t *testing.T) { 129 i := &ProviderInstaller{} 130 if checkPlugin(i.providerURL("test", VersionStr("1.2.3").MustParse().String()), 4) { 131 t.Fatal("protocol version 4 is not compatible") 132 } 133 134 if !checkPlugin(i.providerURL("test", VersionStr("1.2.3").MustParse().String()), 3) { 135 t.Fatal("protocol version 3 should be compatible") 136 } 137 } 138 139 func TestProviderInstallerGet(t *testing.T) { 140 tmpDir, err := ioutil.TempDir("", "tf-plugin") 141 if err != nil { 142 t.Fatal(err) 143 } 144 145 defer os.RemoveAll(tmpDir) 146 147 // attempt to use an incompatible protocol version 148 i := &ProviderInstaller{ 149 Dir: tmpDir, 150 PluginProtocolVersion: 5, 151 SkipVerify: true, 152 } 153 _, err = i.Get("test", AllVersions) 154 if err != ErrorNoVersionCompatible { 155 t.Fatal("want error for incompatible version") 156 } 157 158 i = &ProviderInstaller{ 159 Dir: tmpDir, 160 PluginProtocolVersion: 3, 161 SkipVerify: true, 162 } 163 164 { 165 _, err := i.Get("test", ConstraintStr(">9.0.0").MustParse()) 166 if err != ErrorNoSuitableVersion { 167 t.Fatal("want error for mismatching constraints") 168 } 169 } 170 171 { 172 _, err := i.Get("nonexist", AllVersions) 173 if err != ErrorNoSuchProvider { 174 t.Fatal("want error for no such provider") 175 } 176 } 177 178 gotMeta, err := i.Get("test", AllVersions) 179 if err != nil { 180 t.Fatal(err) 181 } 182 183 // we should have version 1.2.3 184 dest := filepath.Join(tmpDir, "terraform-provider-test_v1.2.3_x3") 185 186 wantMeta := PluginMeta{ 187 Name: "test", 188 Version: VersionStr("1.2.3"), 189 Path: dest, 190 } 191 if !reflect.DeepEqual(gotMeta, wantMeta) { 192 t.Errorf("wrong result meta\ngot: %#v\nwant: %#v", gotMeta, wantMeta) 193 } 194 195 f, err := ioutil.ReadFile(dest) 196 if err != nil { 197 t.Fatal(err) 198 } 199 200 // provider should have been unzipped 201 if string(f) != testProviderFile { 202 t.Fatalf("test provider contains: %q", f) 203 } 204 205 } 206 207 func TestProviderInstallerPurgeUnused(t *testing.T) { 208 tmpDir, err := ioutil.TempDir("", "tf-plugin") 209 if err != nil { 210 t.Fatal(err) 211 } 212 213 defer os.RemoveAll(tmpDir) 214 215 unwantedPath := filepath.Join(tmpDir, "terraform-provider-test_v0.0.1_x2") 216 wantedPath := filepath.Join(tmpDir, "terraform-provider-test_v1.2.3_x3") 217 218 f, err := os.Create(unwantedPath) 219 if err != nil { 220 t.Fatal(err) 221 } 222 f.Close() 223 f, err = os.Create(wantedPath) 224 if err != nil { 225 t.Fatal(err) 226 } 227 f.Close() 228 229 i := &ProviderInstaller{ 230 Dir: tmpDir, 231 PluginProtocolVersion: 3, 232 SkipVerify: true, 233 } 234 purged, err := i.PurgeUnused(map[string]PluginMeta{ 235 "test": PluginMeta{ 236 Name: "test", 237 Version: VersionStr("1.2.3"), 238 Path: wantedPath, 239 }, 240 }) 241 if err != nil { 242 t.Fatal(err) 243 } 244 245 if got, want := purged.Count(), 1; got != want { 246 t.Errorf("wrong purged count %d; want %d", got, want) 247 } 248 if got, want := purged.Newest().Path, unwantedPath; got != want { 249 t.Errorf("wrong purged path %s; want %s", got, want) 250 } 251 252 files, err := ioutil.ReadDir(tmpDir) 253 if err != nil { 254 t.Fatal(err) 255 } 256 257 gotFilenames := make([]string, len(files)) 258 for i, info := range files { 259 gotFilenames[i] = info.Name() 260 } 261 wantFilenames := []string{"terraform-provider-test_v1.2.3_x3"} 262 263 if !reflect.DeepEqual(gotFilenames, wantFilenames) { 264 t.Errorf("wrong filenames after purge\ngot: %#v\nwant: %#v", gotFilenames, wantFilenames) 265 } 266 } 267 268 // Test fetching a provider's checksum file while verifying its signature. 269 func TestProviderChecksum(t *testing.T) { 270 i := &ProviderInstaller{} 271 272 // we only need the checksum, as getter is doing the actual file comparison. 273 sha256sum, err := i.getProviderChecksum("template", "0.1.0") 274 if err != nil { 275 t.Fatal(err) 276 } 277 278 // get the expected checksum for our os/arch 279 sumData, err := ioutil.ReadFile("testdata/terraform-provider-template_0.1.0_SHA256SUMS") 280 if err != nil { 281 t.Fatal(err) 282 } 283 284 expected := checksumForFile(sumData, i.providerFileName("template", "0.1.0")) 285 286 if sha256sum != expected { 287 t.Fatalf("expected: %s\ngot %s\n", sha256sum, expected) 288 } 289 } 290 291 // Test fetching a provider's checksum file witha bad signature 292 func TestProviderChecksumBadSignature(t *testing.T) { 293 i := &ProviderInstaller{} 294 295 // we only need the checksum, as getter is doing the actual file comparison. 296 sha256sum, err := i.getProviderChecksum("badsig", "0.1.0") 297 if err == nil { 298 t.Fatal("expcted error") 299 } 300 301 if !strings.Contains(err.Error(), "signature") { 302 t.Fatal("expected signature error, got:", err) 303 } 304 305 if sha256sum != "" { 306 t.Fatal("expected no checksum, got:", sha256sum) 307 } 308 } 309 310 const versionList = `<!DOCTYPE html> 311 <html> 312 <body> 313 <ul> 314 <li> 315 <a href="../">../</a> 316 </li> 317 <li> 318 <a href="/terraform-provider-test/1.2.3/">terraform-provider-test_1.2.3</a> 319 </li> 320 <li> 321 <a href="/terraform-provider-test/1.2.1/">terraform-provider-test_1.2.1</a> 322 </li> 323 <li> 324 <a href="/terraform-provider-test/1.2.4/">terraform-provider-test_1.2.4</a> 325 </li> 326 </ul> 327 <footer> 328 Proudly fronted by <a href="https://fastly.com/?utm_source=hashicorp" target="_TOP">Fastly</a> 329 </footer> 330 </body> 331 </html> 332 `