harden sanitree population (#5237)

Allow sanity tree checking to require multiple folder subtrees have no
errors. This allows us to ensure both the source folder subtree and
restore folder subtree are populated without issue.

---

#### 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
- [x] 🤖 Supportability/Tests
- [x] 💻 CI/Deployment
- [ ] 🧹 Tech Debt/Cleanup

#### Test Plan

- [ ] 💪 Manual
- [ ]  Unit test
- [ ] 💚 E2E
This commit is contained in:
ashmrtn 2024-02-21 15:53:12 -08:00 committed by GitHub
parent f4dbaf60b0
commit f3fdb4a885
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 28 additions and 16 deletions

View File

@ -5,6 +5,7 @@ import (
"github.com/alcionai/clues"
"github.com/microsoftgraph/msgraph-sdk-go/models"
"golang.org/x/exp/slices"
"github.com/alcionai/corso/src/cmd/sanity_test/common"
"github.com/alcionai/corso/src/internal/common/ptr"
@ -20,19 +21,20 @@ const (
// this increases the chance that we'll run into a race collision with
// the cleanup script. Sometimes that's okay (deleting old data that
// isn't scrutinized in the test), other times it's not. We mark whether
// that's okay to do or not by specifying the folder that's being
// scrutinized for the test. Any errors within that folder should cause
// a fatal exit. Errors outside of that folder get ignored.
// that's okay to do or not by specifying the folders being
// scrutinized for the test. Any errors within those folders should cause
// a fatal exit. Errors outside of those folders get ignored.
//
// since we're using folder names, requireNoErrorsWithinFolderName will
// since we're using folder names, mustPopulateFolders will
// work best (ie: have the fewest collisions/side-effects) if the folder
// name is very specific. Standard sanity tests should include timestamps,
// names are very specific. Standard sanity tests should include timestamps,
// which should help ensure that. Be warned if you try to use it with
// a more generic name: unintended effects could occur.
func populateSanitree(
ctx context.Context,
ac api.Client,
driveID, requireNoErrorsWithinFolderName string,
driveID string,
mustPopulateFolders []string,
) *common.Sanitree[models.DriveItemable, models.DriveItemable] {
common.Infof(ctx, "building sanitree for drive: %s", driveID)
@ -56,8 +58,8 @@ func populateSanitree(
ac,
driveID,
stree.Name+"/",
requireNoErrorsWithinFolderName,
rootName == requireNoErrorsWithinFolderName,
mustPopulateFolders,
slices.Contains(mustPopulateFolders, rootName),
stree)
return stree
@ -66,7 +68,9 @@ func populateSanitree(
func recursivelyBuildTree(
ctx context.Context,
ac api.Client,
driveID, location, requireNoErrorsWithinFolderName string,
driveID string,
location string,
mustPopulateFolders []string,
isChildOfFolderRequiringNoErrors bool,
stree *common.Sanitree[models.DriveItemable, models.DriveItemable],
) {
@ -80,9 +84,9 @@ func recursivelyBuildTree(
common.Infof(
ctx,
"ignoring error getting children in directory %q because it is not within directory %q\nerror: %s\n%+v",
"ignoring error getting children in directory %q because it is not within directory set %v\nerror: %s\n%+v",
location,
requireNoErrorsWithinFolderName,
mustPopulateFolders,
err.Error(),
clues.ToCore(err))
@ -99,11 +103,12 @@ func recursivelyBuildTree(
// currently we don't restore blank folders.
// skip permission check for empty folders
if ptr.Val(driveItem.GetFolder().GetChildCount()) == 0 {
common.Infof(ctx, "skipped empty folder: %s/%s", location, itemName)
common.Infof(ctx, "skipped empty folder: %s%s", location, itemName)
continue
}
cannotAllowErrors := isChildOfFolderRequiringNoErrors || itemName == requireNoErrorsWithinFolderName
cannotAllowErrors := isChildOfFolderRequiringNoErrors ||
slices.Contains(mustPopulateFolders, itemName)
branch := &common.Sanitree[models.DriveItemable, models.DriveItemable]{
Parent: stree,
@ -124,7 +129,7 @@ func recursivelyBuildTree(
ac,
driveID,
location+branch.Name+"/",
requireNoErrorsWithinFolderName,
mustPopulateFolders,
cannotAllowErrors,
branch)
}

View File

@ -32,7 +32,7 @@ func CheckExport(
ctx,
ac,
driveID,
envs.RestoreContainer)
[]string{envs.SourceContainer})
sourceTree, ok := root.Children[envs.SourceContainer]
common.Assert(

View File

@ -45,7 +45,14 @@ func CheckRestoration(
"drive_id", driveID,
"drive_name", driveName)
root := populateSanitree(ctx, ac, driveID, envs.RestoreContainer)
root := populateSanitree(
ctx,
ac,
driveID,
[]string{
envs.SourceContainer,
envs.RestoreContainer,
})
sourceTree, ok := root.Children[envs.SourceContainer]
common.Assert(