From 9e5e7238553d0e9fc590ccb7ec40f27837d879f8 Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Tue, 9 Apr 2019 13:04:04 +0800 Subject: [PATCH] Add unit test cases for Harbor adapter Add unit test cases for Harbor adapter Signed-off-by: Wenkai Yin --- src/replication/ng/adapter/harbor/adapter.go | 2 - .../ng/adapter/harbor/adapter_test.go | 145 ++++++++++++++++ .../ng/adapter/harbor/chart_registry_test.go | 156 ++++++++++++++++++ .../ng/adapter/harbor/image_registry_test.go | 95 +++++++++++ src/replication/ng/model/registry.go | 2 +- 5 files changed, 397 insertions(+), 3 deletions(-) create mode 100644 src/replication/ng/adapter/harbor/adapter_test.go create mode 100644 src/replication/ng/adapter/harbor/chart_registry_test.go create mode 100644 src/replication/ng/adapter/harbor/image_registry_test.go diff --git a/src/replication/ng/adapter/harbor/adapter.go b/src/replication/ng/adapter/harbor/adapter.go index 5c6d6d2c2..54dfd805b 100644 --- a/src/replication/ng/adapter/harbor/adapter.go +++ b/src/replication/ng/adapter/harbor/adapter.go @@ -28,8 +28,6 @@ import ( "github.com/goharbor/harbor/src/replication/ng/util" ) -// TODO add UT - func init() { if err := adp.RegisterFactory(model.RegistryTypeHarbor, func(registry *model.Registry) (adp.Adapter, error) { return newAdapter(registry), nil diff --git a/src/replication/ng/adapter/harbor/adapter_test.go b/src/replication/ng/adapter/harbor/adapter_test.go new file mode 100644 index 000000000..716a7005d --- /dev/null +++ b/src/replication/ng/adapter/harbor/adapter_test.go @@ -0,0 +1,145 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package harbor + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/stretchr/testify/require" + + "github.com/goharbor/harbor/src/common/utils/test" + "github.com/goharbor/harbor/src/replication/ng/model" +) + +func TestInfo(t *testing.T) { + // chart museum enabled + server := test.NewServer(&test.RequestHandlerMapping{ + Method: http.MethodGet, + Pattern: "/api/systeminfo", + Handler: func(w http.ResponseWriter, r *http.Request) { + data := `{"with_chartmuseum":true}` + w.Write([]byte(data)) + }, + }) + registry := &model.Registry{ + URL: server.URL, + } + adapter := newAdapter(registry) + info, err := adapter.Info() + require.Nil(t, err) + assert.Equal(t, model.RegistryTypeHarbor, info.Type) + assert.Equal(t, 3, len(info.SupportedResourceFilters)) + assert.Equal(t, 3, len(info.SupportedTriggers)) + assert.Equal(t, 2, len(info.SupportedResourceTypes)) + assert.Equal(t, model.ResourceTypeRepository, info.SupportedResourceTypes[0]) + assert.Equal(t, model.ResourceTypeChart, info.SupportedResourceTypes[1]) + server.Close() + + // chart museum disabled + server = test.NewServer(&test.RequestHandlerMapping{ + Method: http.MethodGet, + Pattern: "/api/systeminfo", + Handler: func(w http.ResponseWriter, r *http.Request) { + data := `{"with_chartmuseum":false}` + w.Write([]byte(data)) + }, + }) + registry = &model.Registry{ + URL: server.URL, + } + adapter = newAdapter(registry) + info, err = adapter.Info() + require.Nil(t, err) + assert.Equal(t, model.RegistryTypeHarbor, info.Type) + assert.Equal(t, 3, len(info.SupportedResourceFilters)) + assert.Equal(t, 3, len(info.SupportedTriggers)) + assert.Equal(t, 1, len(info.SupportedResourceTypes)) + assert.Equal(t, model.ResourceTypeRepository, info.SupportedResourceTypes[0]) + server.Close() +} + +func TestListNamespaces(t *testing.T) { + // TODO +} + +func TestCreateNamespace(t *testing.T) { + // project doesn't exist + server := test.NewServer(&test.RequestHandlerMapping{ + Method: http.MethodPost, + Pattern: "/api/projects", + Handler: func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusCreated) + }, + }) + registry := &model.Registry{ + URL: server.URL, + } + adapter := newAdapter(registry) + err := adapter.CreateNamespace(&model.Namespace{ + Name: "library", + }) + require.Nil(t, err) + server.Close() + + // project already exists + server = test.NewServer(&test.RequestHandlerMapping{ + Method: http.MethodPost, + Pattern: "/api/projects", + Handler: func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusConflict) + }, + }) + registry = &model.Registry{ + URL: server.URL, + } + adapter = newAdapter(registry) + err = adapter.CreateNamespace(&model.Namespace{ + Name: "library", + }) + require.Nil(t, err) + server.Close() +} + +func TestGetNamespace(t *testing.T) { + // project exists + server := test.NewServer(&test.RequestHandlerMapping{ + Method: http.MethodGet, + Pattern: "/api/projects", + Handler: func(w http.ResponseWriter, r *http.Request) { + data := `[{ + "name": "library", + "metadata": {"public":true} + + }]` + w.Write([]byte(data)) + }, + }) + defer server.Close() + registry := &model.Registry{ + URL: server.URL, + } + adapter := newAdapter(registry) + namespace, err := adapter.GetNamespace("library") + require.Nil(t, err) + assert.Equal(t, "library", namespace.Name) + assert.True(t, namespace.Metadata["public"].(bool)) + + // project doesn't exists + namespace, err = adapter.GetNamespace("test") + require.NotNil(t, err) +} diff --git a/src/replication/ng/adapter/harbor/chart_registry_test.go b/src/replication/ng/adapter/harbor/chart_registry_test.go new file mode 100644 index 000000000..2c7637b51 --- /dev/null +++ b/src/replication/ng/adapter/harbor/chart_registry_test.go @@ -0,0 +1,156 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package harbor + +import ( + "bytes" + "net/http" + "testing" + + "github.com/goharbor/harbor/src/common/utils/test" + "github.com/goharbor/harbor/src/replication/ng/model" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestFetchCharts(t *testing.T) { + server := test.NewServer([]*test.RequestHandlerMapping{ + { + Method: http.MethodGet, + Pattern: "/api/chartrepo/library/charts/harbor", + Handler: func(w http.ResponseWriter, r *http.Request) { + data := `[{ + "name": "harbor", + "version":"1.0" + },{ + "name": "harbor", + "version":"2.0" + }]` + w.Write([]byte(data)) + }, + }, + { + Method: http.MethodGet, + Pattern: "/api/chartrepo/library/charts", + Handler: func(w http.ResponseWriter, r *http.Request) { + data := `[{ + "name": "harbor" + }]` + w.Write([]byte(data)) + }, + }, + }...) + defer server.Close() + registry := &model.Registry{ + URL: server.URL, + } + adapter := newAdapter(registry) + resources, err := adapter.FetchCharts([]string{"library"}, nil) + require.Nil(t, err) + assert.Equal(t, 2, len(resources)) + assert.Equal(t, model.ResourceTypeChart, resources[0].Type) + assert.Equal(t, "library/harbor", resources[0].Metadata.Name) + assert.Equal(t, "library", resources[0].Metadata.Namespace) + assert.Equal(t, 1, len(resources[0].Metadata.Vtags)) + assert.Equal(t, "1.0", resources[0].Metadata.Vtags[0]) +} + +func TestChartExist(t *testing.T) { + server := test.NewServer(&test.RequestHandlerMapping{ + Method: http.MethodGet, + Pattern: "/api/chartrepo/library/charts/harbor/1.0", + Handler: func(w http.ResponseWriter, r *http.Request) { + data := `{ + "metadata": { + "urls":["http://127.0.0.1/charts"] + } + }` + w.Write([]byte(data)) + }, + }) + defer server.Close() + registry := &model.Registry{ + URL: server.URL, + } + adapter := newAdapter(registry) + exist, err := adapter.ChartExist("library/harbor", "1.0") + require.Nil(t, err) + require.True(t, exist) +} + +func TestDownloadChart(t *testing.T) { + server := test.NewServer([]*test.RequestHandlerMapping{ + { + Method: http.MethodGet, + Pattern: "/api/chartrepo/library/charts/harbor/1.0", + Handler: func(w http.ResponseWriter, r *http.Request) { + data := `{ + "metadata": { + "urls":["charts/harbor-1.0.tgz"] + } + }` + w.Write([]byte(data)) + }, + }, + { + Method: http.MethodGet, + Pattern: "/api/chartrepo/library/charts/harbor-1.0.tgz", + Handler: func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + }, + }, + }...) + defer server.Close() + registry := &model.Registry{ + URL: server.URL, + } + adapter := newAdapter(registry) + _, err := adapter.DownloadChart("library/harbor", "1.0") + require.Nil(t, err) +} + +func TestUploadChart(t *testing.T) { + server := test.NewServer(&test.RequestHandlerMapping{ + Method: http.MethodPost, + Pattern: "/api/chartrepo/library/charts", + Handler: func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + }, + }) + defer server.Close() + registry := &model.Registry{ + URL: server.URL, + } + adapter := newAdapter(registry) + err := adapter.UploadChart("library/harbor", "1.0", bytes.NewBuffer(nil)) + require.Nil(t, err) +} + +func TestDeleteChart(t *testing.T) { + server := test.NewServer(&test.RequestHandlerMapping{ + Method: http.MethodDelete, + Pattern: "/api/chartrepo/library/charts/harbor/1.0", + Handler: func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + }, + }) + defer server.Close() + registry := &model.Registry{ + URL: server.URL, + } + adapter := newAdapter(registry) + err := adapter.DeleteChart("library/harbor", "1.0") + require.Nil(t, err) +} diff --git a/src/replication/ng/adapter/harbor/image_registry_test.go b/src/replication/ng/adapter/harbor/image_registry_test.go new file mode 100644 index 000000000..37d8d3680 --- /dev/null +++ b/src/replication/ng/adapter/harbor/image_registry_test.go @@ -0,0 +1,95 @@ +// Copyright Project Harbor Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package harbor + +import ( + "net/http" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/goharbor/harbor/src/common/utils/test" + "github.com/goharbor/harbor/src/replication/ng/model" + "github.com/stretchr/testify/require" +) + +func TestFetchImages(t *testing.T) { + server := test.NewServer([]*test.RequestHandlerMapping{ + { + Method: http.MethodGet, + Pattern: "/api/projects", + Handler: func(w http.ResponseWriter, r *http.Request) { + data := `[{ + "name": "library", + "metadata": {"public":true} + + }]` + w.Write([]byte(data)) + }, + }, + { + Method: http.MethodGet, + Pattern: "/api/repositories/library/hello-world/tags", + Handler: func(w http.ResponseWriter, r *http.Request) { + data := `[{ + "name": "1.0" + },{ + "name": "2.0" + }]` + w.Write([]byte(data)) + }, + }, + { + Method: http.MethodGet, + Pattern: "/api/repositories", + Handler: func(w http.ResponseWriter, r *http.Request) { + data := `[{ + "name": "library/hello-world" + }]` + w.Write([]byte(data)) + }, + }, + }...) + defer server.Close() + registry := &model.Registry{ + URL: server.URL, + } + adapter := newAdapter(registry) + resources, err := adapter.FetchImages([]string{"library"}, nil) + require.Nil(t, err) + assert.Equal(t, 1, len(resources)) + assert.Equal(t, model.ResourceTypeRepository, resources[0].Type) + assert.Equal(t, "library/hello-world", resources[0].Metadata.Name) + assert.Equal(t, "library", resources[0].Metadata.Namespace) + assert.Equal(t, 2, len(resources[0].Metadata.Vtags)) + assert.Equal(t, "1.0", resources[0].Metadata.Vtags[0]) + assert.Equal(t, "2.0", resources[0].Metadata.Vtags[1]) +} + +func TestDeleteManifest(t *testing.T) { + server := test.NewServer(&test.RequestHandlerMapping{ + Method: http.MethodDelete, + Pattern: "/api/repositories/library/hello-world/tags/1.0", + Handler: func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusOK) + }}) + defer server.Close() + registry := &model.Registry{ + URL: server.URL, + } + adapter := newAdapter(registry) + err := adapter.DeleteManifest("library/hello-world", "1.0") + require.Nil(t, err) +} diff --git a/src/replication/ng/model/registry.go b/src/replication/ng/model/registry.go index eca9e03b5..2e53500e6 100644 --- a/src/replication/ng/model/registry.go +++ b/src/replication/ng/model/registry.go @@ -23,7 +23,7 @@ import ( // const definition const ( // RegistryTypeHarbor indicates registry type harbor - RegistryTypeHarbor = "harbor" + RegistryTypeHarbor RegistryType = "harbor" FilterStyleTypeText = "input" FilterStyleTypeRadio = "radio"