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{}
|
folderPaths[driveID] = map[string]string{}
|
||||||
maps.Copy(folderPaths[driveID], paths)
|
maps.Copy(folderPaths[driveID], paths)
|
||||||
|
|
||||||
maps.Copy(excludedItems, excluded)
|
|
||||||
|
|
||||||
logger.Ctx(ctx).Infow(
|
logger.Ctx(ctx).Infow(
|
||||||
"persisted metadata for drive",
|
"persisted metadata for drive",
|
||||||
"num_paths_entries",
|
"num_paths_entries",
|
||||||
len(paths),
|
len(paths),
|
||||||
"num_deltas_entries",
|
"num_deltas_entries",
|
||||||
numDeltas)
|
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)))
|
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": {}},
|
expectedDelList: map[string]struct{}{"file": {}},
|
||||||
doNotMergeItems: false,
|
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 {
|
for _, test := range table {
|
||||||
suite.T().Run(test.name, func(t *testing.T) {
|
suite.T().Run(test.name, func(t *testing.T) {
|
||||||
@ -1574,6 +1657,7 @@ func (suite *OneDriveCollectionsSuite) TestGet() {
|
|||||||
c.drivePagerFunc = drivePagerFunc
|
c.drivePagerFunc = drivePagerFunc
|
||||||
c.itemPagerFunc = itemPagerFunc
|
c.itemPagerFunc = itemPagerFunc
|
||||||
|
|
||||||
|
prevDelta := "prev-delta"
|
||||||
mc, err := graph.MakeMetadataCollection(
|
mc, err := graph.MakeMetadataCollection(
|
||||||
tenant,
|
tenant,
|
||||||
user,
|
user,
|
||||||
@ -1583,8 +1667,8 @@ func (suite *OneDriveCollectionsSuite) TestGet() {
|
|||||||
graph.NewMetadataEntry(
|
graph.NewMetadataEntry(
|
||||||
graph.DeltaURLsFileName,
|
graph.DeltaURLsFileName,
|
||||||
map[string]string{
|
map[string]string{
|
||||||
driveID1: "prev-delta",
|
driveID1: prevDelta,
|
||||||
driveID2: "prev-delta",
|
driveID2: prevDelta,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
graph.NewMetadataEntry(
|
graph.NewMetadataEntry(
|
||||||
@ -1605,7 +1689,13 @@ func (suite *OneDriveCollectionsSuite) TestGet() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, baseCol := range cols {
|
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() {
|
if folderPath == metadataPath.String() {
|
||||||
deltas, paths, err := deserializeMetadata(ctx, []data.RestoreCollection{
|
deltas, paths, err := deserializeMetadata(ctx, []data.RestoreCollection{
|
||||||
data.NotFoundRestoreCollection{Collection: baseCol},
|
data.NotFoundRestoreCollection{Collection: baseCol},
|
||||||
@ -1614,8 +1704,8 @@ func (suite *OneDriveCollectionsSuite) TestGet() {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.Equal(t, test.expectedDeltaURLs, deltas)
|
assert.Equal(t, test.expectedDeltaURLs, deltas, "delta urls")
|
||||||
assert.Equal(t, test.expectedFolderPaths, paths)
|
assert.Equal(t, test.expectedFolderPaths, paths, "folder paths")
|
||||||
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|||||||
@ -213,6 +213,7 @@ func collectItems(
|
|||||||
logger.Ctx(ctx).Infow("Invalid previous delta link", "link", prevDelta)
|
logger.Ctx(ctx).Infow("Invalid previous delta link", "link", prevDelta)
|
||||||
|
|
||||||
invalidPrevDelta = true
|
invalidPrevDelta = true
|
||||||
|
newPaths = map[string]string{}
|
||||||
|
|
||||||
pager.Reset()
|
pager.Reset()
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user