Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,36 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [3.3.0] - 2024-09-16

### Added

- Added cron scheduling (https://github.com/aws-solutions/distributed-load-testing-on-aws/issues/84)
- Added jtl report to s3 bucket logs (https://github.com/aws-solutions/distributed-load-testing-on-aws/issues/150)
- Added enhanced mechanism to collect Anonymized Metrics Feature
- Added new integration tests

### Fixed

- Fixed issues pertaining to (https://github.com/aws-solutions/distributed-load-testing-on-aws/issues/193)

### Security

- `micromatch` to mitigate [CVE-2024-4067](https://github.com/advisories/GHSA-952p-6rrq-rcjv)
- `webpack` to mitigate [CVE-2024-43788](https://github.com/advisories/GHSA-4vvj-4cpr-p986)
- `path-to-regexp` to mitigate [CVE-2024-45296](https://github.com/advisories/GHSA-9wv6-86v2-598j)
- `serve-static` to mitigate [CVE-2024-43800](https://github.com/advisories/GHSA-cm22-4g7w-348p)
- `body-parser` to mitigate [CVE-2024-45590](https://github.com/advisories/GHSA-qwcr-r2fm-qrc7)
- `express` to mitigate [CVE-2024-43796](https://github.com/advisories/GHSA-qw6h-vgh9-j6wx)
- `send` to mitigate [CVE-2024-43799](https://github.com/advisories/GHSA-m6fv-jmcg-4jfg)
- `Flask_Cors` on Docker image to mitigate [CVE-2024-6221](https://github.com/advisories/GHSA-hxwh-jpp2-84pm)

### Updated

- Updated aws-cdk to 2.155.0
- Updated aws-cdk-lib to 2.155.0
- Updated @aws-cdk/aws-servicecatalogappregistry-alpha to 2.155.0-alpha.0

## [3.2.11] - 2024-08-19

### Updated
Expand Down
4 changes: 3 additions & 1 deletion NOTICE
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,6 @@ ts-node under the Massachusetts Institute of Technology (MIT) License
typescript under the Apache License 2.0
uuid under the Massachusetts Institute of Technology (MIT) license
xml-js under the Massachusetts Institute of Technology (MIT) license
source-map-support under the Massachusetts Institute of Technology (MIT) license
source-map-support under the Massachusetts Institute of Technology (MIT) license
react-js-cron under the Massachusetts Institute of Technology (MIT) license
cron-parser under the Massachusetts Institute of Technology (MIT) license
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ The Distributed Load Testing Solution leverages managed, highly available and hi

## Deployment

The solution is deployed using a CloudFormation template with a lambda backed custom resource. To simulate users from regions other than the region the solution is initially deployed in, a regional template must be deployed within the other desired regions. For details on deploying the solution please see the details on the solution implementation guide: [Distributed Load Testing](https://docs.aws.amazon.com/solutions/latest/distributed-load-testing-on-aws/deployment.html)
The solution is deployed using a CloudFormation template with a lambda backed custom resource. To simulate users from regions other than the region the solution is initially deployed in, a regional template must be deployed within the other desired regions. For details on deploying the solution please see the details on the solution implementation guide: [Distributed Load Testing](https://docs.aws.amazon.com/solutions/latest/distributed-load-testing-on-aws/deployment.html).

## Source Code

Expand Down
2 changes: 1 addition & 1 deletion VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.2.11
3.3.0
26 changes: 26 additions & 0 deletions deployment/build-s3-dist.sh
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,32 @@ manifest=(`find * -type f ! -iname ".DS_Store"`)
manifest_json=$(IFS=,;printf "%s" "${manifest[*]}")
echo "[\"${manifest_json}\"]" | sed 's/,/","/g' > ./console-manifest.json

echo "------------------------------------------------------------------------------"
echo "Build Metrics utils lambda archive."
echo "------------------------------------------------------------------------------"
cd ${source_dir}/metrics-utils
npm run build && npm run zip
if [ $? -eq 0 ]
then
echo "Build for metrics-utils succeeded"
else
echo "******************************************************************************"
echo "Build FAILED for metrics-utils"
echo "******************************************************************************"
exit 1
fi
mv ${source_dir}/metrics-utils/dist/*.zip ${build_dist_dir}/metrics-utils.zip
if [ $? -eq 0 ]
then
echo "moved metrics-utils.zip to ${build_dist_dir}"
else
echo "******************************************************************************"
echo "FAILED to move metrics-utils.zip to ${build_dist_dir}"
echo "******************************************************************************"
exit 1
fi


echo "------------------------------------------------------------------------------"
echo "Build S3 Packaging Complete"
echo "------------------------------------------------------------------------------"
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,10 @@ RUN rm -rf /usr/share/dotnet
RUN rm -rf /usr/local/lib/python3.10/dist-packages/aiohttp*
RUN pip install --upgrade aiohttp

# Replacing idna with more stable version to resolve CVE-2024-3651
RUN pip install --upgrade idna
RUN rm -rf /root/.bzt/python-packages/3.10.12/idna*
RUN cp -r /usr/local/lib/python3.10/dist-packages/idna* /root/.bzt/python-packages/3.10.12/
# Replacing idna and Flas_Cors with more stable version to resolve CVE-2024-3651 and CVE-2024-6221
RUN pip install --upgrade idna Flask_Cors
RUN rm -rf /root/.bzt/python-packages/3.10.12/idna* /root/.bzt/python-packages/3.10.12/Flask_Cors*
RUN cp -r /usr/local/lib/python3.10/dist-packages/idna* /usr/local/lib/python3.10/dist-packages/Flask_Cors* /root/.bzt/python-packages/3.10.12/

WORKDIR /bzt-configs/
ENTRYPOINT ["./load-test.sh"]
Original file line number Diff line number Diff line change
Expand Up @@ -25,26 +25,46 @@ trap 'sigterm_handler' SIGTERM
echo "Download test scenario"
aws s3 cp s3://$S3_BUCKET/test-scenarios/$TEST_ID-$AWS_REGION.json test.json --region $MAIN_STACK_REGION

# Set the default log file values to jmeter
LOG_FILE="jmeter.log"
OUT_FILE="jmeter.out"
ERR_FILE="jmeter.err"
KPI_EXT="jtl"

# download JMeter jmx file
if [ "$TEST_TYPE" != "simple" ]; then
# Copy *.jar to JMeter library path. See the Taurus JMeter path: https://gettaurus.org/docs/JMeter/
JMETER_LIB_PATH=`find ~/.bzt/jmeter-taurus -type d -name "lib"`
echo "cp $PWD/*.jar $JMETER_LIB_PATH"
cp $PWD/*.jar $JMETER_LIB_PATH
# setting the log file values to the test type
LOG_FILE="${TEST_TYPE}.log"
OUT_FILE="${TEST_TYPE}.out"
ERR_FILE="${TEST_TYPE}.err"

# set variables based on TEST_TYPE
if [ "$TEST_TYPE" == "jmeter" ]; then
EXT="jmx"
TYPE_NAME="JMeter"
# Copy *.jar to JMeter library path. See the Taurus JMeter path: https://gettaurus.org/docs/JMeter/
JMETER_LIB_PATH=`find ~/.bzt/jmeter-taurus -type d -name "lib"`
echo "cp $PWD/*.jar $JMETER_LIB_PATH"
cp $PWD/*.jar $JMETER_LIB_PATH

fi

if [ "$FILE_TYPE" != "zip" ]; then
aws s3 cp s3://$S3_BUCKET/public/test-scenarios/$TEST_TYPE/$TEST_ID.jmx ./ --region $MAIN_STACK_REGION
aws s3 cp s3://$S3_BUCKET/public/test-scenarios/$TEST_TYPE/$TEST_ID.$EXT ./ --region $MAIN_STACK_REGION
else
aws s3 cp s3://$S3_BUCKET/public/test-scenarios/$TEST_TYPE/$TEST_ID.zip ./ --region $MAIN_STACK_REGION
unzip $TEST_ID.zip
# only looks for the first jmx file.
JMETER_SCRIPT=`find . -name "*.jmx" | head -n 1`
if [ -z "$JMETER_SCRIPT" ]; then
echo "There is no JMeter script in the zip file."
echo "UNZIPPED"
ls -l
# only looks for the first test script file.
TEST_SCRIPT=`find . -name "*.${EXT}" | head -n 1`
echo $TEST_SCRIPT
if [ -z "$TEST_SCRIPT" ]; then
echo "There is no test script (.${EXT}) in the zip file."
exit 1
fi

sed -i -e "s|$TEST_ID.jmx|$JMETER_SCRIPT|g" test.json
sed -i -e "s|$TEST_ID.$EXT|$TEST_SCRIPT|g" test.json

# copy bundled plugin jars to jmeter extension folder to make them available to jmeter
BUNDLED_PLUGIN_DIR=`find $PWD -type d -name "plugins" | head -n 1`
Expand Down Expand Up @@ -75,34 +95,54 @@ else
fi

echo "Running test"

stdbuf -i0 -o0 -e0 bzt test.json -o modules.console.disable=true | stdbuf -i0 -o0 -e0 tee -a result.tmp | sed -u -e "s|^|$TEST_ID $LIVE_DATA_ENABLED |"
CALCULATED_DURATION=`cat result.tmp | grep -m1 "Test duration" | awk -F ' ' '{ print $5 }' | awk -F ':' '{ print ($1 * 3600) + ($2 * 60) + $3 }'`

# upload custom results to S3 if any
# every file goes under $TEST_ID/$PREFIX/$UUID to distinguish the result correctly
if [ "$TEST_TYPE" != "simple" ]; then
if [ "$FILE_TYPE" != "zip" ]; then
cat $TEST_ID.jmx | grep filename > results.txt
cat $TEST_ID.$EXT | grep filename > results.txt
else
cat $JMETER_SCRIPT | grep filename > results.txt
cat $TEST_SCRIPT | grep filename > results.txt
fi
sed -i -e 's/<stringProp name="filename">//g' results.txt
sed -i -e 's/<\/stringProp>//g' results.txt
sed -i -e 's/ //g' results.txt

echo "Files to upload as results"
cat results.txt

files=(`cat results.txt`)
for f in "${files[@]}"; do
p="s3://$S3_BUCKET/results/$TEST_ID/JMeter_Result/$PREFIX/$UUID/$f"
if [[ $f = /* ]]; then
p="s3://$S3_BUCKET/results/$TEST_ID/JMeter_Result/$PREFIX/$UUID$f"
fi

echo "Uploading $p"
aws s3 cp $f $p --region $MAIN_STACK_REGION
done
if [ -f results.txt ]; then
sed -i -e 's/<stringProp name="filename">//g' results.txt
sed -i -e 's/<\/stringProp>//g' results.txt
sed -i -e 's/ //g' results.txt

echo "Files to upload as results"
cat results.txt

files=(`cat results.txt`)
extensions=()
for f in "${files[@]}"; do
ext="${f##*.}"
if [[ ! " ${extensions[@]} " =~ " ${ext} " ]]; then
extensions+=("$ext")
fi
done

# Find all files in the current folder with the same extensions
all_files=()
for ext in "${extensions[@]}"; do
for f in *."$ext"; do
all_files+=("$f")
done
done

for f in "${all_files[@]}"; do
p="s3://$S3_BUCKET/results/$TEST_ID/${TYPE_NAME}_Result/$PREFIX/$UUID/$f"
if [[ $f = /* ]]; then
p="s3://$S3_BUCKET/results/$TEST_ID/${TYPE_NAME}_Result/$PREFIX/$UUID$f"
fi

echo "Uploading $p"
aws s3 cp $f $p --region $MAIN_STACK_REGION
done
fi
fi

if [ -f /tmp/artifacts/results.xml ]; then
Expand All @@ -114,12 +154,18 @@ if [ -f /tmp/artifacts/results.xml ]; then
xmlstarlet ed -L -u /FinalStatus/TestDuration -v $CALCULATED_DURATION /tmp/artifacts/results.xml
fi

if [ "$TEST_TYPE" == "simple" ]; then
TEST_TYPE = "jmeter"
fi

echo "Uploading results, bzt log, and JMeter log, out, and err files"
aws s3 cp /tmp/artifacts/results.xml s3://$S3_BUCKET/results/${TEST_ID}/${PREFIX}-${UUID}-${AWS_REGION}.xml --region $MAIN_STACK_REGION
aws s3 cp /tmp/artifacts/bzt.log s3://$S3_BUCKET/results/${TEST_ID}/bzt-${PREFIX}-${UUID}-${AWS_REGION}.log --region $MAIN_STACK_REGION
aws s3 cp /tmp/artifacts/jmeter.log s3://$S3_BUCKET/results/${TEST_ID}/jmeter-${PREFIX}-${UUID}-${AWS_REGION}.log --region $MAIN_STACK_REGION
aws s3 cp /tmp/artifacts/jmeter.out s3://$S3_BUCKET/results/${TEST_ID}/jmeter-${PREFIX}-${UUID}-${AWS_REGION}.out --region $MAIN_STACK_REGION
aws s3 cp /tmp/artifacts/jmeter.err s3://$S3_BUCKET/results/${TEST_ID}/jmeter-${PREFIX}-${UUID}-${AWS_REGION}.err --region $MAIN_STACK_REGION
aws s3 cp /tmp/artifacts/$LOG_FILE s3://$S3_BUCKET/results/${TEST_ID}/${TEST_TYPE}-${PREFIX}-${UUID}-${AWS_REGION}.log --region $MAIN_STACK_REGION
aws s3 cp /tmp/artifacts/$OUT_FILE s3://$S3_BUCKET/results/${TEST_ID}/${TEST_TYPE}-${PREFIX}-${UUID}-${AWS_REGION}.out --region $MAIN_STACK_REGION
aws s3 cp /tmp/artifacts/$ERR_FILE s3://$S3_BUCKET/results/${TEST_ID}/${TEST_TYPE}-${PREFIX}-${UUID}-${AWS_REGION}.err --region $MAIN_STACK_REGION
aws s3 cp /tmp/artifacts/kpi.${KPI_EXT} s3://$S3_BUCKET/results/${TEST_ID}/kpi-${PREFIX}-${UUID}-${AWS_REGION}.${KPI_EXT} --region $MAIN_STACK_REGION

else
echo "An error occurred while the test was running."
fi
22 changes: 16 additions & 6 deletions source/.eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@
"env": {
"jest": true,
"node": true,
"es6": true
"es6": true,
"cypress/globals": true
},
"ignorePatterns": ["**/node_modules/**"],
"ignorePatterns": ["**/node_modules/**", "**/*.config.ts", "**/dist/**", "**/cdk.out/**"],
"parserOptions": {
"ecmaVersion": "latest"
},
"overrides": [
{
"files": ["**/*.ts", "**/*.tsx"],
"plugins": ["@typescript-eslint", "import", "header"],
"plugins": ["@typescript-eslint", "import", "header", "cypress"],
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
Expand All @@ -32,8 +33,12 @@
"rules": {
"@typescript-eslint/no-inferrable-types": ["off", { "ignoreParameters": true, "ignoreProperties": true }],
"@typescript-eslint/no-useless-constructor": ["off"],
"@typescript-eslint/no-unused-vars": ["error", { "args": "none", "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" }],
"@typescript-eslint/no-unused-vars": [
"error",
{ "args": "none", "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" }
],
"@typescript-eslint/no-throw-literal": ["error"],
"@typescript-eslint/no-empty-interface": ["off"],
"no-new": 0
}
},
Expand All @@ -51,12 +56,17 @@
"no-useless-constructor": ["off"],
"no-throw-literal": ["off"],

"header/header": ["error", "line", [" Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.", " SPDX-License-Identifier: Apache-2.0"], 2],
"header/header": [
"error",
"line",
[" Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.", " SPDX-License-Identifier: Apache-2.0"],
2
],

"jsdoc/require-param-type": ["off"],
"jsdoc/require-returns-type": ["off"],
"jsdoc/newline-after-description": ["off"],

"import/no-unresolved": 1 // warn only on Unable to resolve path import/no-unresolved
}
}
}
6 changes: 5 additions & 1 deletion source/api-services/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,13 +48,17 @@ class APIHandler {
);
}
// Handle creating test
else data = await scenarios.createTest(config);
else data = await scenarios.createTest(config, functionName);
if (process.env.SEND_METRIC === "Yes") {
await utils.sendMetric({
Type: "TaskCreate",
TestType: config.testType,
FileType: config.fileType || (config.testType === "simple" ? "none" : "script"),
TaskCount: config.taskCount,
TestId: data.testId,
TestScheduleStep: config.scheduleStep,
CronValue: config.cronValue,
TestEventBridgeScheduled: config.eventBridge,
});
}
return data;
Expand Down
Loading