diff --git a/src/cli/backup/exchange.go b/src/cli/backup/exchange.go index f7ed855e7..4475456e1 100644 --- a/src/cli/backup/exchange.go +++ b/src/cli/backup/exchange.go @@ -73,7 +73,7 @@ func createExchangeCmd(cmd *cobra.Command, args []string) error { return errors.Wrap(err, "Failed to initialize Exchange backup") } - if err := bo.Run(cmd.Context()); err != nil { + if _, err := bo.Run(cmd.Context()); err != nil { return errors.Wrap(err, "Failed to run Exchange backup") } diff --git a/src/internal/connector/exchange_data_collection.go b/src/internal/connector/exchange_data_collection.go index 155920381..2809dec76 100644 --- a/src/internal/connector/exchange_data_collection.go +++ b/src/internal/connector/exchange_data_collection.go @@ -67,7 +67,9 @@ func (edc *ExchangeDataCollection) PopulateCollection(newData ExchangeData) { // FinishPopulation is used to indicate data population of the collection is complete // TODO: This should be an internal method once we move the message retrieval logic into `ExchangeDataCollection` func (edc *ExchangeDataCollection) FinishPopulation() { - close(edc.data) + if edc != nil && edc.data != nil { + close(edc.data) + } } func (edc *ExchangeDataCollection) Length() int { diff --git a/src/internal/connector/graph_connector.go b/src/internal/connector/graph_connector.go index 7be490441..bd4e18738 100644 --- a/src/internal/connector/graph_connector.go +++ b/src/internal/connector/graph_connector.go @@ -127,7 +127,6 @@ func (gc *GraphConnector) ExchangeDataCollection(user string) (DataCollection, e collection := NewExchangeDataCollection(user, []string{gc.tenant, user}) //TODO: Retry handler to convert return: (DataCollection, error) return gc.serializeMessages(user, collection) - } // optionsForMailFolders creates transforms the 'select' into a more dynamic call for MailFolders. @@ -217,7 +216,9 @@ func (gc *GraphConnector) serializeMessages(user string, dc ExchangeDataCollecti } } fmt.Printf("Returning ExchangeDataColection with %d items\n", dc.Length()) - fmt.Printf("Errors: \n%s\n", errs.Error()) + if errs != nil { + fmt.Printf("Errors: \n%s\n", errs.Error()) + } dc.FinishPopulation() return &dc, errs } diff --git a/src/internal/connector/graph_connector_test.go b/src/internal/connector/graph_connector_test.go index 8f6a192a4..d66c3a7a3 100644 --- a/src/internal/connector/graph_connector_test.go +++ b/src/internal/connector/graph_connector_test.go @@ -1,7 +1,6 @@ package connector import ( - "os" "testing" "github.com/stretchr/testify/assert" @@ -61,8 +60,8 @@ func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_setTenantUsers() } func (suite *GraphConnectorIntegrationSuite) TestGraphConnector_ExchangeDataCollection() { - if os.Getenv("INTEGRATION_TESTING") != "" { - suite.T().Skip("Environmental Variables not set") + if err := ctesting.RunOnAny(ctesting.CorsoCITests); err != nil { + suite.T().Skip(err) } exchangeData, err := suite.connector.ExchangeDataCollection("lidiah@8qzvrj.onmicrosoft.com") assert.NotNil(suite.T(), exchangeData) diff --git a/src/internal/operations/backup.go b/src/internal/operations/backup.go index 7710ac82c..42e717eb8 100644 --- a/src/internal/operations/backup.go +++ b/src/internal/operations/backup.go @@ -51,23 +51,23 @@ func (bo BackupOperation) validate() error { } // Run begins a synchronous backup operation. -func (bo BackupOperation) Run(ctx context.Context) error { +func (bo *BackupOperation) Run(ctx context.Context) (*kopia.BackupStats, error) { gc, err := connector.NewGraphConnector(bo.creds.TenantID, bo.creds.ClientID, bo.creds.ClientSecret) if err != nil { - return errors.Wrap(err, "connecting to graph api") + return nil, errors.Wrap(err, "connecting to graph api") } c, err := gc.ExchangeDataCollection(bo.Targets[0]) if err != nil { - return errors.Wrap(err, "retrieving application data") + return nil, errors.Wrap(err, "retrieving application data") } // todo: utilize stats - _, err = bo.kopia.BackupCollections(ctx, []connector.DataCollection{c}) + stats, err := bo.kopia.BackupCollections(ctx, []connector.DataCollection{c}) if err != nil { - return errors.Wrap(err, "backing up application data") + return nil, errors.Wrap(err, "backing up application data") } bo.Status = Successful - return nil + return stats, nil } diff --git a/src/internal/operations/backup_test.go b/src/internal/operations/backup_test.go index ebc927e88..073144d70 100644 --- a/src/internal/operations/backup_test.go +++ b/src/internal/operations/backup_test.go @@ -12,6 +12,7 @@ import ( "github.com/alcionai/corso/internal/operations" ctesting "github.com/alcionai/corso/internal/testing" "github.com/alcionai/corso/pkg/credentials" + "github.com/alcionai/corso/pkg/repository" ) type BackupOpIntegrationSuite struct { @@ -62,4 +63,37 @@ func (suite *BackupOpIntegrationSuite) TestNewBackupOperation() { } } -// todo (rkeepers) - TestBackup_Run() +func (suite *BackupOpIntegrationSuite) TestBackup_Run() { + t := suite.T() + ctx := context.Background() + timeOfTest := ctesting.LogTimeOfTest(t) + prefix := "backup-op-run-" + timeOfTest + + // m365User := "lidiah@8qzvrj.onmicrosoft.com" + // not the user we want to use, but all the others are + // suffering from JsonParseNode syndrome + m365User := "george.martinez@8qzvrj.onmicrosoft.com" + m365 := credentials.GetM365() + acct := repository.Account{ + ClientID: m365.ClientID, + ClientSecret: m365.ClientSecret, + TenantID: m365.TenantID, + } + + // need to initialize the repository before we can test connecting to it. + st, err := ctesting.NewS3Storage(prefix) + require.NoError(t, err) + + r, err := repository.Initialize(ctx, acct, st) + require.NoError(t, err) + + bo, err := r.NewBackup(ctx, []string{m365User}) + require.NoError(t, err) + + stats, err := bo.Run(ctx) + require.NoError(t, err) + require.NotNil(t, stats) + assert.Equal(t, bo.Status, operations.Successful) + assert.Greater(t, stats.TotalFileCount, 0) + assert.Zero(t, stats.ErrorCount) +} diff --git a/src/internal/testing/config.go b/src/internal/testing/config.go index 068cff079..7def8fda1 100644 --- a/src/internal/testing/config.go +++ b/src/internal/testing/config.go @@ -5,6 +5,7 @@ import ( "path" "strings" + "github.com/alcionai/corso/pkg/credentials" "github.com/pkg/errors" "github.com/spf13/viper" ) @@ -64,7 +65,7 @@ func readTestConfig() (map[string]string, error) { fallbackTo(testEnv, testCfgBucket, vpr.GetString(testCfgBucket), "test-corso-repo-init") fallbackTo(testEnv, testCfgEndpoint, vpr.GetString(testCfgEndpoint), "s3.amazonaws.com") fallbackTo(testEnv, testCfgPrefix, vpr.GetString(testCfgPrefix)) - fallbackTo(testEnv, testCfgTenantID, vpr.GetString(testCfgTenantID)) + fallbackTo(testEnv, testCfgTenantID, os.Getenv(credentials.TenantID), vpr.GetString(testCfgTenantID)) return testEnv, nil }