Compare commits

...

4 Commits

Author SHA1 Message Date
ryanfkeepers
bdbc85fa42 move operations tests to e2e suite 2023-02-24 14:55:49 -07:00
ryanfkeepers
f07c4e407a remove unused test scoping envs 2023-02-24 14:44:45 -07:00
ryanfkeepers
a7cfc6cd5c switch cli to e2e test suits 2023-02-24 14:15:16 -07:00
ryanfkeepers
2703428e44 add e2e test sutie 2023-02-24 14:04:42 -07:00
34 changed files with 534 additions and 492 deletions

View File

@ -38,7 +38,7 @@ var backupDataSets = []path.CategoryType{email, contacts, events}
// tests with no backups // tests with no backups
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type NoBackupExchangeIntegrationSuite struct { type NoBackupExchangeE2ESuite struct {
tester.Suite tester.Suite
acct account.Account acct account.Account
st storage.Storage st storage.Storage
@ -49,15 +49,15 @@ type NoBackupExchangeIntegrationSuite struct {
recorder strings.Builder recorder strings.Builder
} }
func TestNoBackupExchangeIntegrationSuite(t *testing.T) { func TestNoBackupExchangeE2ESuite(t *testing.T) {
suite.Run(t, &NoBackupExchangeIntegrationSuite{Suite: tester.NewIntegrationSuite( suite.Run(t, &NoBackupExchangeE2ESuite{Suite: tester.NewE2ESuite(
t, t,
[][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs}, [][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs},
tester.CorsoCLITests, tester.CorsoCITests,
tester.CorsoCLIBackupTests)}) )})
} }
func (suite *NoBackupExchangeIntegrationSuite) SetupSuite() { func (suite *NoBackupExchangeE2ESuite) SetupSuite() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
@ -87,7 +87,7 @@ func (suite *NoBackupExchangeIntegrationSuite) SetupSuite() {
require.NoError(t, err) require.NoError(t, err)
} }
func (suite *NoBackupExchangeIntegrationSuite) TestExchangeBackupListCmd_empty() { func (suite *NoBackupExchangeE2ESuite) TestExchangeBackupListCmd_empty() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.vpr)
@ -118,7 +118,7 @@ func (suite *NoBackupExchangeIntegrationSuite) TestExchangeBackupListCmd_empty()
// tests with no prior backup // tests with no prior backup
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type BackupExchangeIntegrationSuite struct { type BackupExchangeE2ESuite struct {
tester.Suite tester.Suite
acct account.Account acct account.Account
st storage.Storage st storage.Storage
@ -128,15 +128,15 @@ type BackupExchangeIntegrationSuite struct {
m365UserID string m365UserID string
} }
func TestBackupExchangeIntegrationSuite(t *testing.T) { func TestBackupExchangeE2ESuite(t *testing.T) {
suite.Run(t, &BackupExchangeIntegrationSuite{Suite: tester.NewIntegrationSuite( suite.Run(t, &BackupExchangeE2ESuite{Suite: tester.NewE2ESuite(
t, t,
[][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs}, [][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs},
tester.CorsoCLITests, tester.CorsoCITests,
tester.CorsoCLIBackupTests)}) )})
} }
func (suite *BackupExchangeIntegrationSuite) SetupSuite() { func (suite *BackupExchangeE2ESuite) SetupSuite() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
@ -165,7 +165,7 @@ func (suite *BackupExchangeIntegrationSuite) SetupSuite() {
require.NoError(t, err) require.NoError(t, err)
} }
func (suite *BackupExchangeIntegrationSuite) TestExchangeBackupCmd() { func (suite *BackupExchangeE2ESuite) TestExchangeBackupCmd() {
recorder := strings.Builder{} recorder := strings.Builder{}
for _, set := range backupDataSets { for _, set := range backupDataSets {
@ -205,7 +205,7 @@ func (suite *BackupExchangeIntegrationSuite) TestExchangeBackupCmd() {
// tests prepared with a previous backup // tests prepared with a previous backup
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type PreparedBackupExchangeIntegrationSuite struct { type PreparedBackupExchangeE2ESuite struct {
tester.Suite tester.Suite
acct account.Account acct account.Account
st storage.Storage st storage.Storage
@ -217,15 +217,15 @@ type PreparedBackupExchangeIntegrationSuite struct {
recorder strings.Builder recorder strings.Builder
} }
func TestPreparedBackupExchangeIntegrationSuite(t *testing.T) { func TestPreparedBackupExchangeE2ESuite(t *testing.T) {
suite.Run(t, &PreparedBackupExchangeIntegrationSuite{Suite: tester.NewIntegrationSuite( suite.Run(t, &PreparedBackupExchangeE2ESuite{Suite: tester.NewE2ESuite(
t, t,
[][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs}, [][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs},
tester.CorsoCLITests, tester.CorsoCITests,
tester.CorsoCLIBackupTests)}) )})
} }
func (suite *PreparedBackupExchangeIntegrationSuite) SetupSuite() { func (suite *PreparedBackupExchangeE2ESuite) SetupSuite() {
t := suite.T() t := suite.T()
// prepare common details // prepare common details
@ -296,7 +296,7 @@ func (suite *PreparedBackupExchangeIntegrationSuite) SetupSuite() {
} }
} }
func (suite *PreparedBackupExchangeIntegrationSuite) TestExchangeListCmd() { func (suite *PreparedBackupExchangeE2ESuite) TestExchangeListCmd() {
for _, set := range backupDataSets { for _, set := range backupDataSets {
suite.recorder.Reset() suite.recorder.Reset()
@ -326,7 +326,7 @@ func (suite *PreparedBackupExchangeIntegrationSuite) TestExchangeListCmd() {
} }
} }
func (suite *PreparedBackupExchangeIntegrationSuite) TestExchangeListCmd_singleID() { func (suite *PreparedBackupExchangeE2ESuite) TestExchangeListCmd_singleID() {
for _, set := range backupDataSets { for _, set := range backupDataSets {
suite.recorder.Reset() suite.recorder.Reset()
@ -359,7 +359,7 @@ func (suite *PreparedBackupExchangeIntegrationSuite) TestExchangeListCmd_singleI
} }
} }
func (suite *PreparedBackupExchangeIntegrationSuite) TestExchangeListCmd_badID() { func (suite *PreparedBackupExchangeE2ESuite) TestExchangeListCmd_badID() {
for _, set := range backupDataSets { for _, set := range backupDataSets {
suite.Run(set.String(), func() { suite.Run(set.String(), func() {
t := suite.T() t := suite.T()
@ -382,7 +382,7 @@ func (suite *PreparedBackupExchangeIntegrationSuite) TestExchangeListCmd_badID()
} }
} }
func (suite *PreparedBackupExchangeIntegrationSuite) TestExchangeDetailsCmd() { func (suite *PreparedBackupExchangeE2ESuite) TestExchangeDetailsCmd() {
for _, set := range backupDataSets { for _, set := range backupDataSets {
suite.recorder.Reset() suite.recorder.Reset()
@ -443,7 +443,7 @@ func (suite *PreparedBackupExchangeIntegrationSuite) TestExchangeDetailsCmd() {
// tests for deleting backups // tests for deleting backups
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type BackupDeleteExchangeIntegrationSuite struct { type BackupDeleteExchangeE2ESuite struct {
tester.Suite tester.Suite
acct account.Account acct account.Account
st storage.Storage st storage.Storage
@ -453,17 +453,17 @@ type BackupDeleteExchangeIntegrationSuite struct {
backupOp operations.BackupOperation backupOp operations.BackupOperation
} }
func TestBackupDeleteExchangeIntegrationSuite(t *testing.T) { func TestBackupDeleteExchangeE2ESuite(t *testing.T) {
suite.Run(t, &BackupDeleteExchangeIntegrationSuite{ suite.Run(t, &BackupDeleteExchangeE2ESuite{
Suite: tester.NewIntegrationSuite( Suite: tester.NewE2ESuite(
t, t,
[][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs}, [][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs},
tester.CorsoCLITests, tester.CorsoCITests,
tester.CorsoCLIBackupTests), ),
}) })
} }
func (suite *BackupDeleteExchangeIntegrationSuite) SetupSuite() { func (suite *BackupDeleteExchangeE2ESuite) SetupSuite() {
t := suite.T() t := suite.T()
// prepare common details // prepare common details
@ -501,7 +501,7 @@ func (suite *BackupDeleteExchangeIntegrationSuite) SetupSuite() {
require.NoError(t, err) require.NoError(t, err)
} }
func (suite *BackupDeleteExchangeIntegrationSuite) TestExchangeBackupDeleteCmd() { func (suite *BackupDeleteExchangeE2ESuite) TestExchangeBackupDeleteCmd() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.vpr)
@ -527,7 +527,7 @@ func (suite *BackupDeleteExchangeIntegrationSuite) TestExchangeBackupDeleteCmd()
require.Error(t, cmd.ExecuteContext(ctx)) require.Error(t, cmd.ExecuteContext(ctx))
} }
func (suite *BackupDeleteExchangeIntegrationSuite) TestExchangeBackupDeleteCmd_UnknownID() { func (suite *BackupDeleteExchangeE2ESuite) TestExchangeBackupDeleteCmd_UnknownID() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.vpr)

View File

@ -28,7 +28,7 @@ import (
// tests with no prior backup // tests with no prior backup
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type NoBackupOneDriveIntegrationSuite struct { type NoBackupOneDriveE2ESuite struct {
tester.Suite tester.Suite
acct account.Account acct account.Account
st storage.Storage st storage.Storage
@ -39,17 +39,17 @@ type NoBackupOneDriveIntegrationSuite struct {
recorder strings.Builder recorder strings.Builder
} }
func TestNoBackupOneDriveIntegrationSuite(t *testing.T) { func TestNoBackupOneDriveE2ESuite(t *testing.T) {
suite.Run(t, &NoBackupOneDriveIntegrationSuite{ suite.Run(t, &NoBackupOneDriveE2ESuite{
Suite: tester.NewIntegrationSuite( Suite: tester.NewE2ESuite(
t, t,
[][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs}, [][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs},
tester.CorsoCLITests, tester.CorsoCITests,
tester.CorsoCLIBackupTests), ),
}) })
} }
func (suite *NoBackupOneDriveIntegrationSuite) SetupSuite() { func (suite *NoBackupOneDriveE2ESuite) SetupSuite() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
@ -84,7 +84,7 @@ func (suite *NoBackupOneDriveIntegrationSuite) SetupSuite() {
require.NoError(t, err) require.NoError(t, err)
} }
func (suite *NoBackupOneDriveIntegrationSuite) TestOneDriveBackupListCmd_empty() { func (suite *NoBackupOneDriveE2ESuite) TestOneDriveBackupListCmd_empty() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.vpr)
@ -115,7 +115,7 @@ func (suite *NoBackupOneDriveIntegrationSuite) TestOneDriveBackupListCmd_empty()
// tests for deleting backups // tests for deleting backups
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type BackupDeleteOneDriveIntegrationSuite struct { type BackupDeleteOneDriveE2ESuite struct {
tester.Suite tester.Suite
acct account.Account acct account.Account
st storage.Storage st storage.Storage
@ -126,17 +126,17 @@ type BackupDeleteOneDriveIntegrationSuite struct {
recorder strings.Builder recorder strings.Builder
} }
func TestBackupDeleteOneDriveIntegrationSuite(t *testing.T) { func TestBackupDeleteOneDriveE2ESuite(t *testing.T) {
suite.Run(t, &BackupDeleteOneDriveIntegrationSuite{ suite.Run(t, &BackupDeleteOneDriveE2ESuite{
Suite: tester.NewIntegrationSuite( Suite: tester.NewE2ESuite(
t, t,
[][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs}, [][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs},
tester.CorsoCLITests, tester.CorsoCITests,
tester.CorsoCLIBackupTests), ),
}) })
} }
func (suite *BackupDeleteOneDriveIntegrationSuite) SetupSuite() { func (suite *BackupDeleteOneDriveE2ESuite) SetupSuite() {
t := suite.T() t := suite.T()
// prepare common details // prepare common details
@ -180,7 +180,7 @@ func (suite *BackupDeleteOneDriveIntegrationSuite) SetupSuite() {
require.NoError(t, err) require.NoError(t, err)
} }
func (suite *BackupDeleteOneDriveIntegrationSuite) TestOneDriveBackupDeleteCmd() { func (suite *BackupDeleteOneDriveE2ESuite) TestOneDriveBackupDeleteCmd() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.vpr)
@ -215,7 +215,7 @@ func (suite *BackupDeleteOneDriveIntegrationSuite) TestOneDriveBackupDeleteCmd()
require.Error(t, cmd.ExecuteContext(ctx)) require.Error(t, cmd.ExecuteContext(ctx))
} }
func (suite *BackupDeleteOneDriveIntegrationSuite) TestOneDriveBackupDeleteCmd_unknownID() { func (suite *BackupDeleteOneDriveE2ESuite) TestOneDriveBackupDeleteCmd_unknownID() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.vpr)

View File

@ -28,7 +28,7 @@ import (
// tests with no prior backup // tests with no prior backup
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type NoBackupSharePointIntegrationSuite struct { type NoBackupSharePointE2ESuite struct {
tester.Suite tester.Suite
acct account.Account acct account.Account
st storage.Storage st storage.Storage
@ -39,14 +39,15 @@ type NoBackupSharePointIntegrationSuite struct {
recorder strings.Builder recorder strings.Builder
} }
func TestNoBackupSharePointIntegrationSuite(t *testing.T) { func TestNoBackupSharePointE2ESuite(t *testing.T) {
suite.Run(t, &NoBackupSharePointIntegrationSuite{Suite: tester.NewIntegrationSuite( suite.Run(t, &NoBackupSharePointE2ESuite{Suite: tester.NewE2ESuite(
t, t,
[][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs}, [][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs},
tester.CorsoCLITests, tester.CorsoCLIBackupTests)}) tester.CorsoCITests,
)})
} }
func (suite *NoBackupSharePointIntegrationSuite) SetupSuite() { func (suite *NoBackupSharePointE2ESuite) SetupSuite() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
@ -75,7 +76,7 @@ func (suite *NoBackupSharePointIntegrationSuite) SetupSuite() {
require.NoError(t, err) require.NoError(t, err)
} }
func (suite *NoBackupSharePointIntegrationSuite) TestSharePointBackupListCmd_empty() { func (suite *NoBackupSharePointE2ESuite) TestSharePointBackupListCmd_empty() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.vpr)
@ -106,7 +107,7 @@ func (suite *NoBackupSharePointIntegrationSuite) TestSharePointBackupListCmd_emp
// tests for deleting backups // tests for deleting backups
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type BackupDeleteSharePointIntegrationSuite struct { type BackupDeleteSharePointE2ESuite struct {
tester.Suite tester.Suite
acct account.Account acct account.Account
st storage.Storage st storage.Storage
@ -117,16 +118,17 @@ type BackupDeleteSharePointIntegrationSuite struct {
recorder strings.Builder recorder strings.Builder
} }
func TestBackupDeleteSharePointIntegrationSuite(t *testing.T) { func TestBackupDeleteSharePointE2ESuite(t *testing.T) {
suite.Run(t, &BackupDeleteSharePointIntegrationSuite{ suite.Run(t, &BackupDeleteSharePointE2ESuite{
Suite: tester.NewIntegrationSuite( Suite: tester.NewE2ESuite(
t, t,
[][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs}, [][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs},
tester.CorsoCLITests, tester.CorsoCLIBackupTests), tester.CorsoCITests,
),
}) })
} }
func (suite *BackupDeleteSharePointIntegrationSuite) SetupSuite() { func (suite *BackupDeleteSharePointE2ESuite) SetupSuite() {
t := suite.T() t := suite.T()
// prepare common details // prepare common details
@ -164,7 +166,7 @@ func (suite *BackupDeleteSharePointIntegrationSuite) SetupSuite() {
require.NoError(t, err) require.NoError(t, err)
} }
func (suite *BackupDeleteSharePointIntegrationSuite) TestSharePointBackupDeleteCmd() { func (suite *BackupDeleteSharePointE2ESuite) TestSharePointBackupDeleteCmd() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.vpr)
@ -200,7 +202,7 @@ func (suite *BackupDeleteSharePointIntegrationSuite) TestSharePointBackupDeleteC
// require.Error(t, cmd.ExecuteContext(ctx)) // require.Error(t, cmd.ExecuteContext(ctx))
func (suite *BackupDeleteSharePointIntegrationSuite) TestSharePointBackupDeleteCmd_unknownID() { func (suite *BackupDeleteSharePointE2ESuite) TestSharePointBackupDeleteCmd_unknownID() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
ctx = config.SetViper(ctx, suite.vpr) ctx = config.SetViper(ctx, suite.vpr)

View File

@ -190,7 +190,7 @@ func TestConfigIntegrationSuite(t *testing.T) {
suite.Run(t, &ConfigIntegrationSuite{Suite: tester.NewIntegrationSuite( suite.Run(t, &ConfigIntegrationSuite{Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs}, [][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs},
tester.CorsoCLIConfigTests)}) )})
} }
func (suite *ConfigIntegrationSuite) TestGetStorageAndAccount() { func (suite *ConfigIntegrationSuite) TestGetStorageAndAccount() {

View File

@ -15,19 +15,19 @@ import (
"github.com/alcionai/corso/src/pkg/repository" "github.com/alcionai/corso/src/pkg/repository"
) )
type S3IntegrationSuite struct { type S3E2ESuite struct {
tester.Suite tester.Suite
} }
func TestS3IntegrationSuite(t *testing.T) { func TestS3E2ESuite(t *testing.T) {
suite.Run(t, &S3IntegrationSuite{Suite: tester.NewIntegrationSuite( suite.Run(t, &S3E2ESuite{Suite: tester.NewE2ESuite(
t, t,
[][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs}, [][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs},
tester.CorsoCLITests, tester.CorsoCITests,
tester.CorsoCLIRepoTests)}) )})
} }
func (suite *S3IntegrationSuite) TestInitS3Cmd() { func (suite *S3E2ESuite) TestInitS3Cmd() {
table := []struct { table := []struct {
name string name string
bucketPrefix string bucketPrefix string
@ -75,7 +75,7 @@ func (suite *S3IntegrationSuite) TestInitS3Cmd() {
} }
} }
func (suite *S3IntegrationSuite) TestInitMultipleTimes() { func (suite *S3E2ESuite) TestInitMultipleTimes() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
@ -104,7 +104,7 @@ func (suite *S3IntegrationSuite) TestInitMultipleTimes() {
} }
} }
func (suite *S3IntegrationSuite) TestInitS3Cmd_missingBucket() { func (suite *S3E2ESuite) TestInitS3Cmd_missingBucket() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
@ -128,7 +128,7 @@ func (suite *S3IntegrationSuite) TestInitS3Cmd_missingBucket() {
require.Error(t, cmd.ExecuteContext(ctx)) require.Error(t, cmd.ExecuteContext(ctx))
} }
func (suite *S3IntegrationSuite) TestConnectS3Cmd() { func (suite *S3E2ESuite) TestConnectS3Cmd() {
table := []struct { table := []struct {
name string name string
bucketPrefix string bucketPrefix string
@ -182,7 +182,7 @@ func (suite *S3IntegrationSuite) TestConnectS3Cmd() {
} }
} }
func (suite *S3IntegrationSuite) TestConnectS3Cmd_BadBucket() { func (suite *S3E2ESuite) TestConnectS3Cmd_BadBucket() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
@ -207,7 +207,7 @@ func (suite *S3IntegrationSuite) TestConnectS3Cmd_BadBucket() {
require.Error(t, cmd.ExecuteContext(ctx)) require.Error(t, cmd.ExecuteContext(ctx))
} }
func (suite *S3IntegrationSuite) TestConnectS3Cmd_BadPrefix() { func (suite *S3E2ESuite) TestConnectS3Cmd_BadPrefix() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()

View File

@ -30,7 +30,7 @@ var (
var backupDataSets = []path.CategoryType{email, contacts, events} var backupDataSets = []path.CategoryType{email, contacts, events}
type RestoreExchangeIntegrationSuite struct { type RestoreExchangeE2ESuite struct {
tester.Suite tester.Suite
acct account.Account acct account.Account
st storage.Storage st storage.Storage
@ -41,17 +41,17 @@ type RestoreExchangeIntegrationSuite struct {
backupOps map[path.CategoryType]operations.BackupOperation backupOps map[path.CategoryType]operations.BackupOperation
} }
func TestRestoreExchangeIntegrationSuite(t *testing.T) { func TestRestoreExchangeE2ESuite(t *testing.T) {
suite.Run(t, &RestoreExchangeIntegrationSuite{ suite.Run(t, &RestoreExchangeE2ESuite{
Suite: tester.NewIntegrationSuite( Suite: tester.NewE2ESuite(
t, t,
[][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs}, [][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs},
tester.CorsoCLITests, tester.CorsoCITests,
tester.CorsoCLIRestoreTests), ),
}) })
} }
func (suite *RestoreExchangeIntegrationSuite) SetupSuite() { func (suite *RestoreExchangeE2ESuite) SetupSuite() {
t := suite.T() t := suite.T()
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
@ -115,7 +115,7 @@ func (suite *RestoreExchangeIntegrationSuite) SetupSuite() {
} }
} }
func (suite *RestoreExchangeIntegrationSuite) TestExchangeRestoreCmd() { func (suite *RestoreExchangeE2ESuite) TestExchangeRestoreCmd() {
for _, set := range backupDataSets { for _, set := range backupDataSets {
suite.Run(set.String(), func() { suite.Run(set.String(), func() {
t := suite.T() t := suite.T()
@ -137,7 +137,7 @@ func (suite *RestoreExchangeIntegrationSuite) TestExchangeRestoreCmd() {
} }
} }
func (suite *RestoreExchangeIntegrationSuite) TestExchangeRestoreCmd_badTimeFlags() { func (suite *RestoreExchangeE2ESuite) TestExchangeRestoreCmd_badTimeFlags() {
for _, set := range backupDataSets { for _, set := range backupDataSets {
if set == contacts { if set == contacts {
suite.T().Skip() suite.T().Skip()
@ -172,7 +172,7 @@ func (suite *RestoreExchangeIntegrationSuite) TestExchangeRestoreCmd_badTimeFlag
} }
} }
func (suite *RestoreExchangeIntegrationSuite) TestExchangeRestoreCmd_badBoolFlags() { func (suite *RestoreExchangeE2ESuite) TestExchangeRestoreCmd_badBoolFlags() {
for _, set := range backupDataSets { for _, set := range backupDataSets {
if set != events { if set != events {
suite.T().Skip() suite.T().Skip()

View File

@ -35,8 +35,7 @@ func TestConnectorDataCollectionIntegrationSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.M365AcctCredEnvs}, [][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests, ),
tester.CorsoConnectorDataCollectionTests),
}) })
} }
@ -307,8 +306,7 @@ func TestConnectorCreateSharePointCollectionIntegrationSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.M365AcctCredEnvs}, [][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests, ),
tester.CorsoConnectorCreateSharePointCollectionTests),
}) })
} }

View File

@ -26,8 +26,7 @@ func TestExchangeServiceSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.M365AcctCredEnvs}, [][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests, ),
tester.CorsoGraphConnectorExchangeTests),
}) })
} }

View File

@ -519,9 +519,7 @@ func TestFolderCacheIntegrationSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.M365AcctCredEnvs}, [][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests, ),
tester.CorsoGraphConnectorExchangeTests,
tester.CorsoConnectorExchangeFolderCacheTests),
}) })
} }

View File

@ -219,9 +219,7 @@ func TestDataCollectionsIntegrationSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.M365AcctCredEnvs}, [][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests, ),
tester.CorsoGraphConnectorExchangeTests,
tester.CorsoConnectorCreateExchangeCollectionTests),
}) })
} }

