Mark collections as Deleted if not available and invalid delta (#2503)
## Description <!-- Insert PR description--> ## Does this PR need a docs update or release note? - [ ] ✅ Yes, it's included - [x] 🕐 Yes, but in a later PR - [ ] ⛔ No ## Type of change <!--- Please check the type of change your PR introduces: ---> - [x] 🌻 Feature - [ ] 🐛 Bugfix - [ ] 🗺️ Documentation - [ ] 🤖 Test - [ ] 💻 CI/Deployment - [ ] 🧹 Tech Debt/Cleanup ## Issue(s) <!-- Can reference multiple issues. Use one of the following "magic words" - "closes, fixes" to auto-close the Github issue. --> * Final entry : closes https://github.com/alcionai/corso/issues/2242 ## Test Plan <!-- How will this be tested prior to merging.--> - [ ] 💪 Manual - [x] ⚡ Unit test - [ ] 💚 E2E
This commit is contained in:
parent
8b21e25a82
commit
dd72c4c8f9
@ -344,14 +344,59 @@ func (c *Collections) Get(
|
||||
folderPaths[driveID] = map[string]string{}
|
||||
maps.Copy(folderPaths[driveID], paths)
|
||||
|
||||
maps.Copy(excludedItems, excluded)
|
||||
|
||||
logger.Ctx(ctx).Infow(
|
||||
"persisted metadata for drive",
|
||||
"num_paths_entries",
|
||||
len(paths),
|
||||
"num_deltas_entries",
|
||||
numDeltas)
|
||||
|
||||
if !delta.Reset {
|
||||
maps.Copy(excludedItems, excluded)
|
||||
continue
|
||||
}
|
||||
|
||||
// Set all folders in previous backup but not in the current
|
||||
// one with state deleted
|
||||
modifiedPaths := map[string]struct{}{}
|
||||
for _, p := range c.CollectionMap {
|
||||
modifiedPaths[p.FullPath().String()] = struct{}{}
|
||||
}
|
||||
|
||||
for i, p := range oldPaths {
|
||||
_, found := paths[i]
|
||||
if found {
|
||||
continue
|
||||
}
|
||||
|
||||
_, found = modifiedPaths[p]
|
||||
if found {
|
||||
// Original folder was deleted and new folder with the
|
||||
// same name/path was created in its place
|
||||
continue
|
||||
}
|
||||
|
||||
delete(paths, i)
|
||||
|
||||
prevPath, err := path.FromDataLayerPath(p, false)
|
||||
if err != nil {
|
||||
return nil, map[string]struct{}{},
|
||||
clues.Wrap(err, "invalid previous path").WithClues(ctx).With("deleted_path", p)
|
||||
}
|
||||
|
||||
col := NewCollection(
|
||||
c.itemClient,
|
||||
nil,
|
||||
prevPath,
|
||||
driveID,
|
||||
c.service,
|
||||
c.statusUpdater,
|
||||
c.source,
|
||||
c.ctrl,
|
||||
true,
|
||||
)
|
||||
c.CollectionMap[i] = col
|
||||
}
|
||||
}
|
||||
|
||||
observe.Message(ctx, observe.Safe(fmt.Sprintf("Discovered %d items to backup", c.NumItems)))
|
||||
|
||||
@ -1531,6 +1531,89 @@ func (suite *OneDriveCollectionsSuite) TestGet() {
|
||||
expectedDelList: map[string]struct{}{"file": {}},
|
||||
doNotMergeItems: false,
|
||||
},
|
||||
{
|
||||
name: "OneDrive_OneItemPage_InvalidPrevDelta_DeleteNonExistantFolder",
|
||||
drives: []models.Driveable{drive1},
|
||||
items: map[string][]deltaPagerResult{
|
||||
driveID1: {
|
||||
{
|
||||
err: getDeltaError(),
|
||||
},
|
||||
{
|
||||
items: []models.DriveItemable{
|
||||
driveRootItem("root"),
|
||||
driveItem("folder2", "folder2", driveBasePath1, "root", false, true, false),
|
||||
driveItem("file", "file", driveBasePath1+"/folder2", "folder2", true, false, false),
|
||||
},
|
||||
deltaLink: &delta,
|
||||
},
|
||||
},
|
||||
},
|
||||
errCheck: assert.NoError,
|
||||
prevFolderPaths: map[string]map[string]string{
|
||||
driveID1: {
|
||||
"root": rootFolderPath1,
|
||||
"folder": folderPath1,
|
||||
},
|
||||
},
|
||||
expectedCollections: map[string]map[data.CollectionState][]string{
|
||||
expectedPath1(""): {data.NotMovedState: {"folder2"}},
|
||||
expectedPath1("/folder"): {data.DeletedState: {}},
|
||||
expectedPath1("/folder2"): {data.NewState: {"file"}},
|
||||
},
|
||||
expectedDeltaURLs: map[string]string{
|
||||
driveID1: delta,
|
||||
},
|
||||
expectedFolderPaths: map[string]map[string]string{
|
||||
driveID1: {
|
||||
"root": rootFolderPath1,
|
||||
"folder2": expectedPath1("/folder2"),
|
||||
},
|
||||
},
|
||||
expectedDelList: map[string]struct{}{},
|
||||
doNotMergeItems: true,
|
||||
},
|
||||
{
|
||||
name: "OneDrive_OneItemPage_InvalidPrevDelta_AnotherFolderAtDeletedLocation",
|
||||
drives: []models.Driveable{drive1},
|
||||
items: map[string][]deltaPagerResult{
|
||||
driveID1: {
|
||||
{
|
||||
err: getDeltaError(),
|
||||
},
|
||||
{
|
||||
items: []models.DriveItemable{
|
||||
driveRootItem("root"),
|
||||
driveItem("folder2", "folder", driveBasePath1, "root", false, true, false),
|
||||
driveItem("file", "file", driveBasePath1+"/folder", "folder2", true, false, false),
|
||||
},
|
||||
deltaLink: &delta,
|
||||
},
|
||||
},
|
||||
},
|
||||
errCheck: assert.NoError,
|
||||
prevFolderPaths: map[string]map[string]string{
|
||||
driveID1: {
|
||||
"root": rootFolderPath1,
|
||||
"folder": folderPath1,
|
||||
},
|
||||
},
|
||||
expectedCollections: map[string]map[data.CollectionState][]string{
|
||||
expectedPath1(""): {data.NotMovedState: {"folder2"}},
|
||||
expectedPath1("/folder"): {data.NewState: {"file"}},
|
||||
},
|
||||
expectedDeltaURLs: map[string]string{
|
||||
driveID1: delta,
|
||||
},
|
||||
expectedFolderPaths: map[string]map[string]string{
|
||||
driveID1: {
|
||||
"root": rootFolderPath1,
|
||||
"folder2": expectedPath1("/folder"),
|
||||
},
|
||||
},
|
||||
expectedDelList: map[string]struct{}{},
|
||||
doNotMergeItems: true,
|
||||
},
|
||||
}
|
||||
for _, test := range table {
|
||||
suite.T().Run(test.name, func(t *testing.T) {
|
||||
@ -1574,6 +1657,7 @@ func (suite *OneDriveCollectionsSuite) TestGet() {
|
||||
c.drivePagerFunc = drivePagerFunc
|
||||
c.itemPagerFunc = itemPagerFunc
|
||||
|
||||
prevDelta := "prev-delta"
|
||||
mc, err := graph.MakeMetadataCollection(
|
||||
tenant,
|
||||
user,
|
||||
@ -1583,8 +1667,8 @@ func (suite *OneDriveCollectionsSuite) TestGet() {
|
||||
graph.NewMetadataEntry(
|
||||
graph.DeltaURLsFileName,
|
||||
map[string]string{
|
||||
driveID1: "prev-delta",
|
||||
driveID2: "prev-delta",
|
||||
driveID1: prevDelta,
|
||||
driveID2: prevDelta,
|
||||
},
|
||||
),
|
||||
graph.NewMetadataEntry(
|
||||
@ -1605,7 +1689,13 @@ func (suite *OneDriveCollectionsSuite) TestGet() {
|
||||
}
|
||||
|
||||
for _, baseCol := range cols {
|
||||
folderPath := baseCol.FullPath().String()
|
||||
var folderPath string
|
||||
if baseCol.State() != data.DeletedState {
|
||||
folderPath = baseCol.FullPath().String()
|
||||
} else {
|
||||
folderPath = baseCol.PreviousPath().String()
|
||||
}
|
||||
|
||||
if folderPath == metadataPath.String() {
|
||||
deltas, paths, err := deserializeMetadata(ctx, []data.RestoreCollection{
|
||||
data.NotFoundRestoreCollection{Collection: baseCol},
|
||||
@ -1614,8 +1704,8 @@ func (suite *OneDriveCollectionsSuite) TestGet() {
|
||||
continue
|
||||
}
|
||||
|
||||
assert.Equal(t, test.expectedDeltaURLs, deltas)
|
||||
assert.Equal(t, test.expectedFolderPaths, paths)
|
||||
assert.Equal(t, test.expectedDeltaURLs, deltas, "delta urls")
|
||||
assert.Equal(t, test.expectedFolderPaths, paths, "folder paths")
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
@ -213,6 +213,7 @@ func collectItems(
|
||||
logger.Ctx(ctx).Infow("Invalid previous delta link", "link", prevDelta)
|
||||
|
||||
invalidPrevDelta = true
|
||||
newPaths = map[string]string{}
|
||||
|
||||
pager.Reset()
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user