From 86c2f2c2841b674e1a15d76456f54be9b71924be Mon Sep 17 00:00:00 2001 From: ashmrtn Date: Fri, 18 Nov 2022 16:45:03 -0800 Subject: [PATCH] OneDrive restore/backup test (#1173) ## Description GraphConnector test for OneDrive backup and restore. Tests the following: * restore properly builds the hierarchy for items * items in folders that have the same name restore properly * backup properly selects subfolders * backup separates folders with same name in different parts of hierarchy * input data == backup(restore(input data)) ## Type of change - [ ] :sunflower: Feature - [ ] :bug: Bugfix - [ ] :world_map: Documentation - [x] :robot: Test - [ ] :computer: CI/Deployment - [ ] :hamster: Trivial/Minor ## Issue(s) * #913 ## Test Plan - [ ] :muscle: Manual - [x] :zap: Unit test - [ ] :green_heart: E2E --- .github/workflows/ci.yml | 9 +- src/.golangci.yml | 2 + .../connector/graph_connector_helper_test.go | 25 ++++ .../connector/graph_connector_test.go | 130 ++++++++++++++++++ 4 files changed, 162 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cd239e462..5a24e6a99 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -178,10 +178,11 @@ jobs: CORSO_PASSPHRASE: ${{ secrets.INTEGRATION_TEST_CORSO_PASSPHRASE }} run: | set -euo pipefail - go test \ - -json \ - -v \ - -failfast \ + go test \ + -tags testing \ + -json \ + -v \ + -failfast \ ./... 2>&1 | tee ./testlog/gotest.log | gotestfmt -hide successful-tests # Upload the original go test log as an artifact for later review. diff --git a/src/.golangci.yml b/src/.golangci.yml index 55cae6fd6..ce971c2f9 100644 --- a/src/.golangci.yml +++ b/src/.golangci.yml @@ -1,5 +1,7 @@ run: timeout: 15m + build-tags: + - testing linters: enable: diff --git a/src/internal/connector/graph_connector_helper_test.go b/src/internal/connector/graph_connector_helper_test.go index 70520ec1d..9d63952f8 100644 --- a/src/internal/connector/graph_connector_helper_test.go +++ b/src/internal/connector/graph_connector_helper_test.go @@ -603,6 +603,27 @@ func compareExchangeEvent( checkEvent(t, expectedEvent, itemEvent) } +func compareOneDriveItem( + t *testing.T, + expected map[string][]byte, + item data.Stream, +) { + expectedData := expected[item.UUID()] + if !assert.NotNil(t, expectedData, "unexpected file with name %s", item.UUID) { + return + } + + // OneDrive items are just byte buffers of the data. Nothing special to + // interpret. May need to do chunked comparisons in the future if we test + // large item equality. + buf, err := io.ReadAll(item.ToReader()) + if !assert.NoError(t, err) { + return + } + + assert.Equal(t, expectedData, buf) +} + func compareItem( t *testing.T, expected map[string][]byte, @@ -622,6 +643,10 @@ func compareItem( default: assert.FailNowf(t, "unexpected Exchange category: %s", category.String()) } + + case path.OneDriveService: + compareOneDriveItem(t, expected, item) + default: assert.FailNowf(t, "unexpected service: %s", service.String()) } diff --git a/src/internal/connector/graph_connector_test.go b/src/internal/connector/graph_connector_test.go index 05396a34b..a8cbe5268 100644 --- a/src/internal/connector/graph_connector_test.go +++ b/src/internal/connector/graph_connector_test.go @@ -1,14 +1,19 @@ package connector import ( + "context" + "strings" "testing" "time" + "github.com/pkg/errors" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/stretchr/testify/suite" + "github.com/alcionai/corso/src/internal/connector/graph" "github.com/alcionai/corso/src/internal/connector/mockconnector" + "github.com/alcionai/corso/src/internal/connector/support" "github.com/alcionai/corso/src/internal/data" "github.com/alcionai/corso/src/internal/tester" "github.com/alcionai/corso/src/pkg/path" @@ -149,6 +154,31 @@ func (suite *GraphConnectorIntegrationSuite) TestEmptyCollections() { // Exchange Functions //------------------------------------------------------------- +//revive:disable:context-as-argument +func mustGetDefaultDriveID( + t *testing.T, + ctx context.Context, + service graph.Service, + userID string, +) string { + //revive:enable:context-as-argument + d, err := service.Client().UsersById(userID).Drive().Get(ctx, nil) + if err != nil { + err = errors.Wrapf( + err, + "failed to retrieve default user drive. user: %s, details: %s", + userID, + support.ConnectorStackErrorTrace(err), + ) + } + + require.NoError(t, err) + require.NotNil(t, d.GetId()) + require.NotEmpty(t, *d.GetId()) + + return *d.GetId() +} + func runRestoreBackupTest( t *testing.T, test restoreBackupInfo, @@ -249,6 +279,17 @@ func (suite *GraphConnectorIntegrationSuite) TestRestoreAndBackup() { bodyText := "This email has some text. However, all the text is on the same line." subjectText := "Test message for restore" + ctx, flush := tester.NewContext() + defer flush() + + // Get the default drive ID for the test user. + driveID := mustGetDefaultDriveID( + suite.T(), + ctx, + suite.connector.Service(), + suite.user, + ) + table := []restoreBackupInfo{ { name: "EmailsWithAttachments", @@ -465,6 +506,95 @@ func (suite *GraphConnectorIntegrationSuite) TestRestoreAndBackup() { // }, // }, // }, + { + name: "OneDriveMultipleFoldersAndFiles", + service: path.OneDriveService, + resource: Users, + collections: []colInfo{ + { + pathElements: []string{ + "drives", + driveID, + "root:", + }, + category: path.FilesCategory, + items: []itemInfo{ + { + name: "test-file.txt", + data: []byte(strings.Repeat("a", 33)), + lookupKey: "test-file.txt", + }, + }, + }, + { + pathElements: []string{ + "drives", + driveID, + "root:", + "folder-a", + }, + category: path.FilesCategory, + items: []itemInfo{ + { + name: "test-file.txt", + data: []byte(strings.Repeat("b", 65)), + lookupKey: "test-file.txt", + }, + }, + }, + { + pathElements: []string{ + "drives", + driveID, + "root:", + "folder-a", + "b", + }, + category: path.FilesCategory, + items: []itemInfo{ + { + name: "test-file.txt", + data: []byte(strings.Repeat("c", 129)), + lookupKey: "test-file.txt", + }, + }, + }, + { + pathElements: []string{ + "drives", + driveID, + "root:", + "folder-a", + "b", + "folder-a", + }, + category: path.FilesCategory, + items: []itemInfo{ + { + name: "test-file.txt", + data: []byte(strings.Repeat("d", 257)), + lookupKey: "test-file.txt", + }, + }, + }, + { + pathElements: []string{ + "drives", + driveID, + "root:", + "b", + }, + category: path.FilesCategory, + items: []itemInfo{ + { + name: "test-file.txt", + data: []byte(strings.Repeat("e", 257)), + lookupKey: "test-file.txt", + }, + }, + }, + }, + }, } for _, test := range table {