View File

@ -24,8 +24,7 @@ func TestCacheResolverIntegrationSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.M365AcctCredEnvs}, [][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests, ),
tester.CorsoGraphConnectorExchangeTests),
}) })
} }

View File

@ -36,8 +36,7 @@ func TestMailFolderCacheIntegrationSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.M365AcctCredEnvs}, [][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests, ),
tester.CorsoGraphConnectorExchangeTests),
}) })
} }

View File

@ -33,9 +33,7 @@ func TestExchangeRestoreSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.M365AcctCredEnvs}, [][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests, ),
tester.CorsoGraphConnectorExchangeTests,
tester.CorsoConnectorRestoreExchangeCollectionTests),
}) })
} }

View File

@ -19,10 +19,7 @@ type BetaClientSuite struct {
func TestBetaClientSuite(t *testing.T) { func TestBetaClientSuite(t *testing.T) {
suite.Run(t, &BetaClientSuite{ suite.Run(t, &BetaClientSuite{
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(t, [][]string{tester.M365AcctCredEnvs}),
t,
[][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests),
}) })
} }

View File

@ -96,8 +96,7 @@ func TestGraphConnectorOneDriveIntegrationSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.M365AcctCredEnvs}, [][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests, ),
tester.CorsoGraphConnectorOneDriveTests),
}) })
} }

