144 lines
3.0 KiB
Go
144 lines
3.0 KiB
Go
|
package module
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"net/http"
|
||
|
"net/http/httptest"
|
||
|
"regexp"
|
||
|
"sort"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
|
||
|
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",
|
||
|
}
|
||
|
|
||
|
func latestVersion(versions []string) string {
|
||
|
var col version.Collection
|
||
|
for _, v := range versions {
|
||
|
ver, err := version.NewVersion(v)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
col = append(col, ver)
|
||
|
}
|
||
|
|
||
|
sort.Sort(col)
|
||
|
return col[len(col)-1].String()
|
||
|
}
|
||
|
|
||
|
// Just enough like a registry to exercise our code.
|
||
|
// Returns the location of the latest version
|
||
|
func mockRegistry() *httptest.Server {
|
||
|
mux := http.NewServeMux()
|
||
|
server := httptest.NewServer(mux)
|
||
|
|
||
|
mux.Handle("/v1/modules/",
|
||
|
http.StripPrefix("/v1/modules/", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
p := strings.TrimLeft(r.URL.Path, "/")
|
||
|
// handle download request
|
||
|
download := regexp.MustCompile(`^(\w+/\w+/\w+)/download$`)
|
||
|
|
||
|
// download lookup
|
||
|
matches := download.FindStringSubmatch(p)
|
||
|
if len(matches) != 2 {
|
||
|
w.WriteHeader(http.StatusBadRequest)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
version, ok := testMods[matches[1]]
|
||
|
if !ok {
|
||
|
w.WriteHeader(http.StatusNotFound)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
location := fmt.Sprintf("%s/download/%s/%s", server.URL, matches[1], version)
|
||
|
w.Header().Set(xTerraformGet, location)
|
||
|
w.WriteHeader(http.StatusNoContent)
|
||
|
// no body
|
||
|
return
|
||
|
})),
|
||
|
)
|
||
|
|
||
|
return server
|
||
|
}
|
||
|
|
||
|
func TestDetectRegistry(t *testing.T) {
|
||
|
server := mockRegistry()
|
||
|
defer server.Close()
|
||
|
|
||
|
detector := registryDetector{
|
||
|
api: server.URL + "/v1/modules/",
|
||
|
client: server.Client(),
|
||
|
}
|
||
|
|
||
|
for _, tc := range []struct {
|
||
|
module string
|
||
|
location string
|
||
|
found bool
|
||
|
err bool
|
||
|
}{
|
||
|
{
|
||
|
module: "registry/foo/bar",
|
||
|
location: "download/registry/foo/bar/0.2.3",
|
||
|
found: true,
|
||
|
},
|
||
|
{
|
||
|
module: "registry/foo/baz",
|
||
|
location: "download/registry/foo/baz/1.10.0",
|
||
|
found: true,
|
||
|
},
|
||
|
// this should not be found, but not stop detection
|
||
|
{
|
||
|
module: "registry/foo/notfound",
|
||
|
found: false,
|
||
|
},
|
||
|
|
||
|
// a full url should not be detected
|
||
|
{
|
||
|
module: "http://example.com/registry/foo/notfound",
|
||
|
found: false,
|
||
|
},
|
||
|
|
||
|
// paths should not be detected
|
||
|
{
|
||
|
module: "./local/foo/notfound",
|
||
|
found: false,
|
||
|
},
|
||
|
{
|
||
|
module: "/local/foo/notfound",
|
||
|
found: false,
|
||
|
},
|
||
|
|
||
|
// wrong number of parts can't be regisry IDs
|
||
|
{
|
||
|
module: "something/registry/foo/notfound",
|
||
|
found: false,
|
||
|
},
|
||
|
} {
|
||
|
|
||
|
t.Run(tc.module, func(t *testing.T) {
|
||
|
loc, ok, err := detector.Detect(tc.module, "")
|
||
|
if (err == nil) == tc.err {
|
||
|
t.Fatalf("expected error? %t; got error :%v", tc.err, err)
|
||
|
}
|
||
|
|
||
|
if ok != tc.found {
|
||
|
t.Fatalf("expected OK == %t", tc.found)
|
||
|
}
|
||
|
|
||
|
loc = strings.TrimPrefix(loc, server.URL+"/")
|
||
|
if strings.TrimPrefix(loc, server.URL) != tc.location {
|
||
|
t.Fatalf("expected location: %q, got %q", tc.location, loc)
|
||
|
}
|
||
|
})
|
||
|
|
||
|
}
|
||
|
}
|