Skip to content

Commit

Permalink
Use localstack for AWS testing (#1067)
Browse files Browse the repository at this point in the history
* Use localstack for AWS testing
* Fix AwsSecretsManagerProviderTest
* Modify multipleValueTransfers to wait for each transaction hash in a loop
  • Loading branch information
usmansaleem authored Mar 5, 2025
1 parent c4fddf9 commit 70ad630
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 20 deletions.
20 changes: 15 additions & 5 deletions .github/workflows/ci_main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,25 @@ jobs:
id: project-version
uses: ./.github/actions/project-version

- name: Start LocalStack (AWS)
id: localstack
uses: LocalStack/[email protected]
with:
image-tag: 'latest'
configuration: LOCALSTACK_DEBUG=1

- name: Build and Test
id: build-test
uses: ./.github/actions/build-test
env:
AWS_REGION: ${{ secrets.AWS_REGION }}
AWS_ACCESS_KEY_ID: ${{ secrets.RO_AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.RO_AWS_SECRET_ACCESS_KEY }}
RW_AWS_ACCESS_KEY_ID: ${{ secrets.RW_AWS_ACCESS_KEY_ID }}
RW_AWS_SECRET_ACCESS_KEY: ${{ secrets.RW_AWS_SECRET_ACCESS_KEY }}
AWS_REGION: 'us-east-2'
AWS_ACCESS_KEY_ID: 'test'
AWS_SECRET_ACCESS_KEY: 'test'
RW_AWS_ACCESS_KEY_ID: 'test'
RW_AWS_SECRET_ACCESS_KEY: 'test'
AWS_ACCESS_KEY_ID_TEST2: 'test2'
AWS_SECRET_ACCESS_KEY_TEST2: 'test2'
AWS_ENDPOINT_OVERRIDE: 'http://127.0.0.1:4566'
AZURE_CLIENT_ID: ${{ secrets.AZURE_CLIENT_ID }}
AZURE_CLIENT_SECRET: ${{ secrets.AZURE_CLIENT_SECRET }}
AZURE_INVALID_KEY_VAULT_NAME: ${{ secrets.AZURE_INVALID_KEY_VAULT_NAME }}
Expand Down
4 changes: 4 additions & 0 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ on:
schedule:
- cron: '39 22 * * 5'

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
analyze:
name: Analyze
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,8 @@ public void createAwsYamlFileAt(
final String awsRegion,
final String accessKeyId,
final String secretAccessKey,
final String secretName) {
final String secretName,
final Optional<URI> awsEndpointOverride) {
try {
final Map<String, String> signingMetadata = new HashMap<>();

Expand All @@ -243,23 +244,29 @@ public void createAwsYamlFileAt(
signingMetadata.put("accessKeyId", accessKeyId);
signingMetadata.put("secretAccessKey", secretAccessKey);
signingMetadata.put("secretName", secretName);
awsEndpointOverride.ifPresent(
endpoint -> signingMetadata.put("endpointOverride", endpoint.toString()));

createYamlFile(metadataFilePath, signingMetadata);
} catch (final Exception e) {
throw new RuntimeException("Unable to construct aws yaml file", e);
}
}

public void createAwsYamlFileAt(
final Path metadataFilePath, final String awsRegion, final String secretName) {
public void createAwsYamlFileWithEnvironmentAt(
final Path metadataFilePath,
final String awsRegion,
final String secretName,
final Optional<URI> awsEndpointOverride) {
try {
final Map<String, String> signingMetadata = new HashMap<>();

signingMetadata.put("type", "aws-secret");
signingMetadata.put("authenticationMode", "ENVIRONMENT");
signingMetadata.put("region", awsRegion);
signingMetadata.put("secretName", secretName);

awsEndpointOverride.ifPresent(
endpoint -> signingMetadata.put("endpointOverride", endpoint.toString()));
createYamlFile(metadataFilePath, signingMetadata);
} catch (final Exception e) {
throw new RuntimeException("Unable to construct aws yaml file", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
import tech.pegasys.web3signer.tests.eth1rpc.Eth1RpcAcceptanceTestBase;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -200,11 +202,12 @@ public void multipleValueTransfers() {
RECIPIENT,
transferAmountWei);

String hash = null;
List<String> hashes = new ArrayList<>();
for (int i = 0; i < FIFTY_TRANSACTIONS; i++) {
hash = signer.transactions().submit(transaction);
hashes.add(signer.transactions().submit(transaction));
}
besu.transactions().awaitBlockContaining(hash);

hashes.forEach(hash -> besu.transactions().awaitBlockContaining(hash));

final BigInteger endBalance = besu.accounts().balance(RECIPIENT);
final BigInteger numberOfTransactions = BigInteger.valueOf(FIFTY_TRANSACTIONS);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,20 @@ public void specifiedAwsKeysReturnAppropriatePublicKey() {
AWS_REGION,
RO_AWS_ACCESS_KEY_ID,
RO_AWS_SECRET_ACCESS_KEY,
awsSecretsManagerUtil.getSecretsManagerPrefix() + publicKey);
awsSecretsManagerUtil.getSecretsManagerPrefix() + publicKey,
awsEndpointOverride);
initAndStartSigner("eth2");
final Response response = callApiPublicKeysWithoutOpenApiClientSideFilter(BLS);
validateApiResponse(response, containsInAnyOrder(publicKey));
}

@Test
public void environmentAwsKeysReturnAppropriatePublicKey() {
METADATA_FILE_HELPERS.createAwsYamlFileAt(
METADATA_FILE_HELPERS.createAwsYamlFileWithEnvironmentAt(
testDirectory.resolve(publicKey + ".yaml"),
AWS_REGION,
awsSecretsManagerUtil.getSecretsManagerPrefix() + publicKey);
awsSecretsManagerUtil.getSecretsManagerPrefix() + publicKey,
awsEndpointOverride);
initAndStartSigner("eth2");
final Response response = callApiPublicKeysWithoutOpenApiClientSideFilter(BLS);
validateApiResponse(response, containsInAnyOrder(publicKey));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,12 @@ public void ableToSignUsingAws() throws JsonProcessingException {
final Path keyConfigFile = testDirectory.resolve(configFilename + ".yaml");
try {
METADATA_FILE_HELPERS.createAwsYamlFileAt(
keyConfigFile, region, roAwsAccessKeyId, roAwsSecretAccessKey, fullyPrefixKeyName);
keyConfigFile,
region,
roAwsAccessKeyId,
roAwsSecretAccessKey,
fullyPrefixKeyName,
awsEndpointOverride);

signAndVerifySignature(ArtifactType.BLOCK);
} finally {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@EnabledIfEnvironmentVariable(
named = "RW_AWS_ACCESS_KEY_ID",
named = "AWS_ACCESS_KEY_ID_TEST2",
matches = ".+",
disabledReason = "RW_AWS_ACCESS_KEY_ID env variable is required")
@EnabledIfEnvironmentVariable(
named = "RW_AWS_SECRET_ACCESS_KEY",
named = "AWS_SECRET_ACCESS_KEY_TEST2",
matches = ".+",
disabledReason = "RW_AWS_SECRET_ACCESS_KEY env variable is required")
@EnabledIfEnvironmentVariable(
Expand All @@ -50,8 +50,9 @@ class AwsSecretsManagerProviderTest {
private final String AWS_SECRET_ACCESS_KEY = System.getenv("AWS_SECRET_ACCESS_KEY");
private final String AWS_REGION =
Optional.ofNullable(System.getenv("AWS_REGION")).orElse("us-east-2");
private final String DIFFERENT_AWS_ACCESS_KEY_ID = System.getenv("RW_AWS_ACCESS_KEY_ID");
private final String DIFFERENT_AWS_SECRET_ACCESS_KEY = System.getenv("RW_AWS_SECRET_ACCESS_KEY");
private final String DIFFERENT_AWS_ACCESS_KEY_ID = System.getenv("AWS_ACCESS_KEY_ID_TEST2");
private final String DIFFERENT_AWS_SECRET_ACCESS_KEY =
System.getenv("AWS_SECRET_ACCESS_KEY_TEST2");
private final String DIFFERENT_AWS_REGION = "us-east-1";

// can be pointed to localstack
Expand Down
40 changes: 40 additions & 0 deletions localstack/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Localstack for AWS services testing

The AWS related unit, integration and acceptance tests can be tested against localstack.
Use following command to start localstack services.

```bash
docker compose up
```

Use `CTRL-C` or run `docker compose down` from the same directory but from another shell instance.

Export following environment variables before running Web3Signer tests.

```bash
export RW_AWS_ACCESS_KEY_ID=test
export RW_AWS_SECRET_ACCESS_KEY=test
export AWS_ACCESS_KEY_ID=test
export AWS_SECRET_ACCESS_KEY=test
export AWS_ACCESS_KEY_ID_TEST2=test2
export AWS_SECRET_ACCESS_KEY_TEST2=test2
export AWS_REGION=us-east-2
export AWS_ENDPOINT_OVERRIDE=http://127.0.0.1:4566
```

To import above in IntelliJ IDEA Run configurations:
```
RW_AWS_ACCESS_KEY_ID=test
RW_AWS_SECRET_ACCESS_KEY=test
AWS_ACCESS_KEY_ID=test
AWS_SECRET_ACCESS_KEY=test
AWS_REGION=us-east-2
AWS_ACCESS_KEY_ID_TEST2=test2
AWS_SECRET_ACCESS_KEY_TEST2=test2
AWS_ENDPOINT_OVERRIDE=http://127.0.0.1:4566
```

Run gradle tests.
```bash

```
18 changes: 18 additions & 0 deletions localstack/compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
services:
# see https://docs.localstack.cloud/getting-started/installation/#docker-compose
# see https://docs.localstack.cloud/references/configuration/
localstack:
container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}"
image: localstack/localstack
ports:
- "127.0.0.1:4566:4566" # LocalStack Gateway
- "127.0.0.1:4510-4559:4510-4559" # external services port range
environment:
# LocalStack configuration
- DEBUG=${DEBUG-}
- DOCKER_HOST=unix:///var/run/docker.sock
# ready hook script configuration
volumes:
#- "${LOCALSTACK_VOLUME_DIR:-./volume}:/var/lib/localstack"
#- "./init/ready.d:/etc/localstack/init/ready.d" # ready hooks
- "${DOCKER_HOST_PATH:-/var/run/docker.sock}:/var/run/docker.sock"

0 comments on commit 70ad630

Please sign in to comment.