From f3fdb4a8857b8079d889708788c87e31cc109b18 Mon Sep 17 00:00:00 2001 From: ashmrtn <3891298+ashmrtn@users.noreply.github.com> Date: Wed, 21 Feb 2024 15:53:12 -0800 Subject: [PATCH] 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? - [ ] :white_check_mark: Yes, it's included - [ ] :clock1: Yes, but in a later PR - [x] :no_entry: No #### Type of change - [ ] :sunflower: Feature - [ ] :bug: Bugfix - [ ] :world_map: Documentation - [x] :robot: Supportability/Tests - [x] :computer: CI/Deployment - [ ] :broom: Tech Debt/Cleanup #### Test Plan - [ ] :muscle: Manual - [ ] :zap: Unit test - [ ] :green_heart: E2E --- src/cmd/sanity_test/driveish/driveish.go | 33 ++++++++++++++---------- src/cmd/sanity_test/driveish/export.go | 2 +- src/cmd/sanity_test/driveish/restore.go | 9 ++++++- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/cmd/sanity_test/driveish/driveish.go b/src/cmd/sanity_test/driveish/driveish.go index 12f4317906..158d8c4266 100644 --- a/src/cmd/sanity_test/driveish/driveish.go +++ b/src/cmd/sanity_test/driveish/driveish.go @@ -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) } diff --git a/src/cmd/sanity_test/driveish/export.go b/src/cmd/sanity_test/driveish/export.go index 80d608e61f..449da3c46d 100644 --- a/src/cmd/sanity_test/driveish/export.go +++ b/src/cmd/sanity_test/driveish/export.go @@ -32,7 +32,7 @@ func CheckExport( ctx, ac, driveID, - envs.RestoreContainer) + []string{envs.SourceContainer}) sourceTree, ok := root.Children[envs.SourceContainer] common.Assert( diff --git a/src/cmd/sanity_test/driveish/restore.go b/src/cmd/sanity_test/driveish/restore.go index a95c77cefc..7b44fc1127 100644 --- a/src/cmd/sanity_test/driveish/restore.go +++ b/src/cmd/sanity_test/driveish/restore.go @@ -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(