From 752ff20c6b7c1250e937c9c855bd14c64315914f Mon Sep 17 00:00:00 2001 From: Keepers Date: Wed, 21 Dec 2022 11:38:41 -0700 Subject: [PATCH] require resource owner set on selector create (#1887) ## Description selector creation now includes a parameter for a slice of resource owners (users or sites). This is step one in migrating resource owner lists out of scopes and into the selector. next step is to have the selector utilize the primary list instead of the per-scope list. ## Does this PR need a docs update or release note? - [x] :no_entry: No ## Type of change - [x] :sunflower: Feature ## Issue(s) * #1617 ## Test Plan - [x] :zap: Unit test - [x] :green_heart: E2E --- src/cli/backup/exchange.go | 6 +- src/cli/backup/exchange_integration_test.go | 15 ++-- src/cli/backup/onedrive.go | 6 +- src/cli/backup/onedrive_integration_test.go | 5 +- src/cli/backup/sharepoint.go | 15 ++-- src/cli/backup/sharepoint_integration_test.go | 5 +- src/cli/backup/sharepoint_test.go | 4 + src/cli/restore/exchange.go | 2 +- src/cli/restore/exchange_integration_test.go | 9 +- src/cli/restore/onedrive.go | 2 +- src/cli/restore/sharepoint.go | 2 +- src/cli/utils/exchange_test.go | 8 +- src/cli/utils/onedrive_test.go | 2 +- src/cli/utils/sharepoint_test.go | 2 +- src/cmd/factory/exchange.go | 6 +- src/internal/connector/data_collections.go | 19 +--- .../connector/data_collections_test.go | 54 ++++++----- .../exchange/data_collections_test.go | 35 +++++--- .../connector/exchange/iterators_test.go | 9 +- .../graph_connector_disconnected_test.go | 36 ++++---- .../connector/graph_connector_helper_test.go | 12 ++- src/internal/connector/onedrive/drive_test.go | 2 +- src/internal/operations/backup.go | 11 +-- src/internal/operations/backup_test.go | 27 +++--- src/internal/operations/restore_test.go | 17 ++-- src/pkg/backup/backup_test.go | 2 +- src/pkg/repository/repository_load_test.go | 12 +-- src/pkg/selectors/example_selectors_test.go | 62 +++++-------- src/pkg/selectors/exchange.go | 25 ++---- src/pkg/selectors/exchange_test.go | 90 +++++++++---------- src/pkg/selectors/onedrive.go | 25 ++---- src/pkg/selectors/onedrive_test.go | 44 +++++---- src/pkg/selectors/selectors.go | 42 ++++----- src/pkg/selectors/selectors_reduce_test.go | 36 ++++---- src/pkg/selectors/selectors_test.go | 2 +- src/pkg/selectors/sharepoint.go | 25 ++---- src/pkg/selectors/sharepoint_test.go | 63 ++++++------- 37 files changed, 348 insertions(+), 391 deletions(-) diff --git a/src/cli/backup/exchange.go b/src/cli/backup/exchange.go index beeecca86..7d5d86d10 100644 --- a/src/cli/backup/exchange.go +++ b/src/cli/backup/exchange.go @@ -284,7 +284,7 @@ func createExchangeCmd(cmd *cobra.Command, args []string) error { for _, scope := range sel.DiscreteScopes(users) { for _, selUser := range scope.Get(selectors.ExchangeUser) { - opSel := selectors.NewExchangeBackup() + opSel := selectors.NewExchangeBackup([]string{selUser}) opSel.Include([]selectors.ExchangeScope{scope.DiscreteCopy(selUser)}) bo, err := r.NewBackup(ctx, opSel.Selector) @@ -328,7 +328,7 @@ func createExchangeCmd(cmd *cobra.Command, args []string) error { } func exchangeBackupCreateSelectors(userIDs, data []string) *selectors.ExchangeBackup { - sel := selectors.NewExchangeBackup() + sel := selectors.NewExchangeBackup(userIDs) if len(data) == 0 { sel.Include(sel.ContactFolders(userIDs, selectors.Any())) @@ -510,7 +510,7 @@ func runDetailsExchangeCmd( return nil, errors.Wrap(err, "Failed to get backup details in the repository") } - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(nil) // TODO: generate selector in IncludeExchangeRestoreDataSelectors utils.IncludeExchangeRestoreDataSelectors(sel, opts) utils.FilterExchangeRestoreInfoSelectors(sel, opts) diff --git a/src/cli/backup/exchange_integration_test.go b/src/cli/backup/exchange_integration_test.go index d4d301375..0211fa1df 100644 --- a/src/cli/backup/exchange_integration_test.go +++ b/src/cli/backup/exchange_integration_test.go @@ -283,24 +283,26 @@ func (suite *PreparedBackupExchangeIntegrationSuite) SetupSuite() { suite.backupOps = make(map[path.CategoryType]string) + users := []string{suite.m365UserID} + for _, set := range backupDataSets { var ( - sel = selectors.NewExchangeBackup() + sel = selectors.NewExchangeBackup(users) scopes []selectors.ExchangeScope ) switch set { case email: - scopes = sel.MailFolders([]string{suite.m365UserID}, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch()) + scopes = sel.MailFolders(users, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch()) case contacts: scopes = sel.ContactFolders( - []string{suite.m365UserID}, + users, []string{exchange.DefaultContactFolder}, selectors.PrefixMatch()) case events: - scopes = sel.EventCalendars([]string{suite.m365UserID}, []string{exchange.DefaultCalendar}, selectors.PrefixMatch()) + scopes = sel.EventCalendars(users, []string{exchange.DefaultCalendar}, selectors.PrefixMatch()) } sel.Include(scopes) @@ -515,10 +517,11 @@ func (suite *BackupDeleteExchangeIntegrationSuite) SetupSuite() { require.NoError(t, err) m365UserID := tester.M365UserID(t) + users := []string{m365UserID} // some tests require an existing backup - sel := selectors.NewExchangeBackup() - sel.Include(sel.MailFolders([]string{m365UserID}, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch())) + sel := selectors.NewExchangeBackup(users) + sel.Include(sel.MailFolders(users, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch())) suite.backupOp, err = suite.repo.NewBackup(ctx, sel.Selector) require.NoError(t, suite.backupOp.Run(ctx)) diff --git a/src/cli/backup/onedrive.go b/src/cli/backup/onedrive.go index 6b86cc041..38b118d29 100644 --- a/src/cli/backup/onedrive.go +++ b/src/cli/backup/onedrive.go @@ -206,7 +206,7 @@ func createOneDriveCmd(cmd *cobra.Command, args []string) error { for _, scope := range sel.DiscreteScopes(users) { for _, selUser := range scope.Get(selectors.OneDriveUser) { - opSel := selectors.NewOneDriveBackup() + opSel := selectors.NewOneDriveBackup([]string{selUser}) opSel.Include([]selectors.OneDriveScope{scope.DiscreteCopy(selUser)}) bo, err := r.NewBackup(ctx, opSel.Selector) @@ -258,7 +258,7 @@ func validateOneDriveBackupCreateFlags(users []string) error { } func oneDriveBackupCreateSelectors(users []string) *selectors.OneDriveBackup { - sel := selectors.NewOneDriveBackup() + sel := selectors.NewOneDriveBackup(users) sel.Include(sel.Users(users)) return sel @@ -401,7 +401,7 @@ func runDetailsOneDriveCmd( return nil, errors.Wrap(err, "Failed to get backup details in the repository") } - sel := selectors.NewOneDriveRestore() + sel := selectors.NewOneDriveRestore(nil) // TODO: generate selector in IncludeExchangeRestoreDataSelectors utils.IncludeOneDriveRestoreDataSelectors(sel, opts) utils.FilterOneDriveRestoreInfoSelectors(sel, opts) diff --git a/src/cli/backup/onedrive_integration_test.go b/src/cli/backup/onedrive_integration_test.go index 956f9f075..bcae8b8ff 100644 --- a/src/cli/backup/onedrive_integration_test.go +++ b/src/cli/backup/onedrive_integration_test.go @@ -172,10 +172,11 @@ func (suite *BackupDeleteOneDriveIntegrationSuite) SetupSuite() { require.NoError(t, err) m365UserID := tester.M365UserID(t) + users := []string{m365UserID} // some tests require an existing backup - sel := selectors.NewOneDriveBackup() - sel.Include(sel.Folders([]string{m365UserID}, selectors.Any())) + sel := selectors.NewOneDriveBackup(users) + sel.Include(sel.Folders(users, selectors.Any())) suite.backupOp, err = suite.repo.NewBackup(ctx, sel.Selector) require.NoError(t, suite.backupOp.Run(ctx)) diff --git a/src/cli/backup/sharepoint.go b/src/cli/backup/sharepoint.go index 25bed3793..dba1101ca 100644 --- a/src/cli/backup/sharepoint.go +++ b/src/cli/backup/sharepoint.go @@ -212,7 +212,7 @@ func createSharePointCmd(cmd *cobra.Command, args []string) error { for _, scope := range sel.DiscreteScopes(gc.GetSiteIDs()) { for _, selSite := range scope.Get(selectors.SharePointSite) { - opSel := selectors.NewSharePointBackup() + opSel := selectors.NewSharePointBackup([]string{selSite}) opSel.Include([]selectors.SharePointScope{scope.DiscreteCopy(selSite)}) bo, err := r.NewBackup(ctx, opSel.Selector) @@ -273,19 +273,16 @@ func sharePointBackupCreateSelectors( sites, weburls []string, gc *connector.GraphConnector, ) (*selectors.SharePointBackup, error) { - sel := selectors.NewSharePointBackup() - for _, site := range sites { if site == utils.Wildcard { - sel.Include(sel.Sites(sites)) + sel := selectors.NewSharePointBackup(selectors.Any()) return sel, nil } } for _, wURL := range weburls { if wURL == utils.Wildcard { - // due to the wildcard, selectors will drop any url values. - sel.Include(sel.Sites(weburls)) + sel := selectors.NewSharePointBackup(selectors.Any()) return sel, nil } } @@ -295,9 +292,7 @@ func sharePointBackupCreateSelectors( return nil, err } - sel.Include(sel.Sites(union)) - - return sel, nil + return selectors.NewSharePointBackup(union), nil } // ------------------------------------------------------------------------------------------------ @@ -478,7 +473,7 @@ func runDetailsSharePointCmd( return nil, errors.Wrap(err, "Failed to get backup details in the repository") } - sel := selectors.NewSharePointRestore() + sel := selectors.NewSharePointRestore(nil) // TODO: generate selector in IncludeSharePointRestoreDataSelectors utils.IncludeSharePointRestoreDataSelectors(sel, opts) utils.FilterSharePointRestoreInfoSelectors(sel, opts) diff --git a/src/cli/backup/sharepoint_integration_test.go b/src/cli/backup/sharepoint_integration_test.go index 4abb510d1..6f8b4bd18 100644 --- a/src/cli/backup/sharepoint_integration_test.go +++ b/src/cli/backup/sharepoint_integration_test.go @@ -172,10 +172,11 @@ func (suite *BackupDeleteSharePointIntegrationSuite) SetupSuite() { require.NoError(t, err) m365SiteID := tester.M365SiteID(t) + sites := []string{m365SiteID} // some tests require an existing backup - sel := selectors.NewSharePointBackup() - sel.Include(sel.Libraries([]string{m365SiteID}, selectors.Any())) + sel := selectors.NewSharePointBackup(sites) + sel.Include(sel.Libraries(sites, selectors.Any())) suite.backupOp, err = suite.repo.NewBackup(ctx, sel.Selector) require.NoError(t, suite.backupOp.Run(ctx)) diff --git a/src/cli/backup/sharepoint_test.go b/src/cli/backup/sharepoint_test.go index bf1b1280c..5a410884b 100644 --- a/src/cli/backup/sharepoint_test.go +++ b/src/cli/backup/sharepoint_test.go @@ -180,6 +180,10 @@ func (suite *SharePointSuite) TestSharePointBackupCreateSelectors() { sel, err := sharePointBackupCreateSelectors(ctx, test.site, test.weburl, gc) require.NoError(t, err) + if len(sel.Scopes()) == 0 { + return + } + scope := sel.Scopes()[0] targetSites := scope.Get(selectors.SharePointSite) diff --git a/src/cli/restore/exchange.go b/src/cli/restore/exchange.go index 84d24945e..d034cce98 100644 --- a/src/cli/restore/exchange.go +++ b/src/cli/restore/exchange.go @@ -216,7 +216,7 @@ func restoreExchangeCmd(cmd *cobra.Command, args []string) error { defer utils.CloseRepo(ctx, r) - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(nil) // TODO: generate selector in IncludeExchangeRestoreDataSelectors utils.IncludeExchangeRestoreDataSelectors(sel, opts) utils.FilterExchangeRestoreInfoSelectors(sel, opts) diff --git a/src/cli/restore/exchange_integration_test.go b/src/cli/restore/exchange_integration_test.go index 6cf7db6e7..bd3701eba 100644 --- a/src/cli/restore/exchange_integration_test.go +++ b/src/cli/restore/exchange_integration_test.go @@ -81,6 +81,7 @@ func (suite *RestoreExchangeIntegrationSuite) SetupSuite() { require.NoError(t, err) suite.m365UserID = tester.M365UserID(t) + users := []string{suite.m365UserID} // init the repo first suite.repo, err = repository.Initialize(ctx, suite.acct, suite.st, control.Options{}) @@ -90,22 +91,22 @@ func (suite *RestoreExchangeIntegrationSuite) SetupSuite() { for _, set := range backupDataSets { var ( - sel = selectors.NewExchangeBackup() + sel = selectors.NewExchangeBackup(users) scopes []selectors.ExchangeScope ) switch set { case email: - scopes = sel.MailFolders([]string{suite.m365UserID}, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch()) + scopes = sel.MailFolders(users, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch()) case contacts: scopes = sel.ContactFolders( - []string{suite.m365UserID}, + users, []string{exchange.DefaultContactFolder}, selectors.PrefixMatch()) case events: - scopes = sel.EventCalendars([]string{suite.m365UserID}, []string{exchange.DefaultCalendar}, selectors.PrefixMatch()) + scopes = sel.EventCalendars(users, []string{exchange.DefaultCalendar}, selectors.PrefixMatch()) } sel.Include(scopes) diff --git a/src/cli/restore/onedrive.go b/src/cli/restore/onedrive.go index a31bffccf..a65dae5c6 100644 --- a/src/cli/restore/onedrive.go +++ b/src/cli/restore/onedrive.go @@ -153,7 +153,7 @@ func restoreOneDriveCmd(cmd *cobra.Command, args []string) error { defer utils.CloseRepo(ctx, r) - sel := selectors.NewOneDriveRestore() + sel := selectors.NewOneDriveRestore(nil) // TODO: generate selector in IncludeOneDriveRestoreDataSelectors utils.IncludeOneDriveRestoreDataSelectors(sel, opts) utils.FilterOneDriveRestoreInfoSelectors(sel, opts) diff --git a/src/cli/restore/sharepoint.go b/src/cli/restore/sharepoint.go index ded2e8162..c9e6e2bcc 100644 --- a/src/cli/restore/sharepoint.go +++ b/src/cli/restore/sharepoint.go @@ -140,7 +140,7 @@ func restoreSharePointCmd(cmd *cobra.Command, args []string) error { defer utils.CloseRepo(ctx, r) - sel := selectors.NewSharePointRestore() + sel := selectors.NewSharePointRestore(nil) // TODO: generate selector in IncludeSharePointRestoreDataSelectors utils.IncludeSharePointRestoreDataSelectors(sel, opts) utils.FilterSharePointRestoreInfoSelectors(sel, opts) diff --git a/src/cli/utils/exchange_test.go b/src/cli/utils/exchange_test.go index 7316051ad..58c22d17d 100644 --- a/src/cli/utils/exchange_test.go +++ b/src/cli/utils/exchange_test.go @@ -301,7 +301,7 @@ func (suite *ExchangeUtilsSuite) TestIncludeExchangeRestoreDataSelectors() { } for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(nil) utils.IncludeExchangeRestoreDataSelectors(sel, test.opts) assert.Len(t, sel.Includes, test.expectIncludeLen) }) @@ -316,7 +316,7 @@ func (suite *ExchangeUtilsSuite) TestAddExchangeInclude() { containsOnly = []string{"contains"} prefixOnly = []string{"/prefix"} containsAndPrefix = []string{"contains", "/prefix"} - eisc = selectors.NewExchangeRestore().Contacts // type independent, just need the func + eisc = selectors.NewExchangeRestore(nil).Contacts // type independent, just need the func ) table := []struct { @@ -369,7 +369,7 @@ func (suite *ExchangeUtilsSuite) TestAddExchangeInclude() { } for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(nil) // no return, mutates sel as a side effect utils.AddExchangeInclude(sel, test.resources, test.folders, test.items, eisc) assert.Len(t, sel.Includes, test.expectIncludeLen) @@ -485,7 +485,7 @@ func (suite *ExchangeUtilsSuite) TestFilterExchangeRestoreInfoSelectors() { } for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(nil) utils.FilterExchangeRestoreInfoSelectors(sel, test.opts) assert.Len(t, sel.Filters, test.expectFilterLen) }) diff --git a/src/cli/utils/onedrive_test.go b/src/cli/utils/onedrive_test.go index a0054f0fa..15bc4dce1 100644 --- a/src/cli/utils/onedrive_test.go +++ b/src/cli/utils/onedrive_test.go @@ -90,7 +90,7 @@ func (suite *OneDriveUtilsSuite) TestIncludeOneDriveRestoreDataSelectors() { } for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { - sel := selectors.NewOneDriveRestore() + sel := selectors.NewOneDriveRestore(nil) // no return, mutates sel as a side effect utils.IncludeOneDriveRestoreDataSelectors(sel, test.opts) assert.Len(t, sel.Includes, test.expectIncludeLen) diff --git a/src/cli/utils/sharepoint_test.go b/src/cli/utils/sharepoint_test.go index de5cd5a6e..3367d4a28 100644 --- a/src/cli/utils/sharepoint_test.go +++ b/src/cli/utils/sharepoint_test.go @@ -126,7 +126,7 @@ func (suite *SharePointUtilsSuite) TestIncludeSharePointRestoreDataSelectors() { } for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { - sel := selectors.NewSharePointRestore() + sel := selectors.NewSharePointRestore(nil) // no return, mutates sel as a side effect t.Logf("Options sent: %v\n", test.opts) utils.IncludeSharePointRestoreDataSelectors(sel, test.opts) diff --git a/src/cmd/factory/exchange.go b/src/cmd/factory/exchange.go index bf175a622..b7bbb4afa 100644 --- a/src/cmd/factory/exchange.go +++ b/src/cmd/factory/exchange.go @@ -57,7 +57,7 @@ func handleExchangeEmailFactory(cmd *cobra.Command, args []string) error { gc, service, category, - selectors.NewExchangeRestore().Selector, + selectors.NewExchangeRestore([]string{user}).Selector, tenantID, user, destination, count, func(id, now, subject, body string) []byte { @@ -97,7 +97,7 @@ func handleExchangeCalendarEventFactory(cmd *cobra.Command, args []string) error gc, service, category, - selectors.NewExchangeRestore().Selector, + selectors.NewExchangeRestore([]string{user}).Selector, tenantID, user, destination, count, func(id, now, subject, body string) []byte { @@ -136,7 +136,7 @@ func handleExchangeContactFactory(cmd *cobra.Command, args []string) error { gc, service, category, - selectors.NewExchangeRestore().Selector, + selectors.NewExchangeRestore([]string{user}).Selector, tenantID, user, destination, count, func(id, now, subject, body string) []byte { diff --git a/src/internal/connector/data_collections.go b/src/internal/connector/data_collections.go index 9b7230edf..4057aafda 100644 --- a/src/internal/connector/data_collections.go +++ b/src/internal/connector/data_collections.go @@ -92,10 +92,7 @@ func (gc *GraphConnector) DataCollections( func verifyBackupInputs(sels selectors.Selector, userPNs, siteIDs []string) error { var ids []string - resourceOwners, err := sels.ResourceOwners() - if err != nil { - return errors.Wrap(err, "invalid backup inputs") - } + resourceOwners := sels.DiscreteResourceOwners() switch sels.Service { case selectors.ServiceExchange, selectors.ServiceOneDrive: @@ -112,24 +109,12 @@ func verifyBackupInputs(sels selectors.Selector, userPNs, siteIDs []string) erro normROs[strings.ToLower(id)] = struct{}{} } - for _, ro := range resourceOwners.Includes { + for _, ro := range resourceOwners { if _, ok := normROs[strings.ToLower(ro)]; !ok { return fmt.Errorf("included resource owner %s not found within tenant", ro) } } - for _, ro := range resourceOwners.Excludes { - if _, ok := normROs[strings.ToLower(ro)]; !ok { - return fmt.Errorf("excluded resource owner %s not found within tenant", ro) - } - } - - for _, ro := range resourceOwners.Filters { - if _, ok := normROs[strings.ToLower(ro)]; !ok { - return fmt.Errorf("filtered resource owner %s not found within tenant", ro) - } - } - return nil } diff --git a/src/internal/connector/data_collections_test.go b/src/internal/connector/data_collections_test.go index 58a6a3a84..e7ca6c791 100644 --- a/src/internal/connector/data_collections_test.go +++ b/src/internal/connector/data_collections_test.go @@ -59,6 +59,8 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestExchangeDataCollection ctx, flush := tester.NewContext() defer flush() + selUsers := []string{suite.user} + connector := loadConnector(ctx, suite.T(), Users) tests := []struct { name string @@ -67,8 +69,8 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestExchangeDataCollection { name: suite.user + " Email", getSelector: func(t *testing.T) selectors.Selector { - sel := selectors.NewExchangeBackup() - sel.Include(sel.MailFolders([]string{suite.user}, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch())) + sel := selectors.NewExchangeBackup(selUsers) + sel.Include(sel.MailFolders(selUsers, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch())) return sel.Selector }, @@ -76,9 +78,9 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestExchangeDataCollection { name: suite.user + " Contacts", getSelector: func(t *testing.T) selectors.Selector { - sel := selectors.NewExchangeBackup() + sel := selectors.NewExchangeBackup(selUsers) sel.Include(sel.ContactFolders( - []string{suite.user}, + selUsers, []string{exchange.DefaultContactFolder}, selectors.PrefixMatch())) @@ -88,9 +90,9 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestExchangeDataCollection // { // name: suite.user + " Events", // getSelector: func(t *testing.T) selectors.Selector { - // sel := selectors.NewExchangeBackup() + // sel := selectors.NewExchangeBackup(selUsers) // sel.Include(sel.EventCalendars( - // []string{suite.user}, + // selUsers, // []string{exchange.DefaultCalendar}, // selectors.PrefixMatch(), // )) @@ -142,6 +144,8 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestInvalidUserForDataColl defer flush() invalidUser := "foo@example.com" + selUsers := []string{invalidUser} + connector := loadConnector(ctx, suite.T(), Users) tests := []struct { name string @@ -150,16 +154,16 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestInvalidUserForDataColl { name: "invalid exchange backup user", getSelector: func(t *testing.T) selectors.Selector { - sel := selectors.NewExchangeBackup() - sel.Include(sel.MailFolders([]string{invalidUser}, selectors.Any())) + sel := selectors.NewExchangeBackup(selUsers) + sel.Include(sel.MailFolders(selUsers, selectors.Any())) return sel.Selector }, }, { name: "Invalid onedrive backup user", getSelector: func(t *testing.T) selectors.Selector { - sel := selectors.NewOneDriveBackup() - sel.Include(sel.Folders([]string{invalidUser}, selectors.Any())) + sel := selectors.NewOneDriveBackup(selUsers) + sel.Include(sel.Folders(selUsers, selectors.Any())) return sel.Selector }, }, @@ -181,6 +185,8 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestSharePointDataCollecti ctx, flush := tester.NewContext() defer flush() + selSites := []string{suite.site} + connector := loadConnector(ctx, suite.T(), Sites) tests := []struct { name string @@ -188,11 +194,10 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestSharePointDataCollecti getSelector func() selectors.Selector }{ { - name: "Libraries", - expected: 1, + name: "Libraries", getSelector: func() selectors.Selector { - sel := selectors.NewSharePointBackup() - sel.Include(sel.Libraries([]string{suite.site}, selectors.Any())) + sel := selectors.NewSharePointBackup(selSites) + sel.Include(sel.Libraries(selSites, selectors.Any())) return sel.Selector }, @@ -201,8 +206,8 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestSharePointDataCollecti name: "Lists", expected: 0, getSelector: func() selectors.Selector { - sel := selectors.NewSharePointBackup() - sel.Include(sel.Lists([]string{suite.site}, selectors.Any())) + sel := selectors.NewSharePointBackup(selSites) + sel.Include(sel.Lists(selSites, selectors.Any())) return sel.Selector }, @@ -214,7 +219,7 @@ func (suite *ConnectorDataCollectionIntegrationSuite) TestSharePointDataCollecti collections, err := sharepoint.DataCollections( ctx, test.getSelector(), - []string{suite.site}, + selSites, connector.credentials.AzureTenantID, connector.Service, connector, @@ -283,9 +288,10 @@ func (suite *ConnectorCreateSharePointCollectionIntegrationSuite) TestCreateShar defer flush() var ( - t = suite.T() - siteID = tester.M365SiteID(t) - gc = loadConnector(ctx, t, Sites) + t = suite.T() + siteID = tester.M365SiteID(t) + gc = loadConnector(ctx, t, Sites) + siteIDs = []string{siteID} ) tables := []struct { @@ -297,9 +303,9 @@ func (suite *ConnectorCreateSharePointCollectionIntegrationSuite) TestCreateShar name: "SharePoint.Libraries", comparator: assert.Equal, sel: func() selectors.Selector { - sel := selectors.NewSharePointBackup() + sel := selectors.NewSharePointBackup(siteIDs) sel.Include(sel.Libraries( - []string{siteID}, + siteIDs, []string{"foo"}, selectors.PrefixMatch(), )) @@ -311,9 +317,9 @@ func (suite *ConnectorCreateSharePointCollectionIntegrationSuite) TestCreateShar name: "SharePoint.Lists", comparator: assert.Less, sel: func() selectors.Selector { - sel := selectors.NewSharePointBackup() + sel := selectors.NewSharePointBackup(siteIDs) sel.Include(sel.Lists( - []string{siteID}, + siteIDs, selectors.Any(), selectors.PrefixMatch(), // without this option a SEG Fault occurs )) diff --git a/src/internal/connector/exchange/data_collections_test.go b/src/internal/connector/exchange/data_collections_test.go index 8e26d4adc..82d8b07c7 100644 --- a/src/internal/connector/exchange/data_collections_test.go +++ b/src/internal/connector/exchange/data_collections_test.go @@ -235,6 +235,7 @@ func (suite *DataCollectionsIntegrationSuite) TestMailFetch() { var ( userID = tester.M365UserID(suite.T()) + users = []string{userID} acct, err = tester.NewM365Account(suite.T()).M365Config() ) @@ -247,8 +248,8 @@ func (suite *DataCollectionsIntegrationSuite) TestMailFetch() { }{ { name: "Folder Iterative Check Mail", - scope: selectors.NewExchangeBackup().MailFolders( - []string{userID}, + scope: selectors.NewExchangeBackup(users).MailFolders( + users, []string{DefaultMailFolder}, selectors.PrefixMatch(), )[0], @@ -293,6 +294,7 @@ func (suite *DataCollectionsIntegrationSuite) TestDelta() { var ( userID = tester.M365UserID(suite.T()) + users = []string{userID} acct, err = tester.NewM365Account(suite.T()).M365Config() ) @@ -304,7 +306,7 @@ func (suite *DataCollectionsIntegrationSuite) TestDelta() { }{ { name: "Mail", - scope: selectors.NewExchangeBackup().MailFolders( + scope: selectors.NewExchangeBackup(users).MailFolders( []string{userID}, []string{DefaultMailFolder}, selectors.PrefixMatch(), @@ -312,7 +314,7 @@ func (suite *DataCollectionsIntegrationSuite) TestDelta() { }, { name: "Contacts", - scope: selectors.NewExchangeBackup().ContactFolders( + scope: selectors.NewExchangeBackup(users).ContactFolders( []string{userID}, []string{DefaultContactFolder}, selectors.PrefixMatch(), @@ -382,15 +384,16 @@ func (suite *DataCollectionsIntegrationSuite) TestMailSerializationRegression() defer flush() var ( - t = suite.T() - wg sync.WaitGroup + t = suite.T() + wg sync.WaitGroup + users = []string{suite.user} ) acct, err := tester.NewM365Account(t).M365Config() require.NoError(t, err) - sel := selectors.NewExchangeBackup() - sel.Include(sel.MailFolders([]string{suite.user}, []string{DefaultMailFolder}, selectors.PrefixMatch())) + sel := selectors.NewExchangeBackup(users) + sel.Include(sel.MailFolders(users, []string{DefaultMailFolder}, selectors.PrefixMatch())) collections, err := createCollections( ctx, @@ -440,14 +443,16 @@ func (suite *DataCollectionsIntegrationSuite) TestContactSerializationRegression acct, err := tester.NewM365Account(suite.T()).M365Config() require.NoError(suite.T(), err) + users := []string{suite.user} + tests := []struct { name string scope selectors.ExchangeScope }{ { name: "Default Contact Folder", - scope: selectors.NewExchangeBackup().ContactFolders( - []string{suite.user}, + scope: selectors.NewExchangeBackup(users).ContactFolders( + users, []string{DefaultContactFolder}, selectors.PrefixMatch())[0], }, @@ -513,6 +518,8 @@ func (suite *DataCollectionsIntegrationSuite) TestEventsSerializationRegression( acct, err := tester.NewM365Account(suite.T()).M365Config() require.NoError(suite.T(), err) + users := []string{suite.user} + tests := []struct { name, expected string scope selectors.ExchangeScope @@ -520,16 +527,16 @@ func (suite *DataCollectionsIntegrationSuite) TestEventsSerializationRegression( { name: "Default Event Calendar", expected: DefaultCalendar, - scope: selectors.NewExchangeBackup().EventCalendars( - []string{suite.user}, + scope: selectors.NewExchangeBackup(users).EventCalendars( + users, []string{DefaultCalendar}, selectors.PrefixMatch())[0], }, { name: "Birthday Calendar", expected: "Birthdays", - scope: selectors.NewExchangeBackup().EventCalendars( - []string{suite.user}, + scope: selectors.NewExchangeBackup(users).EventCalendars( + users, []string{"Birthdays"}, selectors.PrefixMatch())[0], }, diff --git a/src/internal/connector/exchange/iterators_test.go b/src/internal/connector/exchange/iterators_test.go index 8e7237e91..913115ed5 100644 --- a/src/internal/connector/exchange/iterators_test.go +++ b/src/internal/connector/exchange/iterators_test.go @@ -81,15 +81,16 @@ func (suite *ExchangeIteratorSuite) TestCollectionFunctions() { t = suite.T() mailScope, contactScope, eventScope []selectors.ExchangeScope userID = tester.M365UserID(t) - sel = selectors.NewExchangeBackup() + users = []string{userID} + sel = selectors.NewExchangeBackup(users) ) eb, err := sel.ToExchangeBackup() require.NoError(suite.T(), err) - contactScope = sel.ContactFolders([]string{userID}, []string{DefaultContactFolder}, selectors.PrefixMatch()) - eventScope = sel.EventCalendars([]string{userID}, []string{DefaultCalendar}, selectors.PrefixMatch()) - mailScope = sel.MailFolders([]string{userID}, []string{DefaultMailFolder}, selectors.PrefixMatch()) + contactScope = sel.ContactFolders(users, []string{DefaultContactFolder}, selectors.PrefixMatch()) + eventScope = sel.EventCalendars(users, []string{DefaultCalendar}, selectors.PrefixMatch()) + mailScope = sel.MailFolders(users, []string{DefaultMailFolder}, selectors.PrefixMatch()) eb.Include(contactScope, eventScope, mailScope) diff --git a/src/internal/connector/graph_connector_disconnected_test.go b/src/internal/connector/graph_connector_disconnected_test.go index caaeffa28..afefcfad8 100644 --- a/src/internal/connector/graph_connector_disconnected_test.go +++ b/src/internal/connector/graph_connector_disconnected_test.go @@ -205,16 +205,16 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs() { }{ { name: "No scopes", - checkError: assert.NoError, + checkError: assert.Error, getSelector: func(t *testing.T) selectors.Selector { - return selectors.NewExchangeBackup().Selector + return selectors.NewExchangeBackup(nil).Selector }, }, { name: "Valid Single User", checkError: assert.NoError, getSelector: func(t *testing.T) selectors.Selector { - sel := selectors.NewExchangeBackup() + sel := selectors.NewExchangeBackup([]string{"bobkelso@someHospital.org"}) sel.Include(sel.MailFolders([]string{"bobkelso@someHospital.org"}, selectors.Any())) return sel.Selector }, @@ -223,7 +223,7 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs() { name: "Partial invalid user", checkError: assert.Error, getSelector: func(t *testing.T) selectors.Selector { - sel := selectors.NewExchangeBackup() + sel := selectors.NewExchangeBackup([]string{"bobkelso@someHospital.org", "janitor@someHospital.org"}) sel.Include(sel.MailFolders([]string{"bobkelso@someHospital.org", "janitor@someHospital.org"}, selectors.Any())) return sel.Selector }, @@ -232,7 +232,9 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs() { name: "Multiple Valid Users", checkError: assert.NoError, getSelector: func(t *testing.T) selectors.Selector { - sel := selectors.NewOneDriveBackup() + sel := selectors.NewOneDriveBackup( + []string{"elliotReid@someHospital.org", "johnDorian@someHospital.org", "christurk@somehospital.org"}, + ) sel.Include( sel.Users([]string{"elliotReid@someHospital.org", "johnDorian@someHospital.org", "christurk@somehospital.org"})) @@ -264,17 +266,17 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs_allServices name: "Valid User", checkError: assert.NoError, excludes: func(t *testing.T) selectors.Selector { - sel := selectors.NewOneDriveBackup() + sel := selectors.NewOneDriveBackup([]string{"elliotReid@someHospital.org"}) sel.Exclude(sel.Folders([]string{"elliotReid@someHospital.org"}, selectors.Any())) return sel.Selector }, filters: func(t *testing.T) selectors.Selector { - sel := selectors.NewOneDriveBackup() + sel := selectors.NewOneDriveBackup([]string{"elliotReid@someHospital.org"}) sel.Filter(sel.Folders([]string{"elliotReid@someHospital.org"}, selectors.Any())) return sel.Selector }, includes: func(t *testing.T) selectors.Selector { - sel := selectors.NewOneDriveBackup() + sel := selectors.NewOneDriveBackup([]string{"elliotReid@someHospital.org"}) sel.Include(sel.Folders([]string{"elliotReid@someHospital.org"}, selectors.Any())) return sel.Selector }, @@ -283,17 +285,17 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs_allServices name: "Invalid User", checkError: assert.Error, excludes: func(t *testing.T) selectors.Selector { - sel := selectors.NewOneDriveBackup() + sel := selectors.NewOneDriveBackup([]string{"foo@SomeCompany.org"}) sel.Exclude(sel.Folders([]string{"foo@SomeCompany.org"}, selectors.Any())) return sel.Selector }, filters: func(t *testing.T) selectors.Selector { - sel := selectors.NewOneDriveBackup() + sel := selectors.NewOneDriveBackup([]string{"foo@SomeCompany.org"}) sel.Filter(sel.Folders([]string{"foo@SomeCompany.org"}, selectors.Any())) return sel.Selector }, includes: func(t *testing.T) selectors.Selector { - sel := selectors.NewOneDriveBackup() + sel := selectors.NewOneDriveBackup([]string{"foo@SomeCompany.org"}) sel.Include(sel.Folders([]string{"foo@SomeCompany.org"}, selectors.Any())) return sel.Selector }, @@ -302,17 +304,17 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs_allServices name: "valid sites", checkError: assert.NoError, excludes: func(t *testing.T) selectors.Selector { - sel := selectors.NewSharePointBackup() + sel := selectors.NewSharePointBackup([]string{"abc.site.foo", "bar.site.baz"}) sel.Exclude(sel.Sites([]string{"abc.site.foo", "bar.site.baz"})) return sel.Selector }, filters: func(t *testing.T) selectors.Selector { - sel := selectors.NewSharePointBackup() + sel := selectors.NewSharePointBackup([]string{"abc.site.foo", "bar.site.baz"}) sel.Filter(sel.Sites([]string{"abc.site.foo", "bar.site.baz"})) return sel.Selector }, includes: func(t *testing.T) selectors.Selector { - sel := selectors.NewSharePointBackup() + sel := selectors.NewSharePointBackup([]string{"abc.site.foo", "bar.site.baz"}) sel.Include(sel.Sites([]string{"abc.site.foo", "bar.site.baz"})) return sel.Selector }, @@ -321,17 +323,17 @@ func (suite *DisconnectedGraphConnectorSuite) TestVerifyBackupInputs_allServices name: "invalid sites", checkError: assert.Error, excludes: func(t *testing.T) selectors.Selector { - sel := selectors.NewSharePointBackup() + sel := selectors.NewSharePointBackup([]string{"fnords.smarfs.brawnhilda"}) sel.Exclude(sel.Sites([]string{"fnords.smarfs.brawnhilda"})) return sel.Selector }, filters: func(t *testing.T) selectors.Selector { - sel := selectors.NewSharePointBackup() + sel := selectors.NewSharePointBackup([]string{"fnords.smarfs.brawnhilda"}) sel.Filter(sel.Sites([]string{"fnords.smarfs.brawnhilda"})) return sel.Selector }, includes: func(t *testing.T) selectors.Selector { - sel := selectors.NewSharePointBackup() + sel := selectors.NewSharePointBackup([]string{"fnords.smarfs.brawnhilda"}) sel.Include(sel.Sites([]string{"fnords.smarfs.brawnhilda"})) return sel.Selector }, diff --git a/src/internal/connector/graph_connector_helper_test.go b/src/internal/connector/graph_connector_helper_test.go index 0084610fd..c4bcf55ac 100644 --- a/src/internal/connector/graph_connector_helper_test.go +++ b/src/internal/connector/graph_connector_helper_test.go @@ -776,13 +776,16 @@ func makeExchangeBackupSel( t *testing.T, dests []destAndCats, ) selectors.Selector { - sel := selectors.NewExchangeBackup() toInclude := [][]selectors.ExchangeScope{} + resourceOwners := []string{} for _, d := range dests { for c := range d.cats { + sel := selectors.NewExchangeBackup(nil) builder := sel.MailFolders + resourceOwners = append(resourceOwners, d.resourceOwner) + switch c { case path.ContactsCategory: builder = sel.ContactFolders @@ -799,6 +802,7 @@ func makeExchangeBackupSel( } } + sel := selectors.NewExchangeBackup(resourceOwners) sel.Include(toInclude...) return sel.Selector @@ -808,10 +812,13 @@ func makeOneDriveBackupSel( t *testing.T, dests []destAndCats, ) selectors.Selector { - sel := selectors.NewOneDriveBackup() toInclude := [][]selectors.OneDriveScope{} + resourceOwners := []string{} for _, d := range dests { + sel := selectors.NewOneDriveBackup(nil) + + resourceOwners = append(resourceOwners, d.resourceOwner) toInclude = append(toInclude, sel.Folders( []string{d.resourceOwner}, []string{d.dest}, @@ -819,6 +826,7 @@ func makeOneDriveBackupSel( )) } + sel := selectors.NewOneDriveBackup(resourceOwners) sel.Include(toInclude...) return sel.Selector diff --git a/src/internal/connector/onedrive/drive_test.go b/src/internal/connector/onedrive/drive_test.go index 67f957a61..19d913549 100644 --- a/src/internal/connector/onedrive/drive_test.go +++ b/src/internal/connector/onedrive/drive_test.go @@ -145,7 +145,7 @@ func (suite *OneDriveSuite) TestOneDriveNewCollections() { suite.T().Run(test.name, func(t *testing.T) { service := loadTestService(t) scope := selectors. - NewOneDriveBackup(). + NewOneDriveBackup([]string{test.user}). Users([]string{test.user})[0] odcs, err := NewCollections( creds.AzureTenantID, diff --git a/src/internal/operations/backup.go b/src/internal/operations/backup.go index 7a2e4b8f4..58eeb3297 100644 --- a/src/internal/operations/backup.go +++ b/src/internal/operations/backup.go @@ -283,15 +283,8 @@ func selectorToOwnersCats(sel selectors.Selector) *kopia.OwnersCats { ServiceCats: map[string]kopia.ServiceCat{}, } - ros, err := sel.ResourceOwners() - if err != nil { - return &kopia.OwnersCats{} - } - - for _, sl := range [][]string{ros.Includes, ros.Filters} { - for _, ro := range sl { - oc.ResourceOwners[ro] = struct{}{} - } + for _, ro := range sel.DiscreteResourceOwners() { + oc.ResourceOwners[ro] = struct{}{} } pcs, err := sel.PathCategories() diff --git a/src/internal/operations/backup_test.go b/src/internal/operations/backup_test.go index 273323c82..74630c0b3 100644 --- a/src/internal/operations/backup_test.go +++ b/src/internal/operations/backup_test.go @@ -340,7 +340,7 @@ func (suite *BackupOpSuite) TestBackupOperation_ConsumeBackupDataCollections_Pat ID: "id2", } - sel = selectors.NewExchangeBackup().Selector + sel = selectors.NewExchangeBackup([]string{resourceOwner}).Selector ) table := []struct { @@ -660,6 +660,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchange() { defer flush() m365UserID := tester.M365UserID(suite.T()) + users := []string{m365UserID} tests := []struct { name string @@ -671,12 +672,8 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchange() { { name: "Mail", selectFunc: func() *selectors.ExchangeBackup { - sel := selectors.NewExchangeBackup() - sel.Include(sel.MailFolders( - []string{m365UserID}, - []string{exchange.DefaultMailFolder}, - selectors.PrefixMatch())) - + sel := selectors.NewExchangeBackup(users) + sel.Include(sel.MailFolders(users, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch())) return sel }, resourceOwner: m365UserID, @@ -686,9 +683,9 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchange() { { name: "Contacts", selectFunc: func() *selectors.ExchangeBackup { - sel := selectors.NewExchangeBackup() + sel := selectors.NewExchangeBackup(users) sel.Include(sel.ContactFolders( - []string{m365UserID}, + users, []string{exchange.DefaultContactFolder}, selectors.PrefixMatch())) @@ -701,12 +698,8 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchange() { { name: "Calendar Events", selectFunc: func() *selectors.ExchangeBackup { - sel := selectors.NewExchangeBackup() - sel.Include(sel.EventCalendars( - []string{m365UserID}, - []string{exchange.DefaultCalendar}, - selectors.PrefixMatch())) - + sel := selectors.NewExchangeBackup(users) + sel.Include(sel.EventCalendars(users, []string{exchange.DefaultCalendar}, selectors.PrefixMatch())) return sel }, resourceOwner: m365UserID, @@ -808,7 +801,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_oneDrive() { t = suite.T() mb = evmock.NewBus() m365UserID = tester.SecondaryM365UserID(t) - sel = selectors.NewOneDriveBackup() + sel = selectors.NewOneDriveBackup([]string{m365UserID}) ) sel.Include(sel.Users([]string{m365UserID})) @@ -841,7 +834,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_sharePoint() { t = suite.T() mb = evmock.NewBus() siteID = tester.M365SiteID(t) - sel = selectors.NewSharePointBackup() + sel = selectors.NewSharePointBackup([]string{siteID}) ) sel.Include(sel.Sites([]string{siteID})) diff --git a/src/internal/operations/restore_test.go b/src/internal/operations/restore_test.go index e09f6febe..5638a210c 100644 --- a/src/internal/operations/restore_test.go +++ b/src/internal/operations/restore_test.go @@ -178,11 +178,13 @@ func (suite *RestoreOpIntegrationSuite) SetupSuite() { sw := store.NewKopiaStore(ms) suite.sw = sw - bsel := selectors.NewExchangeBackup() + users := []string{m365UserID} + + bsel := selectors.NewExchangeBackup(users) bsel.Include( - bsel.MailFolders([]string{m365UserID}, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch()), - bsel.ContactFolders([]string{m365UserID}, []string{exchange.DefaultContactFolder}, selectors.PrefixMatch()), - bsel.EventCalendars([]string{m365UserID}, []string{exchange.DefaultCalendar}, selectors.PrefixMatch()), + bsel.MailFolders(users, []string{exchange.DefaultMailFolder}, selectors.PrefixMatch()), + bsel.ContactFolders(users, []string{exchange.DefaultContactFolder}, selectors.PrefixMatch()), + bsel.EventCalendars(users, []string{exchange.DefaultCalendar}, selectors.PrefixMatch()), ) bo, err := NewBackupOperation( @@ -264,9 +266,10 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run() { defer flush() t := suite.T() + users := []string{tester.M365UserID(t)} - rsel := selectors.NewExchangeRestore() - rsel.Include(rsel.Users([]string{tester.M365UserID(t)})) + rsel := selectors.NewExchangeRestore(users) + rsel.Include(rsel.Users(users)) dest := tester.DefaultTestRestoreDestination() mb := evmock.NewBus() @@ -307,7 +310,7 @@ func (suite *RestoreOpIntegrationSuite) TestRestore_Run_ErrorNoResults() { t := suite.T() - rsel := selectors.NewExchangeRestore() + rsel := selectors.NewExchangeRestore(selectors.None()) rsel.Include(rsel.Users(selectors.None())) dest := tester.DefaultTestRestoreDestination() diff --git a/src/pkg/backup/backup_test.go b/src/pkg/backup/backup_test.go index aad71980b..cb5e49448 100644 --- a/src/pkg/backup/backup_test.go +++ b/src/pkg/backup/backup_test.go @@ -25,7 +25,7 @@ func TestBackupSuite(t *testing.T) { } func stubBackup(t time.Time) backup.Backup { - sel := selectors.NewExchangeBackup() + sel := selectors.NewExchangeBackup(selectors.Any()) sel.Include(sel.Users(selectors.Any())) return backup.Backup{ diff --git a/src/pkg/repository/repository_load_test.go b/src/pkg/repository/repository_load_test.go index 2fdc6ad9d..3b4053a70 100644 --- a/src/pkg/repository/repository_load_test.go +++ b/src/pkg/repository/repository_load_test.go @@ -400,7 +400,7 @@ func (suite *RepositoryLoadTestExchangeSuite) TestExchange() { ctx, flush := tester.WithContext(suite.ctx) defer flush() - bsel := selectors.NewExchangeBackup() + bsel := selectors.NewExchangeBackup(suite.usersUnderTest) bsel.Include(bsel.MailFolders(suite.usersUnderTest, selectors.Any())) bsel.Include(bsel.ContactFolders(suite.usersUnderTest, selectors.Any())) bsel.Include(bsel.EventCalendars(suite.usersUnderTest, selectors.Any())) @@ -451,7 +451,7 @@ func (suite *RepositoryIndividualLoadTestExchangeSuite) TestExchange() { ctx, flush := tester.WithContext(suite.ctx) defer flush() - bsel := selectors.NewExchangeBackup() + bsel := selectors.NewExchangeBackup(suite.usersUnderTest) bsel.Include(bsel.MailFolders(suite.usersUnderTest, selectors.Any())) bsel.Include(bsel.ContactFolders(suite.usersUnderTest, selectors.Any())) bsel.Include(bsel.EventCalendars(suite.usersUnderTest, selectors.Any())) @@ -504,7 +504,7 @@ func (suite *RepositoryLoadTestOneDriveSuite) TestOneDrive() { ctx, flush := tester.WithContext(suite.ctx) defer flush() - bsel := selectors.NewOneDriveBackup() + bsel := selectors.NewOneDriveBackup(suite.usersUnderTest) bsel.Include(bsel.Users(suite.usersUnderTest)) sel := bsel.Selector @@ -551,7 +551,7 @@ func (suite *RepositoryIndividualLoadTestOneDriveSuite) TestOneDrive() { ctx, flush := tester.WithContext(suite.ctx) defer flush() - bsel := selectors.NewOneDriveBackup() + bsel := selectors.NewOneDriveBackup(suite.usersUnderTest) bsel.Include(bsel.Users(suite.usersUnderTest)) sel := bsel.Selector @@ -602,7 +602,7 @@ func (suite *RepositoryLoadTestSharePointSuite) TestSharePoint() { ctx, flush := tester.WithContext(suite.ctx) defer flush() - bsel := selectors.NewSharePointBackup() + bsel := selectors.NewSharePointBackup(suite.sitesUnderTest) bsel.Include(bsel.Sites(suite.sitesUnderTest)) sel := bsel.Selector @@ -649,7 +649,7 @@ func (suite *RepositoryIndividualLoadTestSharePointSuite) TestSharePoint() { ctx, flush := tester.WithContext(suite.ctx) defer flush() - bsel := selectors.NewSharePointBackup() + bsel := selectors.NewSharePointBackup(suite.sitesUnderTest) bsel.Include(bsel.Sites(suite.sitesUnderTest)) sel := bsel.Selector diff --git a/src/pkg/selectors/example_selectors_test.go b/src/pkg/selectors/example_selectors_test.go index f1abaf1ff..5c70cd2db 100644 --- a/src/pkg/selectors/example_selectors_test.go +++ b/src/pkg/selectors/example_selectors_test.go @@ -12,10 +12,19 @@ import ( func Example_newSelector() { // Selectors should use application-specific constructors. // Generate a selector for backup operations. - seb := selectors.NewExchangeBackup() + seb := selectors.NewExchangeBackup(nil) // Generate a selector for restore and 'backup details' operations. - ser := selectors.NewExchangeRestore() + ser := selectors.NewExchangeRestore(nil) + + // Selectors specify the data that should be handled + // in an operation by specifying the Scope of data. + // Initially, the selector will ask for the resource + // owners (users, in this example). Only these users + // will be involved in the backup. + seb = selectors.NewExchangeBackup( + []string{"your-user-id", "foo-user-id", "bar-user-id"}, + ) // The core selector can be passed around without slicing any // application-specific data. @@ -46,42 +55,11 @@ func Example_newSelector() { // Output: OneDrive service is not Exchange: wrong selector service type } -// ExampleIncludeUsers demonstrates how to specify users in a selector. -func Example_includeUsers() { - seb := selectors.NewExchangeBackup() - - // Selectors specify the data that should be handled - // in an operation by specifying the Scope of data. - seb.Include( - // Selector application instances own the API which describes - // the scopes of data that callers may specify. - seb.Users([]string{"my-user-id"}), - ) - - // Selection scopes can be passed around independently. - yourUser := seb.Users([]string{"your-user-id"}) - - // Most scopes accept multiple values, unioning them into the final selection. - otherUsers := seb.Users([]string{"foo-user-id", "bar-user-id"}) - - // Multiple scopes can be added at a time. - // All calls to Include append those scopes to the current set, - // so this addition will also include "my-user-id" from before. - seb.Include( - yourUser, - otherUsers, - ) - - // Two predefined sets of values exist: any and none. - // Any is a wildcard that accepts all values. - seb.Users(selectors.Any()) - // None is the opposite of Any: rejecting all values. - seb.Users(selectors.None()) -} - // ExampleIncludeFoldersAndItems demonstrates how to select for granular data. func Example_includeFoldersAndItems() { - seb := selectors.NewExchangeBackup() + seb := selectors.NewExchangeBackup( + []string{"your-user-id", "foo-user-id", "bar-user-id"}, + ) // Much of the data handled by Corso exists within an established hierarchy. // Resource Owner-level data (such as users) sits at the top, with Folder @@ -116,7 +94,9 @@ func Example_includeFoldersAndItems() { // ExampleFilters demonstrates selector filters. func Example_filters() { - ser := selectors.NewExchangeRestore() + ser := selectors.NewExchangeRestore( + []string{"your-user-id", "foo-user-id", "bar-user-id"}, + ) // In addition to data ownership details (user, folder, itemID), certain operations // like `backup details` and restores allow items to be selected by filtering on @@ -164,7 +144,9 @@ var ( // ExampleReduceDetails demonstrates how selectors are used to filter backup details. func Example_reduceDetails() { - ser := selectors.NewExchangeRestore() + ser := selectors.NewExchangeRestore( + []string{"your-user-id", "foo-user-id", "bar-user-id"}, + ) // The Reduce() call is where our constructed selectors are applied to the data // from a previous backup record. @@ -189,7 +171,9 @@ func Example_scopeMatching() { // Just like sets of backup data can be filtered down using Reduce(), we can check // if an individual bit of data matches our scopes, too. scope := selectors. - NewExchangeBackup(). + NewExchangeBackup( + []string{"your-user-id", "foo-user-id", "bar-user-id"}, + ). Mails( []string{"id-1"}, []string{"Inbox"}, diff --git a/src/pkg/selectors/exchange.go b/src/pkg/selectors/exchange.go index a3e6f11c0..f6097f08f 100644 --- a/src/pkg/selectors/exchange.go +++ b/src/pkg/selectors/exchange.go @@ -37,17 +37,16 @@ type ( ) var ( - _ Reducer = &ExchangeRestore{} - _ printabler = &ExchangeRestore{} - _ resourceOwnerer = &ExchangeRestore{} - _ pathCategorier = &ExchangeRestore{} + _ Reducer = &ExchangeRestore{} + _ printabler = &ExchangeRestore{} + _ pathCategorier = &ExchangeRestore{} ) // NewExchange produces a new Selector with the service set to ServiceExchange. -func NewExchangeBackup() *ExchangeBackup { +func NewExchangeBackup(users []string) *ExchangeBackup { src := ExchangeBackup{ exchange{ - newSelector(ServiceExchange), + newSelector(ServiceExchange, users), }, } @@ -67,10 +66,10 @@ func (s Selector) ToExchangeBackup() (*ExchangeBackup, error) { } // NewExchangeRestore produces a new Selector with the service set to ServiceExchange. -func NewExchangeRestore() *ExchangeRestore { +func NewExchangeRestore(users []string) *ExchangeRestore { src := ExchangeRestore{ exchange{ - newSelector(ServiceExchange), + newSelector(ServiceExchange, users), }, } @@ -94,16 +93,6 @@ func (s exchange) Printable() Printable { return toPrintable[ExchangeScope](s.Selector) } -// ResourceOwners produces the aggregation of discrete users described by each type of scope. -// Any and None values are omitted. -func (s exchange) ResourceOwners() selectorResourceOwners { - return selectorResourceOwners{ - Excludes: resourceOwnersIn(s.Excludes, ExchangeUser.String()), - Filters: resourceOwnersIn(s.Filters, ExchangeUser.String()), - Includes: resourceOwnersIn(s.Includes, ExchangeUser.String()), - } -} - // PathCategories produces the aggregation of discrete users described by each type of scope. func (s exchange) PathCategories() selectorPathCategories { return selectorPathCategories{ diff --git a/src/pkg/selectors/exchange_test.go b/src/pkg/selectors/exchange_test.go index 420a248c4..0701dcdb2 100644 --- a/src/pkg/selectors/exchange_test.go +++ b/src/pkg/selectors/exchange_test.go @@ -25,14 +25,14 @@ func TestExchangeSelectorSuite(t *testing.T) { func (suite *ExchangeSelectorSuite) TestNewExchangeBackup() { t := suite.T() - eb := NewExchangeBackup() + eb := NewExchangeBackup(nil) assert.Equal(t, eb.Service, ServiceExchange) assert.NotZero(t, eb.Scopes()) } func (suite *ExchangeSelectorSuite) TestToExchangeBackup() { t := suite.T() - eb := NewExchangeBackup() + eb := NewExchangeBackup(nil) s := eb.Selector eb, err := s.ToExchangeBackup() require.NoError(t, err) @@ -42,14 +42,14 @@ func (suite *ExchangeSelectorSuite) TestToExchangeBackup() { func (suite *ExchangeSelectorSuite) TestNewExchangeRestore() { t := suite.T() - er := NewExchangeRestore() + er := NewExchangeRestore(nil) assert.Equal(t, er.Service, ServiceExchange) assert.NotZero(t, er.Scopes()) } func (suite *ExchangeSelectorSuite) TestToExchangeRestore() { t := suite.T() - eb := NewExchangeRestore() + eb := NewExchangeRestore(nil) s := eb.Selector eb, err := s.ToExchangeRestore() require.NoError(t, err) @@ -59,7 +59,6 @@ func (suite *ExchangeSelectorSuite) TestToExchangeRestore() { func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Contacts() { t := suite.T() - sel := NewExchangeBackup() const ( user = "user" @@ -68,6 +67,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Contacts() { c2 = "c2" ) + sel := NewExchangeBackup([]string{user}) sel.Exclude(sel.Contacts([]string{user}, []string{folder}, []string{c1, c2})) scopes := sel.Excludes require.Len(t, scopes, 1) @@ -85,7 +85,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Contacts() { func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Contacts() { t := suite.T() - sel := NewExchangeBackup() const ( user = "user" @@ -94,6 +93,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Contacts() { c2 = "c2" ) + sel := NewExchangeBackup([]string{user}) sel.Include(sel.Contacts([]string{user}, []string{folder}, []string{c1, c2})) scopes := sel.Includes require.Len(t, scopes, 1) @@ -113,7 +113,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Contacts() { func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_ContactFolders() { t := suite.T() - sel := NewExchangeBackup() const ( user = "user" @@ -121,6 +120,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_ContactFolders( f2 = "f2" ) + sel := NewExchangeBackup([]string{user}) sel.Exclude(sel.ContactFolders([]string{user}, []string{f1, f2})) scopes := sel.Excludes require.Len(t, scopes, 1) @@ -138,7 +138,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_ContactFolders( func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_ContactFolders() { t := suite.T() - sel := NewExchangeBackup() const ( user = "user" @@ -146,6 +145,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_ContactFolders( f2 = "f2" ) + sel := NewExchangeBackup([]string{user}) sel.Include(sel.ContactFolders([]string{user}, []string{f1, f2})) scopes := sel.Includes require.Len(t, scopes, 1) @@ -165,7 +165,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_ContactFolders( func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Events() { t := suite.T() - sel := NewExchangeBackup() const ( user = "user" @@ -174,6 +173,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Events() { c1 = "c1" ) + sel := NewExchangeBackup([]string{user}) sel.Exclude(sel.Events([]string{user}, []string{c1}, []string{e1, e2})) scopes := sel.Excludes require.Len(t, scopes, 1) @@ -191,7 +191,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Events() { func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_EventCalendars() { t := suite.T() - sel := NewExchangeBackup() const ( user = "user" @@ -199,6 +198,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_EventCalendars( c2 = "c2" ) + sel := NewExchangeBackup([]string{user}) sel.Exclude(sel.EventCalendars([]string{user}, []string{c1, c2})) scopes := sel.Excludes require.Len(t, scopes, 1) @@ -216,7 +216,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_EventCalendars( func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Events() { t := suite.T() - sel := NewExchangeBackup() const ( user = "user" @@ -225,6 +224,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Events() { c1 = "c1" ) + sel := NewExchangeBackup([]string{user}) sel.Include(sel.Events([]string{user}, []string{c1}, []string{e1, e2})) scopes := sel.Includes require.Len(t, scopes, 1) @@ -242,7 +242,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Events() { func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_EventCalendars() { t := suite.T() - sel := NewExchangeBackup() const ( user = "user" @@ -250,6 +249,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_EventCalendars( c2 = "c2" ) + sel := NewExchangeBackup([]string{user}) sel.Include(sel.EventCalendars([]string{user}, []string{c1, c2})) scopes := sel.Includes require.Len(t, scopes, 1) @@ -267,7 +267,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_EventCalendars( func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Mails() { t := suite.T() - sel := NewExchangeBackup() const ( user = "user" @@ -276,6 +275,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Mails() { m2 = "m2" ) + sel := NewExchangeBackup([]string{user}) sel.Exclude(sel.Mails([]string{user}, []string{folder}, []string{m1, m2})) scopes := sel.Excludes require.Len(t, scopes, 1) @@ -293,7 +293,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Mails() { func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Mails() { t := suite.T() - sel := NewExchangeBackup() const ( user = "user" @@ -302,6 +301,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Mails() { m2 = "m2" ) + sel := NewExchangeBackup([]string{user}) sel.Include(sel.Mails([]string{user}, []string{folder}, []string{m1, m2})) scopes := sel.Includes require.Len(t, scopes, 1) @@ -321,7 +321,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Mails() { func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_MailFolders() { t := suite.T() - sel := NewExchangeBackup() const ( user = "user" @@ -329,6 +328,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_MailFolders() { f2 = "f2" ) + sel := NewExchangeBackup([]string{user}) sel.Exclude(sel.MailFolders([]string{user}, []string{f1, f2})) scopes := sel.Excludes require.Len(t, scopes, 1) @@ -346,7 +346,6 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_MailFolders() { func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_MailFolders() { t := suite.T() - sel := NewExchangeBackup() const ( user = "user" @@ -354,6 +353,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_MailFolders() { f2 = "f2" ) + sel := NewExchangeBackup([]string{user}) sel.Include(sel.MailFolders([]string{user}, []string{f1, f2})) scopes := sel.Includes require.Len(t, scopes, 1) @@ -373,13 +373,13 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_MailFolders() { func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Users() { t := suite.T() - sel := NewExchangeBackup() const ( u1 = "u1" u2 = "u2" ) + sel := NewExchangeBackup([]string{u1, u2}) sel.Exclude(sel.Users([]string{u1, u2})) scopes := sel.Excludes require.Len(t, scopes, 3) @@ -427,13 +427,13 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Exclude_Users() { func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Users() { t := suite.T() - sel := NewExchangeBackup() const ( u1 = "u1" u2 = "u2" ) + sel := NewExchangeBackup([]string{u1, u2}) sel.Include(sel.Users([]string{u1, u2})) scopes := sel.Includes require.Len(t, scopes, 3) @@ -480,7 +480,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeSelector_Include_Users() { } func (suite *ExchangeSelectorSuite) TestExchangeBackup_Scopes() { - eb := NewExchangeBackup() + eb := NewExchangeBackup(Any()) eb.Include(eb.Users(Any())) scopes := eb.Scopes() @@ -534,7 +534,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeBackup_DiscreteScopes() { for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { - eb := NewExchangeBackup() + eb := NewExchangeBackup(test.include) eb.Include(eb.Users(test.include)) scopes := eb.DiscreteScopes(test.discrete) @@ -571,7 +571,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_Category() { } for _, test := range table { suite.T().Run(test.is.String()+test.expect.String(), func(t *testing.T) { - eb := NewExchangeBackup() + eb := NewExchangeBackup(Any()) eb.Includes = []scope{ {scopeKeyCategory: filters.Identity(test.is.String())}, } @@ -614,7 +614,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_IncludesCategory() { } for _, test := range table { suite.T().Run(test.is.String()+test.expect.String(), func(t *testing.T) { - eb := NewExchangeBackup() + eb := NewExchangeBackup(Any()) eb.Includes = []scope{ {scopeKeyCategory: filters.Identity(test.is.String())}, } @@ -625,7 +625,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_IncludesCategory() { } func (suite *ExchangeSelectorSuite) TestExchangeScope_Get() { - eb := NewExchangeBackup() + eb := NewExchangeBackup(Any()) eb.Include(eb.Users(Any())) scopes := eb.Scopes() @@ -659,7 +659,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_Get() { } func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesInfo() { - es := NewExchangeRestore() + es := NewExchangeRestore(Any()) const ( name = "smarf mcfnords" @@ -781,7 +781,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeScope_MatchesPath() { var ( pth = stubPath(suite.T(), usr, []string{fld1, fld2, mail}, path.EmailCategory) short = "thisisahashofsomekind" - es = NewExchangeRestore() + es = NewExchangeRestore(Any()) // TODO: move into test so that test user set is embedded in the selector ) table := []struct { @@ -922,7 +922,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { "no refs", makeDeets(), func() *ExchangeRestore { - er := NewExchangeRestore() + er := NewExchangeRestore(Any()) er.Include(er.Users(Any())) return er }, @@ -932,7 +932,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { "contact only", makeDeets(contact), func() *ExchangeRestore { - er := NewExchangeRestore() + er := NewExchangeRestore(Any()) er.Include(er.Users(Any())) return er }, @@ -942,7 +942,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { "event only", makeDeets(event), func() *ExchangeRestore { - er := NewExchangeRestore() + er := NewExchangeRestore(Any()) er.Include(er.Users(Any())) return er }, @@ -952,7 +952,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { "mail only", makeDeets(mail), func() *ExchangeRestore { - er := NewExchangeRestore() + er := NewExchangeRestore(Any()) er.Include(er.Users(Any())) return er }, @@ -962,7 +962,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { "all", makeDeets(contact, event, mail), func() *ExchangeRestore { - er := NewExchangeRestore() + er := NewExchangeRestore(Any()) er.Include(er.Users(Any())) return er }, @@ -972,7 +972,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { "only match contact", makeDeets(contact, event, mail), func() *ExchangeRestore { - er := NewExchangeRestore() + er := NewExchangeRestore([]string{"uid"}) er.Include(er.Contacts([]string{"uid"}, []string{"cfld"}, []string{"cid"})) return er }, @@ -982,7 +982,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { "only match contactInSubFolder", makeDeets(contactInSubFolder, contact, event, mail), func() *ExchangeRestore { - er := NewExchangeRestore() + er := NewExchangeRestore([]string{"uid"}) er.Include(er.ContactFolders([]string{"uid"}, []string{"cfld1/cfld2"})) return er }, @@ -992,7 +992,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { "only match contactInSubFolder by prefix", makeDeets(contactInSubFolder, contact, event, mail), func() *ExchangeRestore { - er := NewExchangeRestore() + er := NewExchangeRestore([]string{"uid"}) er.Include(er.ContactFolders([]string{"uid"}, []string{"cfld1/cfld2"}, PrefixMatch())) return er }, @@ -1002,7 +1002,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { "only match contactInSubFolder by leaf folder", makeDeets(contactInSubFolder, contact, event, mail), func() *ExchangeRestore { - er := NewExchangeRestore() + er := NewExchangeRestore([]string{"uid"}) er.Include(er.ContactFolders([]string{"uid"}, []string{"cfld2"})) return er }, @@ -1012,7 +1012,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { "only match event", makeDeets(contact, event, mail), func() *ExchangeRestore { - er := NewExchangeRestore() + er := NewExchangeRestore([]string{"uid"}) er.Include(er.Events([]string{"uid"}, []string{"ecld"}, []string{"eid"})) return er }, @@ -1022,7 +1022,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { "only match mail", makeDeets(contact, event, mail), func() *ExchangeRestore { - er := NewExchangeRestore() + er := NewExchangeRestore([]string{"uid"}) er.Include(er.Mails([]string{"uid"}, []string{"mfld"}, []string{"mid"})) return er }, @@ -1032,7 +1032,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { "exclude contact", makeDeets(contact, event, mail), func() *ExchangeRestore { - er := NewExchangeRestore() + er := NewExchangeRestore(Any()) er.Include(er.Users(Any())) er.Exclude(er.Contacts([]string{"uid"}, []string{"cfld"}, []string{"cid"})) return er @@ -1043,7 +1043,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { "exclude event", makeDeets(contact, event, mail), func() *ExchangeRestore { - er := NewExchangeRestore() + er := NewExchangeRestore(Any()) er.Include(er.Users(Any())) er.Exclude(er.Events([]string{"uid"}, []string{"ecld"}, []string{"eid"})) return er @@ -1054,7 +1054,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { "exclude mail", makeDeets(contact, event, mail), func() *ExchangeRestore { - er := NewExchangeRestore() + er := NewExchangeRestore(Any()) er.Include(er.Users(Any())) er.Exclude(er.Mails([]string{"uid"}, []string{"mfld"}, []string{"mid"})) return er @@ -1071,7 +1071,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { return ds }(), func() *ExchangeRestore { - er := NewExchangeRestore() + er := NewExchangeRestore(Any()) er.Include(er.Users(Any())) er.Filter(er.MailSubject("subj")) return er @@ -1092,7 +1092,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { return ds }(), func() *ExchangeRestore { - er := NewExchangeRestore() + er := NewExchangeRestore(Any()) er.Include(er.Users(Any())) er.Filter(er.MailSubject("subj")) return er @@ -1115,7 +1115,7 @@ func (suite *ExchangeSelectorSuite) TestExchangeRestore_Reduce() { func (suite *ExchangeSelectorSuite) TestScopesByCategory() { var ( - es = NewExchangeRestore() + es = NewExchangeRestore(Any()) users = es.Users(Any()) contacts = es.ContactFolders(Any(), Any()) events = es.Events(Any(), Any(), Any()) @@ -1178,7 +1178,7 @@ func (suite *ExchangeSelectorSuite) TestPasses() { ) var ( - es = NewExchangeRestore() + es = NewExchangeRestore(Any()) // TODO: move into test and compose with each test value anyUser = setScopesToDefault(es.Users(Any())) noUser = setScopesToDefault(es.Users(None())) mail = setScopesToDefault(es.Mails(Any(), Any(), []string{mid})) @@ -1229,7 +1229,7 @@ func (suite *ExchangeSelectorSuite) TestContains() { target := "fnords" var ( - es = NewExchangeRestore() + es = NewExchangeRestore(Any()) // TODO: move into test and compose with each test value anyUser = setScopesToDefault(es.Users(Any())) noMail = setScopesToDefault(es.Mails(None(), None(), None())) does = setScopesToDefault(es.Mails(Any(), Any(), []string{target})) @@ -1266,7 +1266,7 @@ func (suite *ExchangeSelectorSuite) TestContains() { func (suite *ExchangeSelectorSuite) TestIsAny() { var ( - es = NewExchangeRestore() + es = NewExchangeRestore(Any()) // TODO: move into test and compose with each test value anyUser = setScopesToDefault(es.Users(Any())) noUser = setScopesToDefault(es.Users(None())) specificMail = setScopesToDefault(es.Mails(Any(), Any(), []string{"email"})) diff --git a/src/pkg/selectors/onedrive.go b/src/pkg/selectors/onedrive.go index 3fc07c20a..8d4adb045 100644 --- a/src/pkg/selectors/onedrive.go +++ b/src/pkg/selectors/onedrive.go @@ -36,17 +36,16 @@ type ( ) var ( - _ Reducer = &OneDriveRestore{} - _ printabler = &OneDriveRestore{} - _ resourceOwnerer = &OneDriveRestore{} - _ pathCategorier = &OneDriveRestore{} + _ Reducer = &OneDriveRestore{} + _ printabler = &OneDriveRestore{} + _ pathCategorier = &OneDriveRestore{} ) // NewOneDriveBackup produces a new Selector with the service set to ServiceOneDrive. -func NewOneDriveBackup() *OneDriveBackup { +func NewOneDriveBackup(users []string) *OneDriveBackup { src := OneDriveBackup{ oneDrive{ - newSelector(ServiceOneDrive), + newSelector(ServiceOneDrive, users), }, } @@ -66,10 +65,10 @@ func (s Selector) ToOneDriveBackup() (*OneDriveBackup, error) { } // NewOneDriveRestore produces a new Selector with the service set to ServiceOneDrive. -func NewOneDriveRestore() *OneDriveRestore { +func NewOneDriveRestore(users []string) *OneDriveRestore { src := OneDriveRestore{ oneDrive{ - newSelector(ServiceOneDrive), + newSelector(ServiceOneDrive, users), }, } @@ -93,16 +92,6 @@ func (s oneDrive) Printable() Printable { return toPrintable[OneDriveScope](s.Selector) } -// ResourceOwners produces the aggregation of discrete users described by each type of scope. -// Any and None values are omitted. -func (s oneDrive) ResourceOwners() selectorResourceOwners { - return selectorResourceOwners{ - Excludes: resourceOwnersIn(s.Excludes, OneDriveUser.String()), - Filters: resourceOwnersIn(s.Filters, OneDriveUser.String()), - Includes: resourceOwnersIn(s.Includes, OneDriveUser.String()), - } -} - // PathCategories produces the aggregation of discrete users described by each type of scope. func (s oneDrive) PathCategories() selectorPathCategories { return selectorPathCategories{ diff --git a/src/pkg/selectors/onedrive_test.go b/src/pkg/selectors/onedrive_test.go index 0f163996e..c757a19f7 100644 --- a/src/pkg/selectors/onedrive_test.go +++ b/src/pkg/selectors/onedrive_test.go @@ -24,14 +24,14 @@ func TestOneDriveSelectorSuite(t *testing.T) { func (suite *OneDriveSelectorSuite) TestNewOneDriveBackup() { t := suite.T() - ob := NewOneDriveBackup() + ob := NewOneDriveBackup(Any()) assert.Equal(t, ob.Service, ServiceOneDrive) assert.NotZero(t, ob.Scopes()) } func (suite *OneDriveSelectorSuite) TestToOneDriveBackup() { t := suite.T() - ob := NewOneDriveBackup() + ob := NewOneDriveBackup(Any()) s := ob.Selector ob, err := s.ToOneDriveBackup() require.NoError(t, err) @@ -69,7 +69,7 @@ func (suite *OneDriveSelectorSuite) TestOneDriveBackup_DiscreteScopes() { for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { - eb := NewOneDriveBackup() + eb := NewOneDriveBackup(test.include) eb.Include(eb.Users(test.include)) scopes := eb.DiscreteScopes(test.discrete) @@ -83,14 +83,18 @@ func (suite *OneDriveSelectorSuite) TestOneDriveBackup_DiscreteScopes() { func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Users() { t := suite.T() - sel := NewOneDriveBackup() const ( u1 = "u1" u2 = "u2" ) - userScopes := sel.Users([]string{u1, u2}) + var ( + users = []string{u1, u2} + sel = NewOneDriveBackup(users) + userScopes = sel.Users(users) + ) + for _, scope := range userScopes { // Scope value is either u1 or u2 assert.Contains(t, join(u1, u2), scope[OneDriveUser.String()].Target) @@ -122,14 +126,19 @@ func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Users() { func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Include_Users() { t := suite.T() - sel := NewOneDriveBackup() const ( u1 = "u1" u2 = "u2" ) - sel.Include(sel.Users([]string{u1, u2})) + var ( + users = []string{u1, u2} + sel = NewOneDriveBackup(users) + userScopes = sel.Users(users) + ) + + sel.Include(userScopes) scopes := sel.Includes require.Len(t, scopes, 1) @@ -144,14 +153,19 @@ func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Include_Users() { func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Exclude_Users() { t := suite.T() - sel := NewOneDriveBackup() const ( u1 = "u1" u2 = "u2" ) - sel.Exclude(sel.Users([]string{u1, u2})) + var ( + users = []string{u1, u2} + sel = NewOneDriveBackup(users) + userScopes = sel.Users(users) + ) + + sel.Exclude(userScopes) scopes := sel.Excludes require.Len(t, scopes, 1) @@ -166,14 +180,14 @@ func (suite *OneDriveSelectorSuite) TestOneDriveSelector_Exclude_Users() { func (suite *OneDriveSelectorSuite) TestNewOneDriveRestore() { t := suite.T() - or := NewOneDriveRestore() + or := NewOneDriveRestore(Any()) assert.Equal(t, or.Service, ServiceOneDrive) assert.NotZero(t, or.Scopes()) } func (suite *OneDriveSelectorSuite) TestToOneDriveRestore() { t := suite.T() - eb := NewOneDriveRestore() + eb := NewOneDriveRestore(Any()) s := eb.Selector or, err := s.ToOneDriveRestore() require.NoError(t, err) @@ -233,7 +247,7 @@ func (suite *OneDriveSelectorSuite) TestOneDriveRestore_Reduce() { "all", deets, func() *OneDriveRestore { - odr := NewOneDriveRestore() + odr := NewOneDriveRestore(Any()) odr.Include(odr.Users(Any())) return odr }, @@ -243,7 +257,7 @@ func (suite *OneDriveSelectorSuite) TestOneDriveRestore_Reduce() { "only match file", deets, func() *OneDriveRestore { - odr := NewOneDriveRestore() + odr := NewOneDriveRestore(Any()) odr.Include(odr.Items(Any(), Any(), []string{"file2"})) return odr }, @@ -253,7 +267,7 @@ func (suite *OneDriveSelectorSuite) TestOneDriveRestore_Reduce() { "only match folder", deets, func() *OneDriveRestore { - odr := NewOneDriveRestore() + odr := NewOneDriveRestore([]string{"uid"}) odr.Include(odr.Folders([]string{"uid"}, []string{"folderA/folderB", "folderA/folderC"})) return odr }, @@ -290,7 +304,7 @@ func (suite *OneDriveSelectorSuite) TestOneDriveCategory_PathValues() { } func (suite *OneDriveSelectorSuite) TestOneDriveScope_MatchesInfo() { - ods := NewOneDriveRestore() + ods := NewOneDriveRestore(Any()) var ( epoch = time.Time{} diff --git a/src/pkg/selectors/selectors.go b/src/pkg/selectors/selectors.go index 051398eb4..22bb096aa 100644 --- a/src/pkg/selectors/selectors.go +++ b/src/pkg/selectors/selectors.go @@ -72,19 +72,6 @@ type Reducer interface { Reduce(context.Context, *details.Details) *details.Details } -// selectorResourceOwners aggregates all discrete resource owner ids described -// in the selector. Any and None values are ignored. ResourceOwner sets are -// grouped by their scope type (includes, excludes, filters). -type selectorResourceOwners struct { - Includes []string - Excludes []string - Filters []string -} - -type resourceOwnerer interface { - ResourceOwners() selectorResourceOwners -} - // selectorResourceOwners aggregates all discrete path category types described // in the selector. Category sets are grouped by their scope type (includes, // excludes, filters). @@ -107,6 +94,10 @@ type pathCategorier interface { type Selector struct { // The service scope of the data. Exchange, Teams, SharePoint, etc. Service service `json:"service,omitempty"` + + // A record of the resource owners matched by this selector. + ResourceOwners filters.Filter `json:"resourceOwners,omitempty"` + // A slice of exclusion scopes. Exclusions apply globally to all // inclusions/filters, with any-match behavior. Excludes []scope `json:"exclusions,omitempty"` @@ -118,14 +109,21 @@ type Selector struct { } // helper for specific selector instance constructors. -func newSelector(s service) Selector { +func newSelector(s service, resourceOwners []string) Selector { return Selector{ - Service: s, - Excludes: []scope{}, - Includes: []scope{}, + Service: s, + ResourceOwners: filterize(scopeConfig{}, resourceOwners...), + Excludes: []scope{}, + Includes: []scope{}, } } +// DiscreteResourceOwners returns the list of individual resourceOwners used +// in the selector. +func (s Selector) DiscreteResourceOwners() []string { + return split(s.ResourceOwners.Target) +} + func (s Selector) String() string { bs, err := json.Marshal(s) if err != nil { @@ -215,16 +213,6 @@ func (s Selector) Reduce(ctx context.Context, deets *details.Details) (*details. return r.Reduce(ctx, deets), nil } -// returns the sets of resource owners identified in each scope set. -func (s Selector) ResourceOwners() (selectorResourceOwners, error) { - ro, err := selectorAsIface[resourceOwnerer](s) - if err != nil { - return selectorResourceOwners{}, err - } - - return ro.ResourceOwners(), nil -} - // returns the sets of path categories identified in each scope set. func (s Selector) PathCategories() (selectorPathCategories, error) { ro, err := selectorAsIface[pathCategorier](s) diff --git a/src/pkg/selectors/selectors_reduce_test.go b/src/pkg/selectors/selectors_reduce_test.go index fcc88d7dc..839cd5ace 100644 --- a/src/pkg/selectors/selectors_reduce_test.go +++ b/src/pkg/selectors/selectors_reduce_test.go @@ -35,7 +35,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeAllMail", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.Mails( selectors.Any(), selectors.Any(), @@ -49,7 +49,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeMailFolderPrefixMatch", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.MailFolders( selectors.Any(), []string{testdata.ExchangeEmailInboxPath.Folder()}, @@ -62,7 +62,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeMailSubject", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Filter(sel.MailSubject("foo")) return sel @@ -72,7 +72,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeMailSubjectExcludeItem", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Filter(sel.MailSender("a-person")) sel.Exclude(sel.Mails( selectors.Any(), @@ -87,7 +87,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeMailSender", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Filter(sel.MailSender("a-person")) return sel @@ -100,7 +100,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeMailReceivedTime", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Filter(sel.MailReceivedBefore( common.FormatTime(testdata.Time1.Add(time.Second)), )) @@ -112,7 +112,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeMailID", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.Mails( selectors.Any(), selectors.Any(), @@ -126,7 +126,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeMailShortRef", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.Mails( selectors.Any(), selectors.Any(), @@ -140,7 +140,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeAllEventsAndMailWithSubject", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.Events( selectors.Any(), selectors.Any(), @@ -155,7 +155,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeEventsAndMailWithSubject", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Filter(sel.EventSubject("foo")) sel.Filter(sel.MailSubject("foo")) @@ -166,7 +166,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeAll", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.Users( selectors.Any(), )) @@ -185,7 +185,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeMailByFolder", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.MailFolders( selectors.Any(), []string{testdata.ExchangeEmailBasePath.Folder()}, @@ -201,7 +201,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeMailByFolderPrefix", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.MailFolders( selectors.Any(), []string{testdata.ExchangeEmailBasePath.Folder()}, @@ -215,7 +215,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeMailByFolderRoot", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.MailFolders( selectors.Any(), []string{testdata.ExchangeEmailInboxPath.Folder()}, @@ -228,7 +228,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeContactByFolder", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.ContactFolders( selectors.Any(), []string{testdata.ExchangeContactsBasePath.Folder()}, @@ -241,7 +241,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeContactByFolderRoot", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.ContactFolders( selectors.Any(), []string{testdata.ExchangeContactsRootPath.Folder()}, @@ -255,7 +255,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeEventsByFolder", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.EventCalendars( selectors.Any(), []string{testdata.ExchangeEventsBasePath.Folder()}, @@ -268,7 +268,7 @@ func (suite *SelectorReduceSuite) TestReduce() { { name: "ExchangeEventsByFolderRoot", selFunc: func() selectors.Reducer { - sel := selectors.NewExchangeRestore() + sel := selectors.NewExchangeRestore(selectors.Any()) sel.Include(sel.EventCalendars( selectors.Any(), []string{testdata.ExchangeEventsRootPath.Folder()}, diff --git a/src/pkg/selectors/selectors_test.go b/src/pkg/selectors/selectors_test.go index b3549c660..bd4124791 100644 --- a/src/pkg/selectors/selectors_test.go +++ b/src/pkg/selectors/selectors_test.go @@ -21,7 +21,7 @@ func TestSelectorSuite(t *testing.T) { func (suite *SelectorSuite) TestNewSelector() { t := suite.T() - s := newSelector(ServiceUnknown) + s := newSelector(ServiceUnknown, Any()) assert.NotNil(t, s) assert.Equal(t, s.Service, ServiceUnknown) assert.NotNil(t, s.Includes) diff --git a/src/pkg/selectors/sharepoint.go b/src/pkg/selectors/sharepoint.go index 7dc6ebe08..ed695482b 100644 --- a/src/pkg/selectors/sharepoint.go +++ b/src/pkg/selectors/sharepoint.go @@ -34,17 +34,16 @@ type ( ) var ( - _ Reducer = &SharePointRestore{} - _ printabler = &SharePointRestore{} - _ resourceOwnerer = &SharePointRestore{} - _ pathCategorier = &SharePointRestore{} + _ Reducer = &SharePointRestore{} + _ printabler = &SharePointRestore{} + _ pathCategorier = &SharePointRestore{} ) // NewSharePointBackup produces a new Selector with the service set to ServiceSharePoint. -func NewSharePointBackup() *SharePointBackup { +func NewSharePointBackup(sites []string) *SharePointBackup { src := SharePointBackup{ sharePoint{ - newSelector(ServiceSharePoint), + newSelector(ServiceSharePoint, sites), }, } @@ -64,10 +63,10 @@ func (s Selector) ToSharePointBackup() (*SharePointBackup, error) { } // NewSharePointRestore produces a new Selector with the service set to ServiceSharePoint. -func NewSharePointRestore() *SharePointRestore { +func NewSharePointRestore(sites []string) *SharePointRestore { src := SharePointRestore{ sharePoint{ - newSelector(ServiceSharePoint), + newSelector(ServiceSharePoint, sites), }, } @@ -91,16 +90,6 @@ func (s sharePoint) Printable() Printable { return toPrintable[SharePointScope](s.Selector) } -// ResourceOwners produces the aggregation of discrete sitets described by each type of scope. -// Any and None values are omitted. -func (s sharePoint) ResourceOwners() selectorResourceOwners { - return selectorResourceOwners{ - Excludes: resourceOwnersIn(s.Excludes, SharePointSite.String()), - Filters: resourceOwnersIn(s.Filters, SharePointSite.String()), - Includes: resourceOwnersIn(s.Includes, SharePointSite.String()), - } -} - // PathCategories produces the aggregation of discrete users described by each type of scope. func (s sharePoint) PathCategories() selectorPathCategories { return selectorPathCategories{ diff --git a/src/pkg/selectors/sharepoint_test.go b/src/pkg/selectors/sharepoint_test.go index bb77360ff..d21d05205 100644 --- a/src/pkg/selectors/sharepoint_test.go +++ b/src/pkg/selectors/sharepoint_test.go @@ -22,14 +22,14 @@ func TestSharePointSelectorSuite(t *testing.T) { func (suite *SharePointSelectorSuite) TestNewSharePointBackup() { t := suite.T() - ob := NewSharePointBackup() + ob := NewSharePointBackup(nil) assert.Equal(t, ob.Service, ServiceSharePoint) assert.NotZero(t, ob.Scopes()) } func (suite *SharePointSelectorSuite) TestToSharePointBackup() { t := suite.T() - ob := NewSharePointBackup() + ob := NewSharePointBackup(nil) s := ob.Selector ob, err := s.ToSharePointBackup() require.NoError(t, err) @@ -67,7 +67,7 @@ func (suite *SharePointSelectorSuite) TestSharePointBackup_DiscreteScopes() { for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { - eb := NewSharePointBackup() + eb := NewSharePointBackup(test.include) eb.Include(eb.Sites(test.include)) scopes := eb.DiscreteScopes(test.discrete) @@ -81,14 +81,15 @@ func (suite *SharePointSelectorSuite) TestSharePointBackup_DiscreteScopes() { func (suite *SharePointSelectorSuite) TestSharePointSelector_Sites() { t := suite.T() - sel := NewSharePointBackup() const ( s1 = "s1" s2 = "s2" ) + sel := NewSharePointBackup([]string{s1, s2}) siteScopes := sel.Sites([]string{s1, s2}) + for _, scope := range siteScopes { // Scope value is either s1 or s2 assert.Contains(t, join(s1, s2), scope[SharePointSite.String()].Target) @@ -120,13 +121,13 @@ func (suite *SharePointSelectorSuite) TestSharePointSelector_Sites() { func (suite *SharePointSelectorSuite) TestSharePointSelector_Include_WebURLs() { t := suite.T() - sel := NewSharePointRestore() const ( s1 = "s1" s2 = "s2" ) + sel := NewSharePointRestore([]string{s1, s2}) sel.Include(sel.WebURL([]string{s1, s2})) scopes := sel.Includes require.Len(t, scopes, 2) @@ -159,7 +160,7 @@ func (suite *SharePointSelectorSuite) TestSharePointSelector_Include_WebURLs_any } for _, test := range table { suite.T().Run(test.name, func(t *testing.T) { - sel := NewSharePointRestore() + sel := NewSharePointRestore(Any()) sel.Include(sel.WebURL(test.in)) scopes := sel.Includes require.Len(t, scopes, 2) @@ -177,13 +178,13 @@ func (suite *SharePointSelectorSuite) TestSharePointSelector_Include_WebURLs_any func (suite *SharePointSelectorSuite) TestSharePointSelector_Exclude_WebURLs() { t := suite.T() - sel := NewSharePointRestore() const ( s1 = "s1" s2 = "s2" ) + sel := NewSharePointRestore([]string{s1, s2}) sel.Exclude(sel.WebURL([]string{s1, s2})) scopes := sel.Excludes require.Len(t, scopes, 2) @@ -201,13 +202,13 @@ func (suite *SharePointSelectorSuite) TestSharePointSelector_Exclude_WebURLs() { // SharePoint Libraries & SharePoint Lists are created. func (suite *SharePointSelectorSuite) TestSharePointSelector_Include_Sites() { t := suite.T() - sel := NewSharePointBackup() const ( s1 = "s1" s2 = "s2" ) + sel := NewSharePointBackup([]string{s1, s2}) sel.Include(sel.Sites([]string{s1, s2})) scopes := sel.Includes require.Len(t, scopes, 2) @@ -223,13 +224,13 @@ func (suite *SharePointSelectorSuite) TestSharePointSelector_Include_Sites() { func (suite *SharePointSelectorSuite) TestSharePointSelector_Exclude_Sites() { t := suite.T() - sel := NewSharePointBackup() const ( s1 = "s1" s2 = "s2" ) + sel := NewSharePointBackup([]string{s1, s2}) sel.Exclude(sel.Sites([]string{s1, s2})) scopes := sel.Excludes require.Len(t, scopes, 2) @@ -245,14 +246,14 @@ func (suite *SharePointSelectorSuite) TestSharePointSelector_Exclude_Sites() { func (suite *SharePointSelectorSuite) TestNewSharePointRestore() { t := suite.T() - or := NewSharePointRestore() + or := NewSharePointRestore(nil) assert.Equal(t, or.Service, ServiceSharePoint) assert.NotZero(t, or.Scopes()) } func (suite *SharePointSelectorSuite) TestToSharePointRestore() { t := suite.T() - eb := NewSharePointRestore() + eb := NewSharePointRestore(nil) s := eb.Selector or, err := s.ToSharePointRestore() require.NoError(t, err) @@ -262,9 +263,9 @@ func (suite *SharePointSelectorSuite) TestToSharePointRestore() { func (suite *SharePointSelectorSuite) TestSharePointRestore_Reduce() { var ( - item = stubRepoRef(path.SharePointService, path.LibrariesCategory, "uid", "/folderA/folderB", "item") - item2 = stubRepoRef(path.SharePointService, path.LibrariesCategory, "uid", "/folderA/folderC", "item2") - item3 = stubRepoRef(path.SharePointService, path.LibrariesCategory, "uid", "/folderD/folderE", "item3") + item = stubRepoRef(path.SharePointService, path.LibrariesCategory, "sid", "folderA/folderB", "item") + item2 = stubRepoRef(path.SharePointService, path.LibrariesCategory, "sid", "folderA/folderC", "item2") + item3 = stubRepoRef(path.SharePointService, path.LibrariesCategory, "sid", "folderD/folderE", "item3") ) deets := &details.Details{ @@ -309,34 +310,34 @@ func (suite *SharePointSelectorSuite) TestSharePointRestore_Reduce() { expect []string }{ { - "all", - deets, - func() *SharePointRestore { - odr := NewSharePointRestore() + name: "all", + deets: deets, + makeSelector: func() *SharePointRestore { + odr := NewSharePointRestore(Any()) odr.Include(odr.Sites(Any())) return odr }, - arr(item, item2, item3), + expect: arr(item, item2, item3), }, { - "only match item", - deets, - func() *SharePointRestore { - odr := NewSharePointRestore() + name: "only match item", + deets: deets, + makeSelector: func() *SharePointRestore { + odr := NewSharePointRestore(Any()) odr.Include(odr.LibraryItems(Any(), Any(), []string{"item2"})) return odr }, - arr(item2), + expect: arr(item2), }, { - "only match folder", - deets, - func() *SharePointRestore { - odr := NewSharePointRestore() - odr.Include(odr.Libraries([]string{"uid"}, []string{"folderA/folderB", "folderA/folderC"})) + name: "only match folder", + deets: deets, + makeSelector: func() *SharePointRestore { + odr := NewSharePointRestore([]string{"sid"}) + odr.Include(odr.Libraries([]string{"sid"}, []string{"folderA/folderB", "folderA/folderC"})) return odr }, - arr(item, item2), + expect: arr(item, item2), }, } for _, test := range table { @@ -398,7 +399,7 @@ func (suite *SharePointSelectorSuite) TestSharePointCategory_PathValues() { func (suite *SharePointSelectorSuite) TestSharePointScope_MatchesInfo() { var ( - ods = NewSharePointRestore() + ods = NewSharePointRestore(nil) // TODO: move into test host = "www.website.com" pth = "/foo" url = host + pth