mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-23 02:35:17 +01:00
Fix & UT (#16279)
1. Fix TCR Adapter namespcae check. 2. Add Chart UT. Signed-off-by: 疯魔慕薇 <kfanjian@gmail.com>
This commit is contained in:
parent
3c9fc9fa5a
commit
1c4495361b
@ -90,7 +90,7 @@ func newAdapter(registry *model.Registry) (a *adapter, err error) {
|
|||||||
|
|
||||||
// only validate registryURL.Host in non-UT scenario
|
// only validate registryURL.Host in non-UT scenario
|
||||||
if os.Getenv("UTTEST") != "true" {
|
if os.Getenv("UTTEST") != "true" {
|
||||||
if strings.Index(registryURL.Host, ".tencentcloudcr.com") < 0 {
|
if !strings.Contains(registryURL.Host, ".tencentcloudcr.com") {
|
||||||
log.Errorf("[tencent-tcr.newAdapter] errInvalidTcrEndpoint=%v", err)
|
log.Errorf("[tencent-tcr.newAdapter] errInvalidTcrEndpoint=%v", err)
|
||||||
return nil, errInvalidTcrEndpoint
|
return nil, errInvalidTcrEndpoint
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ var _ adp.ChartRegistry = &adapter{}
|
|||||||
|
|
||||||
func (a *adapter) FetchCharts(filters []*model.Filter) (resources []*model.Resource, err error) {
|
func (a *adapter) FetchCharts(filters []*model.Filter) (resources []*model.Resource, err error) {
|
||||||
log.Debugf("[tencent-tcr.FetchCharts]filters: %#v", filters)
|
log.Debugf("[tencent-tcr.FetchCharts]filters: %#v", filters)
|
||||||
// 1. list namespaces
|
// 1. list namespaces via TCR Special API
|
||||||
var nsPattern, _, _ = filterToPatterns(filters)
|
var nsPattern, _, _ = filterToPatterns(filters)
|
||||||
var nms []string
|
var nms []string
|
||||||
nms, err = a.listCandidateNamespaces(nsPattern)
|
nms, err = a.listCandidateNamespaces(nsPattern)
|
||||||
@ -50,8 +50,12 @@ func (a *adapter) FetchCharts(filters []*model.Filter) (resources []*model.Resou
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. list repositories
|
return a.fetchCharts(nms, filters)
|
||||||
for _, ns := range nms {
|
}
|
||||||
|
|
||||||
|
func (a *adapter) fetchCharts(namespaces []string, filters []*model.Filter) (resources []*model.Resource, err error) {
|
||||||
|
// 1. list repositories
|
||||||
|
for _, ns := range namespaces {
|
||||||
var url = fmt.Sprintf(chartListURL, a.registry.URL, ns)
|
var url = fmt.Sprintf(chartListURL, a.registry.URL, ns)
|
||||||
var repositories = []*model.Repository{}
|
var repositories = []*model.Repository{}
|
||||||
err = a.client.Get(url, &repositories)
|
err = a.client.Get(url, &repositories)
|
||||||
@ -70,7 +74,7 @@ func (a *adapter) FetchCharts(filters []*model.Filter) (resources []*model.Resou
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. list versions
|
// 2. list versions
|
||||||
for _, repository := range repositories {
|
for _, repository := range repositories {
|
||||||
var name = strings.SplitN(repository.Name, "/", 2)[1]
|
var name = strings.SplitN(repository.Name, "/", 2)[1]
|
||||||
var url = fmt.Sprintf(chartVersionURL, a.registry.URL, ns, name)
|
var url = fmt.Sprintf(chartVersionURL, a.registry.URL, ns, name)
|
||||||
|
172
src/pkg/reg/adapter/tencentcr/chart_registry_test.go
Normal file
172
src/pkg/reg/adapter/tencentcr/chart_registry_test.go
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
// 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 tencentcr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"net/http"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
commonhttp "github.com/goharbor/harbor/src/common/http"
|
||||||
|
"github.com/goharbor/harbor/src/common/utils/test"
|
||||||
|
"github.com/goharbor/harbor/src/pkg/reg/model"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func mockChartClient(registry *model.Registry) *adapter {
|
||||||
|
return &adapter{
|
||||||
|
registry: registry,
|
||||||
|
client: commonhttp.NewClient(
|
||||||
|
&http.Client{
|
||||||
|
Transport: commonhttp.GetHTTPTransport(commonhttp.WithInsecure(registry.Insecure)),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
var adapter = mockChartClient(&model.Registry{URL: server.URL})
|
||||||
|
|
||||||
|
// nil filter
|
||||||
|
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.Repository.Name)
|
||||||
|
assert.Equal(t, 1, len(resources[0].Metadata.Artifacts))
|
||||||
|
assert.Equal(t, "1.0", resources[0].Metadata.Artifacts[0].Tags[0])
|
||||||
|
// not nil filter
|
||||||
|
filters := []*model.Filter{
|
||||||
|
{
|
||||||
|
Type: model.FilterTypeName,
|
||||||
|
Value: "library/*",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Type: model.FilterTypeTag,
|
||||||
|
Value: "1.0",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
resources, err = adapter.fetchCharts([]string{"library"}, filters)
|
||||||
|
require.Nil(t, err)
|
||||||
|
require.Equal(t, 1, len(resources))
|
||||||
|
assert.Equal(t, model.ResourceTypeChart, resources[0].Type)
|
||||||
|
assert.Equal(t, "library/harbor", resources[0].Metadata.Repository.Name)
|
||||||
|
assert.Equal(t, 1, len(resources[0].Metadata.Artifacts))
|
||||||
|
assert.Equal(t, "1.0", resources[0].Metadata.Artifacts[0].Tags[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()
|
||||||
|
var adapter = mockChartClient(&model.Registry{URL: server.URL})
|
||||||
|
var 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: "/chartrepo/library/charts/harbor-1.0.tgz",
|
||||||
|
Handler: func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}...)
|
||||||
|
defer server.Close()
|
||||||
|
var adapter = mockChartClient(&model.Registry{URL: server.URL})
|
||||||
|
var _, 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()
|
||||||
|
var adapter = mockChartClient(&model.Registry{URL: server.URL})
|
||||||
|
var 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()
|
||||||
|
var adapter = mockChartClient(&model.Registry{URL: server.URL})
|
||||||
|
var err = adapter.DeleteChart("library/harbor", "1.0")
|
||||||
|
require.Nil(t, err)
|
||||||
|
}
|
@ -131,10 +131,18 @@ func (a *adapter) isNamespaceExist(namespace string) (exist bool, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Warningf("[tencent-tcr.PrepareForPush.isNamespaceExist] namespace=%s, total=%d", namespace, *resp.Response.TotalCount)
|
log.Warningf("[tencent-tcr.PrepareForPush.isNamespaceExist] namespace=%s, total=%d", namespace, *resp.Response.TotalCount)
|
||||||
if int(*resp.Response.TotalCount) != 1 {
|
exist = isTcrNsExist(namespace, resp.Response.NamespaceList)
|
||||||
return
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func isTcrNsExist(name string, list []*tcr.TcrNamespaceInfo) (exist bool) {
|
||||||
|
for _, ns := range list {
|
||||||
|
if *ns.Name == name {
|
||||||
|
exist = true
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exist = true
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,9 @@ package tencentcr
|
|||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common"
|
||||||
|
tcr "github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tcr/v20190924"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Test_adapter_createPrivateNamespace(t *testing.T) {
|
func Test_adapter_createPrivateNamespace(t *testing.T) {
|
||||||
@ -131,3 +134,42 @@ func Test_adapter_getImages(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Test_isTcrNsExist(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
list []*tcr.TcrNamespaceInfo
|
||||||
|
wantExist bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "not_found_any_ns", list: []*tcr.TcrNamespaceInfo{}, wantExist: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "found_one_ns", list: []*tcr.TcrNamespaceInfo{
|
||||||
|
{Name: common.StringPtr("found_one_ns")},
|
||||||
|
},
|
||||||
|
wantExist: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "found_multi_ns", list: []*tcr.TcrNamespaceInfo{
|
||||||
|
{Name: common.StringPtr("found_multi_ns")},
|
||||||
|
{Name: common.StringPtr("found_multi_ns_2")},
|
||||||
|
},
|
||||||
|
wantExist: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "found_but_not_exist", list: []*tcr.TcrNamespaceInfo{
|
||||||
|
{Name: common.StringPtr("found_multi_ns_2")},
|
||||||
|
{Name: common.StringPtr("found_multi_ns_3")},
|
||||||
|
},
|
||||||
|
wantExist: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if gotExist := isTcrNsExist(tt.name, tt.list); gotExist != tt.wantExist {
|
||||||
|
t.Errorf("isTcrNsExist() = %v, want %v", gotExist, tt.wantExist)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user