diff --git a/src/cli/backup/backup.go b/src/cli/backup/backup.go index bf936c5ea..a79a8afb2 100644 --- a/src/cli/backup/backup.go +++ b/src/cli/backup/backup.go @@ -165,7 +165,7 @@ var defaultSelectorConfig = selectors.Config{OnlyMatchItemNames: true} func runBackups( ctx context.Context, - r repository.Repository, + r repository.Repositoryer, serviceName string, selectorSet []selectors.Selector, ins idname.Cacher, @@ -342,7 +342,7 @@ func ifShow(flag string) bool { return strings.ToLower(strings.TrimSpace(flag)) == "show" } -func printBackupStats(ctx context.Context, r repository.Repository, bid string) { +func printBackupStats(ctx context.Context, r repository.Repositoryer, bid string) { b, err := r.Backup(ctx, bid) if err != nil { logger.CtxErr(ctx, err).Error("finding backup immediately after backup operation completion") diff --git a/src/cli/backup/helpers_test.go b/src/cli/backup/helpers_test.go index cba71af95..e7a59f361 100644 --- a/src/cli/backup/helpers_test.go +++ b/src/cli/backup/helpers_test.go @@ -124,7 +124,7 @@ func newIntegrationTesterSetup(t *testing.T) intgTesterSetup { type dependencies struct { st storage.Storage - repo repository.Repository + repo repository.Repositoryer vpr *viper.Viper recorder strings.Builder configFilePath string @@ -154,12 +154,15 @@ func prepM365Test( vpr, cfgFP := tconfig.MakeTempTestConfigClone(t, force) ctx = config.SetViper(ctx, vpr) - repo, err := repository.Initialize( + repo, err := repository.New( ctx, acct, st, control.DefaultOptions(), - ctrlRepo.Retention{}) + repository.NewRepoID) + require.NoError(t, err, clues.ToCore(err)) + + err = repo.Initialize(ctx, ctrlRepo.Retention{}) require.NoError(t, err, clues.ToCore(err)) return dependencies{ diff --git a/src/cli/repo/filesystem.go b/src/cli/repo/filesystem.go index 86273f439..ef03d3657 100644 --- a/src/cli/repo/filesystem.go +++ b/src/cli/repo/filesystem.go @@ -108,13 +108,17 @@ func initFilesystemCmd(cmd *cobra.Command, args []string) error { return Only(ctx, clues.Wrap(err, "Failed to parse m365 account config")) } - r, err := repository.Initialize( + r, err := repository.New( ctx, cfg.Account, cfg.Storage, opt, - retention) + repository.NewRepoID) if err != nil { + return Only(ctx, clues.Wrap(err, "Failed to construct the repository controller")) + } + + if err = r.Initialize(ctx, retention); err != nil { if flags.SucceedIfExistsFV && errors.Is(err, repository.ErrorRepoAlreadyExists) { return nil } @@ -191,13 +195,17 @@ func connectFilesystemCmd(cmd *cobra.Command, args []string) error { opts := utils.ControlWithConfig(cfg) - r, err := repository.ConnectAndSendConnectEvent( + r, err := repository.New( ctx, cfg.Account, cfg.Storage, - repoID, - opts) + opts, + repoID) if err != nil { + return Only(ctx, clues.Wrap(err, "Failed to create a repository controller")) + } + + if err := r.Connect(ctx); err != nil { return Only(ctx, clues.Wrap(err, "Failed to connect to the filesystem repository")) } diff --git a/src/cli/repo/filesystem_e2e_test.go b/src/cli/repo/filesystem_e2e_test.go index f2a99549e..514d0120b 100644 --- a/src/cli/repo/filesystem_e2e_test.go +++ b/src/cli/repo/filesystem_e2e_test.go @@ -132,12 +132,15 @@ func (suite *FilesystemE2ESuite) TestConnectFilesystemCmd() { ctx = config.SetViper(ctx, vpr) // init the repo first - _, err = repository.Initialize( + r, err := repository.New( ctx, account.Account{}, st, control.DefaultOptions(), - ctrlRepo.Retention{}) + repository.NewRepoID) + require.NoError(t, err, clues.ToCore(err)) + + err = r.Initialize(ctx, ctrlRepo.Retention{}) require.NoError(t, err, clues.ToCore(err)) // then test it diff --git a/src/cli/repo/s3.go b/src/cli/repo/s3.go index 1f3762320..343dddf03 100644 --- a/src/cli/repo/s3.go +++ b/src/cli/repo/s3.go @@ -130,13 +130,17 @@ func initS3Cmd(cmd *cobra.Command, args []string) error { return Only(ctx, clues.Wrap(err, "Failed to parse m365 account config")) } - r, err := repository.Initialize( + r, err := repository.New( ctx, cfg.Account, cfg.Storage, opt, - retentionOpts) + repository.NewRepoID) if err != nil { + return Only(ctx, clues.Wrap(err, "Failed to construct the repository controller")) + } + + if err = r.Initialize(ctx, retentionOpts); err != nil { if flags.SucceedIfExistsFV && errors.Is(err, repository.ErrorRepoAlreadyExists) { return nil } @@ -211,12 +215,12 @@ func connectS3Cmd(cmd *cobra.Command, args []string) error { opts := utils.ControlWithConfig(cfg) - r, err := repository.ConnectAndSendConnectEvent( + r, err := repository.New( ctx, cfg.Account, cfg.Storage, - repoID, - opts) + opts, + repoID) if err != nil { return Only(ctx, clues.Wrap(err, "Failed to connect to the S3 repository")) } diff --git a/src/cli/repo/s3_e2e_test.go b/src/cli/repo/s3_e2e_test.go index 55dbcab3a..0bca84ca6 100644 --- a/src/cli/repo/s3_e2e_test.go +++ b/src/cli/repo/s3_e2e_test.go @@ -208,12 +208,15 @@ func (suite *S3E2ESuite) TestConnectS3Cmd() { ctx = config.SetViper(ctx, vpr) // init the repo first - _, err = repository.Initialize( + r, err := repository.New( ctx, account.Account{}, st, control.DefaultOptions(), - ctrlRepo.Retention{}) + repository.NewRepoID) + require.NoError(t, err, clues.ToCore(err)) + + err = r.Initialize(ctx, ctrlRepo.Retention{}) require.NoError(t, err, clues.ToCore(err)) // then test it diff --git a/src/cli/restore/exchange_e2e_test.go b/src/cli/restore/exchange_e2e_test.go index 5b9f9a637..5e3d6181d 100644 --- a/src/cli/restore/exchange_e2e_test.go +++ b/src/cli/restore/exchange_e2e_test.go @@ -43,7 +43,7 @@ type RestoreExchangeE2ESuite struct { st storage.Storage vpr *viper.Viper cfgFP string - repo repository.Repository + repo repository.Repositoryer m365UserID string backupOps map[path.CategoryType]operations.BackupOperation } @@ -86,12 +86,15 @@ func (suite *RestoreExchangeE2ESuite) SetupSuite() { ) // init the repo first - suite.repo, err = repository.Initialize( + r, err := repository.New( ctx, suite.acct, suite.st, - control.Options{}, - ctrlRepo.Retention{}) + control.DefaultOptions(), + repository.NewRepoID) + require.NoError(t, err, clues.ToCore(err)) + + err = r.Initialize(ctx, ctrlRepo.Retention{}) require.NoError(t, err, clues.ToCore(err)) suite.backupOps = make(map[path.CategoryType]operations.BackupOperation) diff --git a/src/cli/utils/utils.go b/src/cli/utils/utils.go index 3cc58e947..e573bdb0a 100644 --- a/src/cli/utils/utils.go +++ b/src/cli/utils/utils.go @@ -31,7 +31,7 @@ func GetAccountAndConnectWithOverrides( ctx context.Context, cmd *cobra.Command, pst path.ServiceType, -) (repository.Repository, *storage.Storage, *account.Account, *control.Options, error) { +) (repository.Repositoryer, *storage.Storage, *account.Account, *control.Options, error) { provider, overrides, err := GetStorageProviderAndOverrides(ctx, cmd) if err != nil { return nil, nil, nil, nil, clues.Stack(err) @@ -45,7 +45,7 @@ func GetAccountAndConnect( pst path.ServiceType, provider storage.ProviderType, overrides map[string]string, -) (repository.Repository, *storage.Storage, *account.Account, *control.Options, error) { +) (repository.Repositoryer, *storage.Storage, *account.Account, *control.Options, error) { cfg, err := config.GetConfigRepoDetails( ctx, provider, @@ -63,8 +63,17 @@ func GetAccountAndConnect( opts := ControlWithConfig(cfg) - r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, repoID, opts) + r, err := repository.New( + ctx, + cfg.Account, + cfg.Storage, + opts, + repoID) if err != nil { + return nil, nil, nil, nil, clues.Wrap(err, "creating a repository controller") + } + + if err := r.Connect(ctx); err != nil { return nil, nil, nil, nil, clues.Wrap(err, "connecting to the "+cfg.Storage.Provider.String()+" repository") } @@ -81,7 +90,7 @@ func AccountConnectAndWriteRepoConfig( ctx context.Context, cmd *cobra.Command, pst path.ServiceType, -) (repository.Repository, *account.Account, error) { +) (repository.Repositoryer, *account.Account, error) { r, stg, acc, opts, err := GetAccountAndConnectWithOverrides( ctx, cmd, @@ -115,7 +124,7 @@ func AccountConnectAndWriteRepoConfig( } // CloseRepo handles closing a repo. -func CloseRepo(ctx context.Context, r repository.Repository) { +func CloseRepo(ctx context.Context, r repository.Repositoryer) { if err := r.Close(ctx); err != nil { fmt.Print("Error closing repository:", err) } diff --git a/src/cmd/longevity_test/longevity.go b/src/cmd/longevity_test/longevity.go index 5072f9683..0b47ea518 100644 --- a/src/cmd/longevity_test/longevity.go +++ b/src/cmd/longevity_test/longevity.go @@ -107,9 +107,19 @@ func pitrListBackups( opts := utils.ControlWithConfig(cfg) opts.Repo.ViewTimestamp = &pitr - r, err := repository.Connect(ctx, cfg.Account, cfg.Storage, cfg.RepoID, opts) + r, err := repository.New( + ctx, + cfg.Account, + cfg.Storage, + opts, + cfg.RepoID) if err != nil { - return clues.Wrap(err, "connecting to repo").WithClues(ctx) + return clues.Wrap(err, "creating a repo") + } + + err = r.Connect(ctx) + if err != nil { + return clues.Wrap(err, "connecting to the repository") } defer r.Close(ctx) diff --git a/src/pkg/repository/loadtest/repository_load_test.go b/src/pkg/repository/loadtest/repository_load_test.go index 4dc6b11c6..9cfc38ffc 100644 --- a/src/pkg/repository/loadtest/repository_load_test.go +++ b/src/pkg/repository/loadtest/repository_load_test.go @@ -87,7 +87,7 @@ func TestMain(m *testing.M) { func initM365Repo(t *testing.T) ( context.Context, - repository.Repository, + repository.Repositoryer, account.Account, storage.Storage, ) { @@ -103,10 +103,18 @@ func initM365Repo(t *testing.T) ( FailureHandling: control.FailFast, } - repo, err := repository.Initialize(ctx, ac, st, opts, ctrlRepo.Retention{}) + r, err := repository.New( + ctx, + ac, + st, + opts, + repository.NewRepoID) require.NoError(t, err, clues.ToCore(err)) - return ctx, repo, ac, st + err = r.Initialize(ctx, ctrlRepo.Retention{}) + require.NoError(t, err, clues.ToCore(err)) + + return ctx, r, ac, st } // ------------------------------------------------------------------------------------------------ @@ -117,7 +125,7 @@ func initM365Repo(t *testing.T) ( func runLoadTest( t *testing.T, ctx context.Context, - r repository.Repository, + r repository.Repositoryer, prefix, service string, usersUnderTest []string, bupSel, restSel selectors.Selector, @@ -142,7 +150,7 @@ func runLoadTest( func runRestoreLoadTest( t *testing.T, ctx context.Context, - r repository.Repository, + r repository.Repositoryer, prefix, service, backupID string, usersUnderTest []string, restSel selectors.Selector, @@ -200,7 +208,7 @@ func runBackupLoadTest( func runBackupListLoadTest( t *testing.T, ctx context.Context, - r repository.Repository, + r repository.Repositoryer, name, expectID string, ) { //revive:enable:context-as-argument @@ -237,7 +245,7 @@ func runBackupListLoadTest( func runBackupDetailsLoadTest( t *testing.T, ctx context.Context, - r repository.Repository, + r repository.Repositoryer, name, backupID string, users []string, ) { @@ -409,7 +417,7 @@ func normalizeCategorySet(t *testing.T, cats map[string]struct{}) []string { type LoadExchangeSuite struct { tester.Suite ctx context.Context - repo repository.Repository + repo repository.Repositoryer acct account.Account //lint:ignore U1000 future test use st storage.Storage //lint:ignore U1000 future test use usersUnderTest []string @@ -459,7 +467,7 @@ func (suite *LoadExchangeSuite) TestExchange() { type IndividualLoadExchangeSuite struct { tester.Suite ctx context.Context - repo repository.Repository + repo repository.Repositoryer acct account.Account //lint:ignore U1000 future test use st storage.Storage //lint:ignore U1000 future test use usersUnderTest []string @@ -512,7 +520,7 @@ func (suite *IndividualLoadExchangeSuite) TestExchange() { type LoadOneDriveSuite struct { tester.Suite ctx context.Context - repo repository.Repository + repo repository.Repositoryer acct account.Account //lint:ignore U1000 future test use st storage.Storage //lint:ignore U1000 future test use usersUnderTest []string @@ -559,7 +567,7 @@ func (suite *LoadOneDriveSuite) TestOneDrive() { type IndividualLoadOneDriveSuite struct { tester.Suite ctx context.Context - repo repository.Repository + repo repository.Repositoryer acct account.Account //lint:ignore U1000 future test use st storage.Storage //lint:ignore U1000 future test use usersUnderTest []string @@ -609,7 +617,7 @@ func (suite *IndividualLoadOneDriveSuite) TestOneDrive() { type LoadSharePointSuite struct { tester.Suite ctx context.Context - repo repository.Repository + repo repository.Repositoryer acct account.Account //lint:ignore U1000 future test use st storage.Storage //lint:ignore U1000 future test use sitesUnderTest []string @@ -656,7 +664,7 @@ func (suite *LoadSharePointSuite) TestSharePoint() { type IndividualLoadSharePointSuite struct { tester.Suite ctx context.Context - repo repository.Repository + repo repository.Repositoryer acct account.Account //lint:ignore U1000 future test use st storage.Storage //lint:ignore U1000 future test use sitesUnderTest []string diff --git a/src/pkg/repository/repository.go b/src/pkg/repository/repository.go index 1189a3ef1..2f836570c 100644 --- a/src/pkg/repository/repository.go +++ b/src/pkg/repository/repository.go @@ -35,6 +35,8 @@ import ( "github.com/alcionai/corso/src/pkg/store" ) +const NewRepoID = "" + var ( ErrorRepoAlreadyExists = clues.New("a repository was already initialized with that configuration") ErrorBackupNotFound = clues.New("no backup exists with that id") @@ -56,7 +58,9 @@ type BackupGetter interface { ) (*fault.Errors, *backup.Backup, *fault.Bus) } -type Repository interface { +type Repositoryer interface { + Initialize(ctx context.Context, retentionOpts ctrlRepo.Retention) error + Connect(ctx context.Context) error GetID() string Close(context.Context) error NewBackup( @@ -117,6 +121,48 @@ func (r repository) GetID() string { return r.ID } +// New constructs a repository that can be used to Initialize or Connect a repo instance. +func New( + ctx context.Context, + acct account.Account, + s storage.Storage, + opts control.Options, + configFileRepoID string, +) (repo *repository, err error) { + ctx = clues.Add( + ctx, + "acct_provider", acct.Provider.String(), + "acct_id", clues.Hide(acct.ID()), + "storage_provider", s.Provider.String()) + + bus, err := events.NewBus(ctx, s, acct.ID(), opts) + if err != nil { + return nil, clues.Wrap(err, "constructing event bus").WithClues(ctx) + } + + repoID := configFileRepoID + if len(configFileRepoID) == 0 { + repoID = newRepoID(s) + } + + bus.SetRepoID(repoID) + + r := repository{ + ID: repoID, + Version: "v1", + Account: acct, + Storage: s, + Bus: bus, + Opts: opts, + } + + if !r.Opts.DisableMetrics { + bus.SetRepoID(r.ID) + } + + return &r, nil +} + // Initialize will: // - validate the m365 account & secrets // - connect to the m365 account to ensure communication capability @@ -125,19 +171,15 @@ func (r repository) GetID() string { // - update maintenance retention parameters as needed // - store the configuration details // - connect to the provider -// - return the connected repository -func Initialize( +func (r *repository) Initialize( ctx context.Context, - acct account.Account, - s storage.Storage, - opts control.Options, retentionOpts ctrlRepo.Retention, -) (repo Repository, err error) { +) (err error) { ctx = clues.Add( ctx, - "acct_provider", acct.Provider.String(), - "acct_id", clues.Hide(acct.ID()), - "storage_provider", s.Provider.String()) + "acct_provider", r.Account.Provider.String(), + "acct_id", clues.Hide(r.Account.ID()), + "storage_provider", r.Storage.Provider.String()) defer func() { if crErr := crash.Recovery(ctx, recover(), "repo init"); crErr != nil { @@ -145,55 +187,36 @@ func Initialize( } }() - kopiaRef := kopia.NewConn(s) - if err := kopiaRef.Initialize(ctx, opts.Repo, retentionOpts); err != nil { + kopiaRef := kopia.NewConn(r.Storage) + if err := kopiaRef.Initialize(ctx, r.Opts.Repo, retentionOpts); err != nil { // replace common internal errors so that sdk users can check results with errors.Is() if errors.Is(err, kopia.ErrorRepoAlreadyExists) { - return nil, clues.Stack(ErrorRepoAlreadyExists, err).WithClues(ctx) + return clues.Stack(ErrorRepoAlreadyExists, err).WithClues(ctx) } - return nil, clues.Wrap(err, "initializing kopia") + return clues.Wrap(err, "initializing kopia") } // kopiaRef comes with a count of 1 and NewWrapper/NewModelStore bumps it again so safe // to close here. defer kopiaRef.Close(ctx) - w, err := kopia.NewWrapper(kopiaRef) + r.dataLayer, err = kopia.NewWrapper(kopiaRef) if err != nil { - return nil, clues.Stack(err).WithClues(ctx) + return clues.Stack(err).WithClues(ctx) } - ms, err := kopia.NewModelStore(kopiaRef) + r.modelStore, err = kopia.NewModelStore(kopiaRef) if err != nil { - return nil, clues.Stack(err).WithClues(ctx) + return clues.Stack(err).WithClues(ctx) } - bus, err := events.NewBus(ctx, s, acct.ID(), opts) - if err != nil { - return nil, clues.Wrap(err, "constructing event bus") - } - - repoID := newRepoID(s) - bus.SetRepoID(repoID) - - r := &repository{ - ID: repoID, - Version: "v1", - Account: acct, - Storage: s, - Bus: bus, - Opts: opts, - dataLayer: w, - modelStore: ms, - } - - if err := newRepoModel(ctx, ms, r.ID); err != nil { - return nil, clues.New("setting up repository").WithClues(ctx) + if err := newRepoModel(ctx, r.modelStore, r.ID); err != nil { + return clues.Wrap(err, "setting up repository").WithClues(ctx) } r.Bus.Event(ctx, events.RepoInit, nil) - return r, nil + return nil } // Connect will: @@ -201,18 +224,12 @@ func Initialize( // - connect to the m365 account to ensure communication capability // - connect to the provider storage // - return the connected repository -func Connect( - ctx context.Context, - acct account.Account, - s storage.Storage, - repoid string, - opts control.Options, -) (r Repository, err error) { +func (r *repository) Connect(ctx context.Context) (err error) { ctx = clues.Add( ctx, - "acct_provider", acct.Provider.String(), - "acct_id", clues.Hide(acct.ID()), - "storage_provider", s.Provider.String()) + "acct_provider", r.Account.Provider.String(), + "acct_id", clues.Hide(r.Account.ID()), + "storage_provider", r.Storage.Provider.String()) defer func() { if crErr := crash.Recovery(ctx, recover(), "repo connect"); crErr != nil { @@ -223,71 +240,36 @@ func Connect( progressBar := observe.MessageWithCompletion(ctx, "Connecting to repository") defer close(progressBar) - kopiaRef := kopia.NewConn(s) - if err := kopiaRef.Connect(ctx, opts.Repo); err != nil { - return nil, clues.Wrap(err, "connecting kopia client") + kopiaRef := kopia.NewConn(r.Storage) + if err := kopiaRef.Connect(ctx, r.Opts.Repo); err != nil { + return clues.Wrap(err, "connecting kopia client") } // kopiaRef comes with a count of 1 and NewWrapper/NewModelStore bumps it again so safe // to close here. defer kopiaRef.Close(ctx) - w, err := kopia.NewWrapper(kopiaRef) + r.dataLayer, err = kopia.NewWrapper(kopiaRef) if err != nil { - return nil, clues.Stack(err).WithClues(ctx) + return clues.Stack(err).WithClues(ctx) } - ms, err := kopia.NewModelStore(kopiaRef) + r.modelStore, err = kopia.NewModelStore(kopiaRef) if err != nil { - return nil, clues.Stack(err).WithClues(ctx) + return clues.Stack(err).WithClues(ctx) } - bus, err := events.NewBus(ctx, s, acct.ID(), opts) - if err != nil { - return nil, clues.Wrap(err, "constructing event bus") - } - - if repoid == events.RepoIDNotFound { - rm, err := getRepoModel(ctx, ms) + if r.ID == events.RepoIDNotFound { + rm, err := getRepoModel(ctx, r.modelStore) if err != nil { - return nil, clues.New("retrieving repo info") + return clues.Wrap(err, "retrieving repo model info") } - repoid = string(rm.ID) + r.ID = string(rm.ID) } - // Do not query repo ID if metrics are disabled - if !opts.DisableMetrics { - bus.SetRepoID(repoid) - } - - // todo: ID and CreatedAt should get retrieved from a stored kopia config. - return &repository{ - ID: repoid, - Version: "v1", - Account: acct, - Storage: s, - Bus: bus, - Opts: opts, - dataLayer: w, - modelStore: ms, - }, nil -} - -func ConnectAndSendConnectEvent(ctx context.Context, - acct account.Account, - s storage.Storage, - repoid string, - opts control.Options, -) (Repository, error) { - repo, err := Connect(ctx, acct, s, repoid, opts) - if err != nil { - return nil, err - } - - r := repo.(*repository) r.Bus.Event(ctx, events.RepoConnect, nil) - return r, nil + return nil } func (r *repository) Close(ctx context.Context) error { diff --git a/src/pkg/repository/repository_test.go b/src/pkg/repository/repository_test.go index a9d262a7f..c276f35f5 100644 --- a/src/pkg/repository/repository_test.go +++ b/src/pkg/repository/repository_test.go @@ -6,7 +6,6 @@ import ( "time" "github.com/alcionai/clues" - "github.com/kopia/kopia/repo/blob/readonly" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" @@ -62,12 +61,15 @@ func (suite *RepositoryUnitSuite) TestInitialize() { st, err := test.storage() assert.NoError(t, err, clues.ToCore(err)) - _, err = Initialize( + r, err := New( ctx, test.account, st, control.DefaultOptions(), - ctrlRepo.Retention{}) + NewRepoID) + require.NoError(t, err, clues.ToCore(err)) + + err = r.Initialize(ctx, ctrlRepo.Retention{}) test.errCheck(t, err, clues.ToCore(err)) }) } @@ -101,7 +103,15 @@ func (suite *RepositoryUnitSuite) TestConnect() { st, err := test.storage() assert.NoError(t, err, clues.ToCore(err)) - _, err = Connect(ctx, test.account, st, "not_found", control.DefaultOptions()) + r, err := New( + ctx, + test.account, + st, + control.DefaultOptions(), + NewRepoID) + require.NoError(t, err, clues.ToCore(err)) + + err = r.Connect(ctx) test.errCheck(t, err, clues.ToCore(err)) }) } @@ -144,12 +154,15 @@ func (suite *RepositoryIntegrationSuite) TestInitialize() { defer flush() st := test.storage(t) - r, err := Initialize( + r, err := New( ctx, test.account, st, control.DefaultOptions(), - ctrlRepo.Retention{}) + NewRepoID) + require.NoError(t, err, clues.ToCore(err)) + + err = r.Initialize(ctx, ctrlRepo.Retention{}) if err == nil { defer func() { err := r.Close(ctx) @@ -168,21 +181,31 @@ const ( ) func (suite *RepositoryIntegrationSuite) TestInitializeWithRole() { + t := suite.T() + if _, ok := os.LookupEnv(roleARNEnvKey); !ok { - suite.T().Skip(roleARNEnvKey + " not set") + t.Skip(roleARNEnvKey + " not set") } - ctx, flush := tester.NewContext(suite.T()) + ctx, flush := tester.NewContext(t) defer flush() - st := storeTD.NewPrefixedS3Storage(suite.T()) + st := storeTD.NewPrefixedS3Storage(t) st.Role = os.Getenv(roleARNEnvKey) st.SessionName = "corso-repository-test" st.SessionDuration = roleDuration.String() - r, err := Initialize(ctx, account.Account{}, st, control.Options{}, ctrlRepo.Retention{}) - require.NoError(suite.T(), err) + r, err := New( + ctx, + account.Account{}, + st, + control.DefaultOptions(), + NewRepoID) + require.NoError(t, err, clues.ToCore(err)) + + err = r.Initialize(ctx, ctrlRepo.Retention{}) + require.NoError(t, err) defer func() { r.Close(ctx) @@ -197,17 +220,19 @@ func (suite *RepositoryIntegrationSuite) TestConnect() { // need to initialize the repository before we can test connecting to it. st := storeTD.NewPrefixedS3Storage(t) - - repo, err := Initialize( + r, err := New( ctx, account.Account{}, st, control.DefaultOptions(), - ctrlRepo.Retention{}) + NewRepoID) + require.NoError(t, err, clues.ToCore(err)) + + err = r.Initialize(ctx, ctrlRepo.Retention{}) require.NoError(t, err, clues.ToCore(err)) // now re-connect - _, err = Connect(ctx, account.Account{}, st, repo.GetID(), control.DefaultOptions()) + err = r.Connect(ctx) assert.NoError(t, err, clues.ToCore(err)) } @@ -219,13 +244,15 @@ func (suite *RepositoryIntegrationSuite) TestConnect_sameID() { // need to initialize the repository before we can test connecting to it. st := storeTD.NewPrefixedS3Storage(t) - - r, err := Initialize( + r, err := New( ctx, account.Account{}, st, control.DefaultOptions(), - ctrlRepo.Retention{}) + NewRepoID) + require.NoError(t, err, clues.ToCore(err)) + + err = r.Initialize(ctx, ctrlRepo.Retention{}) require.NoError(t, err, clues.ToCore(err)) oldID := r.GetID() @@ -234,7 +261,7 @@ func (suite *RepositoryIntegrationSuite) TestConnect_sameID() { require.NoError(t, err, clues.ToCore(err)) // now re-connect - r, err = Connect(ctx, account.Account{}, st, oldID, control.DefaultOptions()) + err = r.Connect(ctx) require.NoError(t, err, clues.ToCore(err)) assert.Equal(t, oldID, r.GetID()) } @@ -249,13 +276,15 @@ func (suite *RepositoryIntegrationSuite) TestNewBackup() { // need to initialize the repository before we can test connecting to it. st := storeTD.NewPrefixedS3Storage(t) - - r, err := Initialize( + r, err := New( ctx, acct, st, control.DefaultOptions(), - ctrlRepo.Retention{}) + NewRepoID) + require.NoError(t, err, clues.ToCore(err)) + + err = r.Initialize(ctx, ctrlRepo.Retention{}) require.NoError(t, err, clues.ToCore(err)) userID := tconfig.M365UserID(t) @@ -276,13 +305,15 @@ func (suite *RepositoryIntegrationSuite) TestNewRestore() { // need to initialize the repository before we can test connecting to it. st := storeTD.NewPrefixedS3Storage(t) - - r, err := Initialize( + r, err := New( ctx, acct, st, control.DefaultOptions(), - ctrlRepo.Retention{}) + "") + require.NoError(t, err, clues.ToCore(err)) + + err = r.Initialize(ctx, ctrlRepo.Retention{}) require.NoError(t, err, clues.ToCore(err)) ro, err := r.NewRestore( @@ -304,13 +335,15 @@ func (suite *RepositoryIntegrationSuite) TestNewBackupAndDelete() { // need to initialize the repository before we can test connecting to it. st := storeTD.NewPrefixedS3Storage(t) - - r, err := Initialize( + r, err := New( ctx, acct, st, control.DefaultOptions(), - ctrlRepo.Retention{}) + NewRepoID) + require.NoError(t, err, clues.ToCore(err)) + + err = r.Initialize(ctx, ctrlRepo.Retention{}) require.NoError(t, err, clues.ToCore(err)) userID := tconfig.M365UserID(t) @@ -355,13 +388,15 @@ func (suite *RepositoryIntegrationSuite) TestNewMaintenance() { // need to initialize the repository before we can test connecting to it. st := storeTD.NewPrefixedS3Storage(t) - - r, err := Initialize( + r, err := New( ctx, acct, st, control.DefaultOptions(), - ctrlRepo.Retention{}) + NewRepoID) + require.NoError(t, err, clues.ToCore(err)) + + err = r.Initialize(ctx, ctrlRepo.Retention{}) require.NoError(t, err, clues.ToCore(err)) mo, err := r.NewMaintenance(ctx, ctrlRepo.Maintenance{}) @@ -369,61 +404,6 @@ func (suite *RepositoryIntegrationSuite) TestNewMaintenance() { require.NotNil(t, mo) } -func (suite *RepositoryIntegrationSuite) TestConnect_DisableMetrics() { - t := suite.T() - - ctx, flush := tester.NewContext(t) - defer flush() - - // need to initialize the repository before we can test connecting to it. - st := storeTD.NewPrefixedS3Storage(t) - - repo, err := Initialize( - ctx, - account.Account{}, - st, - control.DefaultOptions(), - ctrlRepo.Retention{}) - require.NoError(t, err) - - // now re-connect - r, err := Connect(ctx, account.Account{}, st, repo.GetID(), control.Options{DisableMetrics: true}) - assert.NoError(t, err) - - // now we have repoID beforehand - assert.Equal(t, r.GetID(), r.GetID()) -} - -func (suite *RepositoryIntegrationSuite) TestConnect_ReadOnly() { - t := suite.T() - - ctx, flush := tester.NewContext(t) - defer flush() - - // need to initialize the repository before we can test connecting to it. - st := storeTD.NewPrefixedS3Storage(t) - - repo, err := Initialize( - ctx, - account.Account{}, - st, - control.DefaultOptions(), - ctrlRepo.Retention{}) - require.NoError(t, err) - - // now re-connect - r, err := Connect(ctx, account.Account{}, st, repo.GetID(), control.Options{Repo: ctrlRepo.Options{ReadOnly: true}}) - assert.NoError(t, err) - - // Maintenance attempts to write some blobs just to say it was running. Since - // we're in readonly mode it should fail with a sentinel error. - op, err := r.NewMaintenance(ctx, ctrlRepo.Maintenance{}) - require.NoError(t, err, clues.ToCore(err)) - - err = op.Run(ctx) - assert.ErrorIs(t, err, readonly.ErrReadonly) -} - // Test_Options tests that the options are passed through to the repository // correctly func (suite *RepositoryIntegrationSuite) Test_Options() { @@ -477,16 +457,20 @@ func (suite *RepositoryIntegrationSuite) Test_Options() { ctx, flush := tester.NewContext(t) defer flush() - repo, err := Initialize(ctx, acct, st, test.opts(), ctrlRepo.Retention{}) - require.NoError(t, err) + r, err := New( + ctx, + acct, + st, + test.opts(), + NewRepoID) + require.NoError(t, err, clues.ToCore(err)) - r := repo.(*repository) + err = r.Initialize(ctx, ctrlRepo.Retention{}) + require.NoError(t, err) assert.Equal(t, test.expectedLen, len(r.Opts.ItemExtensionFactory)) - repo, err = Connect(ctx, acct, st, repo.GetID(), test.opts()) + err = r.Connect(ctx) assert.NoError(t, err) - - r = repo.(*repository) assert.Equal(t, test.expectedLen, len(r.Opts.ItemExtensionFactory)) }) }