issue 9626: let go for uninitialized repo under readonly mode

Signed-off-by: Lyndon-Li <lyonghui@vmware.com>
This commit is contained in:
Lyndon-Li
2026-03-20 17:26:31 +08:00
parent 856f1296fc
commit a6e579cb93
7 changed files with 532 additions and 177 deletions

View File

@@ -0,0 +1 @@
Fix issue #9626, let go for uninitialized repo under readonly mode

View File

@@ -208,14 +208,16 @@ func (urp *unifiedRepoProvider) PrepareRepo(ctx context.Context, param RepoParam
return errors.Wrap(err, "error to get repo options")
}
if created, err := urp.repoService.IsCreated(ctx, *repoOption); err != nil {
readOnly := (param.BackupLocation.Spec.AccessMode == velerov1api.BackupStorageLocationAccessModeReadOnly)
if ready, err := urp.repoService.IsReady(ctx, *repoOption, readOnly); err != nil {
return errors.Wrap(err, "error to check backup repo")
} else if created {
} else if ready {
log.Info("Repo has already been initialized")
return nil
}
if param.BackupLocation.Spec.AccessMode == velerov1api.BackupStorageLocationAccessModeReadOnly {
if readOnly {
return errors.Errorf("cannot create new backup repo for read-only backup storage location %s/%s", param.BackupLocation.Namespace, param.BackupLocation.Name)
}

View File

@@ -613,7 +613,7 @@ func TestPrepareRepo(t *testing.T) {
getter *credmock.SecretStore
repoService *reposervicenmocks.BackupRepoService
retFuncCreate func(context.Context, udmrepo.RepoOptions) error
retFuncCheck func(context.Context, udmrepo.RepoOptions) (bool, error)
retFuncCheck func(context.Context, udmrepo.RepoOptions, bool) (bool, error)
credStoreReturn string
credStoreError error
readOnlyBSL bool
@@ -656,7 +656,7 @@ func TestPrepareRepo(t *testing.T) {
},
},
repoService: new(reposervicenmocks.BackupRepoService),
retFuncCheck: func(ctx context.Context, repoOption udmrepo.RepoOptions) (bool, error) {
retFuncCheck: func(ctx context.Context, repoOption udmrepo.RepoOptions, readOnly bool) (bool, error) {
return false, errors.New("fake-error")
},
expectedErr: "error to check backup repo: fake-error",
@@ -674,7 +674,7 @@ func TestPrepareRepo(t *testing.T) {
},
},
repoService: new(reposervicenmocks.BackupRepoService),
retFuncCheck: func(ctx context.Context, repoOption udmrepo.RepoOptions) (bool, error) {
retFuncCheck: func(ctx context.Context, repoOption udmrepo.RepoOptions, readOnly bool) (bool, error) {
return true, nil
},
retFuncCreate: func(ctx context.Context, repoOption udmrepo.RepoOptions) error {
@@ -695,7 +695,7 @@ func TestPrepareRepo(t *testing.T) {
},
},
repoService: new(reposervicenmocks.BackupRepoService),
retFuncCheck: func(ctx context.Context, repoOption udmrepo.RepoOptions) (bool, error) {
retFuncCheck: func(ctx context.Context, repoOption udmrepo.RepoOptions, readOnly bool) (bool, error) {
return false, nil
},
retFuncCreate: func(ctx context.Context, repoOption udmrepo.RepoOptions) error {
@@ -716,7 +716,7 @@ func TestPrepareRepo(t *testing.T) {
},
},
repoService: new(reposervicenmocks.BackupRepoService),
retFuncCheck: func(ctx context.Context, repoOption udmrepo.RepoOptions) (bool, error) {
retFuncCheck: func(ctx context.Context, repoOption udmrepo.RepoOptions, readOnly bool) (bool, error) {
return false, nil
},
retFuncCreate: func(ctx context.Context, repoOption udmrepo.RepoOptions) error {
@@ -737,7 +737,7 @@ func TestPrepareRepo(t *testing.T) {
},
},
repoService: new(reposervicenmocks.BackupRepoService),
retFuncCheck: func(ctx context.Context, repoOption udmrepo.RepoOptions) (bool, error) {
retFuncCheck: func(ctx context.Context, repoOption udmrepo.RepoOptions, readOnly bool) (bool, error) {
return false, nil
},
retFuncCreate: func(ctx context.Context, repoOption udmrepo.RepoOptions) error {
@@ -758,7 +758,7 @@ func TestPrepareRepo(t *testing.T) {
},
},
repoService: new(reposervicenmocks.BackupRepoService),
retFuncCheck: func(ctx context.Context, repoOption udmrepo.RepoOptions) (bool, error) {
retFuncCheck: func(ctx context.Context, repoOption udmrepo.RepoOptions, readOnly bool) (bool, error) {
return false, nil
},
retFuncCreate: func(ctx context.Context, repoOption udmrepo.RepoOptions) error {
@@ -785,7 +785,7 @@ func TestPrepareRepo(t *testing.T) {
log: velerotest.NewLogger(),
}
tc.repoService.On("IsCreated", mock.Anything, mock.Anything).Return(tc.retFuncCheck)
tc.repoService.On("IsReady", mock.Anything, mock.Anything, mock.Anything).Return(tc.retFuncCheck)
tc.repoService.On("Create", mock.Anything, mock.Anything, mock.Anything).Return(tc.retFuncCreate)
if tc.readOnlyBSL {

View File

@@ -129,20 +129,28 @@ func (ks *kopiaRepoService) Connect(ctx context.Context, repoOption udmrepo.Repo
return ConnectBackupRepo(repoCtx, repoOption, ks.logger)
}
func (ks *kopiaRepoService) IsCreated(ctx context.Context, repoOption udmrepo.RepoOptions) (bool, error) {
var funcGetRepositoryStatus = GetRepositoryStatus
func (ks *kopiaRepoService) IsReady(ctx context.Context, repoOption udmrepo.RepoOptions, readOnly bool) (bool, error) {
repoCtx := kopia.SetupKopiaLog(ctx, ks.logger)
status, err := GetRepositoryStatus(repoCtx, repoOption, ks.logger)
status, err := funcGetRepositoryStatus(repoCtx, repoOption, ks.logger)
if err != nil {
return false, err
}
if status != RepoStatusCreated {
ks.logger.Infof("Repo is not fully created, status %v", status)
return false, nil
if status == RepoStatusCreated {
return true, nil
}
return true, nil
if status == RepoStatusNotInitialized && readOnly {
ks.logger.Warnf("Repo is not initialized, could be for read")
return true, nil
}
ks.logger.Infof("Repo is not fully created, status %v", status)
return false, nil
}
func (ks *kopiaRepoService) Open(ctx context.Context, repoOption udmrepo.RepoOptions) (udmrepo.BackupRepo, error) {

View File

@@ -27,6 +27,7 @@ import (
"github.com/kopia/kopia/repo/manifest"
"github.com/kopia/kopia/repo/object"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
@@ -1197,3 +1198,79 @@ func TestClientSideCacheLimit(t *testing.T) {
})
}
}
func TestIsReady(t *testing.T) {
testCases := []struct {
name string
funGetStatus func(context.Context, udmrepo.RepoOptions, logrus.FieldLogger) (RepoStatus, error)
readOnly bool
expected bool
expectedErr string
}{
{
name: "get status error",
funGetStatus: func(context.Context, udmrepo.RepoOptions, logrus.FieldLogger) (RepoStatus, error) {
return RepoStatusUnknown, errors.New("fake-get-error")
},
expectedErr: "fake-get-error",
},
{
name: "success",
funGetStatus: func(context.Context, udmrepo.RepoOptions, logrus.FieldLogger) (RepoStatus, error) {
return RepoStatusCreated, nil
},
expected: true,
},
{
name: "not initialized, not readonly",
funGetStatus: func(context.Context, udmrepo.RepoOptions, logrus.FieldLogger) (RepoStatus, error) {
return RepoStatusNotInitialized, nil
},
},
{
name: "not initialized, readonly",
funGetStatus: func(context.Context, udmrepo.RepoOptions, logrus.FieldLogger) (RepoStatus, error) {
return RepoStatusNotInitialized, nil
},
readOnly: true,
expected: true,
},
{
name: "other status 1",
funGetStatus: func(context.Context, udmrepo.RepoOptions, logrus.FieldLogger) (RepoStatus, error) {
return RepoStatusUnknown, nil
},
},
{
name: "other status 2",
funGetStatus: func(context.Context, udmrepo.RepoOptions, logrus.FieldLogger) (RepoStatus, error) {
return RepoStatusCorrupted, nil
},
},
{
name: "other status 3",
funGetStatus: func(context.Context, udmrepo.RepoOptions, logrus.FieldLogger) (RepoStatus, error) {
return RepoStatusSystemNotCreated, nil
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
ks := &kopiaRepoService{
logger: velerotest.NewLogger(),
}
funcGetRepositoryStatus = tc.funGetStatus
ready, err := ks.IsReady(t.Context(), udmrepo.RepoOptions{}, tc.readOnly)
if tc.expectedErr != "" {
require.EqualError(t, err, tc.expectedErr)
} else {
require.NoError(t, err)
}
require.Equal(t, tc.expected, ready)
})
}
}

View File

@@ -1,169 +1,17 @@
// Code generated by mockery v2.53.2. DO NOT EDIT.
// Code generated by mockery; DO NOT EDIT.
// github.com/vektra/mockery
// template: testify
package mocks
import (
context "context"
time "time"
"context"
"time"
mock "github.com/stretchr/testify/mock"
udmrepo "github.com/vmware-tanzu/velero/pkg/repository/udmrepo"
"github.com/vmware-tanzu/velero/pkg/repository/udmrepo"
)
// BackupRepoService is an autogenerated mock type for the BackupRepoService type
type BackupRepoService struct {
mock.Mock
}
// ClientSideCacheLimit provides a mock function with given fields: repoOption
func (_m *BackupRepoService) ClientSideCacheLimit(repoOption map[string]string) int64 {
ret := _m.Called(repoOption)
if len(ret) == 0 {
panic("no return value specified for ClientSideCacheLimit")
}
var r0 int64
if rf, ok := ret.Get(0).(func(map[string]string) int64); ok {
r0 = rf(repoOption)
} else {
r0 = ret.Get(0).(int64)
}
return r0
}
// Connect provides a mock function with given fields: ctx, repoOption
func (_m *BackupRepoService) Connect(ctx context.Context, repoOption udmrepo.RepoOptions) error {
ret := _m.Called(ctx, repoOption)
if len(ret) == 0 {
panic("no return value specified for Connect")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, udmrepo.RepoOptions) error); ok {
r0 = rf(ctx, repoOption)
} else {
r0 = ret.Error(0)
}
return r0
}
// Create provides a mock function with given fields: ctx, repoOption
func (_m *BackupRepoService) Create(ctx context.Context, repoOption udmrepo.RepoOptions) error {
ret := _m.Called(ctx, repoOption)
if len(ret) == 0 {
panic("no return value specified for Create")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, udmrepo.RepoOptions) error); ok {
r0 = rf(ctx, repoOption)
} else {
r0 = ret.Error(0)
}
return r0
}
// DefaultMaintenanceFrequency provides a mock function with no fields
func (_m *BackupRepoService) DefaultMaintenanceFrequency() time.Duration {
ret := _m.Called()
if len(ret) == 0 {
panic("no return value specified for DefaultMaintenanceFrequency")
}
var r0 time.Duration
if rf, ok := ret.Get(0).(func() time.Duration); ok {
r0 = rf()
} else {
r0 = ret.Get(0).(time.Duration)
}
return r0
}
// IsCreated provides a mock function with given fields: ctx, repoOption
func (_m *BackupRepoService) IsCreated(ctx context.Context, repoOption udmrepo.RepoOptions) (bool, error) {
ret := _m.Called(ctx, repoOption)
if len(ret) == 0 {
panic("no return value specified for IsCreated")
}
var r0 bool
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, udmrepo.RepoOptions) (bool, error)); ok {
return rf(ctx, repoOption)
}
if rf, ok := ret.Get(0).(func(context.Context, udmrepo.RepoOptions) bool); ok {
r0 = rf(ctx, repoOption)
} else {
r0 = ret.Get(0).(bool)
}
if rf, ok := ret.Get(1).(func(context.Context, udmrepo.RepoOptions) error); ok {
r1 = rf(ctx, repoOption)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// Maintain provides a mock function with given fields: ctx, repoOption
func (_m *BackupRepoService) Maintain(ctx context.Context, repoOption udmrepo.RepoOptions) error {
ret := _m.Called(ctx, repoOption)
if len(ret) == 0 {
panic("no return value specified for Maintain")
}
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, udmrepo.RepoOptions) error); ok {
r0 = rf(ctx, repoOption)
} else {
r0 = ret.Error(0)
}
return r0
}
// Open provides a mock function with given fields: ctx, repoOption
func (_m *BackupRepoService) Open(ctx context.Context, repoOption udmrepo.RepoOptions) (udmrepo.BackupRepo, error) {
ret := _m.Called(ctx, repoOption)
if len(ret) == 0 {
panic("no return value specified for Open")
}
var r0 udmrepo.BackupRepo
var r1 error
if rf, ok := ret.Get(0).(func(context.Context, udmrepo.RepoOptions) (udmrepo.BackupRepo, error)); ok {
return rf(ctx, repoOption)
}
if rf, ok := ret.Get(0).(func(context.Context, udmrepo.RepoOptions) udmrepo.BackupRepo); ok {
r0 = rf(ctx, repoOption)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(udmrepo.BackupRepo)
}
}
if rf, ok := ret.Get(1).(func(context.Context, udmrepo.RepoOptions) error); ok {
r1 = rf(ctx, repoOption)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// NewBackupRepoService creates a new instance of BackupRepoService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func NewBackupRepoService(t interface {
@@ -177,3 +25,422 @@ func NewBackupRepoService(t interface {
return mock
}
// BackupRepoService is an autogenerated mock type for the BackupRepoService type
type BackupRepoService struct {
mock.Mock
}
type BackupRepoService_Expecter struct {
mock *mock.Mock
}
func (_m *BackupRepoService) EXPECT() *BackupRepoService_Expecter {
return &BackupRepoService_Expecter{mock: &_m.Mock}
}
// ClientSideCacheLimit provides a mock function for the type BackupRepoService
func (_mock *BackupRepoService) ClientSideCacheLimit(repoOption map[string]string) int64 {
ret := _mock.Called(repoOption)
if len(ret) == 0 {
panic("no return value specified for ClientSideCacheLimit")
}
var r0 int64
if returnFunc, ok := ret.Get(0).(func(map[string]string) int64); ok {
r0 = returnFunc(repoOption)
} else {
r0 = ret.Get(0).(int64)
}
return r0
}
// BackupRepoService_ClientSideCacheLimit_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ClientSideCacheLimit'
type BackupRepoService_ClientSideCacheLimit_Call struct {
*mock.Call
}
// ClientSideCacheLimit is a helper method to define mock.On call
// - repoOption map[string]string
func (_e *BackupRepoService_Expecter) ClientSideCacheLimit(repoOption interface{}) *BackupRepoService_ClientSideCacheLimit_Call {
return &BackupRepoService_ClientSideCacheLimit_Call{Call: _e.mock.On("ClientSideCacheLimit", repoOption)}
}
func (_c *BackupRepoService_ClientSideCacheLimit_Call) Run(run func(repoOption map[string]string)) *BackupRepoService_ClientSideCacheLimit_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 map[string]string
if args[0] != nil {
arg0 = args[0].(map[string]string)
}
run(
arg0,
)
})
return _c
}
func (_c *BackupRepoService_ClientSideCacheLimit_Call) Return(n int64) *BackupRepoService_ClientSideCacheLimit_Call {
_c.Call.Return(n)
return _c
}
func (_c *BackupRepoService_ClientSideCacheLimit_Call) RunAndReturn(run func(repoOption map[string]string) int64) *BackupRepoService_ClientSideCacheLimit_Call {
_c.Call.Return(run)
return _c
}
// Connect provides a mock function for the type BackupRepoService
func (_mock *BackupRepoService) Connect(ctx context.Context, repoOption udmrepo.RepoOptions) error {
ret := _mock.Called(ctx, repoOption)
if len(ret) == 0 {
panic("no return value specified for Connect")
}
var r0 error
if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.RepoOptions) error); ok {
r0 = returnFunc(ctx, repoOption)
} else {
r0 = ret.Error(0)
}
return r0
}
// BackupRepoService_Connect_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Connect'
type BackupRepoService_Connect_Call struct {
*mock.Call
}
// Connect is a helper method to define mock.On call
// - ctx context.Context
// - repoOption udmrepo.RepoOptions
func (_e *BackupRepoService_Expecter) Connect(ctx interface{}, repoOption interface{}) *BackupRepoService_Connect_Call {
return &BackupRepoService_Connect_Call{Call: _e.mock.On("Connect", ctx, repoOption)}
}
func (_c *BackupRepoService_Connect_Call) Run(run func(ctx context.Context, repoOption udmrepo.RepoOptions)) *BackupRepoService_Connect_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 udmrepo.RepoOptions
if args[1] != nil {
arg1 = args[1].(udmrepo.RepoOptions)
}
run(
arg0,
arg1,
)
})
return _c
}
func (_c *BackupRepoService_Connect_Call) Return(err error) *BackupRepoService_Connect_Call {
_c.Call.Return(err)
return _c
}
func (_c *BackupRepoService_Connect_Call) RunAndReturn(run func(ctx context.Context, repoOption udmrepo.RepoOptions) error) *BackupRepoService_Connect_Call {
_c.Call.Return(run)
return _c
}
// Create provides a mock function for the type BackupRepoService
func (_mock *BackupRepoService) Create(ctx context.Context, repoOption udmrepo.RepoOptions) error {
ret := _mock.Called(ctx, repoOption)
if len(ret) == 0 {
panic("no return value specified for Create")
}
var r0 error
if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.RepoOptions) error); ok {
r0 = returnFunc(ctx, repoOption)
} else {
r0 = ret.Error(0)
}
return r0
}
// BackupRepoService_Create_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Create'
type BackupRepoService_Create_Call struct {
*mock.Call
}
// Create is a helper method to define mock.On call
// - ctx context.Context
// - repoOption udmrepo.RepoOptions
func (_e *BackupRepoService_Expecter) Create(ctx interface{}, repoOption interface{}) *BackupRepoService_Create_Call {
return &BackupRepoService_Create_Call{Call: _e.mock.On("Create", ctx, repoOption)}
}
func (_c *BackupRepoService_Create_Call) Run(run func(ctx context.Context, repoOption udmrepo.RepoOptions)) *BackupRepoService_Create_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 udmrepo.RepoOptions
if args[1] != nil {
arg1 = args[1].(udmrepo.RepoOptions)
}
run(
arg0,
arg1,
)
})
return _c
}
func (_c *BackupRepoService_Create_Call) Return(err error) *BackupRepoService_Create_Call {
_c.Call.Return(err)
return _c
}
func (_c *BackupRepoService_Create_Call) RunAndReturn(run func(ctx context.Context, repoOption udmrepo.RepoOptions) error) *BackupRepoService_Create_Call {
_c.Call.Return(run)
return _c
}
// DefaultMaintenanceFrequency provides a mock function for the type BackupRepoService
func (_mock *BackupRepoService) DefaultMaintenanceFrequency() time.Duration {
ret := _mock.Called()
if len(ret) == 0 {
panic("no return value specified for DefaultMaintenanceFrequency")
}
var r0 time.Duration
if returnFunc, ok := ret.Get(0).(func() time.Duration); ok {
r0 = returnFunc()
} else {
r0 = ret.Get(0).(time.Duration)
}
return r0
}
// BackupRepoService_DefaultMaintenanceFrequency_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'DefaultMaintenanceFrequency'
type BackupRepoService_DefaultMaintenanceFrequency_Call struct {
*mock.Call
}
// DefaultMaintenanceFrequency is a helper method to define mock.On call
func (_e *BackupRepoService_Expecter) DefaultMaintenanceFrequency() *BackupRepoService_DefaultMaintenanceFrequency_Call {
return &BackupRepoService_DefaultMaintenanceFrequency_Call{Call: _e.mock.On("DefaultMaintenanceFrequency")}
}
func (_c *BackupRepoService_DefaultMaintenanceFrequency_Call) Run(run func()) *BackupRepoService_DefaultMaintenanceFrequency_Call {
_c.Call.Run(func(args mock.Arguments) {
run()
})
return _c
}
func (_c *BackupRepoService_DefaultMaintenanceFrequency_Call) Return(duration time.Duration) *BackupRepoService_DefaultMaintenanceFrequency_Call {
_c.Call.Return(duration)
return _c
}
func (_c *BackupRepoService_DefaultMaintenanceFrequency_Call) RunAndReturn(run func() time.Duration) *BackupRepoService_DefaultMaintenanceFrequency_Call {
_c.Call.Return(run)
return _c
}
// IsReady provides a mock function for the type BackupRepoService
func (_mock *BackupRepoService) IsReady(ctx context.Context, repoOption udmrepo.RepoOptions, readOnly bool) (bool, error) {
ret := _mock.Called(ctx, repoOption, readOnly)
if len(ret) == 0 {
panic("no return value specified for IsReady")
}
var r0 bool
var r1 error
if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.RepoOptions, bool) (bool, error)); ok {
return returnFunc(ctx, repoOption, readOnly)
}
if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.RepoOptions, bool) bool); ok {
r0 = returnFunc(ctx, repoOption, readOnly)
} else {
r0 = ret.Get(0).(bool)
}
if returnFunc, ok := ret.Get(1).(func(context.Context, udmrepo.RepoOptions, bool) error); ok {
r1 = returnFunc(ctx, repoOption, readOnly)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// BackupRepoService_IsReady_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'IsReady'
type BackupRepoService_IsReady_Call struct {
*mock.Call
}
// IsReady is a helper method to define mock.On call
// - ctx context.Context
// - repoOption udmrepo.RepoOptions
// - readOnly bool
func (_e *BackupRepoService_Expecter) IsReady(ctx interface{}, repoOption interface{}, readOnly interface{}) *BackupRepoService_IsReady_Call {
return &BackupRepoService_IsReady_Call{Call: _e.mock.On("IsReady", ctx, repoOption, readOnly)}
}
func (_c *BackupRepoService_IsReady_Call) Run(run func(ctx context.Context, repoOption udmrepo.RepoOptions, readOnly bool)) *BackupRepoService_IsReady_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 udmrepo.RepoOptions
if args[1] != nil {
arg1 = args[1].(udmrepo.RepoOptions)
}
var arg2 bool
if args[2] != nil {
arg2 = args[2].(bool)
}
run(
arg0,
arg1,
arg2,
)
})
return _c
}
func (_c *BackupRepoService_IsReady_Call) Return(b bool, err error) *BackupRepoService_IsReady_Call {
_c.Call.Return(b, err)
return _c
}
func (_c *BackupRepoService_IsReady_Call) RunAndReturn(run func(ctx context.Context, repoOption udmrepo.RepoOptions, readOnly bool) (bool, error)) *BackupRepoService_IsReady_Call {
_c.Call.Return(run)
return _c
}
// Maintain provides a mock function for the type BackupRepoService
func (_mock *BackupRepoService) Maintain(ctx context.Context, repoOption udmrepo.RepoOptions) error {
ret := _mock.Called(ctx, repoOption)
if len(ret) == 0 {
panic("no return value specified for Maintain")
}
var r0 error
if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.RepoOptions) error); ok {
r0 = returnFunc(ctx, repoOption)
} else {
r0 = ret.Error(0)
}
return r0
}
// BackupRepoService_Maintain_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Maintain'
type BackupRepoService_Maintain_Call struct {
*mock.Call
}
// Maintain is a helper method to define mock.On call
// - ctx context.Context
// - repoOption udmrepo.RepoOptions
func (_e *BackupRepoService_Expecter) Maintain(ctx interface{}, repoOption interface{}) *BackupRepoService_Maintain_Call {
return &BackupRepoService_Maintain_Call{Call: _e.mock.On("Maintain", ctx, repoOption)}
}
func (_c *BackupRepoService_Maintain_Call) Run(run func(ctx context.Context, repoOption udmrepo.RepoOptions)) *BackupRepoService_Maintain_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 udmrepo.RepoOptions
if args[1] != nil {
arg1 = args[1].(udmrepo.RepoOptions)
}
run(
arg0,
arg1,
)
})
return _c
}
func (_c *BackupRepoService_Maintain_Call) Return(err error) *BackupRepoService_Maintain_Call {
_c.Call.Return(err)
return _c
}
func (_c *BackupRepoService_Maintain_Call) RunAndReturn(run func(ctx context.Context, repoOption udmrepo.RepoOptions) error) *BackupRepoService_Maintain_Call {
_c.Call.Return(run)
return _c
}
// Open provides a mock function for the type BackupRepoService
func (_mock *BackupRepoService) Open(ctx context.Context, repoOption udmrepo.RepoOptions) (udmrepo.BackupRepo, error) {
ret := _mock.Called(ctx, repoOption)
if len(ret) == 0 {
panic("no return value specified for Open")
}
var r0 udmrepo.BackupRepo
var r1 error
if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.RepoOptions) (udmrepo.BackupRepo, error)); ok {
return returnFunc(ctx, repoOption)
}
if returnFunc, ok := ret.Get(0).(func(context.Context, udmrepo.RepoOptions) udmrepo.BackupRepo); ok {
r0 = returnFunc(ctx, repoOption)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(udmrepo.BackupRepo)
}
}
if returnFunc, ok := ret.Get(1).(func(context.Context, udmrepo.RepoOptions) error); ok {
r1 = returnFunc(ctx, repoOption)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// BackupRepoService_Open_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Open'
type BackupRepoService_Open_Call struct {
*mock.Call
}
// Open is a helper method to define mock.On call
// - ctx context.Context
// - repoOption udmrepo.RepoOptions
func (_e *BackupRepoService_Expecter) Open(ctx interface{}, repoOption interface{}) *BackupRepoService_Open_Call {
return &BackupRepoService_Open_Call{Call: _e.mock.On("Open", ctx, repoOption)}
}
func (_c *BackupRepoService_Open_Call) Run(run func(ctx context.Context, repoOption udmrepo.RepoOptions)) *BackupRepoService_Open_Call {
_c.Call.Run(func(args mock.Arguments) {
var arg0 context.Context
if args[0] != nil {
arg0 = args[0].(context.Context)
}
var arg1 udmrepo.RepoOptions
if args[1] != nil {
arg1 = args[1].(udmrepo.RepoOptions)
}
run(
arg0,
arg1,
)
})
return _c
}
func (_c *BackupRepoService_Open_Call) Return(backupRepo udmrepo.BackupRepo, err error) *BackupRepoService_Open_Call {
_c.Call.Return(backupRepo, err)
return _c
}
func (_c *BackupRepoService_Open_Call) RunAndReturn(run func(ctx context.Context, repoOption udmrepo.RepoOptions) (udmrepo.BackupRepo, error)) *BackupRepoService_Open_Call {
_c.Call.Return(run)
return _c
}

View File

@@ -85,9 +85,9 @@ type BackupRepoService interface {
// repoOption: option to the backup repository and the underlying backup storage.
Connect(ctx context.Context, repoOption RepoOptions) error
// IsCreated checks if the backup repository has been created in the underlying backup storage.
// IsReady checks if the backup repository has been ready in the underlying backup storage.
// repoOption: option to the underlying backup storage
IsCreated(ctx context.Context, repoOption RepoOptions) (bool, error)
IsReady(ctx context.Context, repoOption RepoOptions, readOnly bool) (bool, error)
// Open opens an backup repository that has been created/connected.
// repoOption: options to open the backup repository and the underlying storage.