add ut for pkg/repository
Signed-off-by: Lyndon-Li <lyonghui@vmware.com>pull/6432/head
parent
de83980a05
commit
38d5003c6b
|
@ -887,3 +887,467 @@ func TestForget(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitRepo(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
funcTable localFuncTable
|
||||
getter *credmock.SecretStore
|
||||
repoService *reposervicenmocks.BackupRepoService
|
||||
retFuncInit interface{}
|
||||
credStoreReturn string
|
||||
credStoreError error
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "get repo option fail",
|
||||
expectedErr: "error to get repo options: error to get repo password: invalid credentials interface",
|
||||
},
|
||||
{
|
||||
name: "repo init fail",
|
||||
getter: new(credmock.SecretStore),
|
||||
credStoreReturn: "fake-password",
|
||||
funcTable: localFuncTable{
|
||||
getStorageVariables: func(*velerov1api.BackupStorageLocation, string, string) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
getStorageCredentials: func(*velerov1api.BackupStorageLocation, velerocredentials.FileStore) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
},
|
||||
repoService: new(reposervicenmocks.BackupRepoService),
|
||||
retFuncInit: func(context.Context, udmrepo.RepoOptions, bool) error {
|
||||
return errors.New("fake-error-1")
|
||||
},
|
||||
expectedErr: "error to init backup repo: fake-error-1",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
getter: new(credmock.SecretStore),
|
||||
credStoreReturn: "fake-password",
|
||||
funcTable: localFuncTable{
|
||||
getStorageVariables: func(*velerov1api.BackupStorageLocation, string, string) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
getStorageCredentials: func(*velerov1api.BackupStorageLocation, velerocredentials.FileStore) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
},
|
||||
repoService: new(reposervicenmocks.BackupRepoService),
|
||||
retFuncInit: func(context.Context, udmrepo.RepoOptions, bool) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
funcTable = tc.funcTable
|
||||
|
||||
var secretStore velerocredentials.SecretStore
|
||||
if tc.getter != nil {
|
||||
tc.getter.On("Get", mock.Anything, mock.Anything).Return(tc.credStoreReturn, tc.credStoreError)
|
||||
secretStore = tc.getter
|
||||
}
|
||||
|
||||
urp := unifiedRepoProvider{
|
||||
credentialGetter: velerocredentials.CredentialGetter{
|
||||
FromSecret: secretStore,
|
||||
},
|
||||
repoService: tc.repoService,
|
||||
log: velerotest.NewLogger(),
|
||||
}
|
||||
|
||||
if tc.repoService != nil {
|
||||
tc.repoService.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(tc.retFuncInit)
|
||||
}
|
||||
|
||||
err := urp.InitRepo(context.Background(), RepoParam{
|
||||
BackupLocation: &velerov1api.BackupStorageLocation{},
|
||||
BackupRepo: &velerov1api.BackupRepository{},
|
||||
})
|
||||
|
||||
if tc.expectedErr == "" {
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
assert.EqualError(t, err, tc.expectedErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestConnectToRepo(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
funcTable localFuncTable
|
||||
getter *credmock.SecretStore
|
||||
repoService *reposervicenmocks.BackupRepoService
|
||||
retFuncInit interface{}
|
||||
credStoreReturn string
|
||||
credStoreError error
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "get repo option fail",
|
||||
expectedErr: "error to get repo options: error to get repo password: invalid credentials interface",
|
||||
},
|
||||
{
|
||||
name: "repo init fail",
|
||||
getter: new(credmock.SecretStore),
|
||||
credStoreReturn: "fake-password",
|
||||
funcTable: localFuncTable{
|
||||
getStorageVariables: func(*velerov1api.BackupStorageLocation, string, string) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
getStorageCredentials: func(*velerov1api.BackupStorageLocation, velerocredentials.FileStore) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
},
|
||||
repoService: new(reposervicenmocks.BackupRepoService),
|
||||
retFuncInit: func(context.Context, udmrepo.RepoOptions, bool) error {
|
||||
return errors.New("fake-error-1")
|
||||
},
|
||||
expectedErr: "error to connect backup repo: fake-error-1",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
getter: new(credmock.SecretStore),
|
||||
credStoreReturn: "fake-password",
|
||||
funcTable: localFuncTable{
|
||||
getStorageVariables: func(*velerov1api.BackupStorageLocation, string, string) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
getStorageCredentials: func(*velerov1api.BackupStorageLocation, velerocredentials.FileStore) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
},
|
||||
repoService: new(reposervicenmocks.BackupRepoService),
|
||||
retFuncInit: func(context.Context, udmrepo.RepoOptions, bool) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
funcTable = tc.funcTable
|
||||
|
||||
var secretStore velerocredentials.SecretStore
|
||||
if tc.getter != nil {
|
||||
tc.getter.On("Get", mock.Anything, mock.Anything).Return(tc.credStoreReturn, tc.credStoreError)
|
||||
secretStore = tc.getter
|
||||
}
|
||||
|
||||
urp := unifiedRepoProvider{
|
||||
credentialGetter: velerocredentials.CredentialGetter{
|
||||
FromSecret: secretStore,
|
||||
},
|
||||
repoService: tc.repoService,
|
||||
log: velerotest.NewLogger(),
|
||||
}
|
||||
|
||||
if tc.repoService != nil {
|
||||
tc.repoService.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(tc.retFuncInit)
|
||||
}
|
||||
|
||||
err := urp.ConnectToRepo(context.Background(), RepoParam{
|
||||
BackupLocation: &velerov1api.BackupStorageLocation{},
|
||||
BackupRepo: &velerov1api.BackupRepository{},
|
||||
})
|
||||
|
||||
if tc.expectedErr == "" {
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
assert.EqualError(t, err, tc.expectedErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestBoostRepoConnect(t *testing.T) {
|
||||
var backupRepo *reposervicenmocks.BackupRepo
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
funcTable localFuncTable
|
||||
getter *credmock.SecretStore
|
||||
repoService *reposervicenmocks.BackupRepoService
|
||||
backupRepo *reposervicenmocks.BackupRepo
|
||||
retFuncInit interface{}
|
||||
retFuncOpen []interface{}
|
||||
credStoreReturn string
|
||||
credStoreError error
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "get repo option fail",
|
||||
expectedErr: "error to get repo options: error to get repo password: invalid credentials interface",
|
||||
},
|
||||
{
|
||||
name: "repo not opened and connect fail",
|
||||
getter: new(credmock.SecretStore),
|
||||
credStoreReturn: "fake-password",
|
||||
funcTable: localFuncTable{
|
||||
getStorageVariables: func(*velerov1api.BackupStorageLocation, string, string) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
getStorageCredentials: func(*velerov1api.BackupStorageLocation, velerocredentials.FileStore) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
},
|
||||
repoService: new(reposervicenmocks.BackupRepoService),
|
||||
retFuncOpen: []interface{}{
|
||||
func(context.Context, udmrepo.RepoOptions) udmrepo.BackupRepo {
|
||||
return backupRepo
|
||||
},
|
||||
|
||||
func(context.Context, udmrepo.RepoOptions) error {
|
||||
return errors.New("fake-error-1")
|
||||
},
|
||||
},
|
||||
retFuncInit: func(context.Context, udmrepo.RepoOptions, bool) error {
|
||||
return errors.New("fake-error-2")
|
||||
},
|
||||
expectedErr: "error to connect backup repo: fake-error-2",
|
||||
},
|
||||
{
|
||||
name: "repo not opened and connect succeed",
|
||||
getter: new(credmock.SecretStore),
|
||||
credStoreReturn: "fake-password",
|
||||
funcTable: localFuncTable{
|
||||
getStorageVariables: func(*velerov1api.BackupStorageLocation, string, string) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
getStorageCredentials: func(*velerov1api.BackupStorageLocation, velerocredentials.FileStore) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
},
|
||||
repoService: new(reposervicenmocks.BackupRepoService),
|
||||
retFuncOpen: []interface{}{
|
||||
func(context.Context, udmrepo.RepoOptions) udmrepo.BackupRepo {
|
||||
return backupRepo
|
||||
},
|
||||
|
||||
func(context.Context, udmrepo.RepoOptions) error {
|
||||
return errors.New("fake-error-1")
|
||||
},
|
||||
},
|
||||
retFuncInit: func(context.Context, udmrepo.RepoOptions, bool) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "repo is opened",
|
||||
getter: new(credmock.SecretStore),
|
||||
credStoreReturn: "fake-password",
|
||||
funcTable: localFuncTable{
|
||||
getStorageVariables: func(*velerov1api.BackupStorageLocation, string, string) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
getStorageCredentials: func(*velerov1api.BackupStorageLocation, velerocredentials.FileStore) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
},
|
||||
repoService: new(reposervicenmocks.BackupRepoService),
|
||||
backupRepo: new(reposervicenmocks.BackupRepo),
|
||||
retFuncOpen: []interface{}{
|
||||
func(context.Context, udmrepo.RepoOptions) udmrepo.BackupRepo {
|
||||
return backupRepo
|
||||
},
|
||||
|
||||
func(context.Context, udmrepo.RepoOptions) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
retFuncInit: func(context.Context, udmrepo.RepoOptions, bool) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
funcTable = tc.funcTable
|
||||
|
||||
var secretStore velerocredentials.SecretStore
|
||||
if tc.getter != nil {
|
||||
tc.getter.On("Get", mock.Anything, mock.Anything).Return(tc.credStoreReturn, tc.credStoreError)
|
||||
secretStore = tc.getter
|
||||
}
|
||||
|
||||
urp := unifiedRepoProvider{
|
||||
credentialGetter: velerocredentials.CredentialGetter{
|
||||
FromSecret: secretStore,
|
||||
},
|
||||
repoService: tc.repoService,
|
||||
log: velerotest.NewLogger(),
|
||||
}
|
||||
|
||||
backupRepo = tc.backupRepo
|
||||
|
||||
if tc.repoService != nil {
|
||||
tc.repoService.On("Open", mock.Anything, mock.Anything).Return(tc.retFuncOpen[0], tc.retFuncOpen[1])
|
||||
tc.repoService.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(tc.retFuncInit)
|
||||
}
|
||||
|
||||
if tc.backupRepo != nil {
|
||||
backupRepo.On("Close", mock.Anything).Return(nil)
|
||||
}
|
||||
|
||||
err := urp.BoostRepoConnect(context.Background(), RepoParam{
|
||||
BackupLocation: &velerov1api.BackupStorageLocation{},
|
||||
BackupRepo: &velerov1api.BackupRepository{},
|
||||
})
|
||||
|
||||
if tc.expectedErr == "" {
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
assert.EqualError(t, err, tc.expectedErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPruneRepo(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
funcTable localFuncTable
|
||||
getter *credmock.SecretStore
|
||||
repoService *reposervicenmocks.BackupRepoService
|
||||
retFuncMaintain interface{}
|
||||
credStoreReturn string
|
||||
credStoreError error
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "get repo option fail",
|
||||
expectedErr: "error to get repo options: error to get repo password: invalid credentials interface",
|
||||
},
|
||||
{
|
||||
name: "repo maintain fail",
|
||||
getter: new(credmock.SecretStore),
|
||||
credStoreReturn: "fake-password",
|
||||
funcTable: localFuncTable{
|
||||
getStorageVariables: func(*velerov1api.BackupStorageLocation, string, string) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
getStorageCredentials: func(*velerov1api.BackupStorageLocation, velerocredentials.FileStore) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
},
|
||||
repoService: new(reposervicenmocks.BackupRepoService),
|
||||
retFuncMaintain: func(context.Context, udmrepo.RepoOptions) error {
|
||||
return errors.New("fake-error-1")
|
||||
},
|
||||
expectedErr: "error to prune backup repo: fake-error-1",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
getter: new(credmock.SecretStore),
|
||||
credStoreReturn: "fake-password",
|
||||
funcTable: localFuncTable{
|
||||
getStorageVariables: func(*velerov1api.BackupStorageLocation, string, string) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
getStorageCredentials: func(*velerov1api.BackupStorageLocation, velerocredentials.FileStore) (map[string]string, error) {
|
||||
return map[string]string{}, nil
|
||||
},
|
||||
},
|
||||
repoService: new(reposervicenmocks.BackupRepoService),
|
||||
retFuncMaintain: func(context.Context, udmrepo.RepoOptions) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
funcTable = tc.funcTable
|
||||
|
||||
var secretStore velerocredentials.SecretStore
|
||||
if tc.getter != nil {
|
||||
tc.getter.On("Get", mock.Anything, mock.Anything).Return(tc.credStoreReturn, tc.credStoreError)
|
||||
secretStore = tc.getter
|
||||
}
|
||||
|
||||
urp := unifiedRepoProvider{
|
||||
credentialGetter: velerocredentials.CredentialGetter{
|
||||
FromSecret: secretStore,
|
||||
},
|
||||
repoService: tc.repoService,
|
||||
log: velerotest.NewLogger(),
|
||||
}
|
||||
|
||||
if tc.repoService != nil {
|
||||
tc.repoService.On("Maintain", mock.Anything, mock.Anything).Return(tc.retFuncMaintain)
|
||||
}
|
||||
|
||||
err := urp.PruneRepo(context.Background(), RepoParam{
|
||||
BackupLocation: &velerov1api.BackupStorageLocation{},
|
||||
BackupRepo: &velerov1api.BackupRepository{},
|
||||
})
|
||||
|
||||
if tc.expectedErr == "" {
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
assert.EqualError(t, err, tc.expectedErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetStorageType(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
backupLocation *velerov1api.BackupStorageLocation
|
||||
expectedRet string
|
||||
}{
|
||||
{
|
||||
name: "wrong backend type",
|
||||
backupLocation: &velerov1api.BackupStorageLocation{},
|
||||
},
|
||||
{
|
||||
name: "aws provider",
|
||||
backupLocation: &velerov1api.BackupStorageLocation{
|
||||
Spec: velerov1api.BackupStorageLocationSpec{
|
||||
Provider: "velero.io/aws",
|
||||
},
|
||||
},
|
||||
expectedRet: "s3",
|
||||
},
|
||||
{
|
||||
name: "azure provider",
|
||||
backupLocation: &velerov1api.BackupStorageLocation{
|
||||
Spec: velerov1api.BackupStorageLocationSpec{
|
||||
Provider: "velero.io/azure",
|
||||
},
|
||||
},
|
||||
expectedRet: "azure",
|
||||
},
|
||||
{
|
||||
name: "gcp provider",
|
||||
backupLocation: &velerov1api.BackupStorageLocation{
|
||||
Spec: velerov1api.BackupStorageLocationSpec{
|
||||
Provider: "velero.io/gcp",
|
||||
},
|
||||
},
|
||||
expectedRet: "gcs",
|
||||
},
|
||||
{
|
||||
name: "fs provider",
|
||||
backupLocation: &velerov1api.BackupStorageLocation{
|
||||
Spec: velerov1api.BackupStorageLocationSpec{
|
||||
Provider: "velero.io/fs",
|
||||
},
|
||||
},
|
||||
expectedRet: "filesystem",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
ret := getStorageType(tc.backupLocation)
|
||||
assert.Equal(t, tc.expectedRet, ret)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
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 backend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/kopia/kopia/repo"
|
||||
"github.com/kopia/kopia/repo/content"
|
||||
"github.com/kopia/kopia/repo/encryption"
|
||||
"github.com/kopia/kopia/repo/format"
|
||||
"github.com/kopia/kopia/repo/hashing"
|
||||
"github.com/kopia/kopia/repo/splitter"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/repository/udmrepo"
|
||||
)
|
||||
|
||||
func TestSetupNewRepositoryOptions(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
flags map[string]string
|
||||
expected repo.NewRepositoryOptions
|
||||
}{
|
||||
{
|
||||
name: "with hash algo",
|
||||
flags: map[string]string{
|
||||
udmrepo.StoreOptionGenHashAlgo: "fake-hash",
|
||||
},
|
||||
expected: repo.NewRepositoryOptions{
|
||||
BlockFormat: format.ContentFormat{
|
||||
Hash: "fake-hash",
|
||||
Encryption: encryption.DefaultAlgorithm,
|
||||
},
|
||||
ObjectFormat: format.ObjectFormat{
|
||||
Splitter: splitter.DefaultAlgorithm,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with encrypt algo",
|
||||
flags: map[string]string{
|
||||
udmrepo.StoreOptionGenEncryptAlgo: "fake-encrypt",
|
||||
},
|
||||
expected: repo.NewRepositoryOptions{
|
||||
BlockFormat: format.ContentFormat{
|
||||
Hash: hashing.DefaultAlgorithm,
|
||||
Encryption: "fake-encrypt",
|
||||
},
|
||||
ObjectFormat: format.ObjectFormat{
|
||||
Splitter: splitter.DefaultAlgorithm,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with splitter algo",
|
||||
flags: map[string]string{
|
||||
udmrepo.StoreOptionGenSplitAlgo: "fake-splitter",
|
||||
},
|
||||
expected: repo.NewRepositoryOptions{
|
||||
BlockFormat: format.ContentFormat{
|
||||
Hash: hashing.DefaultAlgorithm,
|
||||
Encryption: encryption.DefaultAlgorithm,
|
||||
},
|
||||
ObjectFormat: format.ObjectFormat{
|
||||
Splitter: "fake-splitter",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with retention algo",
|
||||
flags: map[string]string{
|
||||
udmrepo.StoreOptionGenRetentionMode: "fake-retention-mode",
|
||||
},
|
||||
expected: repo.NewRepositoryOptions{
|
||||
BlockFormat: format.ContentFormat{
|
||||
Hash: hashing.DefaultAlgorithm,
|
||||
Encryption: encryption.DefaultAlgorithm,
|
||||
},
|
||||
ObjectFormat: format.ObjectFormat{
|
||||
Splitter: splitter.DefaultAlgorithm,
|
||||
},
|
||||
RetentionMode: "fake-retention-mode",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
ret := SetupNewRepositoryOptions(context.Background(), tc.flags)
|
||||
assert.Equal(t, tc.expected, ret)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetupConnectOptions(t *testing.T) {
|
||||
defaultCacheOption := content.CachingOptions{
|
||||
MaxCacheSizeBytes: 2000 << 20,
|
||||
MaxMetadataCacheSizeBytes: 2000 << 20,
|
||||
MaxListCacheDuration: content.DurationSeconds(time.Duration(30) * time.Second),
|
||||
}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
repoOptions udmrepo.RepoOptions
|
||||
expected repo.ConnectOptions
|
||||
}{
|
||||
{
|
||||
name: "with domain",
|
||||
repoOptions: udmrepo.RepoOptions{
|
||||
GeneralOptions: map[string]string{
|
||||
udmrepo.GenOptionOwnerDomain: "fake-domain",
|
||||
},
|
||||
},
|
||||
expected: repo.ConnectOptions{
|
||||
CachingOptions: defaultCacheOption,
|
||||
ClientOptions: repo.ClientOptions{
|
||||
Hostname: "fake-domain",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with username",
|
||||
repoOptions: udmrepo.RepoOptions{
|
||||
GeneralOptions: map[string]string{
|
||||
udmrepo.GenOptionOwnerName: "fake-user",
|
||||
},
|
||||
},
|
||||
expected: repo.ConnectOptions{
|
||||
CachingOptions: defaultCacheOption,
|
||||
ClientOptions: repo.ClientOptions{
|
||||
Username: "fake-user",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with wrong readonly",
|
||||
repoOptions: udmrepo.RepoOptions{
|
||||
GeneralOptions: map[string]string{
|
||||
udmrepo.StoreOptionGenReadOnly: "fake-bool",
|
||||
},
|
||||
},
|
||||
expected: repo.ConnectOptions{
|
||||
CachingOptions: defaultCacheOption,
|
||||
ClientOptions: repo.ClientOptions{},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with correct readonly",
|
||||
repoOptions: udmrepo.RepoOptions{
|
||||
GeneralOptions: map[string]string{
|
||||
udmrepo.StoreOptionGenReadOnly: "true",
|
||||
},
|
||||
},
|
||||
expected: repo.ConnectOptions{
|
||||
CachingOptions: defaultCacheOption,
|
||||
ClientOptions: repo.ClientOptions{
|
||||
ReadOnly: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with description",
|
||||
repoOptions: udmrepo.RepoOptions{
|
||||
Description: "fake-description",
|
||||
},
|
||||
expected: repo.ConnectOptions{
|
||||
CachingOptions: defaultCacheOption,
|
||||
ClientOptions: repo.ClientOptions{
|
||||
Description: "fake-description",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
ret := SetupConnectOptions(context.Background(), tc.repoOptions)
|
||||
assert.Equal(t, tc.expected, ret)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
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 backend
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/kopia/kopia/repo/blob/filesystem"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/repository/udmrepo"
|
||||
)
|
||||
|
||||
func TestFSSetup(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
flags map[string]string
|
||||
expectedOptions filesystem.Options
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "must have fs path",
|
||||
flags: map[string]string{},
|
||||
expectedErr: "key " + udmrepo.StoreOptionFsPath + " not found",
|
||||
},
|
||||
{
|
||||
name: "with fs path only",
|
||||
flags: map[string]string{
|
||||
udmrepo.StoreOptionFsPath: "fake/path",
|
||||
},
|
||||
expectedOptions: filesystem.Options{
|
||||
Path: "fake/path",
|
||||
FileMode: 0o600,
|
||||
DirectoryMode: 0o700,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with prefix",
|
||||
flags: map[string]string{
|
||||
udmrepo.StoreOptionFsPath: "fake/path",
|
||||
udmrepo.StoreOptionPrefix: "fake-prefix",
|
||||
},
|
||||
expectedOptions: filesystem.Options{
|
||||
Path: "fake/path/fake-prefix",
|
||||
FileMode: 0o600,
|
||||
DirectoryMode: 0o700,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
fsFlags := FsBackend{}
|
||||
|
||||
err := fsFlags.Setup(context.Background(), tc.flags)
|
||||
|
||||
if tc.expectedErr == "" {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.expectedOptions, fsFlags.options)
|
||||
} else {
|
||||
assert.EqualError(t, err, tc.expectedErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/kopia/kopia/repo/blob/gcs"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/repository/udmrepo"
|
||||
|
@ -27,9 +28,10 @@ import (
|
|||
|
||||
func TestGcsSetup(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
flags map[string]string
|
||||
expectedErr string
|
||||
name string
|
||||
flags map[string]string
|
||||
expectedOptions gcs.Options
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "must have bucket name",
|
||||
|
@ -43,6 +45,44 @@ func TestGcsSetup(t *testing.T) {
|
|||
},
|
||||
expectedErr: "key " + udmrepo.StoreOptionCredentialFile + " not found",
|
||||
},
|
||||
{
|
||||
name: "with prefix",
|
||||
flags: map[string]string{
|
||||
udmrepo.StoreOptionOssBucket: "fake-bucket",
|
||||
udmrepo.StoreOptionCredentialFile: "fake-credential",
|
||||
udmrepo.StoreOptionPrefix: "fake-prefix",
|
||||
},
|
||||
expectedOptions: gcs.Options{
|
||||
BucketName: "fake-bucket",
|
||||
ServiceAccountCredentialsFile: "fake-credential",
|
||||
Prefix: "fake-prefix",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with wrong readonly",
|
||||
flags: map[string]string{
|
||||
udmrepo.StoreOptionOssBucket: "fake-bucket",
|
||||
udmrepo.StoreOptionCredentialFile: "fake-credential",
|
||||
udmrepo.StoreOptionGcsReadonly: "fake-bool",
|
||||
},
|
||||
expectedOptions: gcs.Options{
|
||||
BucketName: "fake-bucket",
|
||||
ServiceAccountCredentialsFile: "fake-credential",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with correct readonly",
|
||||
flags: map[string]string{
|
||||
udmrepo.StoreOptionOssBucket: "fake-bucket",
|
||||
udmrepo.StoreOptionCredentialFile: "fake-credential",
|
||||
udmrepo.StoreOptionGcsReadonly: "true",
|
||||
},
|
||||
expectedOptions: gcs.Options{
|
||||
BucketName: "fake-bucket",
|
||||
ServiceAccountCredentialsFile: "fake-credential",
|
||||
ReadOnly: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
@ -53,6 +93,7 @@ func TestGcsSetup(t *testing.T) {
|
|||
|
||||
if tc.expectedErr == "" {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.expectedOptions, gcsFlags.options)
|
||||
} else {
|
||||
assert.EqualError(t, err, tc.expectedErr)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
// Code generated by mockery v2.22.1. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import mock "github.com/stretchr/testify/mock"
|
||||
|
||||
// Reader is an autogenerated mock type for the Reader type
|
||||
type Reader struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Close provides a mock function with given fields:
|
||||
func (_m *Reader) Close() error {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func() error); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Length provides a mock function with given fields:
|
||||
func (_m *Reader) Length() int64 {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 int64
|
||||
if rf, ok := ret.Get(0).(func() int64); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Read provides a mock function with given fields: p
|
||||
func (_m *Reader) Read(p []byte) (int, error) {
|
||||
ret := _m.Called(p)
|
||||
|
||||
var r0 int
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func([]byte) (int, error)); ok {
|
||||
return rf(p)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func([]byte) int); ok {
|
||||
r0 = rf(p)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func([]byte) error); ok {
|
||||
r1 = rf(p)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Seek provides a mock function with given fields: offset, whence
|
||||
func (_m *Reader) Seek(offset int64, whence int) (int64, error) {
|
||||
ret := _m.Called(offset, whence)
|
||||
|
||||
var r0 int64
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func(int64, int) (int64, error)); ok {
|
||||
return rf(offset, whence)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func(int64, int) int64); ok {
|
||||
r0 = rf(offset, whence)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int64)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func(int64, int) error); ok {
|
||||
r1 = rf(offset, whence)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewReader interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewReader creates a new instance of Reader. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewReader(t mockConstructorTestingTNewReader) *Reader {
|
||||
mock := &Reader{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
|
@ -0,0 +1,114 @@
|
|||
// Code generated by mockery v2.22.1. DO NOT EDIT.
|
||||
|
||||
package mocks
|
||||
|
||||
import (
|
||||
object "github.com/kopia/kopia/repo/object"
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
// Writer is an autogenerated mock type for the Writer type
|
||||
type Writer struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// Checkpoint provides a mock function with given fields:
|
||||
func (_m *Writer) Checkpoint() (object.ID, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 object.ID
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func() (object.ID, error)); ok {
|
||||
return rf()
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func() object.ID); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(object.ID)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Close provides a mock function with given fields:
|
||||
func (_m *Writer) Close() error {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 error
|
||||
if rf, ok := ret.Get(0).(func() error); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Error(0)
|
||||
}
|
||||
|
||||
return r0
|
||||
}
|
||||
|
||||
// Result provides a mock function with given fields:
|
||||
func (_m *Writer) Result() (object.ID, error) {
|
||||
ret := _m.Called()
|
||||
|
||||
var r0 object.ID
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func() (object.ID, error)); ok {
|
||||
return rf()
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func() object.ID); ok {
|
||||
r0 = rf()
|
||||
} else {
|
||||
r0 = ret.Get(0).(object.ID)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func() error); ok {
|
||||
r1 = rf()
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Write provides a mock function with given fields: p
|
||||
func (_m *Writer) Write(p []byte) (int, error) {
|
||||
ret := _m.Called(p)
|
||||
|
||||
var r0 int
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(0).(func([]byte) (int, error)); ok {
|
||||
return rf(p)
|
||||
}
|
||||
if rf, ok := ret.Get(0).(func([]byte) int); ok {
|
||||
r0 = rf(p)
|
||||
} else {
|
||||
r0 = ret.Get(0).(int)
|
||||
}
|
||||
|
||||
if rf, ok := ret.Get(1).(func([]byte) error); ok {
|
||||
r1 = rf(p)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
type mockConstructorTestingTNewWriter interface {
|
||||
mock.TestingT
|
||||
Cleanup(func())
|
||||
}
|
||||
|
||||
// NewWriter creates a new instance of Writer. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||
func NewWriter(t mockConstructorTestingTNewWriter) *Writer {
|
||||
mock := &Writer{}
|
||||
mock.Mock.Test(t)
|
||||
|
||||
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||
|
||||
return mock
|
||||
}
|
|
@ -20,6 +20,7 @@ import (
|
|||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/kopia/kopia/repo/blob/s3"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/vmware-tanzu/velero/pkg/repository/udmrepo"
|
||||
|
@ -27,15 +28,91 @@ import (
|
|||
|
||||
func TestS3Setup(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
flags map[string]string
|
||||
expectedErr string
|
||||
name string
|
||||
flags map[string]string
|
||||
expectedOptions s3.Options
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "must have bucket name",
|
||||
flags: map[string]string{},
|
||||
expectedErr: "key " + udmrepo.StoreOptionOssBucket + " not found",
|
||||
},
|
||||
{
|
||||
name: "with bucket only",
|
||||
flags: map[string]string{
|
||||
udmrepo.StoreOptionOssBucket: "fake-bucket",
|
||||
},
|
||||
expectedOptions: s3.Options{
|
||||
BucketName: "fake-bucket",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with others",
|
||||
flags: map[string]string{
|
||||
udmrepo.StoreOptionOssBucket: "fake-bucket",
|
||||
udmrepo.StoreOptionS3KeyID: "fake-ak",
|
||||
udmrepo.StoreOptionS3SecretKey: "fake-sk",
|
||||
udmrepo.StoreOptionS3Endpoint: "fake-endpoint",
|
||||
udmrepo.StoreOptionOssRegion: "fake-region",
|
||||
udmrepo.StoreOptionPrefix: "fake-prefix",
|
||||
udmrepo.StoreOptionS3Token: "fake-token",
|
||||
},
|
||||
expectedOptions: s3.Options{
|
||||
BucketName: "fake-bucket",
|
||||
AccessKeyID: "fake-ak",
|
||||
SecretAccessKey: "fake-sk",
|
||||
Endpoint: "fake-endpoint",
|
||||
Region: "fake-region",
|
||||
Prefix: "fake-prefix",
|
||||
SessionToken: "fake-token",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with wrong tls",
|
||||
flags: map[string]string{
|
||||
udmrepo.StoreOptionOssBucket: "fake-bucket",
|
||||
udmrepo.StoreOptionS3DisableTLS: "fake-bool",
|
||||
udmrepo.StoreOptionS3DisableTLSVerify: "fake-bool",
|
||||
},
|
||||
expectedOptions: s3.Options{
|
||||
BucketName: "fake-bucket",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with correct tls",
|
||||
flags: map[string]string{
|
||||
udmrepo.StoreOptionOssBucket: "fake-bucket",
|
||||
udmrepo.StoreOptionS3DisableTLS: "true",
|
||||
udmrepo.StoreOptionS3DisableTLSVerify: "false",
|
||||
},
|
||||
expectedOptions: s3.Options{
|
||||
BucketName: "fake-bucket",
|
||||
DoNotUseTLS: true,
|
||||
DoNotVerifyTLS: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with wrong ca",
|
||||
flags: map[string]string{
|
||||
udmrepo.StoreOptionOssBucket: "fake-bucket",
|
||||
udmrepo.StoreOptionS3CustomCA: "fake-base-64",
|
||||
},
|
||||
expectedOptions: s3.Options{
|
||||
BucketName: "fake-bucket",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with correct ca",
|
||||
flags: map[string]string{
|
||||
udmrepo.StoreOptionOssBucket: "fake-bucket",
|
||||
udmrepo.StoreOptionS3CustomCA: "ZmFrZS1jYQ==",
|
||||
},
|
||||
expectedOptions: s3.Options{
|
||||
BucketName: "fake-bucket",
|
||||
RootCA: []byte{'f', 'a', 'k', 'e', '-', 'c', 'a'},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
|
|
|
@ -18,12 +18,14 @@ package kopialib
|
|||
|
||||
import (
|
||||
"context"
|
||||
"math"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/kopia/kopia/repo"
|
||||
"github.com/kopia/kopia/repo/manifest"
|
||||
"github.com/kopia/kopia/repo/object"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
|
@ -713,3 +715,486 @@ func TestFlush(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewObjectWriter(t *testing.T) {
|
||||
rawObjWriter := repomocks.NewWriter(t)
|
||||
testCases := []struct {
|
||||
name string
|
||||
rawWriter *repomocks.DirectRepositoryWriter
|
||||
rawWriterRet object.Writer
|
||||
expectedRet udmrepo.ObjectWriter
|
||||
}{
|
||||
{
|
||||
name: "raw writer is nil",
|
||||
},
|
||||
{
|
||||
name: "new object writer fail",
|
||||
rawWriter: repomocks.NewDirectRepositoryWriter(t),
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
rawWriter: repomocks.NewDirectRepositoryWriter(t),
|
||||
rawWriterRet: rawObjWriter,
|
||||
expectedRet: &kopiaObjectWriter{rawWriter: rawObjWriter},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
kr := &kopiaRepository{}
|
||||
|
||||
if tc.rawWriter != nil {
|
||||
tc.rawWriter.On("NewObjectWriter", mock.Anything, mock.Anything).Return(tc.rawWriterRet)
|
||||
kr.rawWriter = tc.rawWriter
|
||||
}
|
||||
|
||||
ret := kr.NewObjectWriter(context.Background(), udmrepo.ObjectWriteOptions{})
|
||||
|
||||
assert.Equal(t, tc.expectedRet, ret)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateProgress(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
progress int64
|
||||
uploaded int64
|
||||
throttle logThrottle
|
||||
logMessage string
|
||||
}{
|
||||
{
|
||||
name: "should not output",
|
||||
throttle: logThrottle{
|
||||
lastTime: math.MaxInt64,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should output",
|
||||
progress: 100,
|
||||
uploaded: 200,
|
||||
logMessage: "Repo uploaded 300 bytes.",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
logMessage := ""
|
||||
kr := &kopiaRepository{
|
||||
logger: velerotest.NewSingleLogger(&logMessage),
|
||||
throttle: tc.throttle,
|
||||
uploaded: tc.uploaded,
|
||||
}
|
||||
|
||||
kr.updateProgress(tc.progress)
|
||||
|
||||
if len(tc.logMessage) > 0 {
|
||||
assert.Contains(t, logMessage, tc.logMessage)
|
||||
} else {
|
||||
assert.Equal(t, "", logMessage)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReaderRead(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
rawObjReader *repomocks.Reader
|
||||
rawReaderRetErr error
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "raw reader is nil",
|
||||
expectedErr: "object reader is closed or not open",
|
||||
},
|
||||
{
|
||||
name: "raw read fail",
|
||||
rawObjReader: repomocks.NewReader(t),
|
||||
rawReaderRetErr: errors.New("fake-read-error"),
|
||||
expectedErr: "fake-read-error",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
rawObjReader: repomocks.NewReader(t),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
kr := &kopiaObjectReader{}
|
||||
|
||||
if tc.rawObjReader != nil {
|
||||
tc.rawObjReader.On("Read", mock.Anything).Return(0, tc.rawReaderRetErr)
|
||||
kr.rawReader = tc.rawObjReader
|
||||
}
|
||||
|
||||
_, err := kr.Read(nil)
|
||||
|
||||
if tc.expectedErr == "" {
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
assert.EqualError(t, err, tc.expectedErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReaderSeek(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
rawObjReader *repomocks.Reader
|
||||
rawReaderRet int64
|
||||
rawReaderRetErr error
|
||||
expectedRet int64
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "raw reader is nil",
|
||||
expectedErr: "object reader is closed or not open",
|
||||
},
|
||||
{
|
||||
name: "raw seek fail",
|
||||
rawObjReader: repomocks.NewReader(t),
|
||||
rawReaderRetErr: errors.New("fake-seek-error"),
|
||||
expectedErr: "fake-seek-error",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
rawObjReader: repomocks.NewReader(t),
|
||||
rawReaderRet: 100,
|
||||
expectedRet: 100,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
kr := &kopiaObjectReader{}
|
||||
|
||||
if tc.rawObjReader != nil {
|
||||
tc.rawObjReader.On("Seek", mock.Anything, mock.Anything).Return(tc.rawReaderRet, tc.rawReaderRetErr)
|
||||
kr.rawReader = tc.rawObjReader
|
||||
}
|
||||
|
||||
ret, err := kr.Seek(0, 0)
|
||||
|
||||
if tc.expectedErr == "" {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.expectedRet, ret)
|
||||
} else {
|
||||
assert.EqualError(t, err, tc.expectedErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReaderClose(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
rawObjReader *repomocks.Reader
|
||||
rawReaderRetErr error
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "raw reader is nil",
|
||||
},
|
||||
{
|
||||
name: "raw close fail",
|
||||
rawObjReader: repomocks.NewReader(t),
|
||||
rawReaderRetErr: errors.New("fake-close-error"),
|
||||
expectedErr: "fake-close-error",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
rawObjReader: repomocks.NewReader(t),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
kr := &kopiaObjectReader{}
|
||||
|
||||
if tc.rawObjReader != nil {
|
||||
tc.rawObjReader.On("Close").Return(tc.rawReaderRetErr)
|
||||
kr.rawReader = tc.rawObjReader
|
||||
}
|
||||
|
||||
err := kr.Close()
|
||||
|
||||
if tc.expectedErr == "" {
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
assert.EqualError(t, err, tc.expectedErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReaderLength(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
rawObjReader *repomocks.Reader
|
||||
rawReaderRet int64
|
||||
expectedRet int64
|
||||
}{
|
||||
{
|
||||
name: "raw reader is nil",
|
||||
expectedRet: -1,
|
||||
},
|
||||
{
|
||||
name: "raw length fail",
|
||||
rawObjReader: repomocks.NewReader(t),
|
||||
rawReaderRet: 0,
|
||||
expectedRet: 0,
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
rawObjReader: repomocks.NewReader(t),
|
||||
rawReaderRet: 200,
|
||||
expectedRet: 200,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
kr := &kopiaObjectReader{}
|
||||
|
||||
if tc.rawObjReader != nil {
|
||||
tc.rawObjReader.On("Length").Return(tc.rawReaderRet)
|
||||
kr.rawReader = tc.rawObjReader
|
||||
}
|
||||
|
||||
ret := kr.Length()
|
||||
|
||||
assert.Equal(t, tc.expectedRet, ret)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriterWrite(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
rawObjWriter *repomocks.Writer
|
||||
rawWrtierRet int
|
||||
rawWriterRetErr error
|
||||
expectedRet int
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "raw writer is nil",
|
||||
expectedErr: "object writer is closed or not open",
|
||||
},
|
||||
{
|
||||
name: "raw read fail",
|
||||
rawObjWriter: repomocks.NewWriter(t),
|
||||
rawWriterRetErr: errors.New("fake-write-error"),
|
||||
expectedErr: "fake-write-error",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
rawObjWriter: repomocks.NewWriter(t),
|
||||
rawWrtierRet: 200,
|
||||
expectedRet: 200,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
kr := &kopiaObjectWriter{}
|
||||
|
||||
if tc.rawObjWriter != nil {
|
||||
tc.rawObjWriter.On("Write", mock.Anything).Return(tc.rawWrtierRet, tc.rawWriterRetErr)
|
||||
kr.rawWriter = tc.rawObjWriter
|
||||
}
|
||||
|
||||
ret, err := kr.Write(nil)
|
||||
|
||||
if tc.expectedErr == "" {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.expectedRet, ret)
|
||||
} else {
|
||||
assert.EqualError(t, err, tc.expectedErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriterCheckpoint(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
rawObjWriter *repomocks.Writer
|
||||
rawWrtierRet object.ID
|
||||
rawWriterRetErr error
|
||||
expectedRet udmrepo.ID
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "raw writer is nil",
|
||||
expectedErr: "object writer is closed or not open",
|
||||
},
|
||||
{
|
||||
name: "raw checkpoint fail",
|
||||
rawObjWriter: repomocks.NewWriter(t),
|
||||
rawWriterRetErr: errors.New("fake-checkpoint-error"),
|
||||
expectedErr: "error to checkpoint object: fake-checkpoint-error",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
rawObjWriter: repomocks.NewWriter(t),
|
||||
rawWrtierRet: object.ID{},
|
||||
expectedRet: udmrepo.ID(""),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
kr := &kopiaObjectWriter{}
|
||||
|
||||
if tc.rawObjWriter != nil {
|
||||
tc.rawObjWriter.On("Checkpoint").Return(tc.rawWrtierRet, tc.rawWriterRetErr)
|
||||
kr.rawWriter = tc.rawObjWriter
|
||||
}
|
||||
|
||||
ret, err := kr.Checkpoint()
|
||||
|
||||
if tc.expectedErr == "" {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.expectedRet, ret)
|
||||
} else {
|
||||
assert.EqualError(t, err, tc.expectedErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriterResult(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
rawObjWriter *repomocks.Writer
|
||||
rawWrtierRet object.ID
|
||||
rawWriterRetErr error
|
||||
expectedRet udmrepo.ID
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "raw writer is nil",
|
||||
expectedErr: "object writer is closed or not open",
|
||||
},
|
||||
{
|
||||
name: "raw result fail",
|
||||
rawObjWriter: repomocks.NewWriter(t),
|
||||
rawWriterRetErr: errors.New("fake-result-error"),
|
||||
expectedErr: "error to wait object: fake-result-error",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
rawObjWriter: repomocks.NewWriter(t),
|
||||
rawWrtierRet: object.ID{},
|
||||
expectedRet: udmrepo.ID(""),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
kr := &kopiaObjectWriter{}
|
||||
|
||||
if tc.rawObjWriter != nil {
|
||||
tc.rawObjWriter.On("Result").Return(tc.rawWrtierRet, tc.rawWriterRetErr)
|
||||
kr.rawWriter = tc.rawObjWriter
|
||||
}
|
||||
|
||||
ret, err := kr.Result()
|
||||
|
||||
if tc.expectedErr == "" {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, tc.expectedRet, ret)
|
||||
} else {
|
||||
assert.EqualError(t, err, tc.expectedErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriterClose(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
rawObjWriter *repomocks.Writer
|
||||
rawWriterRetErr error
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "raw writer is nil",
|
||||
},
|
||||
{
|
||||
name: "raw close fail",
|
||||
rawObjWriter: repomocks.NewWriter(t),
|
||||
rawWriterRetErr: errors.New("fake-close-error"),
|
||||
expectedErr: "fake-close-error",
|
||||
},
|
||||
{
|
||||
name: "succeed",
|
||||
rawObjWriter: repomocks.NewWriter(t),
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
kr := &kopiaObjectWriter{}
|
||||
|
||||
if tc.rawObjWriter != nil {
|
||||
tc.rawObjWriter.On("Close").Return(tc.rawWriterRetErr)
|
||||
kr.rawWriter = tc.rawObjWriter
|
||||
}
|
||||
|
||||
err := kr.Close()
|
||||
|
||||
if tc.expectedErr == "" {
|
||||
assert.NoError(t, err)
|
||||
} else {
|
||||
assert.EqualError(t, err, tc.expectedErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestMaintainProgress(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
progress int64
|
||||
uploaded int64
|
||||
throttle logThrottle
|
||||
logMessage string
|
||||
}{
|
||||
{
|
||||
name: "should not output",
|
||||
throttle: logThrottle{
|
||||
lastTime: math.MaxInt64,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "should output",
|
||||
progress: 100,
|
||||
uploaded: 200,
|
||||
logMessage: "Repo maintenance uploaded 300 bytes.",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
logMessage := ""
|
||||
km := &kopiaMaintenance{
|
||||
logger: velerotest.NewSingleLogger(&logMessage),
|
||||
throttle: tc.throttle,
|
||||
uploaded: tc.uploaded,
|
||||
}
|
||||
|
||||
km.maintainProgress(tc.progress)
|
||||
|
||||
if len(tc.logMessage) > 0 {
|
||||
assert.Contains(t, logMessage, tc.logMessage)
|
||||
} else {
|
||||
assert.Equal(t, "", logMessage)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue