github.com/vic3lord/terraform@v0.8.0-rc1.0.20170626102919-16c6dd2cb372/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 versions, err := listProviderVersions("test") 104 if err != nil { 105 t.Fatal(err) 106 } 107 108 Versions(versions).Sort() 109 110 expected := []string{ 111 "1.2.4", 112 "1.2.3", 113 "1.2.1", 114 } 115 116 if len(versions) != len(expected) { 117 t.Fatalf("Received wrong number of versions. expected: %q, got: %q", expected, versions) 118 } 119 120 for i, v := range versions { 121 if v.String() != expected[i] { 122 t.Fatalf("incorrect version: %q, expected %q", v, expected[i]) 123 } 124 } 125 } 126 127 func TestCheckProtocolVersions(t *testing.T) { 128 if checkPlugin(providerURL("test", VersionStr("1.2.3").MustParse().String()), 4) { 129 t.Fatal("protocol version 4 is not compatible") 130 } 131 132 if !checkPlugin(providerURL("test", VersionStr("1.2.3").MustParse().String()), 3) { 133 t.Fatal("protocol version 3 should be compatible") 134 } 135 } 136 137 func TestProviderInstallerGet(t *testing.T) { 138 tmpDir, err := ioutil.TempDir("", "tf-plugin") 139 if err != nil { 140 t.Fatal(err) 141 } 142 143 defer os.RemoveAll(tmpDir) 144 145 // attempt to use an incompatible protocol version 146 i := &ProviderInstaller{ 147 Dir: tmpDir, 148 PluginProtocolVersion: 5, 149 SkipVerify: true, 150 } 151 _, err = i.Get("test", AllVersions) 152 if err != ErrorNoVersionCompatible { 153 t.Fatal("want error for incompatible version") 154 } 155 156 i = &ProviderInstaller{ 157 Dir: tmpDir, 158 PluginProtocolVersion: 3, 159 SkipVerify: true, 160 } 161 162 { 163 _, err := i.Get("test", ConstraintStr(">9.0.0").MustParse()) 164 if err != ErrorNoSuitableVersion { 165 t.Fatal("want error for mismatching constraints") 166 } 167 } 168 169 { 170 _, err := i.Get("nonexist", AllVersions) 171 if err != ErrorNoSuchProvider { 172 t.Fatal("want error for no such provider") 173 } 174 } 175 176 gotMeta, err := i.Get("test", AllVersions) 177 if err != nil { 178 t.Fatal(err) 179 } 180 181 // we should have version 1.2.3 182 dest := filepath.Join(tmpDir, "terraform-provider-test_v1.2.3_x3") 183 184 wantMeta := PluginMeta{ 185 Name: "test", 186 Version: VersionStr("1.2.3"), 187 Path: dest, 188 } 189 if !reflect.DeepEqual(gotMeta, wantMeta) { 190 t.Errorf("wrong result meta\ngot: %#v\nwant: %#v", gotMeta, wantMeta) 191 } 192 193 f, err := ioutil.ReadFile(dest) 194 if err != nil { 195 t.Fatal(err) 196 } 197 198 // provider should have been unzipped 199 if string(f) != testProviderFile { 200 t.Fatalf("test provider contains: %q", f) 201 } 202 203 } 204 205 func TestProviderInstallerPurgeUnused(t *testing.T) { 206 tmpDir, err := ioutil.TempDir("", "tf-plugin") 207 if err != nil { 208 t.Fatal(err) 209 } 210 211 defer os.RemoveAll(tmpDir) 212 213 unwantedPath := filepath.Join(tmpDir, "terraform-provider-test_v0.0.1_x2") 214 wantedPath := filepath.Join(tmpDir, "terraform-provider-test_v1.2.3_x3") 215 216 f, err := os.Create(unwantedPath) 217 if err != nil { 218 t.Fatal(err) 219 } 220 f.Close() 221 f, err = os.Create(wantedPath) 222 if err != nil { 223 t.Fatal(err) 224 } 225 f.Close() 226 227 i := &ProviderInstaller{ 228 Dir: tmpDir, 229 PluginProtocolVersion: 3, 230 SkipVerify: true, 231 } 232 purged, err := i.PurgeUnused(map[string]PluginMeta{ 233 "test": PluginMeta{ 234 Name: "test", 235 Version: VersionStr("1.2.3"), 236 Path: wantedPath, 237 }, 238 }) 239 if err != nil { 240 t.Fatal(err) 241 } 242 243 if got, want := purged.Count(), 1; got != want { 244 t.Errorf("wrong purged count %d; want %d", got, want) 245 } 246 if got, want := purged.Newest().Path, unwantedPath; got != want { 247 t.Errorf("wrong purged path %s; want %s", got, want) 248 } 249 250 files, err := ioutil.ReadDir(tmpDir) 251 if err != nil { 252 t.Fatal(err) 253 } 254 255 gotFilenames := make([]string, len(files)) 256 for i, info := range files { 257 gotFilenames[i] = info.Name() 258 } 259 wantFilenames := []string{"terraform-provider-test_v1.2.3_x3"} 260 261 if !reflect.DeepEqual(gotFilenames, wantFilenames) { 262 t.Errorf("wrong filenames after purge\ngot: %#v\nwant: %#v", gotFilenames, wantFilenames) 263 } 264 } 265 266 // Test fetching a provider's checksum file while verifying its signature. 267 func TestProviderChecksum(t *testing.T) { 268 // we only need the checksum, as getter is doing the actual file comparison. 269 sha256sum, err := getProviderChecksum("template", "0.1.0") 270 if err != nil { 271 t.Fatal(err) 272 } 273 274 // get the expected checksum for our os/arch 275 sumData, err := ioutil.ReadFile("testdata/terraform-provider-template_0.1.0_SHA256SUMS") 276 if err != nil { 277 t.Fatal(err) 278 } 279 280 expected := checksumForFile(sumData, providerFileName("template", "0.1.0")) 281 282 if sha256sum != expected { 283 t.Fatalf("expected: %s\ngot %s\n", sha256sum, expected) 284 } 285 } 286 287 // Test fetching a provider's checksum file witha bad signature 288 func TestProviderChecksumBadSignature(t *testing.T) { 289 // we only need the checksum, as getter is doing the actual file comparison. 290 sha256sum, err := getProviderChecksum("badsig", "0.1.0") 291 if err == nil { 292 t.Fatal("expcted error") 293 } 294 295 if !strings.Contains(err.Error(), "signature") { 296 t.Fatal("expected signature error, got:", err) 297 } 298 299 if sha256sum != "" { 300 t.Fatal("expected no checksum, got:", sha256sum) 301 } 302 } 303 304 const versionList = `<!DOCTYPE html> 305 <html> 306 <body> 307 <ul> 308 <li> 309 <a href="../">../</a> 310 </li> 311 <li> 312 <a href="/terraform-provider-test/1.2.3/">terraform-provider-test_1.2.3</a> 313 </li> 314 <li> 315 <a href="/terraform-provider-test/1.2.1/">terraform-provider-test_1.2.1</a> 316 </li> 317 <li> 318 <a href="/terraform-provider-test/1.2.4/">terraform-provider-test_1.2.4</a> 319 </li> 320 </ul> 321 <footer> 322 Proudly fronted by <a href="https://fastly.com/?utm_source=hashicorp" target="_TOP">Fastly</a> 323 </footer> 324 </body> 325 </html> 326 `