View File

@ -151,8 +151,7 @@ func TestGraphConnectorIntegrationSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.M365AcctCredEnvs}, [][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests, ),
tester.CorsoGraphConnectorExchangeTests),
}) })
} }

View File

@ -332,8 +332,7 @@ func TestOneDriveDriveSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.M365AcctCredEnvs}, [][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests, ),
tester.CorsoGraphConnectorOneDriveTests),
}) })
} }

View File

@ -40,8 +40,7 @@ func TestItemIntegrationSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.M365AcctCredEnvs}, [][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests, ),
tester.CorsoGraphConnectorOneDriveTests),
}) })
} }

View File

@ -40,11 +40,7 @@ func (suite *SharePointPageSuite) SetupSuite() {
func TestSharePointPageSuite(t *testing.T) { func TestSharePointPageSuite(t *testing.T) {
suite.Run(t, &SharePointPageSuite{ suite.Run(t, &SharePointPageSuite{
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(t, [][]string{tester.M365AcctCredEnvs}),
t,
[][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests,
tester.CorsoGraphConnectorSharePointTests),
}) })
} }

View File

@ -46,8 +46,7 @@ func TestSharePointCollectionSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.M365AcctCredEnvs}, [][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests, ),
tester.CorsoGraphConnectorSharePointTests),
}) })
} }

