diff --git a/.github/workflows/docker-ecs-worker-image.yml b/.github/workflows/docker-ecs-worker-image.yml index f347254348..8bbc676012 100644 --- a/.github/workflows/docker-ecs-worker-image.yml +++ b/.github/workflows/docker-ecs-worker-image.yml @@ -5,6 +5,15 @@ on: push: branches: - main + workflow_call: + inputs: + ref: + description: 'Branch ref to checkout. Needed for pull_request_target to be able to pull correct ref.' + type: string + secrets: + ECR_WORKER_IMAGE_PUSH_ROLE_ARN: + description: 'ARN of the IAM role to assume to push the image to ECR.' + required: true permissions: id-token: write @@ -16,6 +25,7 @@ jobs: steps: - uses: actions/checkout@v3 with: + ref: ${{ inputs.ref || null }} fetch-depth: 0 - name: Show git ref diff --git a/.github/workflows/run-aws-tests.yml b/.github/workflows/run-aws-tests.yml new file mode 100644 index 0000000000..4a049aef9f --- /dev/null +++ b/.github/workflows/run-aws-tests.yml @@ -0,0 +1,75 @@ +name: Run AWS tests + +on: + pull_request_target: + branches: [main] + #opened, reopened and synchronize will cause the workflow to fail on forks due to permissions + #once labeled, that will then be overridden by the is-collaborator job + types: [opened, labeled, synchronize, reopened] + +jobs: + is-collaborator: + runs-on: ubuntu-latest + steps: + - name: Get User Permission + id: checkAccess + uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b + with: + require: write + username: ${{ github.actor }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Check User Permission + if: steps.checkAccess.outputs.require-result == 'false' + run: | + echo "${{ github.actor }} does not have permissions on this repo." + echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}" + exit 1 + + publish-branch-image: + if: contains( github.event.pull_request.labels.*.name, 'run-aws-tests' ) + needs: is-collaborator + uses: ./.github/workflows/docker-ecs-worker-image.yml + permissions: + contents: read + id-token: write + secrets: + ECR_WORKER_IMAGE_PUSH_ROLE_ARN: ${{ secrets.ECR_WORKER_IMAGE_PUSH_ROLE_ARN }} + with: + ref: ${{ github.event.pull_request.head.sha || null }} # this should only be run with this ref if is-collaborator has been run and passed + + run-tests: + if: contains( github.event.pull_request.labels.*.name, 'run-aws-tests' ) + needs: publish-branch-image + timeout-minutes: 40 + runs-on: ubuntu-latest + permissions: + contents: read + id-token: write + steps: + - uses: actions/checkout@v3 + with: + ref: ${{ github.event.pull_request.head.sha || null }} # this should only be run with this ref if is-collaborator has been run and passed + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v2 + env: + SHOW_STACK_TRACE: true + with: + aws-region: eu-west-1 + role-to-assume: ${{ secrets.ARTILLERY_AWS_CLI_ROLE_ARN_TEST1 }} + role-session-name: OIDCSession + mask-aws-account-id: true + - name: Use Node.js 18.x + uses: actions/setup-node@v2 + with: + node-version: 18.x + - run: npm install + - run: npm run build + - run: npm run test:aws --workspace artillery + env: + FORCE_COLOR: 1 + ECR_IMAGE_VERSION: ${{ github.sha }} # the image is published with the sha of the commit within this repo + ARTILLERY_CLOUD_ENDPOINT: ${{ secrets.ARTILLERY_CLOUD_ENDPOINT_TEST }} + ARTILLERY_CLOUD_API_KEY: ${{ secrets.ARTILLERY_CLOUD_API_KEY_TEST }} + GITHUB_REPO: ${{ github.repository }} + GITHUB_ACTOR: ${{ github.actor }} \ No newline at end of file diff --git a/packages/artillery/lib/cmds/run.js b/packages/artillery/lib/cmds/run.js index e0fff882fa..002d4f9d6e 100644 --- a/packages/artillery/lib/cmds/run.js +++ b/packages/artillery/lib/cmds/run.js @@ -22,7 +22,6 @@ const fs = require('fs'); const path = require('path'); const crypto = require('crypto'); const os = require('os'); -const esbuild = require('esbuild-wasm'); const createLauncher = require('../launch-platform'); const createConsoleReporter = require('../../console-reporter'); @@ -406,6 +405,10 @@ function replaceProcessorIfTypescript(script, scriptPath, platform) { `${processorFileName}-${Date.now()}.js` ); + //TODO: move require to top of file when Lambda bundle size issue is solved + //must be conditionally required for now as this package is removed in Lambda for now to avoid bigger package sizes + const esbuild = require('esbuild-wasm'); + try { esbuild.buildSync({ entryPoints: [actualProcessorPath], @@ -634,6 +637,30 @@ async function sendTelemetry(script, flags, extraProps) { } } + // publish-metrics reporters + if (script.config.plugins['publish-metrics']) { + const OFFICIAL_REPORTERS = [ + 'datadog', + 'open-telemetry', + 'lightstep', + 'newrelic', + 'splunk', + 'dynatrace', + 'cloudwatch', + 'honeycomb', + 'mixpanel', + 'prometheus' + ]; + + properties.officialMonitoringReporters = script.config.plugins[ + 'publish-metrics' + ].map((reporter) => { + if (OFFICIAL_REPORTERS.includes(reporter.type)) { + return reporter.type; + } + }); + } + // before/after hooks if (script.before) { properties.beforeHook = true; diff --git a/packages/artillery/package.json b/packages/artillery/package.json index b9a444db17..d0b0f66aa4 100644 --- a/packages/artillery/package.json +++ b/packages/artillery/package.json @@ -46,7 +46,7 @@ "test:unit": "export ARTILLERY_TELEMETRY_DEFAULTS='{\"source\":\"test-suite\"}' && tap --no-coverage --timeout=420 --color test/unit/*.test.js", "test:acceptance": "export ARTILLERY_TELEMETRY_DEFAULTS='{\"source\":\"test-suite\"}' && tap --no-coverage --timeout=420 test/cli/*.test.js && bash test/lib/run.sh && tap --no-coverage --color test/testcases/plugins/*.test.js", "test": "npm run test:unit && npm run test:acceptance", - "test:cloud": "export ARTILLERY_TELEMETRY_DEFAULTS='{\"source\":\"test-suite\"}' && tap --no-coverage --timeout=300 test/cloud-e2e/*.test.js", + "test:aws": "export ARTILLERY_TELEMETRY_DEFAULTS='{\"source\":\"test-suite\"}' && tap --no-coverage --color --timeout=3600 test/cloud-e2e/**/*.test.js", "lint": "eslint --ext \".js,.ts,.tsx\" .", "lint-fix": "npm run lint -- --fix" }, diff --git a/packages/artillery/test/cli/_helpers.js b/packages/artillery/test/cli/_helpers.js index c2d0c9299c..da40f4f672 100644 --- a/packages/artillery/test/cli/_helpers.js +++ b/packages/artillery/test/cli/_helpers.js @@ -5,6 +5,7 @@ const path = require('path'); const os = require('os'); const { getBinPathSync } = require('get-bin-path'); const a9path = getBinPathSync(); +const { createHash } = require('crypto'); async function execute(args, options) { try { @@ -30,4 +31,27 @@ async function getRootPath(filename) { return path.resolve(__dirname, '..', '..', filename); } -module.exports = { execute, deleteFile, getRootPath, returnTmpPath }; +function generateTmpReportPath(testName, extension) { + return returnTmpPath( + `report-${createHash('md5') + .update(testName) + .digest('hex')}-${Date.now()}.${extension}` + ); +} + +function getTestTags(additionalTags) { + const actorTag = `actor:${process.env.GITHUB_ACTOR || 'localhost'}`; + const repoTag = `repo:${process.env.GITHUB_REPO || 'artilleryio/artillery'}`; + const ciTag = `ci:${process.env.GITHUB_ACTIONS ? 'true' : 'false'}`; + + return `${repoTag},${actorTag},${ciTag},${additionalTags.join(',')}`; +} + +module.exports = { + execute, + deleteFile, + getRootPath, + returnTmpPath, + generateTmpReportPath, + getTestTags +}; diff --git a/packages/artillery/test/cli/command-report.test.js b/packages/artillery/test/cli/command-report.test.js index a3a923a572..4e8b16a091 100644 --- a/packages/artillery/test/cli/command-report.test.js +++ b/packages/artillery/test/cli/command-report.test.js @@ -1,8 +1,8 @@ const tap = require('tap'); -const { execute, returnTmpPath } = require('../cli/_helpers.js'); +const { execute, generateTmpReportPath } = require('../cli/_helpers.js'); tap.test('If we report specifying output, no browser is opened', async (t) => { - const outputFilePath = returnTmpPath('report.html'); + const outputFilePath = generateTmpReportPath(t.name, 'html'); const [exitCode] = await execute([ 'report', diff --git a/packages/artillery/test/cli/command-run.test.js b/packages/artillery/test/cli/command-run.test.js index 905321395b..ec01baa510 100644 --- a/packages/artillery/test/cli/command-run.test.js +++ b/packages/artillery/test/cli/command-run.test.js @@ -3,20 +3,16 @@ const { execute, deleteFile, getRootPath, - returnTmpPath + returnTmpPath, + generateTmpReportPath } = require('../cli/_helpers.js'); const fs = require('fs'); const path = require('path'); const execa = require('execa'); -const { createHash } = require('crypto'); let reportFilePath; tap.beforeEach(async (t) => { - reportFilePath = returnTmpPath( - `report-${createHash('md5') - .update(t.name) - .digest('hex')}-${Date.now()}.json` - ); + reportFilePath = generateTmpReportPath(t.name, 'json'); }); tap.test('Run a simple script', async (t) => { diff --git a/packages/artillery/test/cli/run-typescript.test.js b/packages/artillery/test/cli/run-typescript.test.js index a8d1aebdc1..160a6820ef 100644 --- a/packages/artillery/test/cli/run-typescript.test.js +++ b/packages/artillery/test/cli/run-typescript.test.js @@ -1,15 +1,10 @@ const tap = require('tap'); -const { execute, returnTmpPath } = require('../cli/_helpers.js'); -const { createHash } = require('crypto'); +const { execute, generateTmpReportPath } = require('../cli/_helpers.js'); const fs = require('fs'); let reportFilePath; tap.beforeEach(async (t) => { - reportFilePath = returnTmpPath( - `report-${createHash('md5') - .update(t.name) - .digest('hex')}-${Date.now()}.json` - ); + reportFilePath = generateTmpReportPath(t.name, 'json'); }); tap.test('Can run a Typescript processor', async (t) => { diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/cli-exit-conditions/with-expect-ensure.yml b/packages/artillery/test/cloud-e2e/fargate/fixtures/cli-exit-conditions/with-expect-ensure.yml new file mode 100644 index 0000000000..813515a88f --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/cli-exit-conditions/with-expect-ensure.yml @@ -0,0 +1,18 @@ +config: + target: "http://asciiart.artillery.io:8080" + plugins: + expect: {} + ensure: + p99: 10000 + thresholds: + - "http.response_time.p95": 1 + phases: + - duration: 5 + arrivalRate: 1 +scenarios: + - name: expect-ensure-exit-condition-test + flow: + - get: + url: "/" + expect: + - statusCode: 300 \ No newline at end of file diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/cli-exit-conditions/with-expect.yml b/packages/artillery/test/cloud-e2e/fargate/fixtures/cli-exit-conditions/with-expect.yml new file mode 100644 index 0000000000..80d60f973c --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/cli-exit-conditions/with-expect.yml @@ -0,0 +1,14 @@ +config: + target: "http://asciiart.artillery.io:8080" + plugins: + expect: {} + phases: + - duration: 5 + arrivalRate: 1 +scenarios: + - name: expect-exit-condition-test + flow: + - get: + url: "/" + expect: + - statusCode: 300 \ No newline at end of file diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/cli-kitchen-sink/kitchen-sink-env b/packages/artillery/test/cloud-e2e/fargate/fixtures/cli-kitchen-sink/kitchen-sink-env new file mode 100644 index 0000000000..03b1874c00 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/cli-kitchen-sink/kitchen-sink-env @@ -0,0 +1,2 @@ +DOTENV1=/ +DOTENV2=/dino \ No newline at end of file diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/cli-kitchen-sink/kitchen-sink.yml b/packages/artillery/test/cloud-e2e/fargate/fixtures/cli-kitchen-sink/kitchen-sink.yml new file mode 100644 index 0000000000..4626e3ecda --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/cli-kitchen-sink/kitchen-sink.yml @@ -0,0 +1,22 @@ +config: + target: http://asciiart.artillery.io:8080 + plugins: + ensure: {} + phases: + - duration: 20 + arrivalRate: 1 + ensure: + p99: 10000 + thresholds: + - "http.response_time.p99": 10000 +scenarios: + - name: load homepage + flow: + - get: + url: "{{$processEnvironment.SECRET1}}" + - get: + url: "{{$processEnvironment.SECRET2}}" + - get: + url: "{{$processEnvironment.DOTENV1}}" + - get: + url: "{{$processEnvironment.DOTENV2}}" \ No newline at end of file diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/large-output/lots-of-output.yml b/packages/artillery/test/cloud-e2e/fargate/fixtures/large-output/lots-of-output.yml new file mode 100644 index 0000000000..f30bf82904 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/large-output/lots-of-output.yml @@ -0,0 +1,14 @@ +config: + target: http://asciiart.artillery.io:8080 + phases: + - arrivalRate: 1 + duration: 60 + defaults: + headers: + user-agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" + processor: "./processor.js" +scenarios: + - flow: + - get: + url: "/" + afterResponse: logOutput \ No newline at end of file diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/large-output/processor.js b/packages/artillery/test/cloud-e2e/fargate/fixtures/large-output/processor.js new file mode 100644 index 0000000000..10d9678273 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/large-output/processor.js @@ -0,0 +1,19 @@ +function logOutput(req, res, userContext, events, done) { + for (let i = 0; i < 10; i++) { + events.emit( + 'counter', + `very.very.long.name.for.a.counter.metric.so.that.we.generate.a.lot.of.console.output.${Date.now()}${i}`, + 1 + ); + events.emit( + 'histogram', + `very.very.long.name.for.a.histogram.metric.so.that.we.generate.a.lot.of.console.output.${Date.now()}${i}`, + 100 + ); + } + return done(); +} + +module.exports = { + logOutput +}; diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/memory-hog/memory-hog.yml b/packages/artillery/test/cloud-e2e/fargate/fixtures/memory-hog/memory-hog.yml new file mode 100644 index 0000000000..f1b0fe72f4 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/memory-hog/memory-hog.yml @@ -0,0 +1,20 @@ +# 10 VUs, making 10 calls each to a function that allocates 100MB -> ~10GB total +# This will fail with default configuration, which is: +# - 4GB RAM given to workers on Fargate +# - Node.js memory limit of 4GB + +config: + target: http://asciiart.artillery.io:8080 + phases: + - arrivalRate: 1 + duration: 10 + processor: './processor.js' + +scenarios: + - flow: + - loop: + - get: + url: "/armadillo" + beforeRequest: hogSomeRam + - think: 1 + count: 10 \ No newline at end of file diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/memory-hog/processor.js b/packages/artillery/test/cloud-e2e/fargate/fixtures/memory-hog/processor.js new file mode 100644 index 0000000000..cbbc650ec5 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/memory-hog/processor.js @@ -0,0 +1,18 @@ +let data = []; + +console.log('NODE_OPTIONS:'); +console.log(process.env.NODE_OPTIONS); + +function hogSomeRam(req, context, events, next) { + // Allocate 100MB + data.push(Buffer.alloc(1024 * 1024 * 100, 1)); + + console.log(new Date(), 'allocated more data'); + console.log('RSS (MB):', process.memoryUsage().rss / 1024 / 1024); + + return next(); +} + +module.exports = { + hogSomeRam +}; diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/code/functions.js b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/code/functions.js new file mode 100644 index 0000000000..8ee34d1b9c --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/code/functions.js @@ -0,0 +1,7 @@ +const bc = require('@babel/core'); +const uuid = require('uuid'); +const client = require('aws-sdk/clients/lambda'); + +module.exports = { + setUrl: require('./set-url') +}; diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/code/lib/signer.js b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/code/lib/signer.js new file mode 100644 index 0000000000..db46a46095 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/code/lib/signer.js @@ -0,0 +1,2 @@ +const meow = require('../meow'); +module.exports = require('aws4'); diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/code/meow.js b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/code/meow.js new file mode 100644 index 0000000000..3f8a90f0ea --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/code/meow.js @@ -0,0 +1,2 @@ +const lodash = require('lodash'); +module.export = 'meow'; diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/code/set-url.js b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/code/set-url.js new file mode 100644 index 0000000000..7936887055 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/code/set-url.js @@ -0,0 +1,9 @@ +module.exports = setUrl; + +const AWS = require('aws-sdk'); +const signer = require('./lib/signer'); + +function setUrl(req, res, ctx, ee, done) { + req.url = '/'; + return done(); +} diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/config/config.yml b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/config/config.yml new file mode 100644 index 0000000000..67ae5ef3c5 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/config/config.yml @@ -0,0 +1,22 @@ +config: + target: http://asciiart.artillery.io:8080 + processor: "../code/functions.js" + environments: + main: + phases: + - duration: 20 + arrivalRate: 1 + payload: + - path: "../data/variables.csv" # this is resolved relative to the main script for now, NOT this file + fields: ["username", "email"] + plugins: + metrics-by-endpoint: {} + stage: + plugins: + datadog: {} + plugins: + http-file-uploads: + filePaths: + - ../data/files + publish-metrics: + - type: statsd \ No newline at end of file diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/data/files/abigail-lynn-316133.jpg b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/data/files/abigail-lynn-316133.jpg new file mode 100644 index 0000000000..092a358110 Binary files /dev/null and b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/data/files/abigail-lynn-316133.jpg differ diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/data/files/the-lord-of-the-lens-476134.jpg b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/data/files/the-lord-of-the-lens-476134.jpg new file mode 100644 index 0000000000..b9e4f02e4a Binary files /dev/null and b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/data/files/the-lord-of-the-lens-476134.jpg differ diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/data/variables.csv b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/data/variables.csv new file mode 100644 index 0000000000..3fc9c1fa20 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/data/variables.csv @@ -0,0 +1,4 @@ +bob,bob@example.com +jane,jane@example.com +aditya,aditya@example.com +aadhya,aadhya@example.com diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/package-lock.json b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/package-lock.json new file mode 100644 index 0000000000..d38a6cf088 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/package-lock.json @@ -0,0 +1,1006 @@ +{ + "name": "mixed-hierarchy", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "mixed-hierarchy", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "@babel/core": "latest", + "aws-sdk": "^2.1534.0", + "aws4": "^1.12.0", + "lodash": "^4.17.21" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz", + "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.5.tgz", + "integrity": "sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.7.tgz", + "integrity": "sha512-+UpDgowcmqe36d4NwqvKsyPMlOLNGMsfMmQ5WGCu+siCe3t3dfe9njrzGfdN4qq+bcNUt0+Vw6haRxBOycs4dw==", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-compilation-targets": "^7.23.6", + "@babel/helper-module-transforms": "^7.23.3", + "@babel/helpers": "^7.23.7", + "@babel/parser": "^7.23.6", + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==" + }, + "node_modules/@babel/core/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/core/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/@babel/generator": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.6.tgz", + "integrity": "sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==", + "dependencies": { + "@babel/types": "^7.23.6", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.23.6.tgz", + "integrity": "sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==", + "dependencies": { + "@babel/compat-data": "^7.23.5", + "@babel/helper-validator-option": "^7.23.5", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz", + "integrity": "sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==", + "dependencies": { + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.23.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz", + "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-module-imports": "^7.22.15", + "@babel/helper-simple-access": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/helper-validator-identifier": "^7.22.20" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz", + "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz", + "integrity": "sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz", + "integrity": "sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.23.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.8.tgz", + "integrity": "sha512-KDqYz4PiOWvDFrdHLPhKtCThtIcKVy6avWD2oG4GEvyQ+XDZwHD4YQd+H2vNMnq2rkdxsDkU82T+Vk8U/WXHRQ==", + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/traverse": "^7.23.7", + "@babel/types": "^7.23.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.6.tgz", + "integrity": "sha512-Z2uID7YJ7oNvAI20O9X0bblw7Qqs8Q2hFy0R9tAfnfLkp5MW0UH9eUvnDSnFwKZ0AvgS1ucqR4KzvVHgnke1VQ==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.7.tgz", + "integrity": "sha512-tY3mM8rH9jM0YHFGyfC0/xf+SB5eKUu7HPj7/k3fpi9dAlsMc5YbQvDi0Sh2QTPXqMhyaAtzAr807TIyfQrmyg==", + "dependencies": { + "@babel/code-frame": "^7.23.5", + "@babel/generator": "^7.23.6", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.6", + "@babel/types": "^7.23.6", + "debug": "^4.3.1", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/@babel/traverse/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/@babel/types": { + "version": "7.23.6", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.6.tgz", + "integrity": "sha512-+uarb83brBzPKN38NX1MkB6vb6+mwvR6amUulqAE7ccQw1pEl+bCia9TbdG1lsnFP7lZySvUn37CHyXQdfTwzg==", + "dependencies": { + "@babel/helper-string-parser": "^7.23.4", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", + "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/aws-sdk": { + "version": "2.1534.0", + "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1534.0.tgz", + "integrity": "sha512-J0PUq4C4HS+OuDhYKknPEfUBwcd1b833723rwJiyp4VHT90V5K34rwYQ2DVq7DC5tUgG3ufa4EhZ1eNn5qgP9A==", + "dependencies": { + "buffer": "4.9.2", + "events": "1.1.1", + "ieee754": "1.1.13", + "jmespath": "0.16.0", + "querystring": "0.2.0", + "sax": "1.2.1", + "url": "0.10.3", + "util": "^0.12.4", + "uuid": "8.0.0", + "xml2js": "0.5.0" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/aws4": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", + "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/browserslist": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.2.tgz", + "integrity": "sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001565", + "electron-to-chromium": "^1.4.601", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.13" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001576", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001576.tgz", + "integrity": "sha512-ff5BdakGe2P3SQsMsiqmt1Lc8221NR1VzHj5jXN5vBny9A6fpze94HiVV/n7XRosOlsShJcvMv5mdnpjOGCEgg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.628", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.628.tgz", + "integrity": "sha512-2k7t5PHvLsufpP6Zwk0nof62yLOsCf032wZx7/q0mv8gwlXjhcxI3lz6f0jBr0GrnWKcm3burXzI3t5IrcdUxw==" + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/events": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", + "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dependencies": { + "is-callable": "^1.1.3" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==" + }, + "node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "node_modules/is-arguments": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.1.1.tgz", + "integrity": "sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-generator-function": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.0.10.tgz", + "integrity": "sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + }, + "node_modules/jmespath": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/jmespath/-/jmespath-0.16.0.tgz", + "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==", + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==" + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/sax": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", + "integrity": "sha512-8I2a3LovHTOpm7NV5yOyO8IHqgVsfK4+UuySrXU8YXkSRX7k6hCV9b3HrkKCr3nMpgj+0bmocaJJWpvp1oc7ZA==" + }, + "node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/set-function-length": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.1.1.tgz", + "integrity": "sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ==", + "dependencies": { + "define-data-property": "^1.1.1", + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", + "engines": { + "node": ">=4" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.13", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", + "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/util": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", + "integrity": "sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==", + "dependencies": { + "inherits": "^2.0.3", + "is-arguments": "^1.0.4", + "is-generator-function": "^1.0.7", + "is-typed-array": "^1.1.3", + "which-typed-array": "^1.1.2" + } + }, + "node_modules/uuid": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.0.0.tgz", + "integrity": "sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.4", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/xml2js": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.5.0.tgz", + "integrity": "sha512-drPFnkQJik/O+uPKpqSgr22mpuFHqKdbS835iAQrUC73L2F5WkboIRd63ai/2Yg6I1jzifPFKH2NTK+cfglkIA==", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/xmlbuilder": { + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", + "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + } + } +} diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/package.json b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/package.json new file mode 100644 index 0000000000..944a4829e8 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/package.json @@ -0,0 +1,18 @@ +{ + "name": "mixed-hierarchy", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "@babel/core": "latest", + "aws-sdk": "^2.1534.0", + "aws4": "^1.12.0", + "lodash": "^4.17.21" + } + } \ No newline at end of file diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/scenarios/mixed-hierarchy-dino.yml b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/scenarios/mixed-hierarchy-dino.yml new file mode 100644 index 0000000000..c247fa58e3 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/scenarios/mixed-hierarchy-dino.yml @@ -0,0 +1,4 @@ +scenarios: + - flow: + - get: + url: "/dino" \ No newline at end of file diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/scenarios/mixed-hierarchy-pony.yml b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/scenarios/mixed-hierarchy-pony.yml new file mode 100644 index 0000000000..de4e18abcb --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/mixed-hierarchy/scenarios/mixed-hierarchy-pony.yml @@ -0,0 +1,5 @@ +scenarios: + - name: "dino_scenario" + flow: + - get: + url: "/" \ No newline at end of file diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/README.md b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/README.md new file mode 100644 index 0000000000..e85637f1c9 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/README.md @@ -0,0 +1,6 @@ +## A basic test for BOM + +- Single test script +- A single CSV payload dependency +- A couple of file upload plugin dependencies (a file and a directory) +- A custom JS dependency with a couple of public npm module dependencies \ No newline at end of file diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/README.md b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/README.md new file mode 100644 index 0000000000..0eeb056f9c --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/README.md @@ -0,0 +1,2 @@ +this is just a placeholder file +for testing file upload boms via file-upload plugin diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/data/lists.json b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/data/lists.json new file mode 100644 index 0000000000..6001c443be --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/data/lists.json @@ -0,0 +1 @@ +[1, 2, 3] \ No newline at end of file diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/data/names-local.csv b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/data/names-local.csv new file mode 100644 index 0000000000..5717ca353c --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/data/names-local.csv @@ -0,0 +1,4 @@ +Tiki,/404 +Mali,/404 +Rua,/404 +Simcoe,/404 diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/data/names-prod.csv b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/data/names-prod.csv new file mode 100644 index 0000000000..f5de86f415 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/data/names-prod.csv @@ -0,0 +1,4 @@ +Tiki,/dino/ +Mali,/pony/ +Rua,/armadillo/ +Simcoe,/armadillo/ diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/data/names-test.csv b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/data/names-test.csv new file mode 100644 index 0000000000..cbba3651d1 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/data/names-test.csv @@ -0,0 +1,4 @@ +Tiki,/dino/ +Mali,/armadillo/ +Rua,/pony/ +Simcoe,/dino/ diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/data/user-data.csv b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/data/user-data.csv new file mode 100644 index 0000000000..518cef5226 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/data/user-data.csv @@ -0,0 +1,2 @@ +bob,12345 +joe,78901 diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/dummy-util.js b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/dummy-util.js new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/files/dog.jpg b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/files/dog.jpg new file mode 100644 index 0000000000..f4b34ac652 Binary files /dev/null and b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/files/dog.jpg differ diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/functions.js b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/functions.js new file mode 100644 index 0000000000..e739b83c7c --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/functions.js @@ -0,0 +1,38 @@ +// required files and modules: +const dummyUtil = require('./dummy-util'); +const localModDir = require('./local-mod-dir'); +const nonIncludedJson = require('./not-included.json'); + +// required external packages: +const yaml = require('js-yaml'); +const uuid = require('uuid'); +// const enomod = require('./myenomod'); // won't get detected, rightfully so, but will cause a failure in the worker + +const fs = require('fs'); +const path = require('path'); + +function checkBundle(req, userContext, events, done) { + let maybeErr = null; + try { + // picked up via require() calls in here: + fs.statSync(path.join(__dirname, 'dummy-util.js')); + fs.statSync(path.join(__dirname, 'local-mod-dir', 'index.js')); + fs.statSync(path.join(__dirname, 'not-included.json')); + + // not working right now + // // picked up via plugins.http-file-uploads.filePaths: + // fs.statSync(path.join(__dirname, 'files', 'dog.jpg')); + + // picked up via payload.path: + fs.statSync(path.join(__dirname, 'data', 'user-data.csv')); + + // picked up via includeFiles (as a dir): + fs.statSync(path.join(__dirname, 'data', 'names-prod.csv')); + fs.statSync(path.join(__dirname, 'data', 'lists.json')); + } catch (fsErr) { + maybeErr = fsErr; + } + return done(maybeErr); +} + +module.exports = { checkBundle }; diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/local-mod-dir/index.js b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/local-mod-dir/index.js new file mode 100644 index 0000000000..888cae37af --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/local-mod-dir/index.js @@ -0,0 +1 @@ +module.exports = 42; diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/not-included.json b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/not-included.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/deps/not-included.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/simple-bom.yml b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/simple-bom.yml new file mode 100644 index 0000000000..8b017f243c --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/simple-bom/simple-bom.yml @@ -0,0 +1,36 @@ +config: + environments: + local: + target: "http://localhost:1234" + # This is here to test the case when there are environments, + # but they don't define plugins. + prod: + target: http://asciiart.artillery.io:8080 + test: + target: http://asciiart.artillery.io:8080 + target: "" + # defaults: + # headers: + # user-agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" + phases: + - arrivalRate: 1 + duration: 10 + processor: './deps/functions.js' + payload: + - fields: ["name", "zipCode"] + path: "./deps/data/user-data.csv" + - fields: ["name", "urlFromCSV"] + path: "./deps/data/names-{{ $environment }}.csv" + includeFiles: + - ./deps/data/ # directory + # plugins: + # http-file-uploads: + # filePaths: + # - "./deps/README.md" + # - "./deps/files" # directory + # metrics-by-endpoint: {} +scenarios: + - flow: + - get: + url: "{{ urlFromCSV }}" + beforeRequest: "checkBundle" \ No newline at end of file diff --git a/packages/artillery/test/cloud-e2e/fargate/fixtures/uses-ensure/with-ensure.yaml b/packages/artillery/test/cloud-e2e/fargate/fixtures/uses-ensure/with-ensure.yaml new file mode 100644 index 0000000000..183f4d6e8e --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/fixtures/uses-ensure/with-ensure.yaml @@ -0,0 +1,17 @@ +config: + target: http://asciiart.artillery.io:8080 + plugins: + ensure: {} + phases: + - duration: 20 + arrivalRate: 1 + ensure: + p99: 10000 + thresholds: + - "http.response_time.p99": 1 + +scenarios: + - name: run_uses_ensure + flow: + - get: + url: "/dino" \ No newline at end of file diff --git a/packages/artillery/test/cloud-e2e/fargate/run-fargate.test.js b/packages/artillery/test/cloud-e2e/fargate/run-fargate.test.js new file mode 100644 index 0000000000..bc84fe062f --- /dev/null +++ b/packages/artillery/test/cloud-e2e/fargate/run-fargate.test.js @@ -0,0 +1,212 @@ +const { test, before, beforeEach } = require('tap'); +const { $ } = require('zx'); +const chalk = require('chalk'); +const fs = require('fs'); +const { generateTmpReportPath, getTestTags } = require('../../cli/_helpers.js'); + +const A9 = process.env.A9 || 'artillery'; + +before(async () => { + await $`${A9} -V`; +}); + +//NOTE: all these tests report to Artillery Dashboard to dogfood and improve visibility +const baseTags = getTestTags(['type:acceptance']); +let reportFilePath; +beforeEach(async (t) => { + $.verbose = true; + + reportFilePath = generateTmpReportPath(t.name, 'json'); +}); + +test('Run simple-bom', async (t) => { + const output = + await $`${A9} run-fargate ${__dirname}/fixtures/simple-bom/simple-bom.yml --environment test --region eu-west-1 --count 51 --record --tags ${baseTags}`; + + t.equal(output.exitCode, 0, 'CLI Exit Code should be 0'); + + t.match(output, /summary report/i, 'print summary report'); + t.match(output, /p99/i, 'a p99 value is reported'); + t.match(output, /created:.+510/i, 'expected number of vusers is reported'); +}); + +test('Run mixed-hierarchy', async (t) => { + const scenarioPath = `${__dirname}/fixtures/mixed-hierarchy/scenarios/mixed-hierarchy-dino.yml`; + const configPath = `${__dirname}/fixtures/mixed-hierarchy/config/config.yml`; + + const output = + await $`${A9} run-fargate ${scenarioPath} --config ${configPath} -e main --record --tags ${baseTags} --output ${reportFilePath}`; + + const report = JSON.parse(fs.readFileSync(reportFilePath, 'utf8')); + + t.equal(output.exitCode, 0, 'CLI Exit Code should be 0'); + + t.equal( + report.aggregate.counters['vusers.completed'], + 20, + 'Should have 20 total VUs' + ); + t.equal( + report.aggregate.counters['http.codes.200'], + 20, + 'Should have 20 "200 OK" responses' + ); +}); + +test('Run uses ensure', async (t) => { + try { + await $`${A9} run:fargate ${__dirname}/fixtures/uses-ensure/with-ensure.yaml --record --tags ${baseTags} --output ${reportFilePath} --count 15`; + } catch (output) { + t.equal(output.exitCode, 1, 'CLI Exit Code should be 1'); + t.ok( + output.stdout.includes(`${chalk.red('fail')}: http.response_time.p99 < 1`) + ); + t.ok(output.stdout.includes(`${chalk.green('ok')}: p99 < 10000`)); + + const report = JSON.parse(fs.readFileSync(reportFilePath, 'utf8')); + t.equal( + report.aggregate.counters['vusers.completed'], + 300, + 'Should have 300 total VUs' + ); + t.equal( + report.aggregate.counters['http.codes.200'], + 300, + 'Should have 300 "200 OK" responses' + ); + } +}); + +test('Ensure (with new interface) should still run when workers exit from expect plugin (non zero exit code)', async (t) => { + //Note: this test uses new ensure plugin interface (config.plugins.ensure) to test that indirectly + + try { + await $`${A9} run:fargate ${__dirname}/fixtures/cli-exit-conditions/with-expect-ensure.yml --record --tags ${baseTags} --output ${reportFilePath} --count 2`; + } catch (output) { + t.equal(output.exitCode, 1, 'CLI Exit Code should be 1'); + t.ok( + output.stdout.includes(`${chalk.red('fail')}: http.response_time.p95 < 1`) + ); + t.ok(output.stdout.includes(`${chalk.green('ok')}: p99 < 10000`)); + + const report = JSON.parse(fs.readFileSync(reportFilePath, 'utf8')); + t.equal( + report.aggregate.counters['vusers.completed'], + 10, + 'Should have 10 total VUs' + ); + t.equal( + report.aggregate.counters['http.codes.200'], + 10, + 'Should have 10 "200 OK" responses' + ); + } +}); + +test('CLI should exit with non-zero exit code when there are failed expectations in workers', async (t) => { + try { + await $`${A9} run-fargate ${__dirname}/fixtures/cli-exit-conditions/with-expect.yml --record --tags ${baseTags} --output ${reportFilePath} --count 2`; + } catch (output) { + t.equal(output.exitCode, 6, 'CLI Exit Code should be 6'); + + const report = JSON.parse(fs.readFileSync(reportFilePath, 'utf8')); + t.equal( + report.aggregate.counters['vusers.completed'], + 10, + 'Should have 10 total VUs' + ); + t.equal( + report.aggregate.counters['http.codes.200'], + 10, + 'Should have 10 "200 OK" responses' + ); + } +}); + +test('Kitchen Sink Test - multiple features together', async (t) => { + const scenarioPath = `${__dirname}/fixtures/cli-kitchen-sink/kitchen-sink.yml`; + const dotEnvPath = `${__dirname}/fixtures/cli-kitchen-sink/kitchen-sink-env`; + const launchConfig = { + environment: [ + { name: 'SECRET1', value: '/armadillo' }, + { name: 'SECRET2', value: '/pony' } + ] + }; + + const output = + await $`${A9} run-fargate ${scenarioPath} --output ${reportFilePath} --dotenv ${dotEnvPath} --record --tags ${baseTags} --count 2 --launch-config ${JSON.stringify( + launchConfig + )}`; + + t.equal(output.exitCode, 0, 'CLI Exit Code should be 0'); + t.ok( + output.stdout.includes( + `${chalk.green('ok')}: http.response_time.p99 < 10000` + ) + ); + t.ok(output.stdout.includes(`${chalk.green('ok')}: p99 < 10000`)); + + const report = JSON.parse(fs.readFileSync(reportFilePath, 'utf8')); + t.equal( + report.aggregate.counters['vusers.completed'], + 40, + 'Should have 40 total VUs' + ); + t.equal( + report.aggregate.counters['http.codes.200'], + 160, + 'Should have 160 "200 OK" responses' + ); + + // Check that each endpoint was hit correctly + t.equal( + report.aggregate.counters['plugins.metrics-by-endpoint./.codes.200'], + 40, + 'Should have 40 / "200 OK" responses' + ); + t.equal( + report.aggregate.counters['plugins.metrics-by-endpoint./dino.codes.200'], + 40, + 'Should have 40 /dino "200 OK" responses' + ); + t.equal( + report.aggregate.counters[ + 'plugins.metrics-by-endpoint./armadillo.codes.200' + ], + 40, + 'Should have 40 /armadillo "200 OK" responses' + ); + t.equal( + report.aggregate.counters['plugins.metrics-by-endpoint./pony.codes.200'], + 40, + 'Should have 40 /pony "200 OK" responses' + ); +}); + +test('Run lots-of-output', async (t) => { + $.verbose = false; // we don't want megabytes of output on the console + + const output = + await $`${A9} run:fargate ${__dirname}/fixtures/large-output/lots-of-output.yml --record --tags ${baseTags}`; + + t.equal(output.exitCode, 0, 'CLI Exit Code should be 0'); + + t.match(output.stdout, /summary report/i, 'print summary report'); + t.match( + output.stdout, + /very.very.long.name.for.a.histogram.metric.so.that.we.generate.a.lot.of.console.output/i, + 'includes custom metric output' + ); + t.match(output.stdout, /p99/i, 'a p99 value is reported'); +}); + +test('Run memory hog', async (t) => { + try { + await $`${A9} run-fargate ${__dirname}/fixtures/memory-hog/memory-hog.yml --record --tags ${baseTags} --region us-east-1 --launch-config '{"cpu":"4096", "memory":"12288"}'`; + } catch (output) { + t.equal(output.exitCode, 6, 'CLI Exit Code should be 6'); + + t.match(output, /summary report/i, 'print summary report'); + t.match(output, /p99/i, 'a p99 value is reported'); + } +}); diff --git a/packages/artillery/test/scripts/blitz/scenarios/blitz.yml b/packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/blitz.yml similarity index 100% rename from packages/artillery/test/scripts/blitz/scenarios/blitz.yml rename to packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/blitz.yml diff --git a/packages/artillery/test/scripts/blitz/config.yml b/packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/config.yml similarity index 71% rename from packages/artillery/test/scripts/blitz/config.yml rename to packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/config.yml index cbbfb4bac5..9348116b59 100644 --- a/packages/artillery/test/scripts/blitz/config.yml +++ b/packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/config.yml @@ -1,13 +1,11 @@ config: target: http://asciiart.artillery.io:8080 - processor: ./helpers-blitz.js + processor: ./helpers.js payload: - path: ./test.csv fields: - number - name - plugins: - metrics-by-endpoint: {} phases: - duration: 30 arrivalRate: 1 \ No newline at end of file diff --git a/packages/artillery/test/scripts/blitz/helpers-blitz.js b/packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/helpers.js similarity index 100% rename from packages/artillery/test/scripts/blitz/helpers-blitz.js rename to packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/helpers.js diff --git a/packages/artillery/test/scripts/blitz/test.csv b/packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/test.csv similarity index 67% rename from packages/artillery/test/scripts/blitz/test.csv rename to packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/test.csv index 46c614f175..84816b278e 100644 --- a/packages/artillery/test/scripts/blitz/test.csv +++ b/packages/artillery/test/cloud-e2e/lambda/fixtures/quick-loop-with-csv/test.csv @@ -1,3 +1,3 @@ pony,tiki dog,mali -cat,faye +cat,faye \ No newline at end of file diff --git a/packages/artillery/test/cloud-e2e/lambda/run-lambda.test.js b/packages/artillery/test/cloud-e2e/lambda/run-lambda.test.js new file mode 100644 index 0000000000..fb0cba6505 --- /dev/null +++ b/packages/artillery/test/cloud-e2e/lambda/run-lambda.test.js @@ -0,0 +1,23 @@ +const tap = require('tap'); +const { $ } = require('zx'); +const { getTestTags } = require('../../cli/_helpers.js'); + +tap.test('Run a test on AWS Lambda', 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`; + + const output = + await $`artillery run-lambda --count 10 --region eu-west-1 --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' + ); +}); diff --git a/packages/artillery/test/cloud-e2e/run-lambda.test.js b/packages/artillery/test/cloud-e2e/run-lambda.test.js deleted file mode 100644 index 89a5ded21b..0000000000 --- a/packages/artillery/test/cloud-e2e/run-lambda.test.js +++ /dev/null @@ -1,39 +0,0 @@ -const tap = require('tap'); -const { a9 } = require('../cli/_helpers.js'); -const path = require('path'); - -tap.test('Run a test on AWS Lambda', async (t) => { - const configPath = path.resolve( - __dirname, - '..', - 'scripts', - 'blitz', - 'config.yml' - ); - - const scenarioPath = path.resolve( - __dirname, - '..', - 'scripts', - 'blitz', - 'scenarios', - 'blitz.yml' - ); - const { stdout } = await a9([ - 'run', - '--platform', - 'aws:lambda', - '--count', - '10', - '--platform-opt', - 'memory-size=3000', - '--platform-opt', - 'region=eu-west-1', - '--config', - configPath, - scenarioPath - ]); - - t.ok(stdout.indexOf('Summary report') > 0, 'Should print summary report'); - t.ok(stdout.indexOf('http.codes.200') > 0, 'Should print http.codes.200'); -});