/* Copyright The Velero Contributors. 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 datamover import ( "context" "errors" "fmt" "testing" "github.com/sirupsen/logrus" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" ctlclient "sigs.k8s.io/controller-runtime/pkg/client" "github.com/vmware-tanzu/velero/internal/credentials" cacheMock "github.com/vmware-tanzu/velero/pkg/cmd/cli/datamover/mocks" velerotest "github.com/vmware-tanzu/velero/pkg/test" "github.com/vmware-tanzu/velero/pkg/util/filesystem" ) func fakeCreateDataPathServiceWithErr(_ *dataMoverBackup) (dataPathService, error) { return nil, errors.New("fake-create-data-path-error") } var frHelper *fakeRunHelper func fakeCreateDataPathService(_ *dataMoverBackup) (dataPathService, error) { return frHelper, nil } type fakeRunHelper struct { initErr error runCancelableDataPathErr error runCancelableDataPathResult string exitMessage string succeed bool } func (fr *fakeRunHelper) Init() error { return fr.initErr } func (fr *fakeRunHelper) RunCancelableDataPath(_ context.Context) (string, error) { if fr.runCancelableDataPathErr != nil { return "", fr.runCancelableDataPathErr } else { return fr.runCancelableDataPathResult, nil } } func (fr *fakeRunHelper) Shutdown() { } func (fr *fakeRunHelper) ExitWithMessage(logger logrus.FieldLogger, succeed bool, message string, a ...any) { fr.succeed = succeed fr.exitMessage = fmt.Sprintf(message, a...) } func TestRunDataPath(t *testing.T) { tests := []struct { name string duName string createDataPathFail bool initDataPathErr error runCancelableDataPathErr error runCancelableDataPathResult string expectedMessage string expectedSucceed bool }{ { name: "create data path failed", duName: "fake-name", createDataPathFail: true, expectedMessage: "Failed to create data path service for DataUpload fake-name: fake-create-data-path-error", }, { name: "init data path failed", duName: "fake-name", initDataPathErr: errors.New("fake-init-data-path-error"), expectedMessage: "Failed to init data path service for DataUpload fake-name: fake-init-data-path-error", }, { name: "run data path failed", duName: "fake-name", runCancelableDataPathErr: errors.New("fake-run-data-path-error"), expectedMessage: "Failed to run data path service for DataUpload fake-name: fake-run-data-path-error", }, { name: "succeed", duName: "fake-name", runCancelableDataPathResult: "fake-run-data-path-result", expectedMessage: "fake-run-data-path-result", expectedSucceed: true, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { frHelper = &fakeRunHelper{ initErr: test.initDataPathErr, runCancelableDataPathErr: test.runCancelableDataPathErr, runCancelableDataPathResult: test.runCancelableDataPathResult, } if test.createDataPathFail { funcCreateDataPathService = fakeCreateDataPathServiceWithErr } else { funcCreateDataPathService = fakeCreateDataPathService } funcExitWithMessage = frHelper.ExitWithMessage s := &dataMoverBackup{ logger: velerotest.NewLogger(), cancelFunc: func() {}, config: dataMoverBackupConfig{ duName: test.duName, }, } s.runDataPath() assert.Equal(t, test.expectedMessage, frHelper.exitMessage) assert.Equal(t, test.expectedSucceed, frHelper.succeed) }) } } type fakeCreateDataPathServiceHelper struct { fileStoreErr error secretStoreErr error } func (fc *fakeCreateDataPathServiceHelper) NewNamespacedFileStore(_ ctlclient.Client, _ string, _ string, _ filesystem.Interface) (credentials.FileStore, error) { return nil, fc.fileStoreErr } func (fc *fakeCreateDataPathServiceHelper) NewNamespacedSecretStore(_ ctlclient.Client, _ string) (credentials.SecretStore, error) { return nil, fc.secretStoreErr } func TestCreateDataPathService(t *testing.T) { tests := []struct { name string fileStoreErr error secretStoreErr error mockGetInformer bool getInformerErr error expectedError string }{ { name: "create credential file store error", fileStoreErr: errors.New("fake-file-store-error"), expectedError: "error to create credential file store: fake-file-store-error", }, { name: "create credential secret store", secretStoreErr: errors.New("fake-secret-store-error"), expectedError: "error to create credential secret store: fake-secret-store-error", }, { name: "get informer error", mockGetInformer: true, getInformerErr: errors.New("fake-get-informer-error"), expectedError: "error to get controller-runtime informer from manager: fake-get-informer-error", }, { name: "succeed", mockGetInformer: true, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { fcHelper := &fakeCreateDataPathServiceHelper{ fileStoreErr: test.fileStoreErr, secretStoreErr: test.secretStoreErr, } funcNewCredentialFileStore = fcHelper.NewNamespacedFileStore funcNewCredentialSecretStore = fcHelper.NewNamespacedSecretStore cache := cacheMock.NewCache(t) if test.mockGetInformer { cache.On("GetInformer", mock.Anything, mock.Anything).Return(nil, test.getInformerErr) } funcExitWithMessage = frHelper.ExitWithMessage s := &dataMoverBackup{ cache: cache, } _, err := s.createDataPathService() if test.expectedError != "" { assert.EqualError(t, err, test.expectedError) } else { assert.NoError(t, err) } }) } }