ignore drive sanitree build errors outside of target folder (#5082)

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

- [x]  No

#### Type of change

- [x] 🐛 Bugfix
- [x] 🤖 Supportability/Tests
- [x] 💻 CI/Deployment

#### Issue(s)

* #5081

#### Test Plan

- [x]  Unit test
- [x] 💚 E2E
This commit is contained in:
Keepers 2024-01-22 12:36:12 -07:00 committed by GitHub
parent f1f805b3f8
commit 9a4a664106
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 56 additions and 8 deletions

View File

@ -3,6 +3,7 @@ package driveish
import ( import (
"context" "context"
"github.com/alcionai/clues"
"github.com/microsoftgraph/msgraph-sdk-go/models" "github.com/microsoftgraph/msgraph-sdk-go/models"
"github.com/alcionai/corso/src/cmd/sanity_test/common" "github.com/alcionai/corso/src/cmd/sanity_test/common"
@ -15,10 +16,23 @@ const (
owner = "owner" owner = "owner"
) )
// sanitree population will grab a superset of data in the drive.
// 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.
//
// since we're using folder names, requireNoErrorsWithinFolderName will
// work best (ie: have the fewest collisions/side-effects) if the folder
// name is 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( func populateSanitree(
ctx context.Context, ctx context.Context,
ac api.Client, ac api.Client,
driveID string, driveID, requireNoErrorsWithinFolderName string,
) *common.Sanitree[models.DriveItemable, models.DriveItemable] { ) *common.Sanitree[models.DriveItemable, models.DriveItemable] {
common.Infof(ctx, "building sanitree for drive: %s", driveID) common.Infof(ctx, "building sanitree for drive: %s", driveID)
@ -27,10 +41,12 @@ func populateSanitree(
common.Fatal(ctx, "getting drive root folder", err) common.Fatal(ctx, "getting drive root folder", err)
} }
rootName := ptr.Val(root.GetName())
stree := &common.Sanitree[models.DriveItemable, models.DriveItemable]{ stree := &common.Sanitree[models.DriveItemable, models.DriveItemable]{
Self: root, Self: root,
ID: ptr.Val(root.GetId()), ID: ptr.Val(root.GetId()),
Name: ptr.Val(root.GetName()), Name: rootName,
Leaves: map[string]*common.Sanileaf[models.DriveItemable, models.DriveItemable]{}, Leaves: map[string]*common.Sanileaf[models.DriveItemable, models.DriveItemable]{},
Children: map[string]*common.Sanitree[models.DriveItemable, models.DriveItemable]{}, Children: map[string]*common.Sanitree[models.DriveItemable, models.DriveItemable]{},
} }
@ -40,6 +56,8 @@ func populateSanitree(
ac, ac,
driveID, driveID,
stree.Name+"/", stree.Name+"/",
requireNoErrorsWithinFolderName,
rootName == requireNoErrorsWithinFolderName,
stree) stree)
return stree return stree
@ -48,14 +66,27 @@ func populateSanitree(
func recursivelyBuildTree( func recursivelyBuildTree(
ctx context.Context, ctx context.Context,
ac api.Client, ac api.Client,
driveID, location string, driveID, location, requireNoErrorsWithinFolderName string,
isChildOfFolderRequiringNoErrors bool,
stree *common.Sanitree[models.DriveItemable, models.DriveItemable], stree *common.Sanitree[models.DriveItemable, models.DriveItemable],
) { ) {
common.Debugf(ctx, "adding: %s", location) common.Debugf(ctx, "adding: %s", location)
children, err := ac.Drives().GetFolderChildren(ctx, driveID, stree.ID) children, err := ac.Drives().GetFolderChildren(ctx, driveID, stree.ID)
if err != nil { if err != nil {
common.Fatal(ctx, "getting drive children by id", err) if isChildOfFolderRequiringNoErrors {
common.Fatal(ctx, "getting drive children by id", err)
}
common.Infof(
ctx,
"ignoring error getting children in directory %q because it is not within directory %q\nerror: %s\n%+v",
location,
requireNoErrorsWithinFolderName,
err.Error(),
clues.ToCore(err))
return
} }
for _, driveItem := range children { for _, driveItem := range children {
@ -72,13 +103,15 @@ func recursivelyBuildTree(
continue continue
} }
cannotAllowErrors := isChildOfFolderRequiringNoErrors || itemName == requireNoErrorsWithinFolderName
branch := &common.Sanitree[models.DriveItemable, models.DriveItemable]{ branch := &common.Sanitree[models.DriveItemable, models.DriveItemable]{
Parent: stree, Parent: stree,
Self: driveItem, Self: driveItem,
ID: itemID, ID: itemID,
Name: itemName, Name: itemName,
Expand: map[string]any{ Expand: map[string]any{
expandPermissions: permissionIn(ctx, ac, driveID, itemID), expandPermissions: permissionIn(ctx, ac, driveID, itemID, cannotAllowErrors),
}, },
Leaves: map[string]*common.Sanileaf[models.DriveItemable, models.DriveItemable]{}, Leaves: map[string]*common.Sanileaf[models.DriveItemable, models.DriveItemable]{},
Children: map[string]*common.Sanitree[models.DriveItemable, models.DriveItemable]{}, Children: map[string]*common.Sanitree[models.DriveItemable, models.DriveItemable]{},
@ -91,6 +124,8 @@ func recursivelyBuildTree(
ac, ac,
driveID, driveID,
location+branch.Name+"/", location+branch.Name+"/",
requireNoErrorsWithinFolderName,
cannotAllowErrors,
branch) branch)
} }

View File

@ -31,7 +31,8 @@ func CheckExport(
root := populateSanitree( root := populateSanitree(
ctx, ctx,
ac, ac,
driveID) driveID,
envs.RestoreContainer)
sourceTree, ok := root.Children[envs.SourceContainer] sourceTree, ok := root.Children[envs.SourceContainer]
common.Assert( common.Assert(

View File

@ -45,7 +45,7 @@ func CheckRestoration(
"drive_id", driveID, "drive_id", driveID,
"drive_name", driveName) "drive_name", driveName)
root := populateSanitree(ctx, ac, driveID) root := populateSanitree(ctx, ac, driveID, envs.RestoreContainer)
sourceTree, ok := root.Children[envs.SourceContainer] sourceTree, ok := root.Children[envs.SourceContainer]
common.Assert( common.Assert(
@ -85,12 +85,24 @@ func permissionIn(
ctx context.Context, ctx context.Context,
ac api.Client, ac api.Client,
driveID, itemID string, driveID, itemID string,
cannotAllowErrors bool,
) []common.PermissionInfo { ) []common.PermissionInfo {
pi := []common.PermissionInfo{} pi := []common.PermissionInfo{}
pcr, err := ac.Drives().GetItemPermission(ctx, driveID, itemID) pcr, err := ac.Drives().GetItemPermission(ctx, driveID, itemID)
if err != nil { if err != nil {
common.Fatal(ctx, "getting permission", err) if cannotAllowErrors {
common.Fatal(ctx, "getting permission", err)
}
common.Infof(
ctx,
"ignoring error getting permissions for %q\nerror: %s,%+v",
itemID,
err.Error(),
clues.ToCore(err))
return []common.PermissionInfo{}
} }
for _, perm := range pcr.GetValue() { for _, perm := range pcr.GetValue() {