Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

K6 support #164

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#!/bin/bash

set -e # exit if a command fails
set -u # error/exit if variables are unset
set -f # disable globbing
set -o pipefail # if a command in a pipeline fails, the whole pipeline fails

# set a uuid for the results xml file name in S3
UUID=$(cat /proc/sys/kernel/random/uuid)
pypid=0
Expand All @@ -24,27 +29,43 @@ trap 'sigterm_handler' SIGTERM
echo "Download test scenario"
aws s3 cp s3://$S3_BUCKET/test-scenarios/$TEST_ID-$AWS_REGION.json test.json

# 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
# set variables based on TEST_TYPE
if [ "$TEST_TYPE" == "jmeter" ]; then
EXT="jmx"
TYPE_NAME="JMeter"
elif [ "$TEST_TYPE" == "k6" ]; then
EXT="js"
TYPE_NAME="K6"
fi
LOG_FILE="${TEST_TYPE}.log"
OUT_FILE="${TEST_TYPE}.out"
ERR_FILE="${TEST_TYPE}.err"

if [ "$TEST_TYPE" != "simple" ]; then
if [ "$FILE_TYPE" != "zip" ]; then
aws s3 cp s3://$S3_BUCKET/public/test-scenarios/$TEST_TYPE/$TEST_ID.jmx ./
aws s3 cp s3://$S3_BUCKET/public/test-scenarios/$TEST_TYPE/$TEST_ID.$EXT ./
else
aws s3 cp s3://$S3_BUCKET/public/test-scenarios/$TEST_TYPE/$TEST_ID.zip ./
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."
# only looks for the first test script file.
TEST_SCRIPT=`find . -name "*.${EXT}" | head -n 1`
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
fi
fi

# special case for jmeter zips
if [ "$TEST_TYPE" == "jmeter" ]; 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 || true

