From 129c69a6add69b19140492cae76d92c7d4535a5c Mon Sep 17 00:00:00 2001 From: Bernardo Guerreiro <39738771+bernardobridge@users.noreply.github.com> Date: Mon, 13 May 2024 14:55:26 +0100 Subject: [PATCH] feat(lambda): use artillery-hosted ECR image (#2724) * feat(lambda): use artillery-hosted ECR image * test(lambda): add a smoke test for container lambda * fix(lambda): use old naming to maintain iam backwards compatibility * fix(lambda): use correct ECR repo --- .../lib/platform/aws-lambda/index.js | 51 ++----------------- .../fixtures/quick-loop-with-csv/blitz.yml | 3 +- .../fixtures/quick-loop-with-csv/helpers.js | 14 ++++- .../lambda/run-lambda-container.test.js | 35 +++++++++++++ .../test/cloud-e2e/lambda/run-lambda.test.js | 10 ++++ 5 files changed, 65 insertions(+), 48 deletions(-) create mode 100644 packages/artillery/test/cloud-e2e/lambda/run-lambda-container.test.js diff --git a/packages/artillery/lib/platform/aws-lambda/index.js b/packages/artillery/lib/platform/aws-lambda/index.js index 18484cd32c..17ce826ad9 100644 --- a/packages/artillery/lib/platform/aws-lambda/index.js +++ b/packages/artillery/lib/platform/aws-lambda/index.js @@ -75,8 +75,7 @@ class PlatformLambda { const platformConfig = platformOpts.platformConfig; this.currentVersion = process.env.LAMBDA_IMAGE_VERSION || pkgVersion; - this.ecrImageRepository = - process.env.LAMBDA_IMAGE_REPOSITORY || 'artillery-worker'; + this.ecrImageUrl = process.env.WORKER_IMAGE_URL; this.isContainerLambda = platformConfig.container === 'true'; this.architecture = platformConfig.architecture || 'arm64'; this.region = platformConfig.region || 'us-east-1'; @@ -138,7 +137,6 @@ class PlatformLambda { let bom, s3Path; if (this.isContainerLambda) { - await this.ensureECRImageExists(); const result = await createAndUploadTestDependencies( this.bucketName, this.testRunId, @@ -227,7 +225,7 @@ class PlatformLambda { let shouldCreateLambda; if (this.isContainerLambda) { - this.functionName = `artillery-worker-v${this.currentVersion.replace( + this.functionName = `artilleryio-v${this.currentVersion.replace( /\./g, '-' )}`; @@ -628,47 +626,6 @@ class PlatformLambda { return lambdaRoleArn; } - async ensureECRImageExists() { - const ecr = new AWS.ECR({ apiVersion: '2015-09-21', region: this.region }); - - const params = { - repositoryName: this.ecrImageRepository, - imageIds: [{ imageTag: this.currentVersion }] - }; - - let data; - try { - data = await ecr.describeImages(params).promise(); - } catch (err) { - if (err.code === 'RepositoryNotFoundException') { - //TODO: add links to ECR documentation when available - console.error( - `ECR repository not found: ${this.ecrImageRepository}. Have you created an ECR Private Repository in ${this.region}?` - ); - process.exit(1); - } - - if (err.code === 'ImageNotFoundException') { - //TODO: add links to ECR documentation when available - console.error( - `ECR image ${this.currentVersion} not found in repository ${this.ecrImageRepository}. Have you pushed the image to ECR?` - ); - process.exit(1); - } - - throw new Error(`Unexpected error getting ECR image:\n${err}`); - } - - if (data.imageDetails[0].imageTags.includes(this.currentVersion)) { - return; - } else { - console.error( - `ECR image ${this.currentVersion} not found in repository ${this.ecrImageRepository}. Have you pushed the image to ECR?` - ); - process.exit(1); - } - } - async checkIfNewLambdaIsNeeded({ memorySize, functionName }) { const lambda = new AWS.Lambda({ apiVersion: '2015-03-31', @@ -712,7 +669,9 @@ class PlatformLambda { lambdaConfig = { PackageType: 'Image', Code: { - ImageUri: `${this.accountId}.dkr.ecr.${this.region}.amazonaws.com/${this.ecrImageRepository}:${this.currentVersion}` + ImageUri: + this.ecrImageUrl || + `248481025674.dkr.ecr.${this.region}.amazonaws.com/artillery-worker:${this.currentVersion}` }, ImageConfig: { Command: ['a9-handler-index.handler'], diff --git a/packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/blitz.yml b/packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/blitz.yml index c6c68b74ae..61b09872c5 100644 --- a/packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/blitz.yml +++ b/packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/blitz.yml @@ -1,5 +1,6 @@ scenarios: - - flow: + - beforeScenario: emitCsvCounters + flow: - loop: - get: url: "/dino" diff --git a/packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/helpers.js b/packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/helpers.js index a0e5840bf6..b586c9f660 100644 --- a/packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/helpers.js +++ b/packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/helpers.js @@ -1,4 +1,4 @@ -module.exports = { maybeSleep }; +module.exports = { maybeSleep, emitCsvCounters }; function maybeSleep(req, context, events, done) { if (Math.random() < 0.7) { @@ -9,3 +9,15 @@ function maybeSleep(req, context, events, done) { return done(); }, Math.random() * 1000); } + +function emitCsvCounters(context, events, done) { + if (context.vars.number) { + events.emit('counter', `csv_number_${context.vars.number}`, 1); + } + + if (context.vars.name) { + events.emit('counter', `csv_name_${context.vars.name}`, 1); + } + + return done(); +} diff --git a/packages/artillery/test/cloud-e2e/lambda/run-lambda-container.test.js b/packages/artillery/test/cloud-e2e/lambda/run-lambda-container.test.js new file mode 100644 index 0000000000..2340f962ae --- /dev/null +++ b/packages/artillery/test/cloud-e2e/lambda/run-lambda-container.test.js @@ -0,0 +1,35 @@ +const tap = require('tap'); +const { $ } = require('zx'); +const { getTestTags } = require('../../cli/_helpers.js'); + +tap.test('Run a test on AWS Lambda using containers', async (t) => { + const tags = getTestTags(['type:acceptance']); + const configPath = `${__dirname}/fixtures/quick-loop-with-csv/config.yml`; + const scenarioPath = `${__dirname}/fixtures/quick-loop-with-csv/blitz.yml`; + + process.env.LAMBDA_IMAGE_VERSION = process.env.ECR_IMAGE_VERSION; + + const output = + await $`artillery run-lambda --count 10 --region us-east-1 --container --config ${configPath} --record --tags ${tags} ${scenarioPath}`; + + t.equal(output.exitCode, 0, 'CLI should exit with code 0'); + + t.ok( + output.stdout.indexOf('Summary report') > 0, + 'Should print summary report' + ); + t.ok( + output.stdout.indexOf('http.codes.200') > 0, + 'Should print http.codes.200' + ); + + t.ok( + output.stdout.indexOf('csv_number_') > 0, + 'Should print csv_number_ counters' + ); + + t.ok( + output.stdout.indexOf('csv_name_') > 0, + 'Should print csv_name_ counters' + ); +}); diff --git a/packages/artillery/test/cloud-e2e/lambda/run-lambda.test.js b/packages/artillery/test/cloud-e2e/lambda/run-lambda.test.js index fb0cba6505..53d4eff88a 100644 --- a/packages/artillery/test/cloud-e2e/lambda/run-lambda.test.js +++ b/packages/artillery/test/cloud-e2e/lambda/run-lambda.test.js @@ -20,4 +20,14 @@ tap.test('Run a test on AWS Lambda', async (t) => { output.stdout.indexOf('http.codes.200') > 0, 'Should print http.codes.200' ); + + t.ok( + output.stdout.indexOf('csv_number_') > 0, + 'Should print csv_number_ counters' + ); + + t.ok( + output.stdout.indexOf('csv_name_') > 0, + 'Should print csv_name_ counters' + ); });