Merge branch 'HandlerImplemenation' of https://github.com/alcionai/corso into HandlerImplemenation

This commit is contained in:
neha-Gupta1 2023-08-25 12:07:43 +05:30
commit 79ef5a56fc
11 changed files with 638 additions and 493 deletions

View File

@ -12,7 +12,7 @@ inputs:
required: false required: false
default: "" default: ""
restore-args: restore-args:
description: Arguments to pass for restore description: Arguments to pass for restore; restore is skipped when missing.
required: false required: false
default: "" default: ""
test-folder: test-folder:
@ -28,6 +28,10 @@ inputs:
description: Value for the --collisions flag description: Value for the --collisions flag
requried: false requried: false
default: "replace" default: "replace"
with-export:
description: Runs export tests when true
required: false
default: false
outputs: outputs:
backup-id: backup-id:
@ -52,6 +56,7 @@ runs:
tee $GITHUB_OUTPUT tee $GITHUB_OUTPUT
- name: Restore ${{ inputs.service }} ${{ inputs.kind }} - name: Restore ${{ inputs.service }} ${{ inputs.kind }}
if: inputs.restore-args
id: restore id: restore
shell: bash shell: bash
working-directory: src working-directory: src
@ -73,6 +78,7 @@ runs:
cat /tmp/corsologs cat /tmp/corsologs
- name: Check restore ${{ inputs.service }} ${{ inputs.kind }} - name: Check restore ${{ inputs.service }} ${{ inputs.kind }}
if: inputs.restore-args
shell: bash shell: bash
working-directory: src working-directory: src
env: env:
@ -86,10 +92,10 @@ runs:
./sanity-test ./sanity-test
- name: Export ${{ inputs.service }} ${{ inputs.kind }} - name: Export ${{ inputs.service }} ${{ inputs.kind }}
if: inputs.with-export == true
id: export id: export
shell: bash shell: bash
working-directory: src working-directory: src
if: ${{ inputs.service == 'onedrive' || inputs.service == 'sharepoint' }}
run: | run: |
set -euo pipefail set -euo pipefail
CORSO_LOG_FILE=${{ inputs.log-dir }}/gotest-restore-${{ inputs.service }}-${{inputs.kind }}.log CORSO_LOG_FILE=${{ inputs.log-dir }}/gotest-restore-${{ inputs.service }}-${{inputs.kind }}.log
@ -103,9 +109,9 @@ runs:
cat /tmp/corsologs cat /tmp/corsologs
- name: Check export ${{ inputs.service }} ${{ inputs.kind }} - name: Check export ${{ inputs.service }} ${{ inputs.kind }}
if: inputs.with-export == true
shell: bash shell: bash
working-directory: src working-directory: src
if: ${{ inputs.service == 'onedrive' || inputs.service == 'sharepoint' }}
env: env:
SANITY_TEST_KIND: export SANITY_TEST_KIND: export
SANITY_TEST_FOLDER: /tmp/export-${{ inputs.service }}-${{inputs.kind }} SANITY_TEST_FOLDER: /tmp/export-${{ inputs.service }}-${{inputs.kind }}
@ -117,10 +123,10 @@ runs:
./sanity-test ./sanity-test
- name: Export archive ${{ inputs.service }} ${{ inputs.kind }} - name: Export archive ${{ inputs.service }} ${{ inputs.kind }}
if: inputs.with-export == true
id: export-archive id: export-archive
shell: bash shell: bash
working-directory: src working-directory: src
if: ${{ inputs.service == 'onedrive' }} # Export only available for OneDrive
run: | run: |
set -euo pipefail set -euo pipefail
CORSO_LOG_FILE=${{ inputs.log-dir }}/gotest-restore-${{ inputs.service }}-${{inputs.kind }}.log CORSO_LOG_FILE=${{ inputs.log-dir }}/gotest-restore-${{ inputs.service }}-${{inputs.kind }}.log
@ -137,9 +143,9 @@ runs:
cat /tmp/corsologs cat /tmp/corsologs
- name: Check archive export ${{ inputs.service }} ${{ inputs.kind }} - name: Check archive export ${{ inputs.service }} ${{ inputs.kind }}
if: inputs.with-export == true
shell: bash shell: bash
working-directory: src working-directory: src
if: ${{ inputs.service == 'onedrive' }}
env: env:
SANITY_TEST_KIND: export SANITY_TEST_KIND: export
SANITY_TEST_FOLDER: /tmp/export-${{ inputs.service }}-${{inputs.kind }}-unzipped SANITY_TEST_FOLDER: /tmp/export-${{ inputs.service }}-${{inputs.kind }}-unzipped

View File

@ -241,6 +241,7 @@ jobs:
restore-args: '--folder ${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-onedrive.outputs.result }} --restore-permissions' restore-args: '--folder ${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-onedrive.outputs.result }} --restore-permissions'
test-folder: '${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-onedrive.outputs.result }}' test-folder: '${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-onedrive.outputs.result }}'
log-dir: ${{ env.CORSO_LOG_DIR }} log-dir: ${{ env.CORSO_LOG_DIR }}
with-export: true
# generate some more enteries for incremental check # generate some more enteries for incremental check
- name: OneDrive - Create new data (for incremental) - name: OneDrive - Create new data (for incremental)
@ -263,6 +264,7 @@ jobs:
restore-args: '--folder ${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-onedrive.outputs.result }} --restore-permissions' restore-args: '--folder ${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-onedrive.outputs.result }} --restore-permissions'
test-folder: '${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-onedrive.outputs.result }}' test-folder: '${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-onedrive.outputs.result }}'
log-dir: ${{ env.CORSO_LOG_DIR }} log-dir: ${{ env.CORSO_LOG_DIR }}
with-export: true
########################################################################################################################################## ##########################################################################################################################################
@ -295,6 +297,7 @@ jobs:
restore-args: '--folder ${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-sharepoint.outputs.result }} --restore-permissions' restore-args: '--folder ${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-sharepoint.outputs.result }} --restore-permissions'
test-folder: '${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-sharepoint.outputs.result }}' test-folder: '${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-sharepoint.outputs.result }}'
log-dir: ${{ env.CORSO_LOG_DIR }} log-dir: ${{ env.CORSO_LOG_DIR }}
with-export: true
# generate some more enteries for incremental check # generate some more enteries for incremental check
- name: SharePoint - Create new data (for incremental) - name: SharePoint - Create new data (for incremental)
@ -318,6 +321,53 @@ jobs:
restore-args: '--folder ${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-sharepoint.outputs.result }} --restore-permissions' restore-args: '--folder ${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-sharepoint.outputs.result }} --restore-permissions'
test-folder: '${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-sharepoint.outputs.result }}' test-folder: '${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-sharepoint.outputs.result }}'
log-dir: ${{ env.CORSO_LOG_DIR }} log-dir: ${{ env.CORSO_LOG_DIR }}
with-export: true
##########################################################################################################################################
# Groups and Teams
# generate new entries for test
- name: Groups - Create new data
if: false # TODO: enable when ready
id: new-data-creation-groups
working-directory: ./src/cmd/factory
run: |
suffix=$(date +"%Y-%m-%d_%H-%M-%S")
go run . sharepoint files \
--site ${{ secrets.CORSO_M365_TEST_GROUPS_SITE_URL }} \
--user ${{ env.TEST_USER }} \
--secondaryuser ${{ env.CORSO_SECONDARY_M365_TEST_USER_ID }} \
--tenant ${{ secrets.TENANT_ID }} \
--destination ${{ env.RESTORE_DEST_PFX }}$suffix \
--count 4
echo result="${suffix}" >> $GITHUB_OUTPUT
- name: Groups - Backup
if: false # TODO: enable when ready
id: groups-backup
uses: ./.github/actions/backup-restore-test
with:
service: groups
kind: initial
backup-args: '--group "${{ secrets.CORSO_M365_TEST_TEAM_ID }}"'
test-folder: '${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-groups.outputs.result }}'
log-dir: ${{ env.CORSO_LOG_DIR }}
- name: Teams - Backup
if: false # TODO: enable when ready
id: teams-backup
uses: ./.github/actions/backup-restore-test
with:
service: teams
kind: initial
backup-args: '--group "${{ secrets.CORSO_M365_TEST_TEAM_ID }}"'
test-folder: '${{ env.RESTORE_DEST_PFX }}${{ steps.new-data-creation-groups.outputs.result }}'
log-dir: ${{ env.CORSO_LOG_DIR }}
# TODO: incrementals
########################################################################################################################################## ##########################################################################################################################################

View File