if [ "$FILE_TYPE" == "zip" ]; then
# 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`
# attempt to copy only if a /plugins folder is present in upload
Expand All @@ -58,19 +79,24 @@ if [ "$TEST_TYPE" != "simple" ]; then
echo "jmeter extension path (~/.bzt/jmeter-taurus/**/ext) not found - cannot install bundled plugins"
exit 1
fi
cp -v $BUNDLED_PLUGIN_DIR/*.jar $JMETER_EXT_PATH
cp -v $BUNDLED_PLUGIN_DIR/*.jar $JMETER_EXT_PATH || true
fi
fi
fi

#Download python script
if [ -z "$IPNETWORK" ]; then
python3 -u $SCRIPT $TIMEOUT &
pypid=$!
wait $pypid
pypid=0
else
python3 -u $SCRIPT $IPNETWORK $IPHOSTS
: ${IPNETWORK=''}
: ${SCRIPT=''}

if [ -n "$SCRIPT" ]; then
#Download python script
if [ -z "$IPNETWORK" ]; then
python3 -u $SCRIPT $TIMEOUT &
pypid=$!
wait $pypid
pypid=0
else
python3 -u $SCRIPT $IPNETWORK $IPHOSTS
fi
fi

echo "Running test"
Expand All @@ -81,27 +107,30 @@ CALCULATED_DURATION=`cat result.tmp | grep -m1 "Test duration" | awk -F ' ' '{ p
# 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 || true
else
cat $JMETER_SCRIPT | grep filename > results.txt
cat $TEST_SCRIPT | grep filename > results.txt || true
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
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`)
for f in "${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 || true # Don't fail the build if a file upload fails
done
fi
fi

if [ -f /tmp/artifacts/results.xml ]; then
Expand All @@ -115,10 +144,16 @@ if [ -f /tmp/artifacts/results.xml ]; then

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
aws s3 cp /tmp/artifacts/bzt.log s3://$S3_BUCKET/results/${TEST_ID}/bzt-${PREFIX}-${UUID}-${AWS_REGION}.log
aws s3 cp /tmp/artifacts/jmeter.log s3://$S3_BUCKET/results/${TEST_ID}/jmeter-${PREFIX}-${UUID}-${AWS_REGION}.log
aws s3 cp /tmp/artifacts/jmeter.out s3://$S3_BUCKET/results/${TEST_ID}/jmeter-${PREFIX}-${UUID}-${AWS_REGION}.out
aws s3 cp /tmp/artifacts/jmeter.err s3://$S3_BUCKET/results/${TEST_ID}/jmeter-${PREFIX}-${UUID}-${AWS_REGION}.err
aws s3 cp /tmp/artifacts/bzt.log s3://$S3_BUCKET/results/${TEST_ID}/bzt-${PREFIX}-${UUID}-${AWS_REGION}.log || true # Don't fail the build if the log upload fails
if [ -z "$LOG_FILE" ]; then
aws s3 cp /tmp/artifacts/$LOG_FILE s3://$S3_BUCKET/results/${TEST_ID}/${TEST_TYPE}-${PREFIX}-${UUID}-${AWS_REGION}.log
fi
if [ -z "$OUT_FILE" ]; then
aws s3 cp /tmp/artifacts/$OUT_FILE s3://$S3_BUCKET/results/${TEST_ID}/${TEST_TYPE}-${PREFIX}-${UUID}-${AWS_REGION}.out
fi
if [ -z "$ERR_FILE" ]; then
aws s3 cp /tmp/artifacts/$ERR_FILE s3://$S3_BUCKET/results/${TEST_ID}/${TEST_TYPE}-${PREFIX}-${UUID}-${AWS_REGION}.err
fi
else
echo "An error occurred while the test was running."
fi
16 changes: 16 additions & 0 deletions source/api-services/lib/metrics/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,22 @@ describe("#SEND METRICS", () => {
expect(response).toEqual(200);
});

it('should return "200" on a send metrics success for zip K6 test', async () => {
let mock = new MockAdapter(axios);
mock.onPost().reply(200, {});

let response = await lambda.send({ taskCount: _taskCount, testType: "k6", fileType: "zip" });
expect(response).toEqual(200);
});

it('should return "200" on a send metrics success for script K6 test', async () => {
let mock = new MockAdapter(axios);
mock.onPost().reply(200, {});

let response = await lambda.send({ taskCount: _taskCount, testType: "k6" });
expect(response).toEqual(200);
});

it('should return "Network Error" on connection timedout', async () => {
let mock = new MockAdapter(axios);
mock.onPut().networkError();
Expand Down
17 changes: 13 additions & 4 deletions source/console/src/Components/Create/Create.js
Original file line number Diff line number Diff line change
Expand Up @@ -216,14 +216,22 @@ class Create extends React.Component {
],
};
} else {
var extension;
if (values.testType === "jmeter") {
extension = "jmx";
}
if (values.testType === "k6") {
extension = "js";
}
payload.testScenario.execution[0].executor = values.testType;
payload.testScenario.scenarios[values.testName] = {
script: `${testId}.jmx`,
script: `${testId}.${extension}`,
};

if (this.state.file) {
try {
const file = this.state.file;
let filename = `${testId}.jmx`;
let filename = `${testId}.${extension}`;

if (file.type && file.type.includes("zip")) {
payload.fileType = "zip";
Expand All @@ -232,7 +240,7 @@ class Create extends React.Component {
payload.fileType = "script";
}
this.setState({ isUploading: true });
await Storage.put(`test-scenarios/jmeter/${filename}`, file);
await Storage.put(`test-scenarios/${values.testType}/${filename}`, file);
console.log("Script uploaded successfully");
} catch (error) {
console.error("Error", error);
Expand Down Expand Up @@ -925,6 +933,7 @@ class Create extends React.Component {
>
<option value="simple">Single HTTP Endpoint</option>
<option value="jmeter">JMeter</option>
<option value="k6">K6</option>
</Input>
</FormGroup>
{this.state.formValues.testType === "simple" && (
Expand Down Expand Up @@ -1029,7 +1038,7 @@ class Create extends React.Component {
<FormText color="muted">
You can choose either a <code>.jmx</code> file or a <code>.zip</code> file. Choose{" "}
<code>.zip</code> file if you have any files to upload other than a <code>.jmx</code> script
file.
file, or if you didn't select a "JMeter" as the test type.
</FormText>
{this.state.isUploading && (
<div className="alert alert-info" role="alert">
Expand Down
11 changes: 10 additions & 1 deletion source/console/src/Components/Details/Details.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ class Details extends React.Component {
data.method = data.testScenario.scenarios[`${data.testName}`].requests[0].method;
data.body = data.testScenario.scenarios[`${data.testName}`].requests[0].body;
data.headers = data.testScenario.scenarios[`${data.testName}`].requests[0].headers;
} else {
data.testScenario.execution[0].executor = data.testType;
}

this.setState({
Expand Down Expand Up @@ -131,7 +133,14 @@ class Details extends React.Component {
try {
const testId = this.state.testId;
const { testType } = this.state.data;
let filename = this.state.data.fileType === "zip" ? `${testId}.zip` : `${testId}.jmx`;
var extension;
if (testType === "jmeter") {
extension = "jmx";
}
if (testType === "k6") {
extension = "js";
}
let filename = this.state.data.fileType === "zip" ? `${testId}.zip` : `${testId}.${extension}`;
const url = await Storage.get(`test-scenarios/${testType}/${filename}`, { expires: 10 });
window.open(url, "_blank");
} catch (error) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,16 @@ class TestControlButtons extends React.Component {
],
};
} else {
var extension;
if (data.testType === "jmeter") {
extension = "jmx";
}
if (data.testType === "k6") {
extension = "js";
}
payload.testScenario.execution[0].executor = data.testType;
payload.testScenario.scenarios[data.testName] = {
script: `${testId}.jmx`,
script: `${testId}.${extension}`,
};
payload.fileType = data.fileType;
}
Expand Down
21 changes: 21 additions & 0 deletions source/results-parser/lib/metrics/index.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,27 @@ describe("#SEND METRICS", () => {
expect(response).toEqual(200);
});

it('should return "200" on a send metrics success for zip K6 test', async () => {
let mock = new MockAdapter(axios);
mock.onPost().reply(200, {});

let response = await lambda.send({
totalDuration: _duration,
testType: "k6",
fileType: "zip",
testResult: "failed",
});
expect(response).toEqual(200);
});

it('should return "200" on a send metrics success for script K6 test', async () => {
let mock = new MockAdapter(axios);
mock.onPost().reply(200, {});

let response = await lambda.send({ totalDuration: _duration, testType: "k6", testResult: "cancelled" });
expect(response).toEqual(200);
});

it('should return "Network Error" on connection timeout', async () => {
let mock = new MockAdapter(axios);
mock.onPost().networkError();
Expand Down