implement load tests (#937)
## Description Adds the load test func calls and asserts for both exchange and onedrive. ## Type of change - [x] 🤖 Test ## Issue(s) * #902 ## Test Plan - [x] 💚 E2E
This commit is contained in:
parent
7d1cf2ce5b
commit
e061ce7c73
91
.github/workflows/load_test.yml
vendored
91
.github/workflows/load_test.yml
vendored
@ -9,53 +9,54 @@ permissions:
|
|||||||
id-token: write
|
id-token: write
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
Load-Tests:
|
jobs:
|
||||||
environment: Testing
|
Load-Tests:
|
||||||
runs-on: ubuntu-latest
|
environment: Testing
|
||||||
defaults:
|
runs-on: ubuntu-latest
|
||||||
run:
|
defaults:
|
||||||
working-directory: src
|
run:
|
||||||
steps:
|
working-directory: src
|
||||||
- uses: actions/checkout@v3
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Setup Golang with cache
|
- name: Setup Golang with cache
|
||||||
uses: magnetikonline/action-golang-cache@v3
|
uses: magnetikonline/action-golang-cache@v3
|
||||||
with:
|
with:
|
||||||
go-version-file: src/go.mod
|
go-version-file: src/go.mod
|
||||||
|
|
||||||
# Install gotestfmt
|
# Install gotestfmt
|
||||||
- name: Set up gotestfmt
|
- name: Set up gotestfmt
|
||||||
run: go install github.com/haveyoudebuggedit/gotestfmt/v2/cmd/gotestfmt@latest
|
run: go install github.com/haveyoudebuggedit/gotestfmt/v2/cmd/gotestfmt@latest
|
||||||
|
|
||||||
# AWS creds
|
# AWS creds
|
||||||
- name: Configure AWS credentials from Test account
|
- name: Configure AWS credentials from Test account
|
||||||
uses: aws-actions/configure-aws-credentials@v1
|
uses: aws-actions/configure-aws-credentials@v1
|
||||||
with:
|
with:
|
||||||
role-to-assume: arn:aws:iam::951767375776:role/corso-testing-role
|
role-to-assume: arn:aws:iam::951767375776:role/corso-testing-role
|
||||||
role-session-name: integration-testing
|
role-session-name: integration-testing
|
||||||
aws-region: us-east-1
|
aws-region: us-east-1
|
||||||
|
|
||||||
# run the tests
|
# run the tests
|
||||||
- name: Integration Tests
|
- name: Integration Tests
|
||||||
env:
|
env:
|
||||||
CORSO_LOAD_TESTS: true
|
CORSO_LOAD_TESTS: true
|
||||||
CLIENT_ID: ${{ secrets.CLIENT_ID }}
|
CLIENT_ID: ${{ secrets.CLIENT_ID }}
|
||||||
CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }}
|
CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }}
|
||||||
CORSO_PASSPHRASE: ${{ secrets.INTEGRATION_TEST_CORSO_PASSPHRASE }}
|
CORSO_PASSPHRASE: ${{ secrets.INTEGRATION_TEST_CORSO_PASSPHRASE }}
|
||||||
TENANT_ID: ${{ secrets.TENANT_ID }}
|
TENANT_ID: ${{ secrets.TENANT_ID }}
|
||||||
run: |
|
run: |
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
go test \
|
go test \
|
||||||
-json \
|
-json \
|
||||||
-v \
|
-v \
|
||||||
-count=1 \
|
-count=1 \
|
||||||
--timeout 12h \
|
--timeout 12h \
|
||||||
./... 2>&1 | tee /tmp/gotest.log | gotestfmt -hide successful-tests
|
./... 2>&1 | tee /tmp/gotest.log | gotestfmt -hide successful-tests
|
||||||
|
|
||||||
# Upload the original go test log as an artifact for later review.
|
# Upload the original go test log as an artifact for later review.
|
||||||
- name: Upload test log
|
- name: Upload test log
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
with:
|
with:
|
||||||
name: test-log
|
name: test-log
|
||||||
path: /tmp/gotest.log
|
path: /tmp/gotest.log
|
||||||
if-no-files-found: error
|
if-no-files-found: error
|
||||||
@ -4,14 +4,17 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"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"
|
||||||
|
|
||||||
|
"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/pkg/account"
|
"github.com/alcionai/corso/src/pkg/account"
|
||||||
"github.com/alcionai/corso/src/pkg/control"
|
"github.com/alcionai/corso/src/pkg/control"
|
||||||
"github.com/alcionai/corso/src/pkg/logger"
|
"github.com/alcionai/corso/src/pkg/logger"
|
||||||
"github.com/alcionai/corso/src/pkg/repository"
|
"github.com/alcionai/corso/src/pkg/repository"
|
||||||
|
"github.com/alcionai/corso/src/pkg/selectors"
|
||||||
"github.com/alcionai/corso/src/pkg/storage"
|
"github.com/alcionai/corso/src/pkg/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -38,6 +41,98 @@ func initM365Repo(t *testing.T) (
|
|||||||
return ctx, repo, ac, st
|
return ctx, repo, ac, st
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//revive:disable:context-as-argument
|
||||||
|
func runBackupLoadTest(
|
||||||
|
t *testing.T,
|
||||||
|
ctx context.Context,
|
||||||
|
b *operations.BackupOperation,
|
||||||
|
name string,
|
||||||
|
) {
|
||||||
|
//revive:enable:context-as-argument
|
||||||
|
t.Run("backup_"+name, func(t *testing.T) {
|
||||||
|
require.NoError(t, b.Run(ctx), "running backup")
|
||||||
|
require.NotEmpty(t, b.Results, "has results after run")
|
||||||
|
assert.NotEmpty(t, b.Results.BackupID, "has an ID after run")
|
||||||
|
assert.Equal(t, b.Status, operations.Completed, "backup status")
|
||||||
|
assert.Less(t, 0, b.Results.ItemsRead, "items read")
|
||||||
|
assert.Less(t, 0, b.Results.ItemsWritten, "items written")
|
||||||
|
assert.Less(t, int64(0), b.Results.BytesUploaded, "bytes uploaded")
|
||||||
|
assert.Less(t, 0, b.Results.ResourceOwners, "resource owners")
|
||||||
|
assert.Zero(t, b.Results.ReadErrors, "read errors")
|
||||||
|
assert.Zero(t, b.Results.WriteErrors, "write errors")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//revive:disable:context-as-argument
|
||||||
|
func runBackupListLoadTest(
|
||||||
|
t *testing.T,
|
||||||
|
ctx context.Context,
|
||||||
|
r repository.Repository,
|
||||||
|
name, expectID string,
|
||||||
|
) {
|
||||||
|
//revive:enable:context-as-argument
|
||||||
|
t.Run("backup_list_"+name, func(t *testing.T) {
|
||||||
|
bs, err := r.Backups(ctx)
|
||||||
|
require.NoError(t, err, "retrieving backups")
|
||||||
|
require.Less(t, 0, len(bs), "at least one backup is recorded")
|
||||||
|
|
||||||
|
var found bool
|
||||||
|
|
||||||
|
for _, b := range bs {
|
||||||
|
bid := b.ID
|
||||||
|
assert.NotEmpty(t, bid, "iterating backup ids")
|
||||||
|
|
||||||
|
if string(bid) == expectID {
|
||||||
|
found = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.True(t, found, "expected backup id "+expectID+" found in backups")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//revive:disable:context-as-argument
|
||||||
|
func runBackupDetailsLoadTest(
|
||||||
|
t *testing.T,
|
||||||
|
ctx context.Context,
|
||||||
|
r repository.Repository,
|
||||||
|
name, backupID string,
|
||||||
|
) {
|
||||||
|
//revive:enable:context-as-argument
|
||||||
|
require.NotEmpty(t, backupID, "backup ID to retrieve deails")
|
||||||
|
|
||||||
|
t.Run("backup_details_"+name, func(t *testing.T) {
|
||||||
|
ds, b, err := r.BackupDetails(ctx, backupID)
|
||||||
|
require.NoError(t, err, "retrieving details in backup "+backupID)
|
||||||
|
require.NotNil(t, ds, "backup details")
|
||||||
|
require.NotNil(t, b, "backup")
|
||||||
|
assert.Equal(t, b.ItemsWritten, len(ds.Entries))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
//revive:disable:context-as-argument
|
||||||
|
func runRestoreLoadTest(
|
||||||
|
t *testing.T,
|
||||||
|
ctx context.Context,
|
||||||
|
r operations.RestoreOperation,
|
||||||
|
name string,
|
||||||
|
expectItemCount int,
|
||||||
|
) {
|
||||||
|
//revive:enable:context-as-argument
|
||||||
|
t.Run("restore_"+name, func(t *testing.T) {
|
||||||
|
t.Skip("skipping restore handling while investigating performance")
|
||||||
|
require.NoError(t, r.Run(ctx), "running restore")
|
||||||
|
require.NotEmpty(t, r.Results, "has results after run")
|
||||||
|
assert.Equal(t, r.Status, operations.Completed, "restore status")
|
||||||
|
assert.Less(t, 0, r.Results.ItemsRead, "items read")
|
||||||
|
assert.Less(t, 0, r.Results.ItemsWritten, "items written")
|
||||||
|
assert.Less(t, 0, r.Results.ResourceOwners, "resource owners")
|
||||||
|
assert.Zero(t, r.Results.ReadErrors, "read errors")
|
||||||
|
assert.Zero(t, r.Results.WriteErrors, "write errors")
|
||||||
|
assert.Equal(t, expectItemCount, r.Results.ItemsWritten, "backup and restore wrote the same count of items")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Exchange
|
// Exchange
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@ -76,20 +171,39 @@ func (suite *RepositoryLoadTestExchangeSuite) TeardownTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (suite *RepositoryLoadTestExchangeSuite) TestExchange() {
|
func (suite *RepositoryLoadTestExchangeSuite) TestExchange() {
|
||||||
// var (
|
var (
|
||||||
// t = suite.T()
|
t = suite.T()
|
||||||
// ctx = context.Background()
|
ctx = context.Background()
|
||||||
// )
|
r = suite.repo
|
||||||
|
service = "exchange"
|
||||||
|
)
|
||||||
|
|
||||||
// t.parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
m356User := tester.M365UserID(t)
|
||||||
|
|
||||||
// backup
|
// backup
|
||||||
|
bsel := selectors.NewExchangeBackup()
|
||||||
|
bsel.Include(bsel.Users([]string{m356User}))
|
||||||
|
// bsel.Include(bsel.Users(selectors.Any()))
|
||||||
|
|
||||||
// list
|
b, err := r.NewBackup(ctx, bsel.Selector)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
// details
|
runBackupLoadTest(t, ctx, &b, service)
|
||||||
|
bid := string(b.Results.BackupID)
|
||||||
|
|
||||||
|
runBackupListLoadTest(t, ctx, r, service, bid)
|
||||||
|
runBackupDetailsLoadTest(t, ctx, r, service, bid)
|
||||||
|
|
||||||
// restore
|
// restore
|
||||||
|
rsel, err := bsel.ToExchangeRestore()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
rst, err := r.NewRestore(ctx, bid, rsel.Selector)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
runRestoreLoadTest(t, ctx, rst, service, b.Results.ItemsWritten)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
@ -129,19 +243,35 @@ func (suite *RepositoryLoadTestOneDriveSuite) TeardownTest() {
|
|||||||
logger.Flush(suite.ctx)
|
logger.Flush(suite.ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (suite *RepositoryLoadTestOneDriveSuite) TestExchange() {
|
func (suite *RepositoryLoadTestOneDriveSuite) TestOneDrive() {
|
||||||
// var (
|
var (
|
||||||
// t = suite.T()
|
t = suite.T()
|
||||||
// ctx = context.Background()
|
ctx = context.Background()
|
||||||
// )
|
r = suite.repo
|
||||||
|
service = "one_drive"
|
||||||
|
)
|
||||||
|
|
||||||
// t.parallel()
|
t.Parallel()
|
||||||
|
|
||||||
// backup
|
// backup
|
||||||
|
bsel := selectors.NewOneDriveBackup()
|
||||||
|
bsel.Include(bsel.Users(selectors.Any()))
|
||||||
|
|
||||||
// list
|
b, err := r.NewBackup(ctx, bsel.Selector)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
// details
|
runBackupLoadTest(t, ctx, &b, service)
|
||||||
|
bid := string(b.Results.BackupID)
|
||||||
|
|
||||||
|
runBackupListLoadTest(t, ctx, r, service, bid)
|
||||||
|
runBackupDetailsLoadTest(t, ctx, r, service, bid)
|
||||||
|
|
||||||
// restore
|
// restore
|
||||||
|
rsel, err := bsel.ToOneDriveRestore()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
rst, err := r.NewRestore(ctx, bid, rsel.Selector)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
runRestoreLoadTest(t, ctx, rst, service, b.Results.ItemsWritten)
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user