@ -1,15 +1,12 @@
package backup_test package backup_test
import ( import (
"context"
"fmt" "fmt"
"strings" "strings"
"testing" "testing"
"github.com/alcionai/clues" "github.com/alcionai/clues"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
@ -23,12 +20,9 @@ import (
"github.com/alcionai/corso/src/internal/operations" "github.com/alcionai/corso/src/internal/operations"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/internal/tester/tconfig" "github.com/alcionai/corso/src/internal/tester/tconfig"
"github.com/alcionai/corso/src/pkg/account"
"github.com/alcionai/corso/src/pkg/path" "github.com/alcionai/corso/src/pkg/path"
"github.com/alcionai/corso/src/pkg/repository"
"github.com/alcionai/corso/src/pkg/selectors" "github.com/alcionai/corso/src/pkg/selectors"
"github.com/alcionai/corso/src/pkg/services/m365/api" "github.com/alcionai/corso/src/pkg/services/m365/api"
"github.com/alcionai/corso/src/pkg/storage"
storeTD "github.com/alcionai/corso/src/pkg/storage/testdata" storeTD "github.com/alcionai/corso/src/pkg/storage/testdata"
) )
@ -39,204 +33,17 @@ var (
) )
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// tests with azure flags in exchange create // tests that depend on no backups existing
// ---------------------------------------------------------------------------
type ExchangeCMDWithFlagsE2ESuite struct {
tester.Suite
acct account.Account
st storage.Storage
vpr *viper.Viper
cfgFP string
repo repository.Repository
m365UserID string
recorder strings.Builder
}
func TestExchangeCMDWithFlagsE2ESuite(t *testing.T) {
suite.Run(t, &ExchangeCMDWithFlagsE2ESuite{
Suite: tester.NewE2ESuite(
t,
[][]string{storeTD.AWSStorageCredEnvs, tconfig.M365AcctCredEnvs}),
})
}
func (suite *ExchangeCMDWithFlagsE2ESuite) SetupSuite() {
t := suite.T()
ctx, flush := tester.NewContext(t)
defer flush()
acct, st, repo, vpr, recorder, cfgFilePath := prepM365Test(t, ctx)
suite.acct = acct
suite.st = st
suite.repo = repo
suite.vpr = vpr
suite.recorder = recorder
suite.cfgFP = cfgFilePath
suite.m365UserID = tconfig.M365UserID(t)
}
func (suite *ExchangeCMDWithFlagsE2ESuite) TestBackupCreateExchange_badAzureClientID() {
t := suite.T()
ctx, flush := tester.NewContext(t)
defer flush()
suite.recorder.Reset()
cmd := cliTD.StubRootCmd(
"backup", "create", "exchange",
"--user", suite.m365UserID,
"--azure-client-id", "invalid-value",
)
cli.BuildCommandTree(cmd)
cmd.SetErr(&suite.recorder)
ctx = print.SetRootCmd(ctx, cmd)
// run the command
err := cmd.ExecuteContext(ctx)
require.Error(t, err, clues.ToCore(err))
}
func (suite *ExchangeCMDWithFlagsE2ESuite) TestBackupCreateExchange_azureIDFromConfigFile() {
t := suite.T()
ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr)
defer flush()
suite.recorder.Reset()
cmd := cliTD.StubRootCmd(
"backup", "create", "exchange",
"--user", suite.m365UserID,
"--config-file", suite.cfgFP)
cli.BuildCommandTree(cmd)
cmd.SetOut(&suite.recorder)
ctx = print.SetRootCmd(ctx, cmd)
// run the command
err := cmd.ExecuteContext(ctx)
require.NoError(t, err, clues.ToCore(err))
result := suite.recorder.String()
t.Log("backup results", result)
// as an offhand check: the result should contain the m365 user id
assert.Contains(t, result, suite.m365UserID)
}
func (suite *ExchangeCMDWithFlagsE2ESuite) TestExchangeBackupValueFromEnvCmd_empty() {
t := suite.T()
ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr)
defer flush()
suite.recorder.Reset()
cmd := cliTD.StubRootCmd(
"backup", "create", "exchange",
"--user", suite.m365UserID,
"--config-file", suite.cfgFP)
cli.BuildCommandTree(cmd)
cmd.SetOut(&suite.recorder)
ctx = print.SetRootCmd(ctx, cmd)
// run the command
err := cmd.ExecuteContext(ctx)
require.NoError(t, err, clues.ToCore(err))
result := suite.recorder.String()
t.Log("backup results", result)
// as an offhand check: the result should contain the m365 user id
assert.Contains(t, result, suite.m365UserID)
}
// AWS flags
func (suite *ExchangeCMDWithFlagsE2ESuite) TestExchangeBackupInvalidAWSClientIDCmd_empty() {
t := suite.T()
ctx, flush := tester.NewContext(t)
defer flush()
suite.recorder.Reset()
cmd := cliTD.StubRootCmd(
"backup", "create", "exchange",
"--user", suite.m365UserID,
"--aws-access-key", "invalid-value",
"--aws-secret-access-key", "some-invalid-value",
)
cli.BuildCommandTree(cmd)
cmd.SetOut(&suite.recorder)
ctx = print.SetRootCmd(ctx, cmd)
// run the command
err := cmd.ExecuteContext(ctx)
// since invalid aws creds are explicitly set, should see a failure
require.Error(t, err, clues.ToCore(err))
}
func (suite *ExchangeCMDWithFlagsE2ESuite) TestExchangeBackupAWSValueFromEnvCmd_empty() {
t := suite.T()
ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr)
defer flush()
suite.recorder.Reset()
cmd := cliTD.StubRootCmd(
"backup", "create", "exchange",
"--user", suite.m365UserID,
"--config-file", suite.cfgFP)
cli.BuildCommandTree(cmd)
cmd.SetOut(&suite.recorder)
ctx = print.SetRootCmd(ctx, cmd)
// run the command
err := cmd.ExecuteContext(ctx)
require.NoError(t, err, clues.ToCore(err))
result := suite.recorder.String()
t.Log("backup results", result)
// as an offhand check: the result should contain the m365 user id
assert.Contains(t, result, suite.m365UserID)
}
// ---------------------------------------------------------------------------
// tests with no backups
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type NoBackupExchangeE2ESuite struct { type NoBackupExchangeE2ESuite struct {
tester.Suite tester.Suite
acct account.Account dpnd dependencies
st storage.Storage its intgTesterSetup
vpr *viper.Viper
cfgFP string
repo repository.Repository
m365UserID string
recorder strings.Builder
} }
func TestNoBackupExchangeE2ESuite(t *testing.T) { func TestNoBackupExchangeE2ESuite(t *testing.T) {
suite.Run(t, &NoBackupExchangeE2ESuite{Suite: tester.NewE2ESuite( suite.Run(t, &BackupExchangeE2ESuite{Suite: tester.NewE2ESuite(
t, t,
[][]string{storeTD.AWSStorageCredEnvs, tconfig.M365AcctCredEnvs}, [][]string{storeTD.AWSStorageCredEnvs, tconfig.M365AcctCredEnvs},
)}) )})
@ -248,32 +55,25 @@ func (suite *NoBackupExchangeE2ESuite) SetupSuite() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
acct, st, repo, vpr, recorder, cfgFilePath := prepM365Test(t, ctx) suite.its = newIntegrationTesterSetup(t)
suite.dpnd = prepM365Test(t, ctx)
suite.acct = acct
suite.st = st
suite.repo = repo
suite.vpr = vpr
suite.recorder = recorder
suite.cfgFP = cfgFilePath
suite.m365UserID = tconfig.M365UserID(t)
} }
func (suite *NoBackupExchangeE2ESuite) TestExchangeBackupListCmd_empty() { func (suite *NoBackupExchangeE2ESuite) TestExchangeBackupListCmd_noBackups() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush() defer flush()
suite.recorder.Reset() suite.dpnd.recorder.Reset()
cmd := cliTD.StubRootCmd( cmd := cliTD.StubRootCmd(
"backup", "list", "exchange", "backup", "list", "exchange",
"--config-file", suite.cfgFP) "--config-file", suite.dpnd.configFilePath)
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
cmd.SetErr(&suite.recorder) cmd.SetErr(&suite.dpnd.recorder)
ctx = print.SetRootCmd(ctx, cmd) ctx = print.SetRootCmd(ctx, cmd)
@ -281,7 +81,7 @@ func (suite *NoBackupExchangeE2ESuite) TestExchangeBackupListCmd_empty() {
err := cmd.ExecuteContext(ctx) err := cmd.ExecuteContext(ctx)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
result := suite.recorder.String() result := suite.dpnd.recorder.String()
// as an offhand check: the result should contain the m365 user id // as an offhand check: the result should contain the m365 user id
assert.True(t, strings.HasSuffix(result, "No backups available\n")) assert.True(t, strings.HasSuffix(result, "No backups available\n"))
@ -293,12 +93,8 @@ func (suite *NoBackupExchangeE2ESuite) TestExchangeBackupListCmd_empty() {
type BackupExchangeE2ESuite struct { type BackupExchangeE2ESuite struct {
tester.Suite tester.Suite
acct account.Account dpnd dependencies
st storage.Storage its intgTesterSetup
vpr *viper.Viper
cfgFP string
repo repository.Repository
m365UserID string
} }
func TestBackupExchangeE2ESuite(t *testing.T) { func TestBackupExchangeE2ESuite(t *testing.T) {
@ -314,40 +110,39 @@ func (suite *BackupExchangeE2ESuite) SetupSuite() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
acct, st, repo, vpr, _, cfgFilePath := prepM365Test(t, ctx) suite.its = newIntegrationTesterSetup(t)
suite.dpnd = prepM365Test(t, ctx)
suite.acct = acct
suite.st = st
suite.repo = repo
suite.vpr = vpr
suite.cfgFP = cfgFilePath
suite.m365UserID = tconfig.M365UserID(t)
} }
func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd_email() { func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd_email() {
runExchangeBackupCategoryTest(suite, "email") runExchangeBackupCategoryTest(suite, email)
} }
func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd_contacts() { func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd_contacts() {
runExchangeBackupCategoryTest(suite, "contacts") runExchangeBackupCategoryTest(suite, contacts)
} }
func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd_events() { func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd_events() {
runExchangeBackupCategoryTest(suite, "events") runExchangeBackupCategoryTest(suite, events)
} }
func runExchangeBackupCategoryTest(suite *BackupExchangeE2ESuite, category string) { func runExchangeBackupCategoryTest(suite *BackupExchangeE2ESuite, category path.CategoryType) {
recorder := strings.Builder{} recorder := strings.Builder{}
recorder.Reset() recorder.Reset()
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush() defer flush()
cmd, ctx := buildExchangeBackupCmd(ctx, suite.cfgFP, suite.m365UserID, category, &recorder) cmd, ctx := buildExchangeBackupCmd(
ctx,
suite.dpnd.configFilePath,
suite.its.user.ID,
category.String(),
&recorder)
// run the command // run the command
err := cmd.ExecuteContext(ctx) err := cmd.ExecuteContext(ctx)
@ -357,21 +152,21 @@ func runExchangeBackupCategoryTest(suite *BackupExchangeE2ESuite, category strin
t.Log("backup results", result) t.Log("backup results", result)
// as an offhand check: the result should contain the m365 user id // as an offhand check: the result should contain the m365 user id
assert.Contains(t, result, suite.m365UserID) assert.Contains(t, result, suite.its.user.ID)
} }
func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd_ServiceNotEnabled_email() { func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd_ServiceNotEnabled_email() {
runExchangeBackupServiceNotEnabledTest(suite, "email") runExchangeBackupServiceNotEnabledTest(suite, email)
} }
func runExchangeBackupServiceNotEnabledTest(suite *BackupExchangeE2ESuite, category string) { func runExchangeBackupServiceNotEnabledTest(suite *BackupExchangeE2ESuite, category path.CategoryType) {
recorder := strings.Builder{} recorder := strings.Builder{}
recorder.Reset() recorder.Reset()
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush() defer flush()
@ -379,9 +174,9 @@ func runExchangeBackupServiceNotEnabledTest(suite *BackupExchangeE2ESuite, categ
cmd, ctx := buildExchangeBackupCmd( cmd, ctx := buildExchangeBackupCmd(
ctx, ctx,
suite.cfgFP, suite.dpnd.configFilePath,
fmt.Sprintf("%s,%s", tconfig.UnlicensedM365UserID(suite.T()), suite.m365UserID), fmt.Sprintf("%s,%s", tconfig.UnlicensedM365UserID(suite.T()), suite.its.user.ID),
category, category.String(),
&recorder) &recorder)
err := cmd.ExecuteContext(ctx) err := cmd.ExecuteContext(ctx)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
@ -390,33 +185,38 @@ func runExchangeBackupServiceNotEnabledTest(suite *BackupExchangeE2ESuite, categ
t.Log("backup results", result) t.Log("backup results", result)
// as an offhand check: the result should contain the m365 user id // as an offhand check: the result should contain the m365 user id
assert.Contains(t, result, suite.m365UserID) assert.Contains(t, result, suite.its.user.ID)
} }
func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd_userNotFound_email() { func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd_userNotFound_email() {
runExchangeBackupUserNotFoundTest(suite, "email") runExchangeBackupUserNotFoundTest(suite, email)
} }
func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd_userNotFound_contacts() { func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd_userNotFound_contacts() {
runExchangeBackupUserNotFoundTest(suite, "contacts") runExchangeBackupUserNotFoundTest(suite, contacts)
} }
func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd_userNotFound_events() { func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd_userNotFound_events() {
runExchangeBackupUserNotFoundTest(suite, "events") runExchangeBackupUserNotFoundTest(suite, events)
} }
func runExchangeBackupUserNotFoundTest(suite *BackupExchangeE2ESuite, category string) { func runExchangeBackupUserNotFoundTest(suite *BackupExchangeE2ESuite, category path.CategoryType) {
recorder := strings.Builder{} recorder := strings.Builder{}
recorder.Reset() recorder.Reset()
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush() defer flush()
cmd, ctx := buildExchangeBackupCmd(ctx, suite.cfgFP, "foo@not-there.com", category, &recorder) cmd, ctx := buildExchangeBackupCmd(
ctx,
suite.dpnd.configFilePath,
"foo@not-there.com",
category.String(),
&recorder)
// run the command // run the command
err := cmd.ExecuteContext(ctx) err := cmd.ExecuteContext(ctx)
@ -433,27 +233,104 @@ func runExchangeBackupUserNotFoundTest(suite *BackupExchangeE2ESuite, category s
t.Log("backup results", result) t.Log("backup results", result)
} }
func (suite *BackupExchangeE2ESuite) TestBackupCreateExchange_badAzureClientIDFlag() {
t := suite.T()
ctx, flush := tester.NewContext(t)
defer flush()
suite.dpnd.recorder.Reset()
cmd := cliTD.StubRootCmd(
"backup", "create", "exchange",
"--user", suite.its.user.ID,
"--azure-client-id", "invalid-value",
)
cli.BuildCommandTree(cmd)
cmd.SetErr(&suite.dpnd.recorder)
ctx = print.SetRootCmd(ctx, cmd)
// run the command
err := cmd.ExecuteContext(ctx)
require.Error(t, err, clues.ToCore(err))
}
func (suite *BackupExchangeE2ESuite) TestBackupCreateExchange_fromConfigFile() {
t := suite.T()
ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush()
suite.dpnd.recorder.Reset()
cmd := cliTD.StubRootCmd(
"backup", "create", "exchange",
"--user", suite.its.user.ID,
"--config-file", suite.dpnd.configFilePath)
cli.BuildCommandTree(cmd)
cmd.SetOut(&suite.dpnd.recorder)
ctx = print.SetRootCmd(ctx, cmd)
// run the command
err := cmd.ExecuteContext(ctx)
require.NoError(t, err, clues.ToCore(err))
result := suite.dpnd.recorder.String()
t.Log("backup results", result)
// as an offhand check: the result should contain the m365 user id
assert.Contains(t, result, suite.its.user.ID)
}
// AWS flags
func (suite *BackupExchangeE2ESuite) TestBackupCreateExchange_badAWSFlags() {
t := suite.T()
ctx, flush := tester.NewContext(t)
defer flush()
suite.dpnd.recorder.Reset()
cmd := cliTD.StubRootCmd(
"backup", "create", "exchange",
"--user", suite.its.user.ID,
"--aws-access-key", "invalid-value",
"--aws-secret-access-key", "some-invalid-value",
)
cli.BuildCommandTree(cmd)
cmd.SetOut(&suite.dpnd.recorder)
ctx = print.SetRootCmd(ctx, cmd)
// run the command
err := cmd.ExecuteContext(ctx)
// since invalid aws creds are explicitly set, should see a failure
require.Error(t, err, clues.ToCore(err))
}
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// tests prepared with a previous backup // tests prepared with a previous backup
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type PreparedBackupExchangeE2ESuite struct { type PreparedBackupExchangeE2ESuite struct {
tester.Suite tester.Suite
acct account.Account dpnd dependencies
st storage.Storage backupOps map[path.CategoryType]string
vpr *viper.Viper its intgTesterSetup
cfgFP string
repo repository.Repository
m365UserID string
backupOps map[path.CategoryType]string
recorder strings.Builder
} }
func TestPreparedBackupExchangeE2ESuite(t *testing.T) { func TestPreparedBackupExchangeE2ESuite(t *testing.T) {
suite.Run(t, &PreparedBackupExchangeE2ESuite{Suite: tester.NewE2ESuite( suite.Run(t, &PreparedBackupExchangeE2ESuite{
t, Suite: tester.NewE2ESuite(
[][]string{storeTD.AWSStorageCredEnvs, tconfig.M365AcctCredEnvs}, t,
)}) [][]string{storeTD.AWSStorageCredEnvs, tconfig.M365AcctCredEnvs}),
})
} }
func (suite *PreparedBackupExchangeE2ESuite) SetupSuite() { func (suite *PreparedBackupExchangeE2ESuite) SetupSuite() {
@ -462,20 +339,13 @@ func (suite *PreparedBackupExchangeE2ESuite) SetupSuite() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
acct, st, repo, vpr, recorder, cfgFilePath := prepM365Test(t, ctx) suite.its = newIntegrationTesterSetup(t)
suite.dpnd = prepM365Test(t, ctx)
suite.acct = acct
suite.st = st
suite.repo = repo
suite.vpr = vpr
suite.recorder = recorder
suite.cfgFP = cfgFilePath
suite.m365UserID = tconfig.M365UserID(t)
suite.backupOps = make(map[path.CategoryType]string) suite.backupOps = make(map[path.CategoryType]string)
var ( var (
users = []string{suite.m365UserID} users = []string{suite.its.user.ID}
ins = idname.NewCache(map[string]string{suite.m365UserID: suite.m365UserID}) ins = idname.NewCache(map[string]string{suite.its.user.ID: suite.its.user.ID})
) )
for _, set := range []path.CategoryType{email, contacts, events} { for _, set := range []path.CategoryType{email, contacts, events} {
@ -497,7 +367,7 @@ func (suite *PreparedBackupExchangeE2ESuite) SetupSuite() {
sel.Include(scopes) sel.Include(scopes)
bop, err := suite.repo.NewBackupWithLookup(ctx, sel.Selector, ins) bop, err := suite.dpnd.repo.NewBackupWithLookup(ctx, sel.Selector, ins)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
err = bop.Run(ctx) err = bop.Run(ctx)
@ -506,11 +376,11 @@ func (suite *PreparedBackupExchangeE2ESuite) SetupSuite() {
bIDs := string(bop.Results.BackupID) bIDs := string(bop.Results.BackupID)
// sanity check, ensure we can find the backup and its details immediately // sanity check, ensure we can find the backup and its details immediately
b, err := suite.repo.Backup(ctx, string(bop.Results.BackupID)) b, err := suite.dpnd.repo.Backup(ctx, string(bop.Results.BackupID))
require.NoError(t, err, "retrieving recent backup by ID") require.NoError(t, err, "retrieving recent backup by ID")
require.Equal(t, bIDs, string(b.ID), "repo backup matches results id") require.Equal(t, bIDs, string(b.ID), "repo backup matches results id")
_, b, errs := suite.repo.GetBackupDetails(ctx, bIDs) _, b, errs := suite.dpnd.repo.GetBackupDetails(ctx, bIDs)
require.NoError(t, errs.Failure(), "retrieving recent backup details by ID") require.NoError(t, errs.Failure(), "retrieving recent backup details by ID")
require.Empty(t, errs.Recovered(), "retrieving recent backup details by ID") require.Empty(t, errs.Recovered(), "retrieving recent backup details by ID")
require.Equal(t, bIDs, string(b.ID), "repo details matches results id") require.Equal(t, bIDs, string(b.ID), "repo details matches results id")
@ -532,20 +402,20 @@ func (suite *PreparedBackupExchangeE2ESuite) TestExchangeListCmd_events() {
} }
func runExchangeListCmdTest(suite *PreparedBackupExchangeE2ESuite, category path.CategoryType) { func runExchangeListCmdTest(suite *PreparedBackupExchangeE2ESuite, category path.CategoryType) {
suite.recorder.Reset() suite.dpnd.recorder.Reset()
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush() defer flush()
cmd := cliTD.StubRootCmd( cmd := cliTD.StubRootCmd(
"backup", "list", "exchange", "backup", "list", "exchange",
"--config-file", suite.cfgFP) "--config-file", suite.dpnd.configFilePath)
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
cmd.SetOut(&suite.recorder) cmd.SetOut(&suite.dpnd.recorder)
ctx = print.SetRootCmd(ctx, cmd) ctx = print.SetRootCmd(ctx, cmd)
@ -554,7 +424,7 @@ func runExchangeListCmdTest(suite *PreparedBackupExchangeE2ESuite, category path
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
// compare the output // compare the output
result := suite.recorder.String() result := suite.dpnd.recorder.String()
assert.Contains(t, result, suite.backupOps[category]) assert.Contains(t, result, suite.backupOps[category])
} }
@ -571,12 +441,12 @@ func (suite *PreparedBackupExchangeE2ESuite) TestExchangeListCmd_singleID_events
} }
func runExchangeListSingleCmdTest(suite *PreparedBackupExchangeE2ESuite, category path.CategoryType) { func runExchangeListSingleCmdTest(suite *PreparedBackupExchangeE2ESuite, category path.CategoryType) {
suite.recorder.Reset() suite.dpnd.recorder.Reset()
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush() defer flush()
@ -584,11 +454,11 @@ func runExchangeListSingleCmdTest(suite *PreparedBackupExchangeE2ESuite, categor
cmd := cliTD.StubRootCmd( cmd := cliTD.StubRootCmd(
"backup", "list", "exchange", "backup", "list", "exchange",
"--config-file", suite.cfgFP, "--config-file", suite.dpnd.configFilePath,
"--backup", string(bID)) "--backup", string(bID))
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
cmd.SetOut(&suite.recorder) cmd.SetOut(&suite.dpnd.recorder)
ctx = print.SetRootCmd(ctx, cmd) ctx = print.SetRootCmd(ctx, cmd)
@ -597,7 +467,7 @@ func runExchangeListSingleCmdTest(suite *PreparedBackupExchangeE2ESuite, categor
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
// compare the output // compare the output
result := suite.recorder.String() result := suite.dpnd.recorder.String()
assert.Contains(t, result, bID) assert.Contains(t, result, bID)
} }
@ -605,13 +475,13 @@ func (suite *PreparedBackupExchangeE2ESuite) TestExchangeListCmd_badID() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush() defer flush()
cmd := cliTD.StubRootCmd( cmd := cliTD.StubRootCmd(
"backup", "list", "exchange", "backup", "list", "exchange",
"--config-file", suite.cfgFP, "--config-file", suite.dpnd.configFilePath,
"--backup", "smarfs") "--backup", "smarfs")
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
@ -635,28 +505,28 @@ func (suite *PreparedBackupExchangeE2ESuite) TestExchangeDetailsCmd_events() {
} }
func runExchangeDetailsCmdTest(suite *PreparedBackupExchangeE2ESuite, category path.CategoryType) { func runExchangeDetailsCmdTest(suite *PreparedBackupExchangeE2ESuite, category path.CategoryType) {
suite.recorder.Reset() suite.dpnd.recorder.Reset()
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush() defer flush()
bID := suite.backupOps[category] bID := suite.backupOps[category]
// fetch the details from the repo first // fetch the details from the repo first
deets, _, errs := suite.repo.GetBackupDetails(ctx, string(bID)) deets, _, errs := suite.dpnd.repo.GetBackupDetails(ctx, string(bID))
require.NoError(t, errs.Failure(), clues.ToCore(errs.Failure())) require.NoError(t, errs.Failure(), clues.ToCore(errs.Failure()))
require.Empty(t, errs.Recovered()) require.Empty(t, errs.Recovered())
cmd := cliTD.StubRootCmd( cmd := cliTD.StubRootCmd(
"backup", "details", "exchange", "backup", "details", "exchange",
"--config-file", suite.cfgFP, "--config-file", suite.dpnd.configFilePath,
"--"+flags.BackupFN, string(bID)) "--"+flags.BackupFN, string(bID))
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
cmd.SetOut(&suite.recorder) cmd.SetOut(&suite.dpnd.recorder)
ctx = print.SetRootCmd(ctx, cmd) ctx = print.SetRootCmd(ctx, cmd)
@ -665,7 +535,7 @@ func runExchangeDetailsCmdTest(suite *PreparedBackupExchangeE2ESuite, category p
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
// compare the output // compare the output
result := suite.recorder.String() result := suite.dpnd.recorder.String()
i := 0 i := 0
foundFolders := 0 foundFolders := 0
@ -695,11 +565,7 @@ func runExchangeDetailsCmdTest(suite *PreparedBackupExchangeE2ESuite, category p
type BackupDeleteExchangeE2ESuite struct { type BackupDeleteExchangeE2ESuite struct {
tester.Suite tester.Suite
acct account.Account dpnd dependencies
st storage.Storage
vpr *viper.Viper
cfgFP string
repo repository.Repository
backupOp operations.BackupOperation backupOp operations.BackupOperation
} }
@ -707,8 +573,7 @@ func TestBackupDeleteExchangeE2ESuite(t *testing.T) {
suite.Run(t, &BackupDeleteExchangeE2ESuite{ suite.Run(t, &BackupDeleteExchangeE2ESuite{
Suite: tester.NewE2ESuite( Suite: tester.NewE2ESuite(
t, t,
[][]string{storeTD.AWSStorageCredEnvs, tconfig.M365AcctCredEnvs}, [][]string{storeTD.AWSStorageCredEnvs, tconfig.M365AcctCredEnvs}),
),
}) })
} }
@ -718,13 +583,7 @@ func (suite *BackupDeleteExchangeE2ESuite) SetupSuite() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
acct, st, repo, vpr, _, cfgFilePath := prepM365Test(t, ctx) suite.dpnd = prepM365Test(t, ctx)
suite.acct = acct
suite.st = st
suite.repo = repo
suite.vpr = vpr
suite.cfgFP = cfgFilePath
m365UserID := tconfig.M365UserID(t) m365UserID := tconfig.M365UserID(t)
users := []string{m365UserID} users := []string{m365UserID}
@ -733,7 +592,7 @@ func (suite *BackupDeleteExchangeE2ESuite) SetupSuite() {
sel := selectors.NewExchangeBackup(users) sel := selectors.NewExchangeBackup(users)
sel.Include(sel.MailFolders([]string{api.MailInbox}, selectors.PrefixMatch())) sel.Include(sel.MailFolders([]string{api.MailInbox}, selectors.PrefixMatch()))
backupOp, err := suite.repo.NewBackup(ctx, sel.Selector) backupOp, err := suite.dpnd.repo.NewBackup(ctx, sel.Selector)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
suite.backupOp = backupOp suite.backupOp = backupOp
@ -746,13 +605,13 @@ func (suite *BackupDeleteExchangeE2ESuite) TestExchangeBackupDeleteCmd() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush() defer flush()
cmd := cliTD.StubRootCmd( cmd := cliTD.StubRootCmd(
"backup", "delete", "exchange", "backup", "delete", "exchange",
"--config-file", suite.cfgFP, "--config-file", suite.dpnd.configFilePath,
"--"+flags.BackupFN, string(suite.backupOp.Results.BackupID)) "--"+flags.BackupFN, string(suite.backupOp.Results.BackupID))
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
@ -763,7 +622,7 @@ func (suite *BackupDeleteExchangeE2ESuite) TestExchangeBackupDeleteCmd() {
// a follow-up details call should fail, due to the backup ID being deleted // a follow-up details call should fail, due to the backup ID being deleted
cmd = cliTD.StubRootCmd( cmd = cliTD.StubRootCmd(
"backup", "details", "exchange", "backup", "details", "exchange",
"--config-file", suite.cfgFP, "--config-file", suite.dpnd.configFilePath,
"--backup", string(suite.backupOp.Results.BackupID)) "--backup", string(suite.backupOp.Results.BackupID))
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
@ -775,13 +634,13 @@ func (suite *BackupDeleteExchangeE2ESuite) TestExchangeBackupDeleteCmd_UnknownID
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush() defer flush()
cmd := cliTD.StubRootCmd( cmd := cliTD.StubRootCmd(
"backup", "delete", "exchange", "backup", "delete", "exchange",
"--config-file", suite.cfgFP, "--config-file", suite.dpnd.configFilePath,
"--"+flags.BackupFN, uuid.NewString()) "--"+flags.BackupFN, uuid.NewString())
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
@ -789,23 +648,3 @@ func (suite *BackupDeleteExchangeE2ESuite) TestExchangeBackupDeleteCmd_UnknownID
err := cmd.ExecuteContext(ctx) err := cmd.ExecuteContext(ctx)
require.Error(t, err, clues.ToCore(err)) require.Error(t, err, clues.ToCore(err))
} }
// ---------------------------------------------------------------------------
// helpers
// ---------------------------------------------------------------------------
func buildExchangeBackupCmd(
ctx context.Context,
configFile, user, category string,
recorder *strings.Builder,
) (*cobra.Command, context.Context) {
cmd := cliTD.StubRootCmd(
"backup", "create", "exchange",
"--config-file", configFile,
"--"+flags.UserFN, user,
"--"+flags.CategoryDataFN, category)
cli.BuildCommandTree(cmd)
cmd.SetOut(recorder)
return cmd, print.SetRootCmd(ctx, cmd)
}

View File

@ -1,60 +0,0 @@
package backup_test
import (
"context"
"strings"
"testing"
"github.com/alcionai/clues"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
"github.com/alcionai/corso/src/cli/config"
"github.com/alcionai/corso/src/internal/tester/tconfig"
"github.com/alcionai/corso/src/pkg/account"
"github.com/alcionai/corso/src/pkg/control"
ctrlRepo "github.com/alcionai/corso/src/pkg/control/repository"
"github.com/alcionai/corso/src/pkg/repository"
"github.com/alcionai/corso/src/pkg/storage"
"github.com/alcionai/corso/src/pkg/storage/testdata"
)
func prepM365Test(
t *testing.T,
ctx context.Context, //revive:disable-line:context-as-argument
) (
account.Account,
storage.Storage,
repository.Repository,
*viper.Viper,
strings.Builder,
string,
) {
var (
acct = tconfig.NewM365Account(t)
st = testdata.NewPrefixedS3Storage(t)
recorder = strings.Builder{}
)
cfg, err := st.S3Config()
require.NoError(t, err, clues.ToCore(err))
force := map[string]string{
tconfig.TestCfgAccountProvider: "M365",
tconfig.TestCfgStorageProvider: "S3",
tconfig.TestCfgPrefix: cfg.Prefix,
}
vpr, cfgFP := tconfig.MakeTempTestConfigClone(t, force)
ctx = config.SetViper(ctx, vpr)
repo, err := repository.Initialize(
ctx,
acct,
st,
control.DefaultOptions(),
ctrlRepo.Retention{})
require.NoError(t, err, clues.ToCore(err))
return acct, st, repo, vpr, recorder, cfgFP
}

View File

@ -0,0 +1,190 @@
package backup_test
import (
"context"
"strings"
"testing"
"github.com/alcionai/clues"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/stretchr/testify/require"
"github.com/alcionai/corso/src/cli"
"github.com/alcionai/corso/src/cli/config"
"github.com/alcionai/corso/src/cli/flags"
"github.com/alcionai/corso/src/cli/print"
cliTD "github.com/alcionai/corso/src/cli/testdata"
"github.com/alcionai/corso/src/internal/common/ptr"
"github.com/alcionai/corso/src/internal/m365/graph"
"github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/internal/tester/tconfig"
"github.com/alcionai/corso/src/pkg/account"
"github.com/alcionai/corso/src/pkg/control"
ctrlRepo "github.com/alcionai/corso/src/pkg/control/repository"
"github.com/alcionai/corso/src/pkg/repository"
"github.com/alcionai/corso/src/pkg/services/m365/api"
"github.com/alcionai/corso/src/pkg/services/m365/api/mock"
"github.com/alcionai/corso/src/pkg/storage"
"github.com/alcionai/corso/src/pkg/storage/testdata"
)
// ---------------------------------------------------------------------------
// Suite Setup
// ---------------------------------------------------------------------------
type ids struct {
ID string
DriveID string
DriveRootFolderID string
}
type intgTesterSetup struct {
acct account.Account
ac api.Client
gockAC api.Client
user ids
site ids
group ids
team ids
}
func newIntegrationTesterSetup(t *testing.T) intgTesterSetup {
its := intgTesterSetup{}
ctx, flush := tester.NewContext(t)
defer flush()
graph.InitializeConcurrencyLimiter(ctx, true, 4)
its.acct = tconfig.NewM365Account(t)
creds, err := its.acct.M365Config()
require.NoError(t, err, clues.ToCore(err))
its.ac, err = api.NewClient(creds, control.DefaultOptions())
require.NoError(t, err, clues.ToCore(err))
its.gockAC, err = mock.NewClient(creds)
require.NoError(t, err, clues.ToCore(err))
// user drive
uids := ids{}
uids.ID = tconfig.M365UserID(t)
userDrive, err := its.ac.Users().GetDefaultDrive(ctx, uids.ID)
require.NoError(t, err, clues.ToCore(err))
uids.DriveID = ptr.Val(userDrive.GetId())
userDriveRootFolder, err := its.ac.Drives().GetRootFolder(ctx, uids.DriveID)
require.NoError(t, err, clues.ToCore(err))
uids.DriveRootFolderID = ptr.Val(userDriveRootFolder.GetId())
its.user = uids
// site
sids := ids{}
sids.ID = tconfig.M365SiteID(t)
siteDrive, err := its.ac.Sites().GetDefaultDrive(ctx, sids.ID)
require.NoError(t, err, clues.ToCore(err))
sids.DriveID = ptr.Val(siteDrive.GetId())
siteDriveRootFolder, err := its.ac.Drives().GetRootFolder(ctx, sids.DriveID)
require.NoError(t, err, clues.ToCore(err))
sids.DriveRootFolderID = ptr.Val(siteDriveRootFolder.GetId())
its.site = sids
// group
gids := ids{}
// use of the TeamID is intentional here, so that we are assured
// the group has full usage of the teams api.
gids.ID = tconfig.M365TeamID(t)
its.group = gids
// team
tids := ids{}
tids.ID = tconfig.M365TeamID(t)
its.team = tids
return its
}
type dependencies struct {
st storage.Storage
repo repository.Repository
vpr *viper.Viper
recorder strings.Builder
configFilePath string
}
func prepM365Test(
t *testing.T,
ctx context.Context, //revive:disable-line:context-as-argument
) dependencies {
var (
acct = tconfig.NewM365Account(t)
st = testdata.NewPrefixedS3Storage(t)
recorder = strings.Builder{}
)
cfg, err := st.S3Config()
require.NoError(t, err, clues.ToCore(err))
force := map[string]string{
tconfig.TestCfgAccountProvider: "M365",
tconfig.TestCfgStorageProvider: "S3",
tconfig.TestCfgPrefix: cfg.Prefix,
}
vpr, cfgFP := tconfig.MakeTempTestConfigClone(t, force)
ctx = config.SetViper(ctx, vpr)
repo, err := repository.Initialize(
ctx,
acct,
st,
control.DefaultOptions(),
ctrlRepo.Retention{})
require.NoError(t, err, clues.ToCore(err))
return dependencies{
st: st,
repo: repo,
vpr: vpr,
recorder: recorder,
configFilePath: cfgFP,
}
}
// ---------------------------------------------------------------------------
// funcs
// ---------------------------------------------------------------------------
func buildExchangeBackupCmd(
ctx context.Context,
configFile, user, category string,
recorder *strings.Builder,
) (*cobra.Command, context.Context) {
cmd := cliTD.StubRootCmd(
"backup", "create", "exchange",
"--config-file", configFile,
"--"+flags.UserFN, user,
"--"+flags.CategoryDataFN, category)
cli.BuildCommandTree(cmd)
cmd.SetOut(recorder)
return cmd, print.SetRootCmd(ctx, cmd)
}

View File

@ -7,7 +7,6 @@ import (
"github.com/alcionai/clues" "github.com/alcionai/clues"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
@ -21,11 +20,8 @@ import (
"github.com/alcionai/corso/src/internal/operations" "github.com/alcionai/corso/src/internal/operations"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/internal/tester/tconfig" "github.com/alcionai/corso/src/internal/tester/tconfig"
"github.com/alcionai/corso/src/pkg/account"
"github.com/alcionai/corso/src/pkg/repository"
"github.com/alcionai/corso/src/pkg/selectors" "github.com/alcionai/corso/src/pkg/selectors"
selTD "github.com/alcionai/corso/src/pkg/selectors/testdata" selTD "github.com/alcionai/corso/src/pkg/selectors/testdata"
"github.com/alcionai/corso/src/pkg/storage"
storeTD "github.com/alcionai/corso/src/pkg/storage/testdata" storeTD "github.com/alcionai/corso/src/pkg/storage/testdata"
) )
@ -35,13 +31,7 @@ import (
type NoBackupOneDriveE2ESuite struct { type NoBackupOneDriveE2ESuite struct {
tester.Suite tester.Suite
acct account.Account dpnd dependencies
st storage.Storage
vpr *viper.Viper
cfgFP string
repo repository.Repository
m365UserID string
recorder strings.Builder
} }
func TestNoBackupOneDriveE2ESuite(t *testing.T) { func TestNoBackupOneDriveE2ESuite(t *testing.T) {
@ -58,33 +48,25 @@ func (suite *NoBackupOneDriveE2ESuite) SetupSuite() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
acct, st, repo, vpr, recorder, cfgFilePath := prepM365Test(t, ctx) suite.dpnd = prepM365Test(t, ctx)
suite.acct = acct
suite.st = st
suite.repo = repo
suite.recorder = recorder
suite.vpr = vpr
suite.cfgFP = cfgFilePath
suite.m365UserID = tconfig.M365UserID(t)
} }
func (suite *NoBackupOneDriveE2ESuite) TestOneDriveBackupListCmd_empty() { func (suite *NoBackupOneDriveE2ESuite) TestOneDriveBackupListCmd_empty() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush() defer flush()
suite.recorder.Reset() suite.dpnd.recorder.Reset()
cmd := cliTD.StubRootCmd( cmd := cliTD.StubRootCmd(
"backup", "list", "onedrive", "backup", "list", "onedrive",
"--config-file", suite.cfgFP) "--config-file", suite.dpnd.configFilePath)
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
cmd.SetErr(&suite.recorder) cmd.SetErr(&suite.dpnd.recorder)
ctx = print.SetRootCmd(ctx, cmd) ctx = print.SetRootCmd(ctx, cmd)
@ -92,13 +74,13 @@ func (suite *NoBackupOneDriveE2ESuite) TestOneDriveBackupListCmd_empty() {
err := cmd.ExecuteContext(ctx) err := cmd.ExecuteContext(ctx)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
result := suite.recorder.String() result := suite.dpnd.recorder.String()
// as an offhand check: the result should contain the m365 user id // as an offhand check: the result should contain the m365 user id
assert.True(t, strings.HasSuffix(result, "No backups available\n")) assert.True(t, strings.HasSuffix(result, "No backups available\n"))
} }
func (suite *NoBackupOneDriveE2ESuite) TestOneDriveBackupCmd_UserNotInTenant() { func (suite *NoBackupOneDriveE2ESuite) TestOneDriveBackupCmd_userNotInTenant() {
recorder := strings.Builder{} recorder := strings.Builder{}
t := suite.T() t := suite.T()
@ -106,11 +88,11 @@ func (suite *NoBackupOneDriveE2ESuite) TestOneDriveBackupCmd_UserNotInTenant() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
cmd := cliTD.StubRootCmd( cmd := cliTD.StubRootCmd(
"backup", "create", "onedrive", "backup", "create", "onedrive",
"--config-file", suite.cfgFP, "--config-file", suite.dpnd.configFilePath,
"--"+flags.UserFN, "foo@nothere.com") "--"+flags.UserFN, "foo@nothere.com")
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
@ -139,13 +121,8 @@ func (suite *NoBackupOneDriveE2ESuite) TestOneDriveBackupCmd_UserNotInTenant() {
type BackupDeleteOneDriveE2ESuite struct { type BackupDeleteOneDriveE2ESuite struct {
tester.Suite tester.Suite
acct account.Account dpnd dependencies
st storage.Storage
vpr *viper.Viper
cfgFP string
repo repository.Repository
backupOp operations.BackupOperation backupOp operations.BackupOperation
recorder strings.Builder
} }
func TestBackupDeleteOneDriveE2ESuite(t *testing.T) { func TestBackupDeleteOneDriveE2ESuite(t *testing.T) {
@ -162,14 +139,7 @@ func (suite *BackupDeleteOneDriveE2ESuite) SetupSuite() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
acct, st, repo, vpr, recorder, cfgFilePath := prepM365Test(t, ctx) suite.dpnd = prepM365Test(t, ctx)
suite.acct = acct
suite.st = st
suite.repo = repo
suite.recorder = recorder
suite.vpr = vpr
suite.cfgFP = cfgFilePath
var ( var (
m365UserID = tconfig.M365UserID(t) m365UserID = tconfig.M365UserID(t)
@ -181,7 +151,7 @@ func (suite *BackupDeleteOneDriveE2ESuite) SetupSuite() {
sel := selectors.NewOneDriveBackup(users) sel := selectors.NewOneDriveBackup(users)
sel.Include(selTD.OneDriveBackupFolderScope(sel)) sel.Include(selTD.OneDriveBackupFolderScope(sel))
backupOp, err := suite.repo.NewBackupWithLookup(ctx, sel.Selector, ins) backupOp, err := suite.dpnd.repo.NewBackupWithLookup(ctx, sel.Selector, ins)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
suite.backupOp = backupOp suite.backupOp = backupOp
@ -194,18 +164,18 @@ func (suite *BackupDeleteOneDriveE2ESuite) TestOneDriveBackupDeleteCmd() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush() defer flush()
suite.recorder.Reset() suite.dpnd.recorder.Reset()
cmd := cliTD.StubRootCmd( cmd := cliTD.StubRootCmd(
"backup", "delete", "onedrive", "backup", "delete", "onedrive",
"--config-file", suite.cfgFP, "--config-file", suite.dpnd.configFilePath,
"--"+flags.BackupFN, string(suite.backupOp.Results.BackupID)) "--"+flags.BackupFN, string(suite.backupOp.Results.BackupID))
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
cmd.SetErr(&suite.recorder) cmd.SetErr(&suite.dpnd.recorder)
ctx = print.SetRootCmd(ctx, cmd) ctx = print.SetRootCmd(ctx, cmd)
@ -213,7 +183,7 @@ func (suite *BackupDeleteOneDriveE2ESuite) TestOneDriveBackupDeleteCmd() {
err := cmd.ExecuteContext(ctx) err := cmd.ExecuteContext(ctx)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
result := suite.recorder.String() result := suite.dpnd.recorder.String()
assert.True(t, assert.True(t,
strings.HasSuffix( strings.HasSuffix(
result, result,
@ -224,7 +194,7 @@ func (suite *BackupDeleteOneDriveE2ESuite) TestOneDriveBackupDeleteCmd() {
// a follow-up details call should fail, due to the backup ID being deleted // a follow-up details call should fail, due to the backup ID being deleted
cmd = cliTD.StubRootCmd( cmd = cliTD.StubRootCmd(
"backup", "details", "onedrive", "backup", "details", "onedrive",
"--config-file", suite.cfgFP, "--config-file", suite.dpnd.configFilePath,
"--backup", string(suite.backupOp.Results.BackupID)) "--backup", string(suite.backupOp.Results.BackupID))
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
@ -236,13 +206,13 @@ func (suite *BackupDeleteOneDriveE2ESuite) TestOneDriveBackupDeleteCmd_unknownID
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush() defer flush()
cmd := cliTD.StubRootCmd( cmd := cliTD.StubRootCmd(
"backup", "delete", "onedrive", "backup", "delete", "onedrive",
"--config-file", suite.cfgFP, "--config-file", suite.dpnd.configFilePath,
"--"+flags.BackupFN, uuid.NewString()) "--"+flags.BackupFN, uuid.NewString())
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)

View File

@ -7,7 +7,6 @@ import (
"github.com/alcionai/clues" "github.com/alcionai/clues"
"github.com/google/uuid" "github.com/google/uuid"
"github.com/spf13/viper"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
@ -21,11 +20,8 @@ import (
"github.com/alcionai/corso/src/internal/operations" "github.com/alcionai/corso/src/internal/operations"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/internal/tester/tconfig" "github.com/alcionai/corso/src/internal/tester/tconfig"
"github.com/alcionai/corso/src/pkg/account"
"github.com/alcionai/corso/src/pkg/repository"
"github.com/alcionai/corso/src/pkg/selectors" "github.com/alcionai/corso/src/pkg/selectors"
"github.com/alcionai/corso/src/pkg/selectors/testdata" "github.com/alcionai/corso/src/pkg/selectors/testdata"
"github.com/alcionai/corso/src/pkg/storage"
storeTD "github.com/alcionai/corso/src/pkg/storage/testdata" storeTD "github.com/alcionai/corso/src/pkg/storage/testdata"
) )
@ -35,13 +31,7 @@ import (
type NoBackupSharePointE2ESuite struct { type NoBackupSharePointE2ESuite struct {
tester.Suite tester.Suite
acct account.Account dpnd dependencies
st storage.Storage
vpr *viper.Viper
cfgFP string
repo repository.Repository
m365SiteID string
recorder strings.Builder
} }
func TestNoBackupSharePointE2ESuite(t *testing.T) { func TestNoBackupSharePointE2ESuite(t *testing.T) {
@ -57,33 +47,25 @@ func (suite *NoBackupSharePointE2ESuite) SetupSuite() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
acct, st, repo, vpr, recorder, cfgFilePath := prepM365Test(t, ctx) suite.dpnd = prepM365Test(t, ctx)
suite.acct = acct
suite.st = st
suite.repo = repo
suite.vpr = vpr
suite.recorder = recorder
suite.cfgFP = cfgFilePath
suite.m365SiteID = tconfig.M365SiteID(t)
} }
func (suite *NoBackupSharePointE2ESuite) TestSharePointBackupListCmd_empty() { func (suite *NoBackupSharePointE2ESuite) TestSharePointBackupListCmd_empty() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush() defer flush()
suite.recorder.Reset() suite.dpnd.recorder.Reset()
cmd := cliTD.StubRootCmd( cmd := cliTD.StubRootCmd(
"backup", "list", "sharepoint", "backup", "list", "sharepoint",
"--config-file", suite.cfgFP) "--config-file", suite.dpnd.configFilePath)
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
cmd.SetErr(&suite.recorder) cmd.SetErr(&suite.dpnd.recorder)
ctx = print.SetRootCmd(ctx, cmd) ctx = print.SetRootCmd(ctx, cmd)
@ -91,7 +73,7 @@ func (suite *NoBackupSharePointE2ESuite) TestSharePointBackupListCmd_empty() {
err := cmd.ExecuteContext(ctx) err := cmd.ExecuteContext(ctx)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
result := suite.recorder.String() result := suite.dpnd.recorder.String()
// as an offhand check: the result should contain the m365 sitet id // as an offhand check: the result should contain the m365 sitet id
assert.True(t, strings.HasSuffix(result, "No backups available\n")) assert.True(t, strings.HasSuffix(result, "No backups available\n"))
@ -103,13 +85,8 @@ func (suite *NoBackupSharePointE2ESuite) TestSharePointBackupListCmd_empty() {
type BackupDeleteSharePointE2ESuite struct { type BackupDeleteSharePointE2ESuite struct {
tester.Suite tester.Suite
acct account.Account dpnd dependencies
st storage.Storage
vpr *viper.Viper
cfgFP string
repo repository.Repository
backupOp operations.BackupOperation backupOp operations.BackupOperation
recorder strings.Builder
} }
func TestBackupDeleteSharePointE2ESuite(t *testing.T) { func TestBackupDeleteSharePointE2ESuite(t *testing.T) {
@ -126,14 +103,7 @@ func (suite *BackupDeleteSharePointE2ESuite) SetupSuite() {
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
acct, st, repo, vpr, recorder, cfgFilePath := prepM365Test(t, ctx) suite.dpnd = prepM365Test(t, ctx)
suite.acct = acct
suite.st = st
suite.repo = repo
suite.vpr = vpr
suite.recorder = recorder
suite.cfgFP = cfgFilePath
var ( var (
m365SiteID = tconfig.M365SiteID(t) m365SiteID = tconfig.M365SiteID(t)
@ -145,7 +115,7 @@ func (suite *BackupDeleteSharePointE2ESuite) SetupSuite() {
sel := selectors.NewSharePointBackup(sites) sel := selectors.NewSharePointBackup(sites)
sel.Include(testdata.SharePointBackupFolderScope(sel)) sel.Include(testdata.SharePointBackupFolderScope(sel))
backupOp, err := suite.repo.NewBackupWithLookup(ctx, sel.Selector, ins) backupOp, err := suite.dpnd.repo.NewBackupWithLookup(ctx, sel.Selector, ins)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
suite.backupOp = backupOp suite.backupOp = backupOp
@ -158,18 +128,18 @@ func (suite *BackupDeleteSharePointE2ESuite) TestSharePointBackupDeleteCmd() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush() defer flush()
suite.recorder.Reset() suite.dpnd.recorder.Reset()
cmd := cliTD.StubRootCmd( cmd := cliTD.StubRootCmd(
"backup", "delete", "sharepoint", "backup", "delete", "sharepoint",
"--config-file", suite.cfgFP, "--config-file", suite.dpnd.configFilePath,
"--"+flags.BackupFN, string(suite.backupOp.Results.BackupID)) "--"+flags.BackupFN, string(suite.backupOp.Results.BackupID))
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)
cmd.SetErr(&suite.recorder) cmd.SetErr(&suite.dpnd.recorder)
ctx = print.SetRootCmd(ctx, cmd) ctx = print.SetRootCmd(ctx, cmd)
@ -177,7 +147,7 @@ func (suite *BackupDeleteSharePointE2ESuite) TestSharePointBackupDeleteCmd() {
err := cmd.ExecuteContext(ctx) err := cmd.ExecuteContext(ctx)
require.NoError(t, err, clues.ToCore(err)) require.NoError(t, err, clues.ToCore(err))
result := suite.recorder.String() result := suite.dpnd.recorder.String()
assert.True(t, assert.True(t,
strings.HasSuffix( strings.HasSuffix(
result, result,
@ -201,13 +171,13 @@ func (suite *BackupDeleteSharePointE2ESuite) TestSharePointBackupDeleteCmd_unkno
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.dpnd.vpr)
defer flush() defer flush()
cmd := cliTD.StubRootCmd( cmd := cliTD.StubRootCmd(
"backup", "delete", "sharepoint", "backup", "delete", "sharepoint",
"--config-file", suite.cfgFP, "--config-file", suite.dpnd.configFilePath,
"--"+flags.BackupFN, uuid.NewString()) "--"+flags.BackupFN, uuid.NewString())
cli.BuildCommandTree(cmd) cli.BuildCommandTree(cmd)

View File

@ -0,0 +1,136 @@
package test_test
import (
"testing"
"github.com/stretchr/testify/suite"
evmock "github.com/alcionai/corso/src/internal/events/mock"
"github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/internal/tester/tconfig"
"github.com/alcionai/corso/src/internal/version"
deeTD "github.com/alcionai/corso/src/pkg/backup/details/testdata"
"github.com/alcionai/corso/src/pkg/control"
"github.com/alcionai/corso/src/pkg/path"
"github.com/alcionai/corso/src/pkg/selectors"
selTD "github.com/alcionai/corso/src/pkg/selectors/testdata"
storeTD "github.com/alcionai/corso/src/pkg/storage/testdata"
)
type GroupsBackupIntgSuite struct {
tester.Suite
its intgTesterSetup
}
func TestGroupsBackupIntgSuite(t *testing.T) {
t.Skip("enable when groups e2e v0 backup is complete")
suite.Run(t, &GroupsBackupIntgSuite{
Suite: tester.NewIntegrationSuite(
t,
[][]string{tconfig.M365AcctCredEnvs, storeTD.AWSStorageCredEnvs}),
})
}
func (suite *GroupsBackupIntgSuite) SetupSuite() {
suite.its = newIntegrationTesterSetup(suite.T())
}
// TODO(v1 backup): Incremental backup
// TODO(v0,v1 restore): Library restore
// TODO(v0 export): Channels export
func (suite *GroupsBackupIntgSuite) TestBackup_Run_groupsBasic() {
t := suite.T()
ctx, flush := tester.NewContext(t)
defer flush()
var (
mb = evmock.NewBus()
sel = selectors.NewGroupsBackup([]string{suite.its.site.ID})
opts = control.DefaultOptions()
)
sel.Include(
selTD.GroupsBackupLibraryFolderScope(sel),
selTD.GroupsBackupChannelScope(sel))
bo, bod := prepNewTestBackupOp(t, ctx, mb, sel.Selector, opts, version.Backup)
defer bod.close(t, ctx)
runAndCheckBackup(t, ctx, &bo, mb, false)
checkBackupIsInManifests(
t,
ctx,
bod.kw,
bod.sw,
&bo,
bod.sel,
bod.sel.ID(),
path.LibrariesCategory)
}
func (suite *GroupsBackupIntgSuite) TestBackup_Run_groupsExtensions() {
t := suite.T()
ctx, flush := tester.NewContext(t)
defer flush()
var (
mb = evmock.NewBus()
sel = selectors.NewGroupsBackup([]string{suite.its.site.ID})
opts = control.DefaultOptions()
tenID = tconfig.M365TenantID(t)
svc = path.GroupsService
ws = deeTD.DriveIDFromRepoRef
)
opts.ItemExtensionFactory = getTestExtensionFactories()
// does not apply to channel messages
sel.Include(selTD.GroupsBackupLibraryFolderScope(sel))
bo, bod := prepNewTestBackupOp(t, ctx, mb, sel.Selector, opts, version.Backup)
defer bod.close(t, ctx)
runAndCheckBackup(t, ctx, &bo, mb, false)
checkBackupIsInManifests(
t,
ctx,
bod.kw,
bod.sw,
&bo,
bod.sel,
bod.sel.ID(),
path.LibrariesCategory)
bID := bo.Results.BackupID
deets, expectDeets := deeTD.GetDeetsInBackup(
t,
ctx,
bID,
tenID,
bod.sel.ID(),
svc,
ws,
bod.kms,
bod.sss)
deeTD.CheckBackupDetails(
t,
ctx,
bID,
ws,
bod.kms,
bod.sss,
expectDeets,
false)
// Check that the extensions are in the backup
for _, ent := range deets.Entries {
if ent.Folder == nil {
verifyExtensionData(t, ent.ItemInfo, path.GroupsService)
}
}
}

View File

@ -582,6 +582,7 @@ type intgTesterSetup struct {
secondaryUser ids secondaryUser ids
site ids site ids
secondarySite ids secondarySite ids
group ids
} }
func newIntegrationTesterSetup(t *testing.T) intgTesterSetup { func newIntegrationTesterSetup(t *testing.T) intgTesterSetup {
@ -606,6 +607,9 @@ func newIntegrationTesterSetup(t *testing.T) intgTesterSetup {
its.secondaryUser = userIDs(t, tconfig.SecondaryM365UserID(t), its.ac) its.secondaryUser = userIDs(t, tconfig.SecondaryM365UserID(t), its.ac)
its.site = siteIDs(t, tconfig.M365SiteID(t), its.ac) its.site = siteIDs(t, tconfig.M365SiteID(t), its.ac)
its.secondarySite = siteIDs(t, tconfig.SecondaryM365SiteID(t), its.ac) its.secondarySite = siteIDs(t, tconfig.SecondaryM365SiteID(t), its.ac)
// teamID is used here intentionally. We want the group
// to have access to teams data
its.group = groupIDs(t, tconfig.M365TeamID(t), its.ac)
return its return its
} }
@ -648,6 +652,26 @@ func siteIDs(t *testing.T, id string, ac api.Client) ids {
return r return r
} }
func groupIDs(t *testing.T, id string, ac api.Client) ids {
r := ids{ID: id}
// ctx, flush := tester.NewContext(t)
// defer flush()
// TODO: get default site drive info
// drive, err := ac.Groups().GetDefaultDrive(ctx, id)
// require.NoError(t, err, clues.ToCore(err))
// r.DriveID = ptr.Val(drive.GetId())
// driveRootFolder, err := ac.Drives().GetRootFolder(ctx, r.DriveID)
// require.NoError(t, err, clues.ToCore(err))
// r.DriveRootFolderID = ptr.Val(driveRootFolder.GetId())
return r
}
func getTestExtensionFactories() []extensions.CreateItemExtensioner { func getTestExtensionFactories() []extensions.CreateItemExtensioner {
return []extensions.CreateItemExtensioner{ return []extensions.CreateItemExtensioner{
&extensions.MockItemExtensionFactory{}, &extensions.MockItemExtensionFactory{},

19
src/pkg/selectors/testdata/groups.go vendored Normal file
View File

@ -0,0 +1,19 @@
package testdata
import (
"github.com/alcionai/corso/src/pkg/selectors"
)
const TestChannelName = "test"
// GroupsBackupFolderScope is the standard folder scope that should be used
// in integration backups with groups when interacting with libraries.
func GroupsBackupLibraryFolderScope(sel *selectors.GroupsBackup) []selectors.GroupsScope {
return sel.LibraryFolders([]string{TestFolderName}, selectors.PrefixMatch())
}
// GroupsBackupChannelScope is the standard folder scope that should be used
// in integration backups with groups when interacting with channels.
func GroupsBackupChannelScope(sel *selectors.GroupsBackup) []selectors.GroupsScope {
return sel.Channel(TestChannelName)
}

View File

@ -47,6 +47,7 @@ func (suite *ChannelPagerIntgSuite) SetupSuite() {
func (suite *ChannelPagerIntgSuite) TestChannels_Get() { func (suite *ChannelPagerIntgSuite) TestChannels_Get() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext(t) ctx, flush := tester.NewContext(t)
defer flush() defer flush()
var ( var (