diff --git a/src/internal/kopia/backup_bases.go b/src/internal/kopia/backup_bases.go index 0505fc829..c0b8ecfaa 100644 --- a/src/internal/kopia/backup_bases.go +++ b/src/internal/kopia/backup_bases.go @@ -24,7 +24,7 @@ type BackupBases interface { MergeBackupBases( ctx context.Context, other BackupBases, - reasonToKey func(Reason) string, + reasonToKey func(Reasoner) string, ) BackupBases } @@ -109,10 +109,10 @@ func (bb *backupBases) ClearAssistBases() { // some migration that disrupts lookup), and that the BackupBases used to call // this function contains the current version. // -// reasonToKey should be a function that, given a Reason, will produce some -// string that represents Reason in the context of the merge operation. For -// example, to merge BackupBases across a ResourceOwner migration, the Reason's -// service and category can be used as the key. +// reasonToKey should be a function that, given a Reasoner, will produce some +// string that represents Reasoner in the context of the merge operation. For +// example, to merge BackupBases across a ProtectedResource migration, the +// Reasoner's service and category can be used as the key. // // Selection priority, for each reason key generated by reasonsToKey, follows // these rules: @@ -125,7 +125,7 @@ func (bb *backupBases) ClearAssistBases() { func (bb *backupBases) MergeBackupBases( ctx context.Context, other BackupBases, - reasonToKey func(reason Reason) string, + reasonToKey func(reason Reasoner) string, ) BackupBases { if other == nil || (len(other.MergeBases()) == 0 && len(other.AssistBases()) == 0) { return bb @@ -159,7 +159,7 @@ func (bb *backupBases) MergeBackupBases( // Calculate the set of mergeBases to pull from other into this one. for _, m := range other.MergeBases() { - useReasons := []Reason{} + useReasons := []Reasoner{} for _, r := range m.Reasons { k := reasonToKey(r) @@ -210,7 +210,7 @@ func (bb *backupBases) MergeBackupBases( // Add assistBases from other to this one as needed. for _, m := range other.AssistBases() { - useReasons := []Reason{} + useReasons := []Reasoner{} // Assume that all complete manifests in assist overlap with MergeBases. if len(m.IncompleteReason) == 0 { @@ -267,8 +267,8 @@ func findNonUniqueManifests( } for _, reason := range man.Reasons { - reasonKey := reason.ResourceOwner + reason.Service.String() + reason.Category.String() - reasons[reasonKey] = append(reasons[reasonKey], man) + mapKey := reasonKey(reason) + reasons[mapKey] = append(reasons[mapKey], man) } } diff --git a/src/internal/kopia/backup_bases_test.go b/src/internal/kopia/backup_bases_test.go index f902d4e37..04afb5408 100644 --- a/src/internal/kopia/backup_bases_test.go +++ b/src/internal/kopia/backup_bases_test.go @@ -16,7 +16,7 @@ import ( "github.com/alcionai/corso/src/pkg/path" ) -func makeManifest(id, incmpl, bID string, reasons ...Reason) ManifestEntry { +func makeManifest(id, incmpl, bID string, reasons ...Reasoner) ManifestEntry { bIDKey, _ := makeTagKV(TagBackupID) return ManifestEntry{ @@ -223,14 +223,10 @@ func (suite *BackupBasesUnitSuite) TestMergeBackupBases() { ir = "checkpoint" } - reasons := make([]Reason, 0, len(i.cat)) + reasons := make([]Reasoner, 0, len(i.cat)) for _, c := range i.cat { - reasons = append(reasons, Reason{ - ResourceOwner: ro, - Service: path.ExchangeService, - Category: c, - }) + reasons = append(reasons, NewReason("", ro, path.ExchangeService, c)) } m := makeManifest(baseID, ir, "b"+baseID, reasons...) @@ -457,8 +453,8 @@ func (suite *BackupBasesUnitSuite) TestMergeBackupBases() { got := bb.MergeBackupBases( ctx, other, - func(reason Reason) string { - return reason.Service.String() + reason.Category.String() + func(r Reasoner) string { + return r.Service().String() + r.Category().String() }) AssertBackupBasesEqual(t, expect, got) }) @@ -469,13 +465,8 @@ func (suite *BackupBasesUnitSuite) TestFixupAndVerify() { ro := "resource_owner" makeMan := func(pct path.CategoryType, id, incmpl, bID string) ManifestEntry { - reason := Reason{ - ResourceOwner: ro, - Service: path.ExchangeService, - Category: pct, - } - - return makeManifest(id, incmpl, bID, reason) + r := NewReason("", ro, path.ExchangeService, pct) + return makeManifest(id, incmpl, bID, r) } // Make a function so tests can modify things without messing with each other. @@ -606,11 +597,7 @@ func (suite *BackupBasesUnitSuite) TestFixupAndVerify() { res := validMail1() res.mergeBases[0].Reasons = append( res.mergeBases[0].Reasons, - Reason{ - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.ContactsCategory, - }) + NewReason("", ro, path.ExchangeService, path.ContactsCategory)) res.assistBases = res.mergeBases return res @@ -619,11 +606,7 @@ func (suite *BackupBasesUnitSuite) TestFixupAndVerify() { res := validMail1() res.mergeBases[0].Reasons = append( res.mergeBases[0].Reasons, - Reason{ - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.ContactsCategory, - }) + NewReason("", ro, path.ExchangeService, path.ContactsCategory)) res.assistBases = res.mergeBases return res diff --git a/src/internal/kopia/base_finder.go b/src/internal/kopia/base_finder.go index 9ac651512..f8119587b 100644 --- a/src/internal/kopia/base_finder.go +++ b/src/internal/kopia/base_finder.go @@ -29,39 +29,98 @@ const ( userTagPrefix = "tag:" ) -type Reason struct { - ResourceOwner string - Service path.ServiceType - Category path.CategoryType +// TODO(ashmrtn): Move this into some inject package. Here to avoid import +// cycles. +type Reasoner interface { + Tenant() string + ProtectedResource() string + Service() path.ServiceType + Category() path.CategoryType + // SubtreePath returns the path prefix for data in existing backups that have + // parameters (tenant, protected resourced, etc) that match this Reasoner. + SubtreePath() (path.Path, error) + // TODO(ashmrtn): Remove this when kopia generates tags from Reasons. + TagKeys() []string } -func (r Reason) TagKeys() []string { - return []string{ - r.ResourceOwner, - serviceCatString(r.Service, r.Category), +func NewReason( + tenant, resource string, + service path.ServiceType, + category path.CategoryType, +) Reasoner { + return reason{ + tenant: tenant, + resource: resource, + service: service, + category: category, } } -// Key is the concatenation of the ResourceOwner, Service, and Category. -func (r Reason) Key() string { - return r.ResourceOwner + r.Service.String() + r.Category.String() +type reason struct { + // tenant appears here so that when this is moved to an inject package nothing + // needs changed. However, kopia itself is blind to the fields in the reason + // struct and relies on helper functions to get the information it needs. + tenant string + resource string + service path.ServiceType + category path.CategoryType +} + +func (r reason) Tenant() string { + return r.tenant +} + +func (r reason) ProtectedResource() string { + return r.resource +} + +func (r reason) Service() path.ServiceType { + return r.service +} + +func (r reason) Category() path.CategoryType { + return r.category +} + +func (r reason) SubtreePath() (path.Path, error) { + p, err := path.ServicePrefix( + r.Tenant(), + r.ProtectedResource(), + r.Service(), + r.Category()) + + return p, clues.Wrap(err, "building path").OrNil() +} + +// TODO(ashmrtn): Remove this when kopia generates tags based off Reasons. Here +// at the moment so things compile. +func (r reason) TagKeys() []string { + return []string{ + r.ProtectedResource(), + serviceCatString(r.Service(), r.Category()), + } +} + +// reasonKey returns the concatenation of the ProtectedResource, Service, and Category. +func reasonKey(r Reasoner) string { + return r.ProtectedResource() + r.Service().String() + r.Category().String() } type BackupEntry struct { *backup.Backup - Reasons []Reason + Reasons []Reasoner } type ManifestEntry struct { *snapshot.Manifest - // Reason contains the ResourceOwners and Service/Categories that caused this + // Reasons contains the ResourceOwners and Service/Categories that caused this // snapshot to be selected as a base. We can't reuse OwnersCats here because // it's possible some ResourceOwners will have a subset of the Categories as // the reason for selecting a snapshot. For example: // 1. backup user1 email,contacts -> B1 // 2. backup user1 contacts -> B2 (uses B1 as base) // 3. backup user1 email,contacts,events (uses B1 for email, B2 for contacts) - Reasons []Reason + Reasons []Reasoner } func (me ManifestEntry) GetTag(key string) (string, bool) { @@ -157,7 +216,7 @@ func (b *baseFinder) getBackupModel( // most recent complete backup as the base. func (b *baseFinder) findBasesInSet( ctx context.Context, - reason Reason, + reason Reasoner, metas []*manifest.EntryMetadata, ) (*BackupEntry, *ManifestEntry, []ManifestEntry, error) { // Sort manifests by time so we can go through them sequentially. The code in @@ -190,7 +249,7 @@ func (b *baseFinder) findBasesInSet( kopiaAssistSnaps = append(kopiaAssistSnaps, ManifestEntry{ Manifest: man, - Reasons: []Reason{reason}, + Reasons: []Reasoner{reason}, }) logger.Ctx(ictx).Info("found incomplete backup") @@ -211,7 +270,7 @@ func (b *baseFinder) findBasesInSet( kopiaAssistSnaps = append(kopiaAssistSnaps, ManifestEntry{ Manifest: man, - Reasons: []Reason{reason}, + Reasons: []Reasoner{reason}, }) logger.Ctx(ictx).Info("found incomplete backup") @@ -235,7 +294,7 @@ func (b *baseFinder) findBasesInSet( kopiaAssistSnaps = append(kopiaAssistSnaps, ManifestEntry{ Manifest: man, - Reasons: []Reason{reason}, + Reasons: []Reasoner{reason}, }) logger.Ctx(ictx).Infow( @@ -253,13 +312,13 @@ func (b *baseFinder) findBasesInSet( me := ManifestEntry{ Manifest: man, - Reasons: []Reason{reason}, + Reasons: []Reasoner{reason}, } kopiaAssistSnaps = append(kopiaAssistSnaps, me) return &BackupEntry{ Backup: bup, - Reasons: []Reason{reason}, + Reasons: []Reasoner{reason}, }, &me, kopiaAssistSnaps, nil } @@ -270,12 +329,12 @@ func (b *baseFinder) findBasesInSet( func (b *baseFinder) getBase( ctx context.Context, - reason Reason, + r Reasoner, tags map[string]string, ) (*BackupEntry, *ManifestEntry, []ManifestEntry, error) { allTags := map[string]string{} - for _, k := range reason.TagKeys() { + for _, k := range r.TagKeys() { allTags[k] = "" } @@ -292,12 +351,12 @@ func (b *baseFinder) getBase( return nil, nil, nil, nil } - return b.findBasesInSet(ctx, reason, metas) + return b.findBasesInSet(ctx, r, metas) } func (b *baseFinder) FindBases( ctx context.Context, - reasons []Reason, + reasons []Reasoner, tags map[string]string, ) BackupBases { var ( @@ -310,14 +369,14 @@ func (b *baseFinder) FindBases( kopiaAssistSnaps = map[manifest.ID]ManifestEntry{} ) - for _, reason := range reasons { + for _, searchReason := range reasons { ictx := clues.Add( ctx, - "search_service", reason.Service.String(), - "search_category", reason.Category.String()) + "search_service", searchReason.Service().String(), + "search_category", searchReason.Category().String()) logger.Ctx(ictx).Info("searching for previous manifests") - baseBackup, baseSnap, assistSnaps, err := b.getBase(ictx, reason, tags) + baseBackup, baseSnap, assistSnaps, err := b.getBase(ictx, searchReason, tags) if err != nil { logger.Ctx(ctx).Info( "getting base, falling back to full backup for reason", diff --git a/src/internal/kopia/base_finder_test.go b/src/internal/kopia/base_finder_test.go index f76b3c81a..cb3239ca1 100644 --- a/src/internal/kopia/base_finder_test.go +++ b/src/internal/kopia/base_finder_test.go @@ -39,61 +39,24 @@ var ( testUser2 = "user2" testUser3 = "user3" - testAllUsersAllCats = []Reason{ - { - ResourceOwner: testUser1, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, - { - ResourceOwner: testUser1, - Service: path.ExchangeService, - Category: path.EventsCategory, - }, - { - ResourceOwner: testUser2, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, - { - ResourceOwner: testUser2, - Service: path.ExchangeService, - Category: path.EventsCategory, - }, - { - ResourceOwner: testUser3, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, - { - ResourceOwner: testUser3, - Service: path.ExchangeService, - Category: path.EventsCategory, - }, + testAllUsersAllCats = []Reasoner{ + // User1 email and events. + NewReason("", testUser1, path.ExchangeService, path.EmailCategory), + NewReason("", testUser1, path.ExchangeService, path.EventsCategory), + // User2 email and events. + NewReason("", testUser2, path.ExchangeService, path.EmailCategory), + NewReason("", testUser2, path.ExchangeService, path.EventsCategory), + // User3 email and events. + NewReason("", testUser3, path.ExchangeService, path.EmailCategory), + NewReason("", testUser3, path.ExchangeService, path.EventsCategory), } - testAllUsersMail = []Reason{ - { - ResourceOwner: testUser1, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, - { - ResourceOwner: testUser2, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, - { - ResourceOwner: testUser3, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, + testAllUsersMail = []Reasoner{ + NewReason("", testUser1, path.ExchangeService, path.EmailCategory), + NewReason("", testUser2, path.ExchangeService, path.EmailCategory), + NewReason("", testUser3, path.ExchangeService, path.EmailCategory), } - testUser1Mail = []Reason{ - { - ResourceOwner: testUser1, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, + testUser1Mail = []Reasoner{ + NewReason("", testUser1, path.ExchangeService, path.EmailCategory), } ) @@ -322,12 +285,8 @@ func (suite *BaseFinderUnitSuite) TestNoResult_NoBackupsOrSnapshots() { sm: mockEmptySnapshotManager{}, bg: mockEmptyModelGetter{}, } - reasons := []Reason{ - { - ResourceOwner: "a-user", - Service: path.ExchangeService, - Category: path.EmailCategory, - }, + reasons := []Reasoner{ + NewReason("", "a-user", path.ExchangeService, path.EmailCategory), } bb := bf.FindBases(ctx, reasons, nil) @@ -345,12 +304,8 @@ func (suite *BaseFinderUnitSuite) TestNoResult_ErrorListingSnapshots() { sm: &mockSnapshotManager{findErr: assert.AnError}, bg: mockEmptyModelGetter{}, } - reasons := []Reason{ - { - ResourceOwner: "a-user", - Service: path.ExchangeService, - Category: path.EmailCategory, - }, + reasons := []Reasoner{ + NewReason("", "a-user", path.ExchangeService, path.EmailCategory), } bb := bf.FindBases(ctx, reasons, nil) @@ -361,14 +316,14 @@ func (suite *BaseFinderUnitSuite) TestNoResult_ErrorListingSnapshots() { func (suite *BaseFinderUnitSuite) TestGetBases() { table := []struct { name string - input []Reason + input []Reasoner manifestData []manifestInfo // Use this to denote the Reasons a base backup or base manifest is // selected. The int maps to the index of the backup or manifest in data. - expectedBaseReasons map[int][]Reason + expectedBaseReasons map[int][]Reasoner // Use this to denote the Reasons a kopia assised incrementals manifest is // selected. The int maps to the index of the manifest in data. - expectedAssistManifestReasons map[int][]Reason + expectedAssistManifestReasons map[int][]Reasoner backupData []backupInfo }{ { @@ -394,10 +349,10 @@ func (suite *BaseFinderUnitSuite) TestGetBases() { testUser1, ), }, - expectedBaseReasons: map[int][]Reason{ + expectedBaseReasons: map[int][]Reasoner{ 1: testUser1Mail, }, - expectedAssistManifestReasons: map[int][]Reason{ + expectedAssistManifestReasons: map[int][]Reasoner{ 1: testUser1Mail, }, backupData: []backupInfo{ @@ -428,10 +383,10 @@ func (suite *BaseFinderUnitSuite) TestGetBases() { testUser1, ), }, - expectedBaseReasons: map[int][]Reason{ + expectedBaseReasons: map[int][]Reasoner{ 1: testUser1Mail, }, - expectedAssistManifestReasons: map[int][]Reason{ + expectedAssistManifestReasons: map[int][]Reasoner{ 0: testUser1Mail, 1: testUser1Mail, }, @@ -463,10 +418,10 @@ func (suite *BaseFinderUnitSuite) TestGetBases() { testUser1, ), }, - expectedBaseReasons: map[int][]Reason{ + expectedBaseReasons: map[int][]Reasoner{ 1: testUser1Mail, }, - expectedAssistManifestReasons: map[int][]Reason{ + expectedAssistManifestReasons: map[int][]Reasoner{ 0: testUser1Mail, 1: testUser1Mail, }, @@ -492,10 +447,10 @@ func (suite *BaseFinderUnitSuite) TestGetBases() { testUser3, ), }, - expectedBaseReasons: map[int][]Reason{ + expectedBaseReasons: map[int][]Reasoner{ 0: testUser1Mail, }, - expectedAssistManifestReasons: map[int][]Reason{ + expectedAssistManifestReasons: map[int][]Reasoner{ 0: testUser1Mail, }, backupData: []backupInfo{ @@ -519,10 +474,10 @@ func (suite *BaseFinderUnitSuite) TestGetBases() { testUser3, ), }, - expectedBaseReasons: map[int][]Reason{ + expectedBaseReasons: map[int][]Reasoner{ 0: testAllUsersAllCats, }, - expectedAssistManifestReasons: map[int][]Reason{ + expectedAssistManifestReasons: map[int][]Reasoner{ 0: testAllUsersAllCats, }, backupData: []backupInfo{ @@ -557,76 +512,28 @@ func (suite *BaseFinderUnitSuite) TestGetBases() { testUser3, ), }, - expectedBaseReasons: map[int][]Reason{ + expectedBaseReasons: map[int][]Reasoner{ 0: { - { - ResourceOwner: testUser1, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, - { - ResourceOwner: testUser2, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, - { - ResourceOwner: testUser3, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, + NewReason("", testUser1, path.ExchangeService, path.EmailCategory), + NewReason("", testUser2, path.ExchangeService, path.EmailCategory), + NewReason("", testUser3, path.ExchangeService, path.EmailCategory), }, 1: { - Reason{ - ResourceOwner: testUser1, - Service: path.ExchangeService, - Category: path.EventsCategory, - }, - Reason{ - ResourceOwner: testUser2, - Service: path.ExchangeService, - Category: path.EventsCategory, - }, - Reason{ - ResourceOwner: testUser3, - Service: path.ExchangeService, - Category: path.EventsCategory, - }, + NewReason("", testUser1, path.ExchangeService, path.EventsCategory), + NewReason("", testUser2, path.ExchangeService, path.EventsCategory), + NewReason("", testUser3, path.ExchangeService, path.EventsCategory), }, }, - expectedAssistManifestReasons: map[int][]Reason{ + expectedAssistManifestReasons: map[int][]Reasoner{ 0: { - { - ResourceOwner: testUser1, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, - { - ResourceOwner: testUser2, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, - { - ResourceOwner: testUser3, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, + NewReason("", testUser1, path.ExchangeService, path.EmailCategory), + NewReason("", testUser2, path.ExchangeService, path.EmailCategory), + NewReason("", testUser3, path.ExchangeService, path.EmailCategory), }, 1: { - Reason{ - ResourceOwner: testUser1, - Service: path.ExchangeService, - Category: path.EventsCategory, - }, - Reason{ - ResourceOwner: testUser2, - Service: path.ExchangeService, - Category: path.EventsCategory, - }, - Reason{ - ResourceOwner: testUser3, - Service: path.ExchangeService, - Category: path.EventsCategory, - }, + NewReason("", testUser1, path.ExchangeService, path.EventsCategory), + NewReason("", testUser2, path.ExchangeService, path.EventsCategory), + NewReason("", testUser3, path.ExchangeService, path.EventsCategory), }, }, backupData: []backupInfo{ @@ -657,10 +564,10 @@ func (suite *BaseFinderUnitSuite) TestGetBases() { testUser1, ), }, - expectedBaseReasons: map[int][]Reason{ + expectedBaseReasons: map[int][]Reasoner{ 0: testUser1Mail, }, - expectedAssistManifestReasons: map[int][]Reason{ + expectedAssistManifestReasons: map[int][]Reasoner{ 0: testUser1Mail, 1: testUser1Mail, }, @@ -693,10 +600,10 @@ func (suite *BaseFinderUnitSuite) TestGetBases() { testUser1, ), }, - expectedBaseReasons: map[int][]Reason{ + expectedBaseReasons: map[int][]Reasoner{ 1: testUser1Mail, }, - expectedAssistManifestReasons: map[int][]Reason{ + expectedAssistManifestReasons: map[int][]Reasoner{ 1: testUser1Mail, }, backupData: []backupInfo{ @@ -728,8 +635,8 @@ func (suite *BaseFinderUnitSuite) TestGetBases() { testUser1, ), }, - expectedBaseReasons: map[int][]Reason{}, - expectedAssistManifestReasons: map[int][]Reason{ + expectedBaseReasons: map[int][]Reasoner{}, + expectedAssistManifestReasons: map[int][]Reasoner{ 1: testUser1Mail, }, backupData: []backupInfo{ @@ -752,10 +659,10 @@ func (suite *BaseFinderUnitSuite) TestGetBases() { testUser1, ), }, - expectedBaseReasons: map[int][]Reason{ + expectedBaseReasons: map[int][]Reasoner{ 0: testUser1Mail, }, - expectedAssistManifestReasons: map[int][]Reason{ + expectedAssistManifestReasons: map[int][]Reasoner{ 0: testUser1Mail, }, backupData: []backupInfo{ @@ -787,10 +694,10 @@ func (suite *BaseFinderUnitSuite) TestGetBases() { testUser1, ), }, - expectedBaseReasons: map[int][]Reason{ + expectedBaseReasons: map[int][]Reasoner{ 0: testUser1Mail, }, - expectedAssistManifestReasons: map[int][]Reason{ + expectedAssistManifestReasons: map[int][]Reasoner{ 0: testUser1Mail, }, backupData: []backupInfo{ @@ -857,17 +764,17 @@ func (suite *BaseFinderUnitSuite) TestFindBases_CustomTags() { table := []struct { name string - input []Reason + input []Reasoner tags map[string]string // Use this to denote which manifests in data should be expected. Allows // defining data in a table while not repeating things between data and // expected. - expectedIdxs map[int][]Reason + expectedIdxs map[int][]Reasoner }{ { name: "no tags specified", tags: nil, - expectedIdxs: map[int][]Reason{ + expectedIdxs: map[int][]Reasoner{ 0: testUser1Mail, }, }, @@ -877,14 +784,14 @@ func (suite *BaseFinderUnitSuite) TestFindBases_CustomTags() { "fnords": "", "smarf": "", }, - expectedIdxs: map[int][]Reason{ + expectedIdxs: map[int][]Reasoner{ 0: testUser1Mail, }, }, { name: "subset of custom tags", tags: map[string]string{"fnords": ""}, - expectedIdxs: map[int][]Reason{ + expectedIdxs: map[int][]Reasoner{ 0: testUser1Mail, }, }, @@ -925,7 +832,7 @@ func checkManifestEntriesMatch( t *testing.T, retSnaps []ManifestEntry, allExpected []manifestInfo, - expectedIdxsAndReasons map[int][]Reason, + expectedIdxsAndReasons map[int][]Reasoner, ) { // Check the proper snapshot manifests were returned. expected := make([]*snapshot.Manifest, 0, len(expectedIdxsAndReasons)) @@ -941,7 +848,7 @@ func checkManifestEntriesMatch( assert.ElementsMatch(t, expected, got) // Check the reasons for selecting each manifest are correct. - expectedReasons := make(map[manifest.ID][]Reason, len(expectedIdxsAndReasons)) + expectedReasons := make(map[manifest.ID][]Reasoner, len(expectedIdxsAndReasons)) for idx, reasons := range expectedIdxsAndReasons { expectedReasons[allExpected[idx].man.ID] = reasons } @@ -967,7 +874,7 @@ func checkBackupEntriesMatch( t *testing.T, retBups []BackupEntry, allExpected []backupInfo, - expectedIdxsAndReasons map[int][]Reason, + expectedIdxsAndReasons map[int][]Reasoner, ) { // Check the proper snapshot manifests were returned. expected := make([]*backup.Backup, 0, len(expectedIdxsAndReasons)) @@ -983,7 +890,7 @@ func checkBackupEntriesMatch( assert.ElementsMatch(t, expected, got) // Check the reasons for selecting each manifest are correct. - expectedReasons := make(map[model.StableID][]Reason, len(expectedIdxsAndReasons)) + expectedReasons := make(map[model.StableID][]Reasoner, len(expectedIdxsAndReasons)) for idx, reasons := range expectedIdxsAndReasons { expectedReasons[allExpected[idx].b.ID] = reasons } diff --git a/src/internal/kopia/inject/inject.go b/src/internal/kopia/inject/inject.go index 6921c353d..ed0a8f5e8 100644 --- a/src/internal/kopia/inject/inject.go +++ b/src/internal/kopia/inject/inject.go @@ -37,7 +37,7 @@ type ( BaseFinder interface { FindBases( ctx context.Context, - reasons []kopia.Reason, + reasons []kopia.Reasoner, tags map[string]string, ) kopia.BackupBases } diff --git a/src/internal/kopia/wrapper_test.go b/src/internal/kopia/wrapper_test.go index 12857904f..5af044f94 100644 --- a/src/internal/kopia/wrapper_test.go +++ b/src/internal/kopia/wrapper_test.go @@ -703,17 +703,19 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections() { "brunhilda": "", } - reasons := []Reason{ - { - ResourceOwner: suite.storePath1.ResourceOwner(), - Service: suite.storePath1.Service(), - Category: suite.storePath1.Category(), - }, - { - ResourceOwner: suite.storePath2.ResourceOwner(), - Service: suite.storePath2.Service(), - Category: suite.storePath2.Category(), - }, + reasons := []Reasoner{ + NewReason( + testTenant, + suite.storePath1.ResourceOwner(), + suite.storePath1.Service(), + suite.storePath1.Category(), + ), + NewReason( + testTenant, + suite.storePath2.ResourceOwner(), + suite.storePath2.Service(), + suite.storePath2.Category(), + ), } for _, r := range reasons { @@ -837,12 +839,12 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections_NoDetailsForMeta() { "brunhilda": "", } - reasons := []Reason{ - { - ResourceOwner: storePath.ResourceOwner(), - Service: storePath.Service(), - Category: storePath.Category(), - }, + reasons := []Reasoner{ + NewReason( + testTenant, + storePath.ResourceOwner(), + storePath.Service(), + storePath.Category()), } for _, r := range reasons { @@ -1017,13 +1019,9 @@ func (suite *KopiaIntegrationSuite) TestRestoreAfterCompressionChange() { w := &Wrapper{k} tags := map[string]string{} - reason := Reason{ - ResourceOwner: testUser, - Service: path.ExchangeService, - Category: path.EmailCategory, - } + r := NewReason(testTenant, testUser, path.ExchangeService, path.EmailCategory) - for _, k := range reason.TagKeys() { + for _, k := range r.TagKeys() { tags[k] = "" } @@ -1113,13 +1111,9 @@ func (suite *KopiaIntegrationSuite) TestBackupCollections_ReaderError() { loc1 := path.Builder{}.Append(suite.storePath1.Folders()...) loc2 := path.Builder{}.Append(suite.storePath2.Folders()...) tags := map[string]string{} - reason := Reason{ - ResourceOwner: testUser, - Service: path.ExchangeService, - Category: path.EmailCategory, - } + r := NewReason(testTenant, testUser, path.ExchangeService, path.EmailCategory) - for _, k := range reason.TagKeys() { + for _, k := range r.TagKeys() { tags[k] = "" } @@ -1392,13 +1386,9 @@ func (suite *KopiaSimpleRepoIntegrationSuite) SetupTest() { } tags := map[string]string{} - reason := Reason{ - ResourceOwner: testUser, - Service: path.ExchangeService, - Category: path.EmailCategory, - } + r := NewReason(testTenant, testUser, path.ExchangeService, path.EmailCategory) - for _, k := range reason.TagKeys() { + for _, k := range r.TagKeys() { tags[k] = "" } @@ -1437,11 +1427,7 @@ func (c *i64counter) Count(i int64) { } func (suite *KopiaSimpleRepoIntegrationSuite) TestBackupExcludeItem() { - reason := Reason{ - ResourceOwner: testUser, - Service: path.ExchangeService, - Category: path.EmailCategory, - } + r := NewReason(testTenant, testUser, path.ExchangeService, path.EmailCategory) subtreePathTmp, err := path.Build( testTenant, @@ -1459,7 +1445,7 @@ func (suite *KopiaSimpleRepoIntegrationSuite) TestBackupExcludeItem() { tags := map[string]string{} - for _, k := range reason.TagKeys() { + for _, k := range r.TagKeys() { tags[k] = "" } diff --git a/src/internal/operations/backup.go b/src/internal/operations/backup.go index 00eb82884..0d6509d1d 100644 --- a/src/internal/operations/backup.go +++ b/src/internal/operations/backup.go @@ -280,8 +280,8 @@ func (op *BackupOperation) do( backupID model.StableID, ) (*details.Builder, error) { var ( - reasons = selectorToReasons(op.Selectors, false) - fallbackReasons = makeFallbackReasons(op.Selectors) + reasons = selectorToReasons(op.account.ID(), op.Selectors, false) + fallbackReasons = makeFallbackReasons(op.account.ID(), op.Selectors) lastBackupVersion = version.NoBackup ) @@ -370,10 +370,10 @@ func (op *BackupOperation) do( return deets, nil } -func makeFallbackReasons(sel selectors.Selector) []kopia.Reason { +func makeFallbackReasons(tenant string, sel selectors.Selector) []kopia.Reasoner { if sel.PathService() != path.SharePointService && sel.DiscreteOwner != sel.DiscreteOwnerName { - return selectorToReasons(sel, true) + return selectorToReasons(tenant, sel, true) } return nil @@ -420,9 +420,13 @@ func produceBackupDataCollections( // Consumer funcs // --------------------------------------------------------------------------- -func selectorToReasons(sel selectors.Selector, useOwnerNameForID bool) []kopia.Reason { +func selectorToReasons( + tenant string, + sel selectors.Selector, + useOwnerNameForID bool, +) []kopia.Reasoner { service := sel.PathService() - reasons := []kopia.Reason{} + reasons := []kopia.Reasoner{} pcs, err := sel.PathCategories() if err != nil { @@ -438,28 +442,24 @@ func selectorToReasons(sel selectors.Selector, useOwnerNameForID bool) []kopia.R for _, sl := range [][]path.CategoryType{pcs.Includes, pcs.Filters} { for _, cat := range sl { - reasons = append(reasons, kopia.Reason{ - ResourceOwner: owner, - Service: service, - Category: cat, - }) + reasons = append(reasons, kopia.NewReason(tenant, owner, service, cat)) } } return reasons } -func builderFromReason(ctx context.Context, tenant string, r kopia.Reason) (*path.Builder, error) { - ctx = clues.Add(ctx, "category", r.Category.String()) +func builderFromReason(ctx context.Context, tenant string, r kopia.Reasoner) (*path.Builder, error) { + ctx = clues.Add(ctx, "category", r.Category().String()) // This is hacky, but we want the path package to format the path the right // way (e.x. proper order for service, category, etc), but we don't care about // the folders after the prefix. p, err := path.Build( tenant, - r.ResourceOwner, - r.Service, - r.Category, + r.ProtectedResource(), + r.Service(), + r.Category(), false, "tmp") if err != nil { @@ -474,7 +474,7 @@ func consumeBackupCollections( ctx context.Context, bc kinject.BackupConsumer, tenantID string, - reasons []kopia.Reason, + reasons []kopia.Reasoner, bbs kopia.BackupBases, cs []data.BackupCollection, pmr prefixmatcher.StringSetReader, @@ -530,8 +530,8 @@ func consumeBackupCollections( } paths = append(paths, pb) - services[reason.Service.String()] = struct{}{} - categories[reason.Category.String()] = struct{}{} + services[reason.Service().String()] = struct{}{} + categories[reason.Category().String()] = struct{}{} } ids[m.ID] = struct{}{} @@ -609,11 +609,11 @@ func consumeBackupCollections( return kopiaStats, deets, itemsSourcedFromBase, err } -func matchesReason(reasons []kopia.Reason, p path.Path) bool { +func matchesReason(reasons []kopia.Reasoner, p path.Path) bool { for _, reason := range reasons { - if p.ResourceOwner() == reason.ResourceOwner && - p.Service() == reason.Service && - p.Category() == reason.Category { + if p.ResourceOwner() == reason.ProtectedResource() && + p.Service() == reason.Service() && + p.Category() == reason.Category() { return true } } diff --git a/src/internal/operations/backup_test.go b/src/internal/operations/backup_test.go index ffa164c81..49f8d4aa5 100644 --- a/src/internal/operations/backup_test.go +++ b/src/internal/operations/backup_test.go @@ -395,25 +395,23 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_ConsumeBackupDataCollections tenant, path.ExchangeService.String(), resourceOwner, - path.EmailCategory.String(), - ) + path.EmailCategory.String()) contactsBuilder = path.Builder{}.Append( tenant, path.ExchangeService.String(), resourceOwner, - path.ContactsCategory.String(), - ) + path.ContactsCategory.String()) - emailReason = kopia.Reason{ - ResourceOwner: resourceOwner, - Service: path.ExchangeService, - Category: path.EmailCategory, - } - contactsReason = kopia.Reason{ - ResourceOwner: resourceOwner, - Service: path.ExchangeService, - Category: path.ContactsCategory, - } + emailReason = kopia.NewReason( + "", + resourceOwner, + path.ExchangeService, + path.EmailCategory) + contactsReason = kopia.NewReason( + "", + resourceOwner, + path.ExchangeService, + path.ContactsCategory) manifest1 = &snapshot.Manifest{ ID: "id1", @@ -434,7 +432,7 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_ConsumeBackupDataCollections input: kopia.NewMockBackupBases().WithMergeBases( kopia.ManifestEntry{ Manifest: manifest1, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ emailReason, }, }).ClearMockAssistBases(), @@ -452,7 +450,7 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_ConsumeBackupDataCollections input: kopia.NewMockBackupBases().WithMergeBases( kopia.ManifestEntry{ Manifest: manifest1, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ emailReason, contactsReason, }, @@ -472,14 +470,14 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_ConsumeBackupDataCollections input: kopia.NewMockBackupBases().WithMergeBases( kopia.ManifestEntry{ Manifest: manifest1, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ emailReason, contactsReason, }, }, kopia.ManifestEntry{ Manifest: manifest2, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ emailReason, contactsReason, }, @@ -506,13 +504,13 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_ConsumeBackupDataCollections input: kopia.NewMockBackupBases().WithMergeBases( kopia.ManifestEntry{ Manifest: manifest1, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ emailReason, }, }).WithAssistBases( kopia.ManifestEntry{ Manifest: manifest2, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ contactsReason, }, }), @@ -629,16 +627,16 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_MergeBackupDetails_AddsItems DetailsID: "did2", } - pathReason1 = kopia.Reason{ - ResourceOwner: itemPath1.ResourceOwner(), - Service: itemPath1.Service(), - Category: itemPath1.Category(), - } - pathReason3 = kopia.Reason{ - ResourceOwner: itemPath3.ResourceOwner(), - Service: itemPath3.Service(), - Category: itemPath3.Category(), - } + pathReason1 = kopia.NewReason( + "", + itemPath1.ResourceOwner(), + itemPath1.Service(), + itemPath1.Category()) + pathReason3 = kopia.NewReason( + "", + itemPath3.ResourceOwner(), + itemPath3.Service(), + itemPath3.Category()) ) itemParents1, err := path.GetDriveFolderPath(itemPath1) @@ -684,7 +682,7 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_MergeBackupDetails_AddsItems }, DetailsID: "foo", }, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ pathReason1, }, }, @@ -703,7 +701,7 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_MergeBackupDetails_AddsItems inputBackups: []kopia.BackupEntry{ { Backup: &backup1, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ pathReason1, }, }, @@ -730,13 +728,13 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_MergeBackupDetails_AddsItems inputBackups: []kopia.BackupEntry{ { Backup: &backup1, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ pathReason1, }, }, { Backup: &backup1, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ pathReason1, }, }, @@ -763,7 +761,7 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_MergeBackupDetails_AddsItems inputBackups: []kopia.BackupEntry{ { Backup: &backup1, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ pathReason1, }, }, @@ -822,7 +820,7 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_MergeBackupDetails_AddsItems inputBackups: []kopia.BackupEntry{ { Backup: &backup1, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ pathReason1, }, }, @@ -849,7 +847,7 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_MergeBackupDetails_AddsItems inputBackups: []kopia.BackupEntry{ { Backup: &backup1, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ pathReason1, }, }, @@ -879,7 +877,7 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_MergeBackupDetails_AddsItems inputBackups: []kopia.BackupEntry{ { Backup: &backup1, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ pathReason1, }, }, @@ -909,7 +907,7 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_MergeBackupDetails_AddsItems inputBackups: []kopia.BackupEntry{ { Backup: &backup1, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ pathReason1, }, }, @@ -940,7 +938,7 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_MergeBackupDetails_AddsItems inputBackups: []kopia.BackupEntry{ { Backup: &backup1, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ pathReason1, }, }, @@ -971,13 +969,13 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_MergeBackupDetails_AddsItems inputBackups: []kopia.BackupEntry{ { Backup: &backup1, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ pathReason1, }, }, { Backup: &backup2, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ pathReason3, }, }, @@ -1064,11 +1062,11 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_MergeBackupDetails_AddsFolde locPath1 = path.Builder{}.Append(itemPath1.Folders()...) - pathReason1 = kopia.Reason{ - ResourceOwner: itemPath1.ResourceOwner(), - Service: itemPath1.Service(), - Category: itemPath1.Category(), - } + pathReason1 = kopia.NewReason( + "", + itemPath1.ResourceOwner(), + itemPath1.Service(), + itemPath1.Category()) backup1 = kopia.BackupEntry{ Backup: &backup.Backup{ @@ -1077,7 +1075,7 @@ func (suite *BackupOpUnitSuite) TestBackupOperation_MergeBackupDetails_AddsFolde }, DetailsID: "did1", }, - Reasons: []kopia.Reason{ + Reasons: []kopia.Reasoner{ pathReason1, }, } diff --git a/src/internal/operations/manifests.go b/src/internal/operations/manifests.go index 5e1c79e4f..1c5d1716c 100644 --- a/src/internal/operations/manifests.go +++ b/src/internal/operations/manifests.go @@ -23,7 +23,7 @@ func produceManifestsAndMetadata( ctx context.Context, bf inject.BaseFinder, rp inject.RestoreProducer, - reasons, fallbackReasons []kopia.Reason, + reasons, fallbackReasons []kopia.Reasoner, tenantID string, getMetadata bool, ) (kopia.BackupBases, []data.RestoreCollection, bool, error) { @@ -47,8 +47,8 @@ func produceManifestsAndMetadata( bb = bb.MergeBackupBases( ctx, fbb, - func(r kopia.Reason) string { - return r.Service.String() + r.Category.String() + func(r kopia.Reasoner) string { + return r.Service().String() + r.Category().String() }) if !getMetadata { @@ -115,9 +115,9 @@ func collectMetadata( Append(fn). ToServiceCategoryMetadataPath( tenantID, - reason.ResourceOwner, - reason.Service, - reason.Category, + reason.ProtectedResource(), + reason.Service(), + reason.Category(), true) if err != nil { return nil, clues. diff --git a/src/internal/operations/manifests_test.go b/src/internal/operations/manifests_test.go index e4ae9b6d3..5fdf22424 100644 --- a/src/internal/operations/manifests_test.go +++ b/src/internal/operations/manifests_test.go @@ -47,7 +47,7 @@ type mockBackupFinder struct { func (bf *mockBackupFinder) FindBases( _ context.Context, - reasons []kopia.Reason, + reasons []kopia.Reasoner, _ map[string]string, ) kopia.BackupBases { if len(reasons) == 0 { @@ -58,7 +58,7 @@ func (bf *mockBackupFinder) FindBases( return kopia.NewMockBackupBases() } - b := bf.data[reasons[0].ResourceOwner] + b := bf.data[reasons[0].ProtectedResource()] if b == nil { return kopia.NewMockBackupBases() } @@ -102,7 +102,7 @@ func (suite *OperationsManifestsUnitSuite) TestCollectMetadata() { table := []struct { name string manID string - reasons []kopia.Reason + reasons []kopia.Reasoner fileNames []string expectPaths func(*testing.T, []string) []path.Path expectErr error @@ -110,12 +110,8 @@ func (suite *OperationsManifestsUnitSuite) TestCollectMetadata() { { name: "single reason, single file", manID: "single single", - reasons: []kopia.Reason{ - { - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, + reasons: []kopia.Reasoner{ + kopia.NewReason(tid, ro, path.ExchangeService, path.EmailCategory), }, expectPaths: func(t *testing.T, files []string) []path.Path { ps := make([]path.Path, 0, len(files)) @@ -133,12 +129,8 @@ func (suite *OperationsManifestsUnitSuite) TestCollectMetadata() { { name: "single reason, multiple files", manID: "single multi", - reasons: []kopia.Reason{ - { - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, + reasons: []kopia.Reasoner{ + kopia.NewReason(tid, ro, path.ExchangeService, path.EmailCategory), }, expectPaths: func(t *testing.T, files []string) []path.Path { ps := make([]path.Path, 0, len(files)) @@ -156,17 +148,9 @@ func (suite *OperationsManifestsUnitSuite) TestCollectMetadata() { { name: "multiple reasons, single file", manID: "multi single", - reasons: []kopia.Reason{ - { - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, - { - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.ContactsCategory, - }, + reasons: []kopia.Reasoner{ + kopia.NewReason(tid, ro, path.ExchangeService, path.EmailCategory), + kopia.NewReason(tid, ro, path.ExchangeService, path.ContactsCategory), }, expectPaths: func(t *testing.T, files []string) []path.Path { ps := make([]path.Path, 0, len(files)) @@ -187,17 +171,9 @@ func (suite *OperationsManifestsUnitSuite) TestCollectMetadata() { { name: "multiple reasons, multiple file", manID: "multi multi", - reasons: []kopia.Reason{ - { - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, - { - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.ContactsCategory, - }, + reasons: []kopia.Reasoner{ + kopia.NewReason(tid, ro, path.ExchangeService, path.EmailCategory), + kopia.NewReason(tid, ro, path.ExchangeService, path.ContactsCategory), }, expectPaths: func(t *testing.T, files []string) []path.Path { ps := make([]path.Path, 0, len(files)) @@ -243,17 +219,13 @@ func buildReasons( ro string, service path.ServiceType, cats ...path.CategoryType, -) []kopia.Reason { - var reasons []kopia.Reason +) []kopia.Reasoner { + var reasons []kopia.Reasoner for _, cat := range cats { reasons = append( reasons, - kopia.Reason{ - ResourceOwner: ro, - Service: service, - Category: cat, - }) + kopia.NewReason("", ro, service, cat)) } return reasons @@ -280,7 +252,7 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata() { name string bf *mockBackupFinder rp mockRestoreProducer - reasons []kopia.Reason + reasons []kopia.Reasoner getMeta bool assertErr assert.ErrorAssertionFunc assertB assert.BoolAssertionFunc @@ -291,7 +263,7 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata() { { name: "don't get metadata, no mans", rp: mockRestoreProducer{}, - reasons: []kopia.Reason{}, + reasons: []kopia.Reasoner{}, getMeta: false, assertErr: assert.NoError, assertB: assert.False, @@ -308,12 +280,8 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata() { }, }, rp: mockRestoreProducer{}, - reasons: []kopia.Reason{ - { - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, + reasons: []kopia.Reasoner{ + kopia.NewReason("", ro, path.ExchangeService, path.EmailCategory), }, getMeta: false, assertErr: assert.NoError, @@ -333,12 +301,8 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata() { }, }, rp: mockRestoreProducer{}, - reasons: []kopia.Reason{ - { - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, + reasons: []kopia.Reasoner{ + kopia.NewReason("", ro, path.ExchangeService, path.EmailCategory), }, getMeta: true, assertErr: assert.NoError, @@ -365,17 +329,9 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata() { "id1": {data.NoFetchRestoreCollection{Collection: mockColl{id: "id1"}}}, }, }, - reasons: []kopia.Reason{ - { - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, - { - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.ContactsCategory, - }, + reasons: []kopia.Reasoner{ + kopia.NewReason("", ro, path.ExchangeService, path.EmailCategory), + kopia.NewReason("", ro, path.ExchangeService, path.ContactsCategory), }, getMeta: true, assertErr: assert.NoError, @@ -421,12 +377,8 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata() { "id2": {data.NoFetchRestoreCollection{Collection: mockColl{id: "id2"}}}, }, }, - reasons: []kopia.Reason{ - { - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, + reasons: []kopia.Reasoner{ + kopia.NewReason("", ro, path.ExchangeService, path.EmailCategory), }, getMeta: true, assertErr: assert.NoError, @@ -454,12 +406,8 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata() { "id2": {data.NoFetchRestoreCollection{Collection: mockColl{id: "id2"}}}, }, }, - reasons: []kopia.Reason{ - { - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, + reasons: []kopia.Reasoner{ + kopia.NewReason("", ro, path.ExchangeService, path.EmailCategory), }, getMeta: true, assertErr: assert.NoError, @@ -480,12 +428,8 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata() { }, }, rp: mockRestoreProducer{err: assert.AnError}, - reasons: []kopia.Reason{ - { - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.EmailCategory, - }, + reasons: []kopia.Reasoner{ + kopia.NewReason("", ro, path.ExchangeService, path.EmailCategory), }, getMeta: true, assertErr: assert.Error, @@ -588,24 +532,24 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata_Fallb } } - emailReason := kopia.Reason{ - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.EmailCategory, - } + emailReason := kopia.NewReason( + "", + ro, + path.ExchangeService, + path.EmailCategory) - fbEmailReason := kopia.Reason{ - ResourceOwner: fbro, - Service: path.ExchangeService, - Category: path.EmailCategory, - } + fbEmailReason := kopia.NewReason( + "", + fbro, + path.ExchangeService, + path.EmailCategory) table := []struct { name string bf *mockBackupFinder rp mockRestoreProducer - reasons []kopia.Reason - fallbackReasons []kopia.Reason + reasons []kopia.Reasoner + fallbackReasons []kopia.Reasoner getMeta bool assertErr assert.ErrorAssertionFunc assertB assert.BoolAssertionFunc @@ -624,7 +568,7 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata_Fallb }, }, rp: mockRestoreProducer{}, - fallbackReasons: []kopia.Reason{fbEmailReason}, + fallbackReasons: []kopia.Reasoner{fbEmailReason}, getMeta: false, assertErr: assert.NoError, assertB: assert.False, @@ -649,7 +593,7 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata_Fallb "fb_id1": {data.NoFetchRestoreCollection{Collection: mockColl{id: "fb_id1"}}}, }, }, - fallbackReasons: []kopia.Reason{fbEmailReason}, + fallbackReasons: []kopia.Reasoner{fbEmailReason}, getMeta: true, assertErr: assert.NoError, assertB: assert.True, @@ -680,8 +624,8 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata_Fallb "fb_id1": {data.NoFetchRestoreCollection{Collection: mockColl{id: "fb_id1"}}}, }, }, - reasons: []kopia.Reason{emailReason}, - fallbackReasons: []kopia.Reason{fbEmailReason}, + reasons: []kopia.Reasoner{emailReason}, + fallbackReasons: []kopia.Reasoner{fbEmailReason}, getMeta: true, assertErr: assert.NoError, assertB: assert.True, @@ -708,8 +652,8 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata_Fallb "fb_id2": {data.NoFetchRestoreCollection{Collection: mockColl{id: "fb_id2"}}}, }, }, - reasons: []kopia.Reason{emailReason}, - fallbackReasons: []kopia.Reason{fbEmailReason}, + reasons: []kopia.Reasoner{emailReason}, + fallbackReasons: []kopia.Reasoner{fbEmailReason}, getMeta: true, assertErr: assert.NoError, assertB: assert.True, @@ -744,8 +688,8 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata_Fallb "fb_id2": {data.NoFetchRestoreCollection{Collection: mockColl{id: "fb_id2"}}}, }, }, - reasons: []kopia.Reason{emailReason}, - fallbackReasons: []kopia.Reason{fbEmailReason}, + reasons: []kopia.Reasoner{emailReason}, + fallbackReasons: []kopia.Reasoner{fbEmailReason}, getMeta: true, assertErr: assert.NoError, assertB: assert.True, @@ -776,8 +720,8 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata_Fallb "fb_id1": {data.NoFetchRestoreCollection{Collection: mockColl{id: "fb_id1"}}}, }, }, - reasons: []kopia.Reason{emailReason}, - fallbackReasons: []kopia.Reason{fbEmailReason}, + reasons: []kopia.Reasoner{emailReason}, + fallbackReasons: []kopia.Reasoner{fbEmailReason}, getMeta: true, assertErr: assert.NoError, assertB: assert.True, @@ -808,8 +752,8 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata_Fallb "fb_id2": {data.NoFetchRestoreCollection{Collection: mockColl{id: "fb_id2"}}}, }, }, - reasons: []kopia.Reason{emailReason}, - fallbackReasons: []kopia.Reason{fbEmailReason}, + reasons: []kopia.Reasoner{emailReason}, + fallbackReasons: []kopia.Reasoner{fbEmailReason}, getMeta: true, assertErr: assert.NoError, assertB: assert.True, @@ -838,21 +782,13 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata_Fallb "fb_id1": {data.NoFetchRestoreCollection{Collection: mockColl{id: "fb_id1"}}}, }, }, - reasons: []kopia.Reason{ + reasons: []kopia.Reasoner{ emailReason, - { - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.ContactsCategory, - }, + kopia.NewReason("", ro, path.ExchangeService, path.ContactsCategory), }, - fallbackReasons: []kopia.Reason{ + fallbackReasons: []kopia.Reasoner{ fbEmailReason, - { - ResourceOwner: fbro, - Service: path.ExchangeService, - Category: path.ContactsCategory, - }, + kopia.NewReason("", fbro, path.ExchangeService, path.ContactsCategory), }, getMeta: true, assertErr: assert.NoError, @@ -882,13 +818,9 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata_Fallb "fb_id1": {data.NoFetchRestoreCollection{Collection: mockColl{id: "fb_id1"}}}, }, }, - reasons: []kopia.Reason{emailReason}, - fallbackReasons: []kopia.Reason{ - { - ResourceOwner: fbro, - Service: path.ExchangeService, - Category: path.ContactsCategory, - }, + reasons: []kopia.Reasoner{emailReason}, + fallbackReasons: []kopia.Reasoner{ + kopia.NewReason("", fbro, path.ExchangeService, path.ContactsCategory), }, getMeta: true, assertErr: assert.NoError, @@ -921,21 +853,13 @@ func (suite *OperationsManifestsUnitSuite) TestProduceManifestsAndMetadata_Fallb "fb_id1": {data.NoFetchRestoreCollection{Collection: mockColl{id: "fb_id1"}}}, }, }, - reasons: []kopia.Reason{ + reasons: []kopia.Reasoner{ emailReason, - { - ResourceOwner: ro, - Service: path.ExchangeService, - Category: path.ContactsCategory, - }, + kopia.NewReason("", ro, path.ExchangeService, path.ContactsCategory), }, - fallbackReasons: []kopia.Reason{ + fallbackReasons: []kopia.Reasoner{ fbEmailReason, - { - ResourceOwner: fbro, - Service: path.ExchangeService, - Category: path.ContactsCategory, - }, + kopia.NewReason("", fbro, path.ExchangeService, path.ContactsCategory), }, getMeta: true, assertErr: assert.NoError, diff --git a/src/internal/operations/test/helper_test.go b/src/internal/operations/test/helper_test.go index 93a609365..31dbb9544 100644 --- a/src/internal/operations/test/helper_test.go +++ b/src/internal/operations/test/helper_test.go @@ -242,13 +242,7 @@ func checkBackupIsInManifests( for _, category := range categories { t.Run(category.String(), func(t *testing.T) { var ( - reasons = []kopia.Reason{ - { - ResourceOwner: resourceOwner, - Service: sel.PathService(), - Category: category, - }, - } + r = kopia.NewReason("", resourceOwner, sel.PathService(), category) tags = map[string]string{kopia.TagBackupCategory: ""} found bool ) @@ -256,7 +250,7 @@ func checkBackupIsInManifests( bf, err := kw.NewBaseFinder(sw) require.NoError(t, err, clues.ToCore(err)) - mans := bf.FindBases(ctx, reasons, tags) + mans := bf.FindBases(ctx, []kopia.Reasoner{r}, tags) for _, man := range mans.MergeBases() { bID, ok := man.GetTag(kopia.TagBackupID) if !assert.Truef(t, ok, "snapshot manifest %s missing backup ID tag", man.ID) {