From 59089ef46107c306495f46d6a051e543b41ab4f0 Mon Sep 17 00:00:00 2001 From: James Bardin Date: Thu, 21 Sep 2017 15:32:55 -0500 Subject: [PATCH] add test loading an archive with `//*` subdir The registry uses the `//*` subdir format to unpack github archives. Add a test to cover this pattern. --- config/module/get_test.go | 90 ++++++++++++++++-- .../test-fixtures/registry-tar-subdir/foo.tgz | Bin 0 -> 236 bytes .../test-fixtures/registry-tar-subdir/main.tf | 4 + config/module/tree_test.go | 7 +- 4 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 config/module/test-fixtures/registry-tar-subdir/foo.tgz create mode 100644 config/module/test-fixtures/registry-tar-subdir/main.tf diff --git a/config/module/get_test.go b/config/module/get_test.go index a24ea4a81..bdf48bdf3 100644 --- a/config/module/get_test.go +++ b/config/module/get_test.go @@ -16,11 +16,26 @@ import ( version "github.com/hashicorp/go-version" ) -// map of module names and version for test module. -// only one version for now, as we only lookup latest from the registry -var testMods = map[string]string{ - "registry/foo/bar": "0.2.3", - "registry/foo/baz": "1.10.0", +// Map of module names and location of test modules. +// Only one version for now, as we only lookup latest from the registry. +type testMod struct { + location string + version string +} + +var testMods = map[string]testMod{ + "registry/foo/bar": { + location: "file:///download/registry/foo/bar/0.2.3//*?archive=tar.gz", + version: "0.2.3", + }, + "registry/foo/baz": { + location: "file:///download/registry/foo/baz/1.10.0//*?archive=tar.gz", + version: "1.10.0", + }, + "registry/local/sub": { + location: "test-fixtures/registry-tar-subdir/foo.tgz//*?archive=tar.gz", + version: "0.1.2", + }, } func latestVersion(versions []string) string { @@ -56,13 +71,19 @@ func mockRegistry() *httptest.Server { return } - version, ok := testMods[matches[1]] + mod, ok := testMods[matches[1]] if !ok { w.WriteHeader(http.StatusNotFound) return } - location := fmt.Sprintf("%s/download/%s/%s", server.URL, matches[1], version) + location := mod.location + if !strings.HasPrefix(location, "file:///") { + // we can't use filepath.Abs because it will clean `//` + wd, _ := os.Getwd() + location = fmt.Sprintf("file://%s/%s", wd, location) + } + w.Header().Set(xTerraformGet, location) w.WriteHeader(http.StatusNoContent) // no body @@ -90,12 +111,12 @@ func TestDetectRegistry(t *testing.T) { }{ { source: "registry/foo/bar", - location: "download/registry/foo/bar/0.2.3", + location: testMods["registry/foo/bar"].location, found: true, }, { source: "registry/foo/baz", - location: "download/registry/foo/baz/1.10.0", + location: testMods["registry/foo/baz"].location, found: true, }, // this should not be found, but not stop detection @@ -177,7 +198,7 @@ func TestDetectors(t *testing.T) { }{ { source: "registry/foo/bar", - location: "download/registry/foo/bar/0.2.3", + location: "file:///download/registry/foo/bar/0.2.3//*?archive=tar.gz", }, // this should not be found, but not stop detection { @@ -248,6 +269,55 @@ func TestDetectors(t *testing.T) { } } +// GitHub archives always contain the module source in a single subdirectory, +// so the registry will return a path with with a `//*` suffix. We need to make +// sure this doesn't intefere with our internal handling of `//` subdir. +func TestRegistryGitHubArchive(t *testing.T) { + server := mockRegistry() + defer server.Close() + + regDetector := ®istryDetector{ + api: server.URL + "/v1/modules/", + client: server.Client(), + } + + origDetectors := detectors + defer func() { + detectors = origDetectors + }() + + detectors = []getter.Detector{ + new(getter.GitHubDetector), + new(getter.BitBucketDetector), + new(getter.S3Detector), + new(localDetector), + regDetector, + } + + storage := testStorage(t) + tree := NewTree("", testConfig(t, "registry-tar-subdir")) + + if err := tree.Load(storage, GetModeGet); err != nil { + t.Fatalf("err: %s", err) + } + + if !tree.Loaded() { + t.Fatal("should be loaded") + } + + // This should no longer error + if err := tree.Load(storage, GetModeNone); err != nil { + t.Fatalf("err: %s", err) + } + + actual := strings.TrimSpace(tree.String()) + expected := strings.TrimSpace(treeLoadSubdirStr) + if actual != expected { + t.Fatalf("got: \n\n%s\nexpected: \n\n%s", actual, expected) + } + +} + func TestAccRegistryDiscover(t *testing.T) { if os.Getenv("TF_ACC") == "" { t.Skip("skipping ACC test") diff --git a/config/module/test-fixtures/registry-tar-subdir/foo.tgz b/config/module/test-fixtures/registry-tar-subdir/foo.tgz new file mode 100644 index 0000000000000000000000000000000000000000..7ea938b7b3d689b9463009f22ee76ab1f6f8b47e GIT binary patch literal 236 zcmV9?wF=3 z0z?2IgAnhtnT-|Aw)=O_#bcYz%y%wxTz9-gm_R z5zJ=tx9}=|Q*)VUqJCcZ=lSmrtMP6vMV!8n`&^>oF!sx}+(=PAErue0$bY*_r1HG~ m)9ru{-~XHaZ$Ulp9{>OV000000001h&w2zDNG!GhC;$MV9(o@D literal 0 HcmV?d00001 diff --git a/config/module/test-fixtures/registry-tar-subdir/main.tf b/config/module/test-fixtures/registry-tar-subdir/main.tf new file mode 100644 index 000000000..660f23764 --- /dev/null +++ b/config/module/test-fixtures/registry-tar-subdir/main.tf @@ -0,0 +1,4 @@ +module "foo" { + // the mock test registry will redirect this to the local tar file + source = "registry/local/sub" +} diff --git a/config/module/tree_test.go b/config/module/tree_test.go index a08dc2cd4..444c8066f 100644 --- a/config/module/tree_test.go +++ b/config/module/tree_test.go @@ -212,7 +212,12 @@ func TestTreeLoad_subdir(t *testing.T) { fixtures := []string{ "basic-subdir", "basic-tar-subdir", - "tar-sbudir-to-parent", + + // Passing a subpath to go getter extracts only this subpath. The old + // internal code would keep the entire directory structure, allowing a + // top-level module to reference others through its parent directory. + // TODO: this can be removed as a breaking change in a major release. + "tar-subdir-to-parent", } for _, tc := range fixtures {