Setup for separating base sets (#4179)

Start setting things up to split the
base types into distinct sets. This
* Renames some functions
* makes a minor change to how bases
  are "cleared" from the struct.
  Instead of removing them, it just
  hides them

Work in this PR will be used in later
PRs

---

#### Does this PR need a docs update or release note?

- [ ]  Yes, it's included
- [ ] 🕐 Yes, but in a later PR
- [x]  No

#### Type of change

- [ ] 🌻 Feature
- [ ] 🐛 Bugfix
- [ ] 🗺️ Documentation
- [ ] 🤖 Supportability/Tests
- [ ] 💻 CI/Deployment
- [x] 🧹 Tech Debt/Cleanup

#### Issue(s)

* #3943
* #4178

#### Test Plan

- [ ] 💪 Manual
- [x]  Unit test
- [x] 💚 E2E
This commit is contained in:
ashmrtn 2023-09-11 14:31:38 -07:00 committed by GitHub
parent e484fc8967
commit f335f6de6f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 88 additions and 45 deletions

View File

@ -17,12 +17,12 @@ import (
type BackupBases interface { type BackupBases interface {
RemoveMergeBaseByManifestID(manifestID manifest.ID) RemoveMergeBaseByManifestID(manifestID manifest.ID)
Backups() []BackupEntry Backups() []BackupEntry
AssistBackups() []BackupEntry UniqueAssistBackups() []BackupEntry
MinBackupVersion() int MinBackupVersion() int
MergeBases() []ManifestEntry MergeBases() []ManifestEntry
ClearMergeBases() DisableMergeBases()
AssistBases() []ManifestEntry UniqueAssistBases() []ManifestEntry
ClearAssistBases() DisableAssistBases()
MergeBackupBases( MergeBackupBases(
ctx context.Context, ctx context.Context,
other BackupBases, other BackupBases,
@ -37,6 +37,13 @@ type backupBases struct {
mergeBases []ManifestEntry mergeBases []ManifestEntry
assistBackups []BackupEntry assistBackups []BackupEntry
assistBases []ManifestEntry assistBases []ManifestEntry
// disableAssistBases denote whether any assist bases should be returned to
// kopia during snapshot operation.
disableAssistBases bool
// disableMergeBases denotes whether any bases should be returned from calls
// to MergeBases().
disableMergeBases bool
} }
func (bb *backupBases) RemoveMergeBaseByManifestID(manifestID manifest.ID) { func (bb *backupBases) RemoveMergeBaseByManifestID(manifestID manifest.ID) {
@ -71,10 +78,18 @@ func (bb *backupBases) RemoveMergeBaseByManifestID(manifestID manifest.ID) {
} }
func (bb backupBases) Backups() []BackupEntry { func (bb backupBases) Backups() []BackupEntry {
if bb.disableMergeBases {
return nil
}
return slices.Clone(bb.backups) return slices.Clone(bb.backups)
} }
func (bb backupBases) AssistBackups() []BackupEntry { func (bb backupBases) UniqueAssistBackups() []BackupEntry {
if bb.disableAssistBases {
return nil
}
return slices.Clone(bb.assistBackups) return slices.Clone(bb.assistBackups)
} }
@ -95,20 +110,27 @@ func (bb *backupBases) MinBackupVersion() int {
} }
func (bb backupBases) MergeBases() []ManifestEntry { func (bb backupBases) MergeBases() []ManifestEntry {
if bb.disableMergeBases {
return nil
}
return slices.Clone(bb.mergeBases) return slices.Clone(bb.mergeBases)
} }
func (bb *backupBases) ClearMergeBases() { func (bb *backupBases) DisableMergeBases() {
bb.mergeBases = nil bb.disableMergeBases = true
bb.backups = nil
} }
func (bb backupBases) AssistBases() []ManifestEntry { func (bb backupBases) UniqueAssistBases() []ManifestEntry {
if bb.disableAssistBases {
return nil
}
return slices.Clone(bb.assistBases) return slices.Clone(bb.assistBases)
} }
func (bb *backupBases) ClearAssistBases() { func (bb *backupBases) DisableAssistBases() {
bb.assistBases = nil bb.disableAssistBases = true
} }
// MergeBackupBases reduces the two BackupBases into a single BackupBase. // MergeBackupBases reduces the two BackupBases into a single BackupBase.
@ -116,6 +138,9 @@ func (bb *backupBases) ClearAssistBases() {
// some migration that disrupts lookup), and that the BackupBases used to call // some migration that disrupts lookup), and that the BackupBases used to call
// this function contains the current version. // this function contains the current version.
// //
// This call should be made prior to Disable*Bases being called on either the
// called BackupBases or the passed in BackupBases.
//
// reasonToKey should be a function that, given a Reasoner, will produce some // reasonToKey should be a function that, given a Reasoner, will produce some
// string that represents Reasoner in the context of the merge operation. For // string that represents Reasoner in the context of the merge operation. For
// example, to merge BackupBases across a ProtectedResource migration, the // example, to merge BackupBases across a ProtectedResource migration, the
@ -134,11 +159,11 @@ func (bb *backupBases) MergeBackupBases(
other BackupBases, other BackupBases,
reasonToKey func(reason identity.Reasoner) string, reasonToKey func(reason identity.Reasoner) string,
) BackupBases { ) BackupBases {
if other == nil || (len(other.MergeBases()) == 0 && len(other.AssistBases()) == 0) { if other == nil || (len(other.MergeBases()) == 0 && len(other.UniqueAssistBases()) == 0) {
return bb return bb
} }
if bb == nil || (len(bb.MergeBases()) == 0 && len(bb.AssistBases()) == 0) { if bb == nil || (len(bb.MergeBases()) == 0 && len(bb.UniqueAssistBases()) == 0) {
return other return other
} }
@ -189,11 +214,11 @@ func (bb *backupBases) MergeBackupBases(
res := &backupBases{ res := &backupBases{
backups: bb.Backups(), backups: bb.Backups(),
mergeBases: bb.MergeBases(), mergeBases: bb.MergeBases(),
assistBases: bb.AssistBases(), assistBases: bb.UniqueAssistBases(),
// Note that assistBackups are a new feature and don't exist // Note that assistBackups are a new feature and don't exist
// in prior versions where we were using UPN based reasons i.e. // in prior versions where we were using UPN based reasons i.e.
// other won't have any assistBackups. // other won't have any assistBackups.
assistBackups: bb.AssistBackups(), assistBackups: bb.UniqueAssistBackups(),
} }
// Add new mergeBases and backups. // Add new mergeBases and backups.

View File

@ -185,22 +185,40 @@ func (suite *BackupBasesUnitSuite) TestRemoveMergeBaseByManifestID() {
} }
} }
func (suite *BackupBasesUnitSuite) TestClearMergeBases() { func (suite *BackupBasesUnitSuite) TestDisableMergeBases() {
t := suite.T()
bb := &backupBases{ bb := &backupBases{
backups: make([]BackupEntry, 2), backups: make([]BackupEntry, 2),
mergeBases: make([]ManifestEntry, 2), mergeBases: make([]ManifestEntry, 2),
assistBackups: make([]BackupEntry, 2),
assistBases: make([]ManifestEntry, 2),
} }
bb.ClearMergeBases() bb.DisableMergeBases()
assert.Empty(suite.T(), bb.Backups()) assert.Empty(t, bb.Backups())
assert.Empty(suite.T(), bb.MergeBases()) assert.Empty(t, bb.MergeBases())
// Assist base set should be unchanged.
assert.Len(t, bb.UniqueAssistBackups(), 2)
assert.Len(t, bb.UniqueAssistBases(), 2)
} }
func (suite *BackupBasesUnitSuite) TestClearAssistBases() { func (suite *BackupBasesUnitSuite) TestDisableAssistBases() {
bb := &backupBases{assistBases: make([]ManifestEntry, 2)} t := suite.T()
bb := &backupBases{
backups: make([]BackupEntry, 2),
mergeBases: make([]ManifestEntry, 2),
assistBases: make([]ManifestEntry, 2),
assistBackups: make([]BackupEntry, 2),
}
bb.ClearAssistBases() bb.DisableAssistBases()
assert.Empty(suite.T(), bb.AssistBases()) assert.Empty(t, bb.UniqueAssistBases())
assert.Empty(t, bb.UniqueAssistBackups())
// Merge base should be unchanged.
assert.Len(t, bb.Backups(), 2)
assert.Len(t, bb.MergeBases(), 2)
} }
func (suite *BackupBasesUnitSuite) TestMergeBackupBases() { func (suite *BackupBasesUnitSuite) TestMergeBackupBases() {

View File

@ -299,7 +299,7 @@ func (suite *BaseFinderUnitSuite) TestNoResult_NoBackupsOrSnapshots() {
bb := bf.FindBases(ctx, reasons, nil) bb := bf.FindBases(ctx, reasons, nil)
assert.Empty(t, bb.MergeBases()) assert.Empty(t, bb.MergeBases())
assert.Empty(t, bb.AssistBases()) assert.Empty(t, bb.UniqueAssistBases())
} }
func (suite *BaseFinderUnitSuite) TestNoResult_ErrorListingSnapshots() { func (suite *BaseFinderUnitSuite) TestNoResult_ErrorListingSnapshots() {
@ -318,7 +318,7 @@ func (suite *BaseFinderUnitSuite) TestNoResult_ErrorListingSnapshots() {
bb := bf.FindBases(ctx, reasons, nil) bb := bf.FindBases(ctx, reasons, nil)
assert.Empty(t, bb.MergeBases()) assert.Empty(t, bb.MergeBases())
assert.Empty(t, bb.AssistBases()) assert.Empty(t, bb.UniqueAssistBases())
} }
func (suite *BaseFinderUnitSuite) TestGetBases() { func (suite *BaseFinderUnitSuite) TestGetBases() {
@ -1061,7 +1061,7 @@ func (suite *BaseFinderUnitSuite) TestGetBases() {
test.expectedBaseReasons) test.expectedBaseReasons)
checkBackupEntriesMatch( checkBackupEntriesMatch(
t, t,
bb.AssistBackups(), bb.UniqueAssistBackups(),
test.backupData, test.backupData,
test.expectedAssistReasons) test.expectedAssistReasons)
@ -1072,7 +1072,7 @@ func (suite *BaseFinderUnitSuite) TestGetBases() {
test.expectedBaseReasons) test.expectedBaseReasons)
checkManifestEntriesMatch( checkManifestEntriesMatch(
t, t,
bb.AssistBases(), bb.UniqueAssistBases(),
test.manifestData, test.manifestData,
test.expectedAssistManifestReasons) test.expectedAssistManifestReasons)
}) })

View File

@ -14,17 +14,17 @@ func AssertBackupBasesEqual(t *testing.T, expect, got BackupBases) {
if expect == nil { if expect == nil {
assert.Empty(t, got.Backups(), "backups") assert.Empty(t, got.Backups(), "backups")
assert.Empty(t, got.MergeBases(), "merge bases") assert.Empty(t, got.MergeBases(), "merge bases")
assert.Empty(t, got.AssistBackups(), "assist backups") assert.Empty(t, got.UniqueAssistBackups(), "assist backups")
assert.Empty(t, got.AssistBases(), "assist bases") assert.Empty(t, got.UniqueAssistBases(), "assist bases")
return return
} }
if got == nil { if got == nil {
if len(expect.Backups()) > 0 && if len(expect.Backups()) > 0 ||
len(expect.MergeBases()) > 0 && len(expect.MergeBases()) > 0 ||
len(expect.AssistBackups()) > 0 && len(expect.UniqueAssistBackups()) > 0 ||
len(expect.AssistBases()) > 0 { len(expect.UniqueAssistBases()) > 0 {
assert.Fail(t, "got was nil but expected non-nil result %v", expect) assert.Fail(t, "got was nil but expected non-nil result %v", expect)
} }
@ -33,8 +33,8 @@ func AssertBackupBasesEqual(t *testing.T, expect, got BackupBases) {
assert.ElementsMatch(t, expect.Backups(), got.Backups(), "backups") assert.ElementsMatch(t, expect.Backups(), got.Backups(), "backups")
assert.ElementsMatch(t, expect.MergeBases(), got.MergeBases(), "merge bases") assert.ElementsMatch(t, expect.MergeBases(), got.MergeBases(), "merge bases")
assert.ElementsMatch(t, expect.AssistBackups(), got.AssistBackups(), "assist backups") assert.ElementsMatch(t, expect.UniqueAssistBackups(), got.UniqueAssistBackups(), "assist backups")
assert.ElementsMatch(t, expect.AssistBases(), got.AssistBases(), "assist bases") assert.ElementsMatch(t, expect.UniqueAssistBases(), got.UniqueAssistBases(), "assist bases")
} }
func NewMockBackupBases() *MockBackupBases { func NewMockBackupBases() *MockBackupBases {
@ -52,22 +52,22 @@ func (bb *MockBackupBases) WithBackups(b ...BackupEntry) *MockBackupBases {
func (bb *MockBackupBases) WithMergeBases(m ...ManifestEntry) *MockBackupBases { func (bb *MockBackupBases) WithMergeBases(m ...ManifestEntry) *MockBackupBases {
bb.backupBases.mergeBases = append(bb.MergeBases(), m...) bb.backupBases.mergeBases = append(bb.MergeBases(), m...)
bb.backupBases.assistBases = append(bb.AssistBases(), m...) bb.backupBases.assistBases = append(bb.UniqueAssistBases(), m...)
return bb return bb
} }
func (bb *MockBackupBases) WithAssistBackups(b ...BackupEntry) *MockBackupBases { func (bb *MockBackupBases) WithAssistBackups(b ...BackupEntry) *MockBackupBases {
bb.backupBases.assistBackups = append(bb.AssistBackups(), b...) bb.backupBases.assistBackups = append(bb.UniqueAssistBackups(), b...)
return bb return bb
} }
func (bb *MockBackupBases) WithAssistBases(m ...ManifestEntry) *MockBackupBases { func (bb *MockBackupBases) WithAssistBases(m ...ManifestEntry) *MockBackupBases {
bb.backupBases.assistBases = append(bb.AssistBases(), m...) bb.backupBases.assistBases = append(bb.UniqueAssistBases(), m...)
return bb return bb
} }
func (bb *MockBackupBases) ClearMockAssistBases() *MockBackupBases { func (bb *MockBackupBases) ClearMockAssistBases() *MockBackupBases {
bb.backupBases.ClearAssistBases() bb.backupBases.DisableAssistBases()
return bb return bb
} }

View File

@ -178,7 +178,7 @@ func (w Wrapper) ConsumeBackupCollections(
mergeBase = bases.MergeBases() mergeBase = bases.MergeBases()
} }
assistBase = bases.AssistBases() assistBase = bases.UniqueAssistBases()
} }
dirTree, err := inflateDirTree( dirTree, err := inflateDirTree(

View File

@ -732,7 +732,7 @@ func mergeDetails(
// leaves us in a bit of a pickle if the user has run any concurrent backups // leaves us in a bit of a pickle if the user has run any concurrent backups
// with overlapping Reasons that turn into assist bases, but the modTime check // with overlapping Reasons that turn into assist bases, but the modTime check
// in DetailsMergeInfoer should handle that. // in DetailsMergeInfoer should handle that.
for _, base := range bases.AssistBackups() { for _, base := range bases.UniqueAssistBackups() {
added, err := mergeItemsFromBase( added, err := mergeItemsFromBase(
ctx, ctx,
false, false,

View File

@ -39,13 +39,13 @@ func produceManifestsAndMetadata(
if !useMergeBases || !getMetadata { if !useMergeBases || !getMetadata {
logger.Ctx(ctx).Debug("full backup requested, dropping merge bases") logger.Ctx(ctx).Debug("full backup requested, dropping merge bases")
bb.ClearMergeBases() bb.DisableMergeBases()
} }
if dropAssistBases { if dropAssistBases {
logger.Ctx(ctx).Debug("no caching requested, dropping assist bases") logger.Ctx(ctx).Debug("no caching requested, dropping assist bases")
bb.ClearAssistBases() bb.DisableAssistBases()
} }
return bb, meta, useMergeBases, nil return bb, meta, useMergeBases, nil