From 3c4c9886cd1692b235730c22e1bc386fd214e46a Mon Sep 17 00:00:00 2001 From: Robert Raynor <35671663+mooselumph@users.noreply.github.com> Date: Fri, 17 Nov 2023 15:44:34 -0800 Subject: [PATCH] Efficient-unit-tests (#50) --- .github/actions/test-coverage/action.yml | 6 ++ .github/actions/test-coverage/coverage.sh | 8 ++- .github/workflows/test-coverage.yml | 40 ----------- .github/workflows/unit-tests.yml | 21 +++++- Makefile | 4 +- common/aws/dynamodb/client_test.go | 27 ++++--- common/store/dynamo_store_test.go | 37 ++++++---- disperser/apiserver/server_test.go | 38 ++++++---- disperser/blobstore/blobstore_test.go | 43 +++++++---- inabox/Makefile | 12 ++-- inabox/deploy/cmd/main.go | 87 +++++++++++++---------- inabox/deploy/localstack.go | 1 + test.sh | 14 ++++ 13 files changed, 202 insertions(+), 136 deletions(-) delete mode 100644 .github/workflows/test-coverage.yml create mode 100755 test.sh diff --git a/.github/actions/test-coverage/action.yml b/.github/actions/test-coverage/action.yml index 764ffb1fdc..1c70f87971 100644 --- a/.github/actions/test-coverage/action.yml +++ b/.github/actions/test-coverage/action.yml @@ -36,6 +36,12 @@ runs: with: go-version: ${{inputs.go-version}} + - name: Download coverage artifact + uses: actions/download-artifact@v2 + with: + name: coverage + path: . + - name: Generate coverage report shell: bash env: diff --git a/.github/actions/test-coverage/coverage.sh b/.github/actions/test-coverage/coverage.sh index 8599f42a45..01e3878d12 100755 --- a/.github/actions/test-coverage/coverage.sh +++ b/.github/actions/test-coverage/coverage.sh @@ -52,10 +52,12 @@ set -euo pipefail SCRIPT_DIR="$(dirname -- "$(readlink -f "${BASH_SOURCE[0]}")")" OUT_DIR="${1-$SCRIPT_DIR}" -OUT_FILE="$(mktemp)" -# Get coverage for all packages in the current directory; store next to script. -go test -short ./... -coverprofile "$OUT_FILE" +# OUT_FILE="$(mktemp)" +# # Get coverage for all packages in the current directory; store next to script. +# go test -short ./... -coverprofile "$OUT_FILE" + +OUT_FILE="coverage.out" if [[ "${INPUT_REPORT-true}" == "true" ]]; then # Create an HTML report; store next to script. diff --git a/.github/workflows/test-coverage.yml b/.github/workflows/test-coverage.yml deleted file mode 100644 index 06e3a8a611..0000000000 --- a/.github/workflows/test-coverage.yml +++ /dev/null @@ -1,40 +0,0 @@ -name: test-coverage - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - workflow_dispatch: - -jobs: - - build: - runs-on: ubuntu-latest - steps: - - name: Add LocalStack AWS Credentials - run: | - mkdir -p ~/.aws - touch ~/.aws/credentials - - echo '[default]' >> ~/.aws/credentials - echo 'aws_access_key_id=localstack' >> ~/.aws/credentials - echo 'aws_secret_access_key=localstack' >> ~/.aws/credentials - - - name: Set Test Profile to default - run: | - aws configure --profile test-profile set region us-east-1 - aws configure --profile test-profile set source_profile default - - - uses: actions/checkout@v3 - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: '1.21' - - - name: Update coverage badge - uses: ./.github/actions/test-coverage - with: - chart: true - amend: true diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index d096307532..f7a7ad0432 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -38,4 +38,23 @@ jobs: run: make build - name: Test all - run: go test -coverprofile=coverage.out -short ./... + run: ./test.sh -coverprofile=coverage.out + + - name: Upload coverage artifact + uses: actions/upload-artifact@v2 + with: + name: coverage + path: coverage.out + + coverage-report: + name: Coverage Report + needs: unit-tests + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Update coverage badge + uses: ./.github/actions/test-coverage + with: + chart: true + amend: true \ No newline at end of file diff --git a/Makefile b/Makefile index be4b043d1b..87025870e7 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: compile-el compile-dl clean protoc lint +.PHONY: compile-el compile-dl clean protoc lint build unit-tests integration-tests-churner integration-tests-indexer integration-tests-inabox integration-tests-inabox-nochurner integration-tests-graph-indexer PROTOS := ./api/proto PROTOS_DISPERSER := ./disperser/proto @@ -45,7 +45,7 @@ build: cd tools/traffic && make build unit-tests: - go clean -testcache && go test -short ./... -p 2 -race + ./test.sh integration-tests-churner: go test -v ./churner/tests diff --git a/common/aws/dynamodb/client_test.go b/common/aws/dynamodb/client_test.go index 609bdeb698..f9e86a2038 100644 --- a/common/aws/dynamodb/client_test.go +++ b/common/aws/dynamodb/client_test.go @@ -23,6 +23,9 @@ var ( dockertestResource *dockertest.Resource dynamoClient *commondynamodb.Client clientConfig commonaws.ClientConfig + + deployLocalStack bool + localStackPort = "4567" ) func TestMain(m *testing.M) { @@ -33,13 +36,19 @@ func TestMain(m *testing.M) { } func setup(m *testing.M) { - localStackPort := "4567" - pool, resource, err := deploy.StartDockertestWithLocalstackContainer(localStackPort) - dockertestPool = pool - dockertestResource = resource - if err != nil { - teardown() - panic("failed to start localstack container") + + deployLocalStack = !(os.Getenv("DEPLOY_LOCALSTACK") == "false") + if !deployLocalStack { + localStackPort = os.Getenv("LOCALSTACK_PORT") + } + + if deployLocalStack { + var err error + dockertestPool, dockertestResource, err = deploy.StartDockertestWithLocalstackContainer(localStackPort) + if err != nil { + teardown() + panic("failed to start localstack container") + } } logger, err := logging.GetLogger(logging.DefaultCLIConfig()) @@ -62,7 +71,9 @@ func setup(m *testing.M) { } func teardown() { - deploy.PurgeDockertestResources(dockertestPool, dockertestResource) + if deployLocalStack { + deploy.PurgeDockertestResources(dockertestPool, dockertestResource) + } } func createTable(t *testing.T, tableName string) { diff --git a/common/store/dynamo_store_test.go b/common/store/dynamo_store_test.go index dd86e3f883..4e9b67f2c7 100644 --- a/common/store/dynamo_store_test.go +++ b/common/store/dynamo_store_test.go @@ -23,7 +23,9 @@ var ( dockertestPool *dockertest.Pool dockertestResource *dockertest.Resource - localStackPort string + + deployLocalStack bool + localStackPort = "4566" dynamoClient *dynamodb.Client dynamoParamStore common.KVStore[common.RateBucketParams] @@ -38,13 +40,19 @@ func TestMain(m *testing.M) { } func setup(m *testing.M) { - localStackPort = "4569" - pool, resource, err := deploy.StartDockertestWithLocalstackContainer(localStackPort) - dockertestPool = pool - dockertestResource = resource - if err != nil { - teardown() - panic("failed to start localstack container") + + deployLocalStack = !(os.Getenv("DEPLOY_LOCALSTACK") == "false") + if !deployLocalStack { + localStackPort = os.Getenv("LOCALSTACK_PORT") + } + + if deployLocalStack { + var err error + dockertestPool, dockertestResource, err = deploy.StartDockertestWithLocalstackContainer(localStackPort) + if err != nil { + teardown() + panic("failed to start localstack container") + } } cfg := aws.ClientConfig{ @@ -53,23 +61,26 @@ func setup(m *testing.M) { SecretAccessKey: "localstack", EndpointURL: fmt.Sprintf("http://0.0.0.0:%s", localStackPort), } - dynamoClient, err = dynamodb.NewClient(cfg, logger) + + _, err := test_utils.CreateTable(context.Background(), cfg, bucketTableName, store.GenerateTableSchema(10, 10, bucketTableName)) if err != nil { teardown() - panic("failed to create dynamodb client: " + err.Error()) + panic("failed to create dynamodb table: " + err.Error()) } - _, err = test_utils.CreateTable(context.Background(), cfg, bucketTableName, store.GenerateTableSchema(10, 10, bucketTableName)) + dynamoClient, err = dynamodb.NewClient(cfg, logger) if err != nil { teardown() - panic("failed to create dynamodb table: " + err.Error()) + panic("failed to create dynamodb client: " + err.Error()) } dynamoParamStore = store.NewDynamoParamStore[common.RateBucketParams](dynamoClient, bucketTableName) } func teardown() { - deploy.PurgeDockertestResources(dockertestPool, dockertestResource) + if deployLocalStack { + deploy.PurgeDockertestResources(dockertestPool, dockertestResource) + } } func TestDynamoBucketStore(t *testing.T) { diff --git a/disperser/apiserver/server_test.go b/disperser/apiserver/server_test.go index 309a3bc82d..7afae05920 100644 --- a/disperser/apiserver/server_test.go +++ b/disperser/apiserver/server_test.go @@ -12,6 +12,7 @@ import ( "github.com/Layr-Labs/eigenda/disperser/apiserver" "github.com/Layr-Labs/eigenda/disperser/blobstore" gethcommon "github.com/ethereum/go-ethereum/common" + "github.com/google/uuid" pb "github.com/Layr-Labs/eigenda/api/grpc/disperser" "github.com/Layr-Labs/eigenda/common" @@ -36,9 +37,12 @@ var ( dispersalServer *apiserver.DispersalServer dockertestPool *dockertest.Pool dockertestResource *dockertest.Resource - localStackPort string - metadataTableName = "test-BlobMetadata" - bucketTableName = "test-BucketStore" + UUID = uuid.New() + metadataTableName = fmt.Sprintf("test-BlobMetadata-%v", UUID) + bucketTableName = fmt.Sprintf("test-BucketStore-%v", UUID) + + deployLocalStack bool + localStackPort = "4568" ) func TestMain(m *testing.M) { @@ -276,16 +280,24 @@ func TestDisperseBlobWithExceedSizeLimit(t *testing.T) { } func setup(m *testing.M) { - localStackPort = "4568" - pool, resource, err := deploy.StartDockertestWithLocalstackContainer(localStackPort) - dockertestPool = pool - dockertestResource = resource - if err != nil { - teardown() - panic("failed to start localstack container") + + deployLocalStack = !(os.Getenv("DEPLOY_LOCALSTACK") == "false") + if !deployLocalStack { + localStackPort = os.Getenv("LOCALSTACK_PORT") + } + + if deployLocalStack { + + var err error + dockertestPool, dockertestResource, err = deploy.StartDockertestWithLocalstackContainer(localStackPort) + if err != nil { + teardown() + panic("failed to start localstack container") + } + } - err = deploy.DeployResources(pool, localStackPort, metadataTableName, bucketTableName) + err := deploy.DeployResources(dockertestPool, localStackPort, metadataTableName, bucketTableName) if err != nil { teardown() panic("failed to deploy AWS resources") @@ -295,7 +307,9 @@ func setup(m *testing.M) { } func teardown() { - deploy.PurgeDockertestResources(dockertestPool, dockertestResource) + if deployLocalStack { + deploy.PurgeDockertestResources(dockertestPool, dockertestResource) + } } func newTestServer(m *testing.M) *apiserver.DispersalServer { diff --git a/disperser/blobstore/blobstore_test.go b/disperser/blobstore/blobstore_test.go index ff79acc52f..3fb769bad9 100644 --- a/disperser/blobstore/blobstore_test.go +++ b/disperser/blobstore/blobstore_test.go @@ -10,6 +10,7 @@ import ( "github.com/Layr-Labs/eigenda/common/aws" "github.com/Layr-Labs/eigenda/common/aws/dynamodb" test_utils "github.com/Layr-Labs/eigenda/common/aws/dynamodb/utils" + "github.com/google/uuid" cmock "github.com/Layr-Labs/eigenda/common/mock" "github.com/Layr-Labs/eigenda/core" @@ -39,12 +40,16 @@ var ( dockertestPool *dockertest.Pool dockertestResource *dockertest.Resource - localStackPort string + + deployLocalStack bool + localStackPort = "4569" dynamoClient *dynamodb.Client blobMetadataStore *blobstore.BlobMetadataStore - metadataTableName = "test-BlobMetadata" sharedStorage *blobstore.SharedBlobStore + + UUID = uuid.New() + metadataTableName = fmt.Sprintf("test-BlobMetadata-%v", UUID) ) func TestMain(m *testing.M) { @@ -55,13 +60,20 @@ func TestMain(m *testing.M) { } func setup(m *testing.M) { - localStackPort = "4569" - pool, resource, err := deploy.StartDockertestWithLocalstackContainer(localStackPort) - dockertestPool = pool - dockertestResource = resource - if err != nil { - teardown() - panic("failed to start localstack container") + + deployLocalStack = !(os.Getenv("DEPLOY_LOCALSTACK") == "false") + if !deployLocalStack { + localStackPort = os.Getenv("LOCALSTACK_PORT") + } + + if deployLocalStack { + var err error + dockertestPool, dockertestResource, err = deploy.StartDockertestWithLocalstackContainer(localStackPort) + if err != nil { + teardown() + panic("failed to start localstack container") + } + } cfg := aws.ClientConfig{ @@ -70,16 +82,17 @@ func setup(m *testing.M) { SecretAccessKey: "localstack", EndpointURL: fmt.Sprintf("http://0.0.0.0:%s", localStackPort), } - dynamoClient, err = dynamodb.NewClient(cfg, logger) + + _, err := test_utils.CreateTable(context.Background(), cfg, metadataTableName, blobstore.GenerateTableSchema(metadataTableName, 10, 10)) if err != nil { teardown() - panic("failed to create dynamodb client: " + err.Error()) + panic("failed to create dynamodb table: " + err.Error()) } - _, err = test_utils.CreateTable(context.Background(), cfg, metadataTableName, blobstore.GenerateTableSchema(metadataTableName, 10, 10)) + dynamoClient, err = dynamodb.NewClient(cfg, logger) if err != nil { teardown() - panic("failed to create dynamodb table: " + err.Error()) + panic("failed to create dynamodb client: " + err.Error()) } blobMetadataStore = blobstore.NewBlobMetadataStore(dynamoClient, logger, metadataTableName, time.Hour) @@ -87,5 +100,7 @@ func setup(m *testing.M) { } func teardown() { - deploy.PurgeDockertestResources(dockertestPool, dockertestResource) + if deployLocalStack { + deploy.PurgeDockertestResources(dockertestPool, dockertestResource) + } } diff --git a/inabox/Makefile b/inabox/Makefile index f7ecdc897c..d494e95ee4 100644 --- a/inabox/Makefile +++ b/inabox/Makefile @@ -13,7 +13,7 @@ stop-geth: cd geth && docker compose down -.PHONY: new-anvil new-docker-anvil infra resources exp deploy-all stop-infra run-e2e run-e2e-nochurner run-e2e-nograph clean +.PHONY: new-anvil new-docker-anvil chain localstack exp deploy-all stop-infra run-e2e run-e2e-nochurner run-e2e-nograph clean new-anvil: mkdir -p "testdata/$(dt)" @@ -23,11 +23,11 @@ new-docker-anvil: mkdir -p "testdata/$(dt)" cp ./templates/testconfig-anvil-docker.yaml "testdata/$(dt)/config.yaml" -infra: - go run ./deploy/cmd -localstack-port 4570 infra +chain: + go run ./deploy/cmd -localstack-port 4570 chain -resources: - go run ./deploy/cmd -localstack-port 4570 resources +localstack: + go run ./deploy/cmd -localstack-port 4570 localstack exp: go run ./deploy/cmd exp @@ -38,7 +38,7 @@ deploy-all: stop-infra: ./bin.sh stop-anvil ./bin.sh stop-graph - docker stop $(shell docker container ls --all --filter=ancestor=localstack/localstack:latest --format "{{.ID}}") + docker stop localstack-test run-e2e: go test ./tests -v -config=../templates/testconfig-anvil.yaml diff --git a/inabox/deploy/cmd/main.go b/inabox/deploy/cmd/main.go index 30a1bea10d..2f519b1b91 100644 --- a/inabox/deploy/cmd/main.go +++ b/inabox/deploy/cmd/main.go @@ -7,22 +7,22 @@ import ( "path/filepath" "github.com/Layr-Labs/eigenda/inabox/deploy" - "github.com/ory/dockertest/v3" "github.com/urfave/cli/v2" ) var ( - testNameFlagName = "testname" - rootPathFlagName = "root-path" - localstackFlagName = "localstack-port" + testNameFlagName = "testname" + rootPathFlagName = "root-path" + localstackFlagName = "localstack-port" + deployResourcesFlagName = "deploy-resources" metadataTableName = "test-BlobMetadata" bucketTableName = "test-BucketStore" - infraCmdName = "infra" - resourcesCmdName = "resources" - expCmdName = "exp" - allCmdName = "all" + chainCmdName = "chain" + localstackCmdName = "localstack" + expCmdName = "exp" + allCmdName = "all" ) func main() { @@ -44,17 +44,22 @@ func main() { Value: "", Usage: "path to the config file", }, + &cli.StringFlag{ + Name: deployResourcesFlagName, + Value: "", + Usage: "whether to deploy localstack resources", + }, }, Commands: []*cli.Command{ { - Name: infraCmdName, - Usage: "deploy the infrastructure (anvil, graph, localstack) for the inabox test", - Action: getRunner(infraCmdName), + Name: chainCmdName, + Usage: "deploy the chain infrastructure (anvil, graph) for the inabox test", + Action: getRunner(chainCmdName), }, { - Name: resourcesCmdName, - Usage: "deploy the AWS resources needed for the inabox test", - Action: getRunner(resourcesCmdName), + Name: localstackCmdName, + Usage: "deploy localstack and create the AWS resources needed for the inabox test", + Action: getRunner(localstackCmdName), }, { Name: expCmdName, @@ -78,28 +83,27 @@ func getRunner(command string) func(ctx *cli.Context) error { return func(ctx *cli.Context) error { - rootPath, err := filepath.Abs(ctx.String(rootPathFlagName)) - if err != nil { - return err - } - - testname := ctx.String(testNameFlagName) - - if testname == "" { - testname, err = deploy.GetLatestTestDirectory(rootPath) + var config *deploy.Config + if command != localstackCmdName { + rootPath, err := filepath.Abs(ctx.String(rootPathFlagName)) if err != nil { return err } + testname := ctx.String(testNameFlagName) + if testname == "" { + testname, err = deploy.GetLatestTestDirectory(rootPath) + if err != nil { + return err + } + } + config = deploy.NewTestConfig(testname, rootPath) } - config := deploy.NewTestConfig(testname, rootPath) - switch command { - case infraCmdName: - _, _, err = infra(ctx, config) - return err - case resourcesCmdName: - return resources(ctx) + case chainCmdName: + return chainInfra(ctx, config) + case localstackCmdName: + return localstack(ctx) case expCmdName: config.DeployExperiment() case allCmdName: @@ -112,9 +116,8 @@ func getRunner(command string) func(ctx *cli.Context) error { } -func infra(ctx *cli.Context, config *deploy.Config) (*dockertest.Pool, *dockertest.Resource, error) { +func chainInfra(ctx *cli.Context, config *deploy.Config) error { - pool, resources, err := deploy.StartDockertestWithLocalstackContainer(ctx.String(localstackFlagName)) config.StartAnvil() if deployer, ok := config.GetDeployer(config.EigenDA.Deployer); ok && deployer.DeploySubgraphs { @@ -122,22 +125,32 @@ func infra(ctx *cli.Context, config *deploy.Config) (*dockertest.Pool, *dockerte config.StartGraphNode() } - return pool, resources, err + return nil } -func resources(ctx *cli.Context) error { - return deploy.DeployResources(nil, ctx.String(localstackFlagName), metadataTableName, bucketTableName) +func localstack(ctx *cli.Context) error { + + pool, _, err := deploy.StartDockertestWithLocalstackContainer(ctx.String(localstackFlagName)) + if err != nil { + return err + } + + if ctx.Bool(deployResourcesFlagName) { + return deploy.DeployResources(pool, ctx.String(localstackFlagName), metadataTableName, bucketTableName) + } + + return nil } func all(ctx *cli.Context, config *deploy.Config) error { - pool, _, err := infra(ctx, config) + err := chainInfra(ctx, config) if err != nil { return err } - err = deploy.DeployResources(pool, ctx.String(localstackFlagName), metadataTableName, bucketTableName) + err = localstack(ctx) if err != nil { return err } diff --git a/inabox/deploy/localstack.go b/inabox/deploy/localstack.go index 0214bac2db..47e29eef4a 100644 --- a/inabox/deploy/localstack.go +++ b/inabox/deploy/localstack.go @@ -36,6 +36,7 @@ func StartDockertestWithLocalstackContainer(localStackPort string) (*dockertest. resource, err := pool.RunWithOptions(&dockertest.RunOptions{ Repository: "localstack/localstack", Tag: "latest", + Name: "localstack-test", ExposedPorts: []string{localStackPort}, PortBindings: map[docker.Port][]docker.PortBinding{ docker.Port(localStackPort): { diff --git a/test.sh b/test.sh new file mode 100755 index 0000000000..a427db184d --- /dev/null +++ b/test.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +result=0 +function tearDown { + docker stop localstack-test + exit $result +} +trap tearDown EXIT + +go run ./inabox/deploy/cmd -localstack-port=4570 -deploy-resources=false localstack +go clean -testcache +# expand all arguments to script at the end of this line +LOCALSTACK_PORT=4570 DEPLOY_LOCALSTACK=false go test -short ./... "$@" +result=$?