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  `