diff --git a/Makefile b/Makefile index a166fb7..10c4fbd 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ test-build: test build test: - go test ./... + go test -race ./... build: go build -o bin/ ./... diff --git a/pkg/registry/http.go b/pkg/registry/http.go index 1623f66..3126114 100644 --- a/pkg/registry/http.go +++ b/pkg/registry/http.go @@ -8,9 +8,13 @@ import ( "time" ) +type httpGetter interface { + Get(url string) (resp *http.Response, err error) +} + // SchemaRegistry is a file repository (local or remote) that contains JSON schemas for Kubernetes resources type SchemaRegistry struct { - c *http.Client + c httpGetter schemaPathTemplate string strict bool } diff --git a/pkg/registry/http_test.go b/pkg/registry/http_test.go new file mode 100644 index 0000000..45a7ee6 --- /dev/null +++ b/pkg/registry/http_test.go @@ -0,0 +1,101 @@ +package registry + +import ( + "bytes" + "fmt" + "io/ioutil" + "net/http" + "strings" + "testing" +) + +type mockHTTPGetter struct { + httpGet func(string) (*http.Response, error) +} + +func newMockHTTPGetter(f func(string) (*http.Response, error)) *mockHTTPGetter { + return &mockHTTPGetter{ + httpGet: f, + } +} +func (m mockHTTPGetter) Get(url string) (resp *http.Response, err error) { + return m.httpGet(url) +} + +func TestDownloadSchema(t *testing.T) { + for _, testCase := range []struct { + name string + c httpGetter + schemaPathTemplate string + strict bool + resourceKind, resourceAPIVersion, k8sversion string + expect []byte + expectErr error + }{ + { + "error when downloading", + newMockHTTPGetter(func(url string) (resp *http.Response, err error) { + return nil, fmt.Errorf("failed downloading from registry") + }), + "http://kubernetesjson.dev", + true, + "Deployment", + "v1", + "1.18.0", + nil, + fmt.Errorf("failed downloading schema at http://kubernetesjson.dev: failed downloading from registry"), + }, + { + "getting 404", + newMockHTTPGetter(func(url string) (resp *http.Response, err error) { + return &http.Response{ + StatusCode: http.StatusNotFound, + Body: ioutil.NopCloser(strings.NewReader("http response mock body")), + }, nil + }), + "http://kubernetesjson.dev", + true, + "Deployment", + "v1", + "1.18.0", + nil, + fmt.Errorf("no schema found"), + }, + { + "200", + newMockHTTPGetter(func(url string) (resp *http.Response, err error) { + return &http.Response{ + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(strings.NewReader("http response mock body")), + }, nil + }), + "http://kubernetesjson.dev", + true, + "Deployment", + "v1", + "1.18.0", + []byte("http response mock body"), + nil, + }, + } { + reg := SchemaRegistry{ + c: testCase.c, + schemaPathTemplate: testCase.schemaPathTemplate, + strict: testCase.strict, + } + + res, err := reg.DownloadSchema(testCase.resourceKind, testCase.resourceAPIVersion, testCase.k8sversion) + if err == nil || testCase.expectErr == nil { + if err != testCase.expectErr { + t.Errorf("during test '%s': expected error, got:\n%s\n%s\n", testCase.name, testCase.expectErr, err) + } + } else if err.Error() != testCase.expectErr.Error() { + t.Errorf("during test '%s': expected error, got:\n%s\n%s\n", testCase.name, testCase.expectErr, err) + } + + if bytes.Compare(res, testCase.expect) != 0 { + t.Errorf("during test '%s': expected %s, got %s", testCase.name, testCase.expect, res) + } + } + +}