Skip to content

Commit f700dc9

Browse files
authored
chore(tests): convert remote datastore remote tests to testcontainers… (#543)
We have totally skipped remote datastore tests in CI. This PR rewrites Datastore Remote tests to use testcontainers that can use running service or create the service out of docker image locally and in CI. Updating workflows to actually get the service docker image and run tests on it. https://smartcontract-it.atlassian.net/browse/CLD-760 CI run https://github.com/smartcontractkit/chainlink-deployments-framework/actions/runs/18840463376/job/53751297255?pr=543 ~1 minute
1 parent 2229818 commit f700dc9

File tree

7 files changed

+536
-9
lines changed

7 files changed

+536
-9
lines changed

.github/workflows/pull-request-main.yml

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ jobs:
4545
# disable the checkptr runtime check due a false positive in github.com/xssnick/tonutils-go
4646
# causing tests in ci to fail "fatal error: checkptr: pointer arithmetic result points to invalid allocation"
4747
# https://github.com/xssnick/tonutils-go/issues/310
48-
# Exclude provider packages which use Docker containers
49-
go-test-cmd: go test -race -gcflags=all=-d=checkptr=0 -coverprofile=coverage.txt $(go list ./... | grep -v '/provider')
48+
# Exclude provider packages which use Docker containers and remote catalog tests
49+
go-test-cmd: go test -race -gcflags=all=-d=checkptr=0 -coverprofile=coverage.txt $(go list ./... | grep -v '/provider' | grep -v '/catalog/remote')
5050
use-go-cache: true
5151
artifact-name: unit-tests
5252

@@ -71,11 +71,39 @@ jobs:
7171
use-go-cache: true
7272
artifact-name: provider-tests
7373

74+
ci-test-catalog-remote:
75+
name: Catalog Remote Tests
76+
runs-on: ubuntu-latest
77+
timeout-minutes: 15
78+
permissions:
79+
id-token: write
80+
contents: read
81+
actions: read
82+
env:
83+
CATALOG_SERVICE_IMAGE: ${{ secrets.AWS_ACCOUNT_NUMBER_PROD }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com/op-catalog-service:latest
84+
steps:
85+
- name: Pull Catalog Service ECR Image
86+
uses: smartcontractkit/.github/actions/pull-private-ecr-image@2f8f0baf38e46140c6a119eb551a56eaaabcc09e # [email protected]
87+
with:
88+
aws-account-number: ${{ secrets.AWS_ACCOUNT_NUMBER_PROD }}
89+
aws-region: ${{ secrets.AWS_REGION }}
90+
aws-role-arn: ${{ secrets.ECR_READ_ROLE_ARN }}
91+
ecr-repository: "op-catalog-service"
92+
image-tag: "latest"
93+
94+
- name: Run Catalog Remote Integration Tests
95+
uses: smartcontractkit/.github/actions/ci-test-go@dfcba48f05933158428bce867d790e3d5a9baa6b # [email protected]
96+
with:
97+
# Must cd into datastore/catalog/remote because TestMain only runs from package directory
98+
go-test-cmd: cd datastore/catalog/remote && go test -v -race -timeout 10m -gcflags=all=-d=checkptr=0 -coverprofile=../../../coverage.txt
99+
use-go-cache: true
100+
artifact-name: catalog-remote-tests
101+
74102
sonarqube:
75103
name: Sonar Scan
76104
if: github.event_name == 'pull_request'
77105
runs-on: ubuntu-24.04
78-
needs: [ci-test, ci-test-provider, ci-lint-misc, ci-lint]
106+
needs: [ci-test, ci-test-provider, ci-test-catalog-remote, ci-lint-misc, ci-lint]
79107
permissions:
80108
contents: read
81109
actions: read

.github/workflows/schedule-main.yml

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,19 +40,65 @@ jobs:
4040
actions: read
4141
steps:
4242
- name: Build and test
43-
uses: smartcontractkit/.github/actions/ci-test-go@eeb76b5870e3c17856d5a60fd064a053c023b5f5 # [email protected]
43+
uses: smartcontractkit/.github/actions/ci-test-go@dfcba48f05933158428bce867d790e3d5a9baa6b # [email protected]
44+
with:
45+
# disable the checkptr runtime check due a false positive in github.com/xssnick/tonutils-go
46+
# Exclude provider packages which use Docker containers and remote catalog tests
47+
go-test-cmd: go test -race -gcflags=all=-d=checkptr=0 -coverprofile=coverage.txt $(go list ./... | grep -v '/provider' | grep -v '/catalog/remote')
48+
use-go-cache: true
49+
artifact-name: unit-tests
50+
51+
ci-test-provider:
52+
name: Provider Tests
53+
runs-on: ubuntu-latest
54+
timeout-minutes: 10
55+
permissions:
56+
id-token: write
57+
contents: read
58+
actions: read
59+
steps:
60+
- name: Build and test provider packages
61+
uses: smartcontractkit/.github/actions/ci-test-go@dfcba48f05933158428bce867d790e3d5a9baa6b # [email protected]
4462
with:
4563
# disable the checkptr runtime check due a false positive in github.com/xssnick/tonutils-go
46-
# causing tests in ci to fail "fatal error: checkptr: pointer arithmetic result points to invalid allocation"
47-
# https://github.com/xssnick/tonutils-go/issues/310
4864
# -p 2 -parallel 3 = 2 packages, 3 tests max = 6 containers max
49-
go-test-cmd: go test -race -gcflags=all=-d=checkptr=0 -p 2 -parallel 3 -coverprofile=coverage.txt $(go list ./...)
65+
# Only run provider packages which use Docker containers
66+
go-test-cmd: go test -race -gcflags=all=-d=checkptr=0 -p 2 -parallel 3 -coverprofile=coverage.txt $(go list ./... | grep '/provider')
67+
use-go-cache: true
68+
artifact-name: provider-tests
69+
70+
ci-test-catalog-remote:
71+
name: Catalog Remote Tests
72+
runs-on: ubuntu-latest
73+
timeout-minutes: 15
74+
permissions:
75+
id-token: write
76+
contents: read
77+
actions: read
78+
env:
79+
CATALOG_SERVICE_IMAGE: ${{ secrets.AWS_ACCOUNT_NUMBER_PROD }}.dkr.ecr.${{ secrets.AWS_REGION }}.amazonaws.com/op-catalog-service:latest
80+
steps:
81+
- name: Pull Catalog Service ECR Image
82+
uses: smartcontractkit/.github/actions/pull-private-ecr-image@2f8f0baf38e46140c6a119eb551a56eaaabcc09e # [email protected]
83+
with:
84+
aws-account-number: ${{ secrets.AWS_ACCOUNT_NUMBER_PROD }}
85+
aws-region: ${{ secrets.AWS_REGION }}
86+
aws-role-arn: ${{ secrets.ECR_READ_ROLE_ARN }}
87+
ecr-repository: "op-catalog-service"
88+
image-tag: "latest"
89+
90+
- name: Run Catalog Remote Integration Tests
91+
uses: smartcontractkit/.github/actions/ci-test-go@dfcba48f05933158428bce867d790e3d5a9baa6b # [email protected]
92+
with:
93+
# Must cd into datastore/catalog/remote because TestMain only runs from package directory
94+
go-test-cmd: cd datastore/catalog/remote && go test -v -race -timeout 10m -gcflags=all=-d=checkptr=0 -coverprofile=../../../coverage.txt
5095
use-go-cache: true
96+
artifact-name: catalog-remote-tests
5197

5298
sonarqube:
5399
name: Sonar Scan
54100
runs-on: ubuntu-24.04
55-
needs: [ci-test, ci-lint-misc, ci-lint]
101+
needs: [ci-test, ci-test-provider, ci-test-catalog-remote, ci-lint-misc, ci-lint]
56102
permissions:
57103
contents: read
58104
actions: read

datastore/catalog/remote/README.md

Lines changed: 88 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,91 @@ state to be maintained through that stream connection. If the stream closes,
66
normal cleanup will rollback the transaction. The [Catalog service APIs] include
77
message to begin, commit, and roll-back a transaction.
88

9-
[Catalog service APIs]: http://github.com/smartcontractkit/chainlink-catalog
9+
[Catalog service APIs]: http://github.com/smartcontractkit/op-catalog
10+
11+
## Running Tests
12+
13+
The tests in this package use **testcontainers** to automatically start the required services:
14+
- PostgreSQL database
15+
- Catalog service (from ECR or local image)
16+
- Database migration
17+
18+
**Important:** Testcontainers uses images from your local Docker daemon. You must either:
19+
1. Build the image locally from the `op-catalog` directory:
20+
```bash
21+
cd op-catalog
22+
docker build -t op-catalog-service:latest .
23+
```
24+
2. Pull from ECR with a specific tag: `docker pull 123123123123.dkr.ecr.us-east-1.amazonaws.com/op-catalog-service:TAG`
25+
- Use `aws ecr describe-images` to find available tags
26+
- Common patterns: version tags (v0.0.1)
27+
28+
### Quick Start (Local Build)
29+
30+
```bash
31+
# Build the catalog service image first
32+
cd op-catalog
33+
docker build -t op-catalog-service:latest .
34+
35+
# Run the tests (must be in the remote directory)
36+
cd ../chainlink-deployments-framework/datastore/catalog/remote
37+
go test -v
38+
```
39+
40+
## Configuration Options
41+
42+
### Environment Variables
43+
44+
- `CATALOG_SERVICE_IMAGE`: The Docker image to use for the catalog service
45+
- Default: `op-catalog-service:latest`
46+
- CI: Set to the ECR image URL
47+
- Example: `export CATALOG_SERVICE_IMAGE="123456789.dkr.ecr.us-east-1.amazonaws.com/op-catalog-service:latest"`
48+
49+
- `CATALOG_GRPC_ADDRESS`: Connect to an existing catalog service instead of starting containers
50+
- Example: `export CATALOG_GRPC_ADDRESS="localhost:8080"`
51+
52+
## Running Without Testcontainers
53+
54+
If you prefer to manage the services manually:
55+
56+
### Option 1: Docker Compose
57+
58+
```bash
59+
cd op-catalog
60+
docker-compose up -d
61+
62+
# Wait for the service to be ready
63+
sleep 5
64+
65+
# Run tests pointing to the local service
66+
cd ../chainlink-deployments-framework/datastore/catalog/remote
67+
export CATALOG_GRPC_ADDRESS="localhost:8080"
68+
go test -v
69+
```
70+
71+
## CI/CD Integration
72+
73+
The CI workflow automatically:
74+
1. Downloads the latest Catalog service image from ECR
75+
2. Runs the tests with testcontainers using the downloaded image
76+
3. Generates coverage reports
77+
78+
See `.github/workflows/pull-request-main.yml` for the full configuration.
79+
80+
## Test Workflow
81+
82+
The test setup follows this flow:
83+
84+
1. **TestMain** (`main_test.go`) - Entry point that:
85+
- Checks for `CATALOG_GRPC_ADDRESS` environment variable
86+
- If not set, starts testcontainers automatically
87+
- Sets up PostgreSQL and Catalog service
88+
- Runs all tests
89+
- Cleans up containers
90+
91+
2. **TestContainerSetup** (`testcontainer_setup.go`) - Manages:
92+
- Docker network creation
93+
- PostgreSQL container startup
94+
- Database migration via catalog service
95+
- Catalog service container startup
96+
- Port mapping and connection details
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package remote
2+
3+
import (
4+
"context"
5+
"log"
6+
"os"
7+
"testing"
8+
"time"
9+
)
10+
11+
var (
12+
// globalTestSetup is the shared testcontainer setup for all remote tests
13+
globalTestSetup *TestContainerSetup
14+
// catalogGRPCAddress is the address of the catalog service for tests
15+
catalogGRPCAddress string
16+
)
17+
18+
// TestMain is the entry point for all tests in this package
19+
// It sets up testcontainers once for all tests and tears them down at the end
20+
func TestMain(m *testing.M) {
21+
// Check if we should use an existing catalog service instead of testcontainers
22+
existingAddr := os.Getenv("CATALOG_GRPC_ADDRESS")
23+
if existingAddr != "" {
24+
log.Printf("Using existing catalog service at: %s", existingAddr)
25+
catalogGRPCAddress = existingAddr
26+
// Run tests and exit
27+
os.Exit(m.Run())
28+
}
29+
30+
// Setup context with timeout for initialization
31+
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute)
32+
defer cancel()
33+
34+
log.Println("========================================")
35+
log.Println("Setting up testcontainers for catalog remote tests...")
36+
log.Println("========================================")
37+
38+
// Setup testcontainers
39+
setup, err := SetupCatalogTestContainers(ctx)
40+
if err != nil {
41+
log.Fatalf("Failed to setup testcontainers: %v", err)
42+
}
43+
globalTestSetup = setup
44+
catalogGRPCAddress = setup.GetCatalogGRPCAddress()
45+
46+
log.Println("========================================")
47+
log.Println("Testcontainers setup complete!")
48+
log.Printf("PostgreSQL DSN: %s", setup.PostgresDSN)
49+
log.Printf("Catalog gRPC Address: %s", catalogGRPCAddress)
50+
log.Println("========================================")
51+
52+
// Set the environment variable so tests can find the service
53+
os.Setenv("CATALOG_GRPC_ADDRESS", catalogGRPCAddress)
54+
55+
// Run all tests
56+
exitCode := m.Run()
57+
58+
// Cleanup
59+
log.Println("========================================")
60+
log.Println("Cleaning up testcontainers...")
61+
log.Println("========================================")
62+
63+
// Use a fresh context for cleanup to avoid timeout issues
64+
cleanupCtx, cleanupCancel := context.WithTimeout(context.Background(), 2*time.Minute)
65+
defer cleanupCancel()
66+
67+
if err := globalTestSetup.Teardown(cleanupCtx); err != nil {
68+
log.Printf("Warning: Failed to teardown testcontainers: %v", err)
69+
}
70+
71+
log.Println("Cleanup complete!")
72+
os.Exit(exitCode)
73+
}

0 commit comments

Comments
 (0)