diff --git a/go.mod b/go.mod index c08dabc3b..5237f3eda 100644 --- a/go.mod +++ b/go.mod @@ -136,6 +136,7 @@ require ( github.com/sirupsen/logrus v1.9.3 // indirect github.com/spf13/cast v1.7.0 // indirect github.com/tetratelabs/wabin v0.0.0-20230304001439-f6f874872834 // indirect + github.com/stretchr/objx v0.5.2 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.2.0 // indirect go.opentelemetry.io/auto/sdk v1.1.0 // indirect diff --git a/pkg/pusher/pusher.go b/pkg/pusher/pusher.go index e3c767be9..73de8a7f0 100644 --- a/pkg/pusher/pusher.go +++ b/pkg/pusher/pusher.go @@ -93,6 +93,11 @@ func (p Provider) Provides(scheme string) bool { // Providers is a collection of Provider objects. type Providers []Provider +// ProvidersResolver is an interface for retrieving Pusher objects +type ProvidersResolver interface { + ByScheme(scheme string) (Pusher, error) +} + // ByScheme returns a Provider that handles the given scheme. // // If no provider handles this scheme, this will return an error. diff --git a/pkg/uploader/chart_uploader.go b/pkg/uploader/chart_uploader.go index b3d612e38..b6f51c5b0 100644 --- a/pkg/uploader/chart_uploader.go +++ b/pkg/uploader/chart_uploader.go @@ -29,7 +29,7 @@ type ChartUploader struct { // Out is the location to write warning and info messages. Out io.Writer // Pusher collection for the operation - Pushers pusher.Providers + Pushers pusher.ProvidersResolver // Options provide parameters to be passed along to the Pusher being initialized. Options []pusher.Option // RegistryClient is a client for interacting with registries. diff --git a/pkg/uploader/chart_uploader_test.go b/pkg/uploader/chart_uploader_test.go new file mode 100644 index 000000000..e40f83682 --- /dev/null +++ b/pkg/uploader/chart_uploader_test.go @@ -0,0 +1,108 @@ +/* +Copyright The Helm 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 uploader + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + + "helm.sh/helm/v4/pkg/cli" + "helm.sh/helm/v4/pkg/pusher" +) + +type MockedPusher struct { + mock.Mock +} + +func (m *MockedPusher) Push(chartRef string, url string, _ ...pusher.Option) error { + m.Called(chartRef, url) + return nil +} + +type MockedProviders struct { + mock.Mock +} + +func (m *MockedProviders) ByScheme(string) (pusher.Pusher, error) { + args := m.Called() + mockedPusher := args.Get(0).(pusher.Pusher) + return mockedPusher, nil +} + +func TestChartUploader_UploadTo_Happy(t *testing.T) { + mockedPusher := new(MockedPusher) + mockedPusher.On("Push").Return(nil) + + mockedProviders := new(MockedProviders) + mockedProviders.On("ByScheme").Return(mockedPusher, nil) + + uploader := ChartUploader{ + Pushers: mockedProviders, + } + + mockedPusher.On("Push", "testdata/test-0.1.0.tgz", "oci://test").Return(nil) + err := uploader.UploadTo("testdata/test-0.1.0.tgz", "oci://test") + mockedPusher.AssertCalled(t, "Push", "testdata/test-0.1.0.tgz", "oci://test") + + assert.NoError(t, err) +} + +func TestChartUploader_UploadTo_InvalidChartUrlFormat(t *testing.T) { + envSettings := cli.EnvSettings{} + + pushers := pusher.All(&envSettings) + + uploader := ChartUploader{ + Pushers: pushers, + } + + err := uploader.UploadTo("main", "://invalid.com") + const expectedError = "invalid chart URL format" + assert.ErrorContains(t, err, expectedError) +} + +func TestChartUploader_UploadTo_SchemePrefixMissingFromRemote(t *testing.T) { + envSettings := cli.EnvSettings{} + + pushers := pusher.All(&envSettings) + + uploader := ChartUploader{ + Pushers: pushers, + } + + err := uploader.UploadTo("main", "invalid.com") + const expectedError = "scheme prefix missing from remote" + + assert.ErrorContains(t, err, expectedError) +} + +func TestChartUploader_UploadTo_SchemeNotRegistered(t *testing.T) { + envSettings := cli.EnvSettings{} + + pushers := pusher.All(&envSettings) + + uploader := ChartUploader{ + Pushers: pushers, + } + + err := uploader.UploadTo("main", "grpc://invalid.com") + const expectedError = "scheme \"grpc\" not supported" + + assert.ErrorContains(t, err, expectedError) +}