github.com/paybyphone/terraform@v0.9.5-0.20170613192930-9706042ddd51/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 // returns a 200 for a valid provider url, using the patch number for the 26 // plugin protocol version. 27 func testHandler(w http.ResponseWriter, r *http.Request) { 28 if r.URL.Path == "/terraform-provider-test/" { 29 testListingHandler(w, r) 30 return 31 } 32 33 parts := strings.Split(r.URL.Path, "/") 34 if len(parts) != 4 { 35 http.Error(w, "not found", http.StatusNotFound) 36 return 37 } 38 39 filename := parts[3] 40 41 reg := regexp.MustCompile(`(terraform-provider-test)_(\d).(\d).(\d)_([^_]+)_([^._]+).zip`) 42 43 fileParts := reg.FindStringSubmatch(filename) 44 if len(fileParts) != 7 { 45 http.Error(w, "invalid provider: "+filename, http.StatusNotFound) 46 return 47 } 48 49 w.Header().Set(protocolVersionHeader, fileParts[4]) 50 51 // write a dummy file 52 z := zip.NewWriter(w) 53 fn := fmt.Sprintf("%s_v%s.%s.%s_x%s", fileParts[1], fileParts[2], fileParts[3], fileParts[4], fileParts[4]) 54 f, err := z.Create(fn) 55 if err != nil { 56 panic(err) 57 } 58 io.WriteString(f, testProviderFile) 59 z.Close() 60 } 61 62 func testReleaseServer() *httptest.Server { 63 handler := http.NewServeMux() 64 handler.HandleFunc("/terraform-provider-test/", testHandler) 65 66 return httptest.NewServer(handler) 67 } 68 69 func TestMain(m *testing.M) { 70 server := testReleaseServer() 71 releaseHost = server.URL 72 73 os.Exit(m.Run()) 74 } 75 76 func TestVersionListing(t *testing.T) { 77 versions, err := listProviderVersions("test") 78 if err != nil { 79 t.Fatal(err) 80 } 81 82 Versions(versions).Sort() 83 84 expected := []string{ 85 "1.2.4", 86 "1.2.3", 87 "1.2.1", 88 } 89 90 if len(versions) != len(expected) { 91 t.Fatalf("Received wrong number of versions. expected: %q, got: %q", expected, versions) 92 } 93 94 for i, v := range versions { 95 if v.String() != expected[i] { 96 t.Fatalf("incorrect version: %q, expected %q", v, expected[i]) 97 } 98 } 99 } 100 101 func TestCheckProtocolVersions(t *testing.T) { 102 if checkPlugin(providerURL("test", VersionStr("1.2.3").MustParse().String()), 4) { 103 t.Fatal("protocol version 4 is not compatible") 104 } 105 106 if !checkPlugin(providerURL("test", VersionStr("1.2.3").MustParse().String()), 3) { 107 t.Fatal("protocol version 3 should be compatible") 108 } 109 } 110 111 func TestProviderInstallerGet(t *testing.T) { 112 tmpDir, err := ioutil.TempDir("", "tf-plugin") 113 if err != nil { 114 t.Fatal(err) 115 } 116 117 defer os.RemoveAll(tmpDir) 118 119 // attempt to use an incompatible protocol version 120 i := &ProviderInstaller{ 121 Dir: tmpDir, 122 123 PluginProtocolVersion: 5, 124 } 125 _, err = i.Get("test", AllVersions) 126 if err == nil { 127 t.Fatal("want error for incompatible version") 128 } 129 130 i = &ProviderInstaller{ 131 Dir: tmpDir, 132 133 PluginProtocolVersion: 3, 134 } 135 gotMeta, err := i.Get("test", AllVersions) 136 if err != nil { 137 t.Fatal(err) 138 } 139 140 // we should have version 1.2.3 141 dest := filepath.Join(tmpDir, "terraform-provider-test_v1.2.3_x3") 142 143 wantMeta := PluginMeta{ 144 Name: "test", 145 Version: VersionStr("1.2.3"), 146 Path: dest, 147 } 148 if !reflect.DeepEqual(gotMeta, wantMeta) { 149 t.Errorf("wrong result meta\ngot: %#v\nwant: %#v", gotMeta, wantMeta) 150 } 151 152 f, err := ioutil.ReadFile(dest) 153 if err != nil { 154 t.Fatal(err) 155 } 156 157 // provider should have been unzipped 158 if string(f) != testProviderFile { 159 t.Fatalf("test provider contains: %q", f) 160 } 161 162 } 163 164 func TestProviderInstallerPurgeUnused(t *testing.T) { 165 tmpDir, err := ioutil.TempDir("", "tf-plugin") 166 if err != nil { 167 t.Fatal(err) 168 } 169 170 defer os.RemoveAll(tmpDir) 171 172 unwantedPath := filepath.Join(tmpDir, "terraform-provider-test_v0.0.1_x2") 173 wantedPath := filepath.Join(tmpDir, "terraform-provider-test_v1.2.3_x3") 174 175 f, err := os.Create(unwantedPath) 176 if err != nil { 177 t.Fatal(err) 178 } 179 f.Close() 180 f, err = os.Create(wantedPath) 181 if err != nil { 182 t.Fatal(err) 183 } 184 f.Close() 185 186 i := &ProviderInstaller{ 187 Dir: tmpDir, 188 189 PluginProtocolVersion: 3, 190 } 191 purged, err := i.PurgeUnused(map[string]PluginMeta{ 192 "test": PluginMeta{ 193 Name: "test", 194 Version: VersionStr("1.2.3"), 195 Path: wantedPath, 196 }, 197 }) 198 if err != nil { 199 t.Fatal(err) 200 } 201 202 if got, want := purged.Count(), 1; got != want { 203 t.Errorf("wrong purged count %d; want %d", got, want) 204 } 205 if got, want := purged.Newest().Path, unwantedPath; got != want { 206 t.Errorf("wrong purged path %s; want %s", got, want) 207 } 208 209 files, err := ioutil.ReadDir(tmpDir) 210 if err != nil { 211 t.Fatal(err) 212 } 213 214 gotFilenames := make([]string, len(files)) 215 for i, info := range files { 216 gotFilenames[i] = info.Name() 217 } 218 wantFilenames := []string{"terraform-provider-test_v1.2.3_x3"} 219 220 if !reflect.DeepEqual(gotFilenames, wantFilenames) { 221 t.Errorf("wrong filenames after purge\ngot: %#v\nwant: %#v", gotFilenames, wantFilenames) 222 } 223 } 224 225 const versionList = `<!DOCTYPE html> 226 <html> 227 <body> 228 <ul> 229 <li> 230 <a href="../">../</a> 231 </li> 232 <li> 233 <a href="/terraform-provider-test/1.2.3/">terraform-provider-test_1.2.3</a> 234 </li> 235 <li> 236 <a href="/terraform-provider-test/1.2.1/">terraform-provider-test_1.2.1</a> 237 </li> 238 <li> 239 <a href="/terraform-provider-test/1.2.4/">terraform-provider-test_1.2.4</a> 240 </li> 241 </ul> 242 <footer> 243 Proudly fronted by <a href="https://fastly.com/?utm_source=hashicorp" target="_TOP">Fastly</a> 244 </footer> 245 </body> 246 </html> 247 `