View File

@ -169,8 +169,7 @@ func TestSharePointPagesSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.M365AcctCredEnvs}, [][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests, ),
tester.CorsoGraphConnectorSharePointTests),
}) })
} }

View File

@ -31,8 +31,7 @@ func TestSharePointSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.M365AcctCredEnvs}, [][]string{tester.M365AcctCredEnvs},
tester.CorsoGraphConnectorTests, ),
tester.CorsoGraphConnectorSharePointTests),
}) })
} }

View File

@ -63,7 +63,6 @@ func TestWrapperIntegrationSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.AWSStorageCredEnvs}, [][]string{tester.AWSStorageCredEnvs},
tester.CorsoKopiaWrapperTests,
), ),
}) })
} }

View File

@ -67,7 +67,6 @@ func TestModelStoreIntegrationSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.AWSStorageCredEnvs}, [][]string{tester.AWSStorageCredEnvs},
tester.CorsoModelStoreTests,
), ),
}) })
} }
@ -724,7 +723,6 @@ func TestModelStoreRegressionSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.AWSStorageCredEnvs}, [][]string{tester.AWSStorageCredEnvs},
tester.CorsoModelStoreTests,
), ),
}) })
} }

View File

@ -158,7 +158,6 @@ func TestKopiaIntegrationSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.AWSStorageCredEnvs}, [][]string{tester.AWSStorageCredEnvs},
tester.CorsoKopiaWrapperTests,
), ),
}) })
} }
@ -574,7 +573,6 @@ func TestKopiaSimpleRepoIntegrationSuite(t *testing.T) {
Suite: tester.NewIntegrationSuite( Suite: tester.NewIntegrationSuite(
t, t,
[][]string{tester.AWSStorageCredEnvs}, [][]string{tester.AWSStorageCredEnvs},
tester.CorsoKopiaWrapperTests,
), ),
}) })
} }

View File

@ -447,32 +447,30 @@ func toDataLayerPath(
} }
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// integration tests // e2e tests
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
type BackupOpIntegrationSuite struct { type BackupOpE2ESuite struct {
suite.Suite tester.Suite
user, site string user, site string
} }
func TestBackupOpIntegrationSuite(t *testing.T) { func TestBackupOpE2ESuite(t *testing.T) {
tester.RunOnAny( suite.Run(t, &BackupOpE2ESuite{
t, Suite: tester.NewE2ESuite(
tester.CorsoCITests, t,
tester.CorsoOperationTests, [][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs},
tester.CorsoOperationBackupTests) tester.CorsoCITests,
),
suite.Run(t, new(BackupOpIntegrationSuite)) })
} }
func (suite *BackupOpIntegrationSuite) SetupSuite() { func (suite *BackupOpE2ESuite) SetupSuite() {
tester.MustGetEnvSets(suite.T(), tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs)
suite.user = tester.M365UserID(suite.T()) suite.user = tester.M365UserID(suite.T())
suite.site = tester.M365SiteID(suite.T()) suite.site = tester.M365SiteID(suite.T())
} }
func (suite *BackupOpIntegrationSuite) TestNewBackupOperation() { func (suite *BackupOpE2ESuite) TestNewBackupOperation() {
kw := &kopia.Wrapper{} kw := &kopia.Wrapper{}
sw := &store.Wrapper{} sw := &store.Wrapper{}
acct := tester.NewM365Account(suite.T()) acct := tester.NewM365Account(suite.T())
@ -514,7 +512,7 @@ func (suite *BackupOpIntegrationSuite) TestNewBackupOperation() {
// TestBackup_Run ensures that Integration Testing works // TestBackup_Run ensures that Integration Testing works
// for the following scopes: Contacts, Events, and Mail // for the following scopes: Contacts, Events, and Mail
func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchange() { func (suite *BackupOpE2ESuite) TestBackup_Run_exchange() {
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
defer flush() defer flush()
@ -642,7 +640,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchange() {
// TestBackup_Run ensures that Integration Testing works // TestBackup_Run ensures that Integration Testing works
// for the following scopes: Contacts, Events, and Mail // for the following scopes: Contacts, Events, and Mail
func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchangeIncrementals() { func (suite *BackupOpE2ESuite) TestBackup_Run_exchangeIncrementals() {
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
defer flush() defer flush()
@ -1074,7 +1072,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_exchangeIncrementals() {
// OneDrive // OneDrive
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
func (suite *BackupOpIntegrationSuite) TestBackup_Run_oneDrive() { func (suite *BackupOpE2ESuite) TestBackup_Run_oneDrive() {
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
defer flush() defer flush()
@ -1097,7 +1095,7 @@ func (suite *BackupOpIntegrationSuite) TestBackup_Run_oneDrive() {
// SharePoint // SharePoint
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
func (suite *BackupOpIntegrationSuite) TestBackup_Run_sharePoint() { func (suite *BackupOpE2ESuite) TestBackup_Run_sharePoint() {
ctx, flush := tester.NewContext() ctx, flush := tester.NewContext()
defer flush() defer flush()

View File

@ -0,0 +1,236 @@
package operations
import (
"context"
"testing"
"github.com/alcionai/corso/src/internal/connector/exchange"
"github.com/alcionai/corso/src/internal/events"
evmock "github.com/alcionai/corso/src/internal/events/mock"
"github.com/alcionai/corso/src/internal/kopia"
"github.com/alcionai/corso/src/internal/model"
"github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/pkg/account"
"github.com/alcionai/corso/src/pkg/control"
"github.com/alcionai/corso/src/pkg/selectors"
"github.com/alcionai/corso/src/pkg/store"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)
type RestoreOpE2ESuite struct {
tester.Suite
backupID model.StableID
numItems int
kopiaCloser func(ctx context.Context)
kw *kopia.Wrapper
sw *store.Wrapper
ms *kopia.ModelStore
}
func TestRestoreOpE2ESuite(t *testing.T) {
suite.Run(t, &RestoreOpE2ESuite{
Suite: tester.NewE2ESuite(
t,
[][]string{tester.AWSStorageCredEnvs, tester.M365AcctCredEnvs},
tester.CorsoCITests,
),
})
}
func (suite *RestoreOpE2ESuite) SetupSuite() {
ctx, flush := tester.NewContext()
defer flush()
t := suite.T()
m365UserID := tester.M365UserID(t)
acct := tester.NewM365Account(t)
// need to initialize the repository before we can test connecting to it.
st := tester.NewPrefixedS3Storage(t)
k := kopia.NewConn(st)
require.NoError(t, k.Initialize(ctx))
suite.kopiaCloser = func(ctx context.Context) {
k.Close(ctx)
}
kw, err := kopia.NewWrapper(k)
require.NoError(t, err)
suite.kw = kw
ms, err := kopia.NewModelStore(k)
require.NoError(t, err)
suite.ms = ms
sw := store.NewKopiaStore(ms)
suite.sw = sw
users := []string{m365UserID}
bsel := selectors.NewExchangeBackup(users)
bsel.DiscreteOwner = m365UserID
bsel.Include(
bsel.MailFolders([]string{exchange.DefaultMailFolder}, selectors.PrefixMatch()),
bsel.ContactFolders([]string{exchange.DefaultContactFolder}, selectors.PrefixMatch()),
bsel.EventCalendars([]string{exchange.DefaultCalendar}, selectors.PrefixMatch()),
)
bo, err := NewBackupOperation(
ctx,
control.Options{},
kw,
sw,
acct,
bsel.Selector,
evmock.NewBus())
require.NoError(t, err)
require.NoError(t, bo.Run(ctx))
require.NotEmpty(t, bo.Results.BackupID)
suite.backupID = bo.Results.BackupID
// Discount metadata files (3 paths, 3 deltas) as
// they are not part of the data restored.
suite.numItems = bo.Results.ItemsWritten - 6
}
func (suite *RestoreOpE2ESuite) TearDownSuite() {
ctx, flush := tester.NewContext()
defer flush()
if suite.ms != nil {
suite.ms.Close(ctx)
}
if suite.kw != nil {
suite.kw.Close(ctx)
}
if suite.kopiaCloser != nil {
suite.kopiaCloser(ctx)
}
}
func (suite *RestoreOpE2ESuite) TestNewRestoreOperation() {
kw := &kopia.Wrapper{}
sw := &store.Wrapper{}
acct := tester.NewM365Account(suite.T())
dest := tester.DefaultTestRestoreDestination()
table := []struct {
name string
opts control.Options
kw *kopia.Wrapper
sw *store.Wrapper
acct account.Account
targets []string
errCheck assert.ErrorAssertionFunc
}{
{"good", control.Options{}, kw, sw, acct, nil, assert.NoError},
{"missing kopia", control.Options{}, nil, sw, acct, nil, assert.Error},
{"missing modelstore", control.Options{}, kw, nil, acct, nil, assert.Error},
}
for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) {
ctx, flush := tester.NewContext()
defer flush()
_, err := NewRestoreOperation(
ctx,
test.opts,
test.kw,
test.sw,
test.acct,
"backup-id",
selectors.Selector{DiscreteOwner: "test"},
dest,
evmock.NewBus())
test.errCheck(t, err)
})
}
}
func (suite *RestoreOpE2ESuite) TestRestore_Run() {
ctx, flush := tester.NewContext()
defer flush()
t := suite.T()
users := []string{tester.M365UserID(t)}
rsel := selectors.NewExchangeRestore(users)
rsel.Include(rsel.AllData())
dest := tester.DefaultTestRestoreDestination()
mb := evmock.NewBus()
ro, err := NewRestoreOperation(
ctx,
control.Options{},
suite.kw,
suite.sw,
tester.NewM365Account(t),
suite.backupID,
rsel.Selector,
dest,
mb)
require.NoError(t, err)
ds, err := ro.Run(ctx)
require.NoError(t, err, "restoreOp.Run()")
require.Empty(t, ro.Errors.Errs(), "restoreOp.Run() recoverable errors")
require.NotEmpty(t, ro.Results, "restoreOp results")
require.NotNil(t, ds, "restored details")
assert.Equal(t, ro.Status, Completed, "restoreOp status")
assert.Equal(t, ro.Results.ItemsWritten, len(ds.Entries), "count of items written matches restored entries in details")
assert.Less(t, 0, ro.Results.ItemsRead, "restore items read")
assert.Less(t, 0, ro.Results.ItemsWritten, "restored items written")
assert.Less(t, int64(0), ro.Results.BytesRead, "bytes read")
assert.Equal(t, 1, ro.Results.ResourceOwners, "resource Owners")
assert.NoError(t, ro.Errors.Err(), "non-recoverable error")
assert.Empty(t, ro.Errors.Errs(), "recoverable errors")
assert.NoError(t, ro.Results.ReadErrors, "errors while reading restore data")
assert.NoError(t, ro.Results.WriteErrors, "errors while writing restore data")
assert.Equal(t, suite.numItems, ro.Results.ItemsWritten, "backup and restore wrote the same num of items")
assert.Equal(t, 1, mb.TimesCalled[events.RestoreStart], "restore-start events")
assert.Equal(t, 1, mb.TimesCalled[events.RestoreEnd], "restore-end events")
}
func (suite *RestoreOpE2ESuite) TestRestore_Run_ErrorNoResults() {
ctx, flush := tester.NewContext()
defer flush()
t := suite.T()
rsel := selectors.NewExchangeRestore(selectors.None())
rsel.Include(rsel.AllData())
dest := tester.DefaultTestRestoreDestination()
mb := evmock.NewBus()
ro, err := NewRestoreOperation(
ctx,
control.Options{},
suite.kw,
suite.sw,
tester.NewM365Account(t),
suite.backupID,
rsel.Selector,
dest,
mb)
require.NoError(t, err)
ds, err := ro.Run(ctx)
require.Error(t, err, "restoreOp.Run() should have errored")
require.Nil(t, ds, "restoreOp.Run() should not produce details")
assert.Zero(t, ro.Results.ResourceOwners, "resource owners")
assert.Zero(t, ro.Results.BytesRead, "bytes read")
assert.Equal(t, 1, mb.TimesCalled[events.RestoreStart], "restore-start events")
assert.Zero(t, mb.TimesCalled[events.RestoreEnd], "restore-end events")
}

View File

@ -1,7 +1,6 @@
package operations package operations
import ( import (
"context"
"testing" "testing"
"time" "time"
@ -9,14 +8,11 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/alcionai/corso/src/internal/connector/exchange"
"github.com/alcionai/corso/src/internal/connector/mockconnector" "github.com/alcionai/corso/src/internal/connector/mockconnector"
"github.com/alcionai/corso/src/internal/connector/support" "github.com/alcionai/corso/src/internal/connector/support"
"github.com/alcionai/corso/src/internal/data" "github.com/alcionai/corso/src/internal/data"
"github.com/alcionai/corso/src/internal/events"
evmock "github.com/alcionai/corso/src/internal/events/mock" evmock "github.com/alcionai/corso/src/internal/events/mock"
"github.com/alcionai/corso/src/internal/kopia" "github.com/alcionai/corso/src/internal/kopia"
"github.com/alcionai/corso/src/internal/model"
"github.com/alcionai/corso/src/internal/stats" "github.com/alcionai/corso/src/internal/stats"
"github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/internal/tester"
"github.com/alcionai/corso/src/pkg/account" "github.com/alcionai/corso/src/pkg/account"
@ -119,224 +115,3 @@ func (suite *RestoreOpSuite) TestRestoreOperation_PersistResults() {
}) })
} }
} }
// ---------------------------------------------------------------------------
// integration
// ---------------------------------------------------------------------------
type RestoreOpIntegrationSuite struct {
suite.Suite
backupID model.StableID
numItems int
kopiaCloser func(ctx context.Context)
kw *kopia.Wrapper
sw *store.Wrapper
ms *kopia.ModelStore
}
func TestRestoreOpIntegrationSuite(t *testing.T) {
tester.RunOnAny(
t,
tester.CorsoCITests,
tester.CorsoOperationTests)
suite.Run(t, new(RestoreOpIntegrationSuite))
}
func (suite *RestoreOpIntegrationSuite) SetupSuite() {
ctx, flush := tester.NewContext()
defer flush()
tester.MustGetEnvSets(suite.T(), tester.M365AcctCredEnvs)
t := suite.T()
m365UserID := tester.M365UserID(t)
acct := tester.NewM365Account(t)
// need to initialize the repository before we can test connecting to it.
st := tester.NewPrefixedS3Storage(t)
k := kopia.NewConn(st)
require.NoError(t, k.Initialize(ctx))
suite.kopiaCloser = func(ctx context.Context) {
k.Close(ctx)
}
kw, err := kopia.NewWrapper(k)
require.NoError(t, err)
suite.kw = kw
ms, err := kopia.NewModelStore(k)
require.NoError(t, err)
suite.ms = ms
sw := store.NewKopiaStore(ms)
suite.sw = sw
users := []string{m365UserID}
bsel := selectors.NewExchangeBackup(users)
bsel.DiscreteOwner = m365UserID
bsel.Include(
bsel.MailFolders([]string{exchange.DefaultMailFolder}, selectors.PrefixMatch()),
bsel.ContactFolders([]string{exchange.DefaultContactFolder}, selectors.PrefixMatch()),
bsel.EventCalendars([]string{exchange.DefaultCalendar}, selectors.PrefixMatch()),
)
bo, err := NewBackupOperation(
ctx,
control.Options{},
kw,
sw,
acct,
bsel.Selector,
evmock.NewBus())
require.NoError(t, err)
require.NoError(t, bo.Run(ctx))
require.NotEmpty(t, bo.Results.BackupID)
suite.backupID = bo.Results.BackupID
// Discount metadata files (3 paths, 3 deltas) as
// they are not part of the data restored.
suite.numItems = bo.Results.ItemsWritten - 6
}
func (suite *RestoreOpIntegrationSuite) TearDownSuite() {
ctx, flush := tester.NewContext()
defer flush()
if suite.ms != nil {
suite.ms.Close(ctx)
}
if suite.kw != nil {
suite.kw.Close(ctx)
}
if suite.kopiaCloser != nil {
suite.kopiaCloser(ctx)
}
}
func (suite *RestoreOpIntegrationSuite) TestNewRestoreOperation() {
kw := &kopia.Wrapper{}
sw := &store.Wrapper{}
acct := tester.NewM365Account(suite.T())
dest := tester.DefaultTestRestoreDestination()
table := []struct {
name string
opts control.Options
kw *kopia.Wrapper
sw *store.Wrapper
acct account.Account
targets []string
errCheck assert.ErrorAssertionFunc
}{
{"good", control.Options{}, kw, sw, acct, nil, assert.NoError},
{"missing kopia", control.Options{}, nil, sw, acct, nil, assert.Error},
{"missing modelstore", control.Options{}, kw, nil, acct, nil, assert.Error},
}
for _, test := range table {
suite.T().Run(test.name, func(t *testing.T) {
ctx, flush := tester.NewContext()
defer flush()
_, err := NewRestoreOperation(
ctx,
test.opts,
test.kw,
test.sw,
test.acct,
"backup-id",
selectors.Selector{DiscreteOwner: "test"},
dest,
evmock.NewBus())
test.errCheck(t, err)
})
}
}
func (suite *RestoreOpIntegrationSuite) TestRestore_Run() {
ctx, flush := tester.NewContext()
defer flush()
t := suite.T()
users := []string{tester.M365UserID(t)}
rsel := selectors.NewExchangeRestore(users)
rsel.Include(rsel.AllData())
dest := tester.DefaultTestRestoreDestination()
mb := evmock.NewBus()
ro, err := NewRestoreOperation(
ctx,
control.Options{},
suite.kw,
suite.sw,
tester.NewM365Account(t),
suite.backupID,
rsel.Selector,
dest,
mb)
require.NoError(t, err)
ds, err := ro.Run(ctx)
require.NoError(t, err, "restoreOp.Run()")
require.Empty(t, ro.Errors.Errs(), "restoreOp.Run() recoverable errors")
require.NotEmpty(t, ro.Results, "restoreOp results")
require.NotNil(t, ds, "restored details")
assert.Equal(t, ro.Status, Completed, "restoreOp status")
assert.Equal(t, ro.Results.ItemsWritten, len(ds.Entries), "count of items written matches restored entries in details")
assert.Less(t, 0, ro.Results.ItemsRead, "restore items read")
assert.Less(t, 0, ro.Results.ItemsWritten, "restored items written")
assert.Less(t, int64(0), ro.Results.BytesRead, "bytes read")
assert.Equal(t, 1, ro.Results.ResourceOwners, "resource Owners")
assert.NoError(t, ro.Errors.Err(), "non-recoverable error")
assert.Empty(t, ro.Errors.Errs(), "recoverable errors")
assert.NoError(t, ro.Results.ReadErrors, "errors while reading restore data")
assert.NoError(t, ro.Results.WriteErrors, "errors while writing restore data")
assert.Equal(t, suite.numItems, ro.Results.ItemsWritten, "backup and restore wrote the same num of items")
assert.Equal(t, 1, mb.TimesCalled[events.RestoreStart], "restore-start events")
assert.Equal(t, 1, mb.TimesCalled[events.RestoreEnd], "restore-end events")
}
func (suite *RestoreOpIntegrationSuite) TestRestore_Run_ErrorNoResults() {
ctx, flush := tester.NewContext()
defer flush()
t := suite.T()
rsel := selectors.NewExchangeRestore(selectors.None())
rsel.Include(rsel.AllData())
dest := tester.DefaultTestRestoreDestination()
mb := evmock.NewBus()
ro, err := NewRestoreOperation(
ctx,
control.Options{},
suite.kw,
suite.sw,
tester.NewM365Account(t),
suite.backupID,
rsel.Selector,
dest,
mb)
require.NoError(t, err)
ds, err := ro.Run(ctx)
require.Error(t, err, "restoreOp.Run() should have errored")
require.Nil(t, ds, "restoreOp.Run() should not produce details")
assert.Zero(t, ro.Results.ResourceOwners, "resource owners")
assert.Zero(t, ro.Results.BytesRead, "bytes read")
assert.Equal(t, 1, mb.TimesCalled[events.RestoreStart], "restore-start events")
assert.Zero(t, mb.TimesCalled[events.RestoreEnd], "restore-end events")
}

View File

@ -1,103 +0,0 @@
package tester
import (
"os"
"strings"
"testing"
"time"
"github.com/stretchr/testify/require"
"golang.org/x/exp/maps"
)
const (
CorsoLoadTests = "CORSO_LOAD_TESTS"
CorsoCITests = "CORSO_CI_TESTS"
CorsoCLIBackupTests = "CORSO_COMMAND_LINE_BACKUP_TESTS"
CorsoCLIConfigTests = "CORSO_COMMAND_LINE_CONFIG_TESTS"
CorsoCLIRepoTests = "CORSO_COMMAND_LINE_REPO_TESTS"
CorsoCLIRestoreTests = "CORSO_COMMAND_LINE_RESTORE_TESTS"
CorsoCLITests = "CORSO_COMMAND_LINE_TESTS"
CorsoConnectorCreateCollectionTests = "CORSO_CONNECTOR_CREATE_COLLECTION_TESTS"
CorsoConnectorCreateExchangeCollectionTests = "CORSO_CONNECTOR_CREATE_EXCHANGE_COLLECTION_TESTS"
CorsoConnectorCreateSharePointCollectionTests = "CORSO_CONNECTOR_CREATE_SHAREPOINT_COLLECTION_TESTS"
CorsoConnectorDataCollectionTests = "CORSO_CONNECTOR_DATA_COLLECTION_TESTS"
CorsoConnectorExchangeFolderCacheTests = "CORSO_CONNECTOR_EXCHANGE_FOLDER_CACHE_TESTS"
CorsoConnectorRestoreExchangeCollectionTests = "CORSO_CONNECTOR_RESTORE_EXCHANGE_COLLECTION_TESTS"
CorsoGraphConnectorTests = "CORSO_GRAPH_CONNECTOR_TESTS"
CorsoGraphConnectorExchangeTests = "CORSO_GRAPH_CONNECTOR_EXCHANGE_TESTS"
CorsoGraphConnectorOneDriveTests = "CORSO_GRAPH_CONNECTOR_ONE_DRIVE_TESTS"
CorsoGraphConnectorSharePointTests = "CORSO_GRAPH_CONNECTOR_SHAREPOINT_TESTS"
CorsoKopiaWrapperTests = "CORSO_KOPIA_WRAPPER_TESTS"
CorsoModelStoreTests = "CORSO_MODEL_STORE_TESTS"
CorsoOneDriveTests = "CORSO_ONE_DRIVE_TESTS"
CorsoOperationTests = "CORSO_OPERATION_TESTS"
CorsoOperationBackupTests = "CORSO_OPERATION_BACKUP_TESTS"
CorsoRepositoryTests = "CORSO_REPOSITORY_TESTS"
)
// File needs to be a single message .json
// Use: https://developer.microsoft.com/en-us/graph/graph-explorer for details
const CorsoGraphConnectorTestSupportFile = "CORSO_TEST_SUPPORT_FILE"
// RunOnAny takes in a list of env variable names and returns
// an error if all of them are zero valued. Implication being:
// if any of those env vars are truthy, you should run the
// subsequent tests.
func RunOnAny(t *testing.T, tests ...string) {
var l int
for _, test := range tests {
l += len(os.Getenv(test))
}
if l == 0 {
t.Skipf(
"one or more env vars must be flagged to run this test: %v",
strings.Join(tests, ", "))
}
}
// LogTimeOfTest logs the test name and the time that it was run.
func LogTimeOfTest(t *testing.T) string {
now := time.Now().UTC().Format(time.RFC3339Nano)
name := t.Name()
if name == "" {
t.Logf("Test run at %s.", now)
return now
}
t.Logf("%s run at %s", name, now)
return now
}
// MustGetEnvVars retrieves the provided env vars from the os.
// Retrieved values are populated into the resulting map.
// If any of the env values are zero length, the test errors.
func MustGetEnvVars(t *testing.T, evs ...string) map[string]string {
vals := map[string]string{}
for _, ev := range evs {
ge := os.Getenv(ev)
require.NotEmpty(t, ev, ev+" env var required for test suite")
vals[ev] = ge
}
return vals
}
// MustGetEnvSls retrieves the provided env vars from the os.
// Retrieved values are populated into the resulting map.
// If any of the env values are zero length, the test errors.
func MustGetEnvSets(t *testing.T, evs ...[]string) map[string]string {
vals := map[string]string{}
for _, ev := range evs {
r := MustGetEnvVars(t, ev...)
maps.Copy(vals, r)
}
return vals
}

View File

@ -1,9 +1,20 @@
package tester package tester
import ( import (
"os"
"strings"
"testing" "testing"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"golang.org/x/exp/maps"
)
// Flags for declaring which scope of tests to run.
const (
CorsoCITests = "CORSO_CI_TESTS"
CorsoE2ETests = "CORSO_E2E_TESTS"
CorsoLoadTests = "CORSO_LOAD_TESTS"
) )
type Suite interface { type Suite interface {
@ -11,6 +22,10 @@ type Suite interface {
Run(name string, subtest func()) bool Run(name string, subtest func()) bool
} }
// ---------------------------------------------------------------------------
// Unit
// ---------------------------------------------------------------------------
func NewUnitSuite(t *testing.T) *unitSuite { func NewUnitSuite(t *testing.T) *unitSuite {
return new(unitSuite) return new(unitSuite)
} }
@ -19,16 +34,20 @@ type unitSuite struct {
suite.Suite suite.Suite
} }
// ---------------------------------------------------------------------------
// Integration
// ---------------------------------------------------------------------------
func NewIntegrationSuite( func NewIntegrationSuite(
t *testing.T, t *testing.T,
envSets [][]string, envSets [][]string,
includeGroups ...string, runOnAnyEnv ...string,
) *integrationSuite { ) *integrationSuite {
RunOnAny( RunOnAny(
t, t,
append( append(
[]string{CorsoCITests}, []string{CorsoCITests},
includeGroups..., runOnAnyEnv...,
)..., )...,
) )
@ -40,3 +59,80 @@ func NewIntegrationSuite(
type integrationSuite struct { type integrationSuite struct {
suite.Suite suite.Suite
} }
// ---------------------------------------------------------------------------
// Smoke/e2e
// ---------------------------------------------------------------------------
func NewE2ESuite(
t *testing.T,
envSets [][]string,
runOnAnyEnv ...string,
) *e2eSuite {
RunOnAny(
t,
append(
[]string{CorsoE2ETests},
runOnAnyEnv...,
)...,
)
MustGetEnvSets(t, envSets...)
return new(e2eSuite)
}
type e2eSuite struct {
suite.Suite
}
// ---------------------------------------------------------------------------
// Run Condition Checkers
// ---------------------------------------------------------------------------
// RunOnAny takes in a list of env variable names and returns
// an error if all of them are zero valued. Implication being:
// if any of those env vars are truthy, you should run the
// subsequent tests.
func RunOnAny(t *testing.T, tests ...string) {
var l int
for _, test := range tests {
l += len(os.Getenv(test))
}
if l == 0 {
t.Skipf(
"one or more env vars must be flagged to run this test: %v",
strings.Join(tests, ", "))
}
}
// MustGetEnvVars retrieves the provided env vars from the os.
// Retrieved values are populated into the resulting map.
// If any of the env values are zero length, the test errors.
func MustGetEnvVars(t *testing.T, evs ...string) map[string]string {
vals := map[string]string{}
for _, ev := range evs {
ge := os.Getenv(ev)
require.NotEmpty(t, ev, ev+" env var required for test suite")
vals[ev] = ge
}
return vals
}
// MustGetEnvSls retrieves the provided env vars from the os.
// Retrieved values are populated into the resulting map.
// If any of the env values are zero length, the test errors.
func MustGetEnvSets(t *testing.T, evs ...[]string) map[string]string {
vals := map[string]string{}
for _, ev := range evs {
r := MustGetEnvVars(t, ev...)
maps.Copy(vals, r)
}
return vals
}

View File

@ -0,0 +1,60 @@
package tester_test
import (
"testing"
"github.com/alcionai/corso/src/internal/tester"
"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
)
type TesterUnitSuite struct {
tester.Suite
called bool
}
func TestTesterUnitSuite(t *testing.T) {
suite.Run(t, &TesterUnitSuite{Suite: tester.NewUnitSuite(t)})
}
func (suite *TesterUnitSuite) SetupSuite() {
suite.called = true
}
func (suite *TesterUnitSuite) TestUnitSuite() {
require.True(suite.T(), suite.called)
}
type TesterIntegrationSuite struct {
tester.Suite
called bool
}
func TestTesterIntegrationSuite(t *testing.T) {
suite.Run(t, &TesterIntegrationSuite{Suite: tester.NewIntegrationSuite(t, nil)})
}
func (suite *TesterIntegrationSuite) SetupSuite() {
suite.called = true
}
func (suite *TesterIntegrationSuite) TestIntegrationSuite() {
require.True(suite.T(), suite.called)
}
type TesterE2ESuite struct {
tester.Suite
called bool
}
func TestTesterE2ESuite(t *testing.T) {
suite.Run(t, &TesterE2ESuite{Suite: tester.NewE2ESuite(t, nil)})
}
func (suite *TesterE2ESuite) SetupSuite() {
suite.called = true
}
func (suite *TesterE2ESuite) TestE2ESuite() {
require.True(suite.T(), suite.called)
}

View File

@ -4,6 +4,7 @@ import (
"reflect" "reflect"
"runtime" "runtime"
"testing" "testing"
"time"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -24,3 +25,18 @@ func AreSameFunc(t *testing.T, expect, have any) {
).Name(), ).Name(),
) )
} }
// LogTimeOfTest logs the test name and the time that it was run.
func LogTimeOfTest(t *testing.T) string {
now := time.Now().UTC().Format(time.RFC3339Nano)
name := t.Name()
if name == "" {
t.Logf("Test run at %s.", now)
return now
}
t.Logf("%s run at %s", name, now)
return now
}

View File

@ -96,11 +96,7 @@ type RepositoryIntegrationSuite struct {
} }
func TestRepositoryIntegrationSuite(t *testing.T) { func TestRepositoryIntegrationSuite(t *testing.T) {
tester.RunOnAny( tester.RunOnAny(t, tester.CorsoCITests)
t,
tester.CorsoCITests,
tester.CorsoRepositoryTests)
suite.Run(t, new(RepositoryIntegrationSuite)) suite.Run(t, new(RepositoryIntegrationSuite))
} }

View File

@ -16,11 +16,7 @@ type RepositoryModelSuite struct {
} }
func TestRepositoryModelSuite(t *testing.T) { func TestRepositoryModelSuite(t *testing.T) {
tester.RunOnAny( tester.RunOnAny(t, tester.CorsoCITests)
t,
tester.CorsoCITests,
tester.CorsoRepositoryTests)
suite.Run(t, new(RepositoryModelSuite)) suite.Run(t, new(RepositoryModelSuite))
} }