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

Limit thread duration #59

Open
wants to merge 2 commits into
base: master
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ The following required and optional environment variables are supported:
|RETAIN_CLUSTER||None|Set to `true` if you want to re-use your cluster for future tests. Warning, you will incur AWS charges if you leave your cluster running.|
|CUSTOM_PLUGIN_URL||None|The URL of a custom plugin you want to install in the Minions. File will be copied to $JMETER_HOME/lib/ext.||
|COPY_DIR||None|Set to `true` if you want to copy the directory in which the .jmx file is located to all Minions and Gru. The files will be located in all Docker containers in ` /plans`. Update your JMX file to reference external files at `/plans/...`|
|TIME_LIMIT||None|*Since 5.5:* Limits Thread lifetime of Thread Group. Value is in seconds.|

## Notes
All current JMeter Plugins are installed via the Plugins Manager.
Expand Down
48 changes: 48 additions & 0 deletions jmeter/5.2/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
FROM openjdk:8-alpine

LABEL maintainer="David Sperling <[email protected]>"

ENV JMETER_VERSION apache-jmeter-5.2
ENV JMETER_HOME /opt/$JMETER_VERSION
ENV PATH $PATH:$JMETER_HOME/bin
ENV CMDRUNNER_VERSION 2.2
ENV PLUGINMGR_VERSION 1.3

# overridable environment variables
ENV RESULTS_LOG results.jtl
ENV JMETER_FLAGS=
ENV CUSTOM_PLUGIN_URL=

# Install the required tools for JMeter
RUN apk add --update --no-cache \
curl \
openssh-client

WORKDIR /opt

# install JMeter and the JMeter Plugins Manager
RUN curl -O https://archive.apache.org/dist/jmeter/binaries/$JMETER_VERSION.tgz \
&& tar -xvf $JMETER_VERSION.tgz \
&& rm $JMETER_VERSION.tgz \
&& rm -rf $JMETER_VERSION/docs $JMETER_VERSION/printable_docs \
&& cd $JMETER_HOME/lib \
&& curl -OL http://search.maven.org/remotecontent?filepath=kg/apc/cmdrunner/$CMDRUNNER_VERSION/cmdrunner-$CMDRUNNER_VERSION.jar \
&& cd $JMETER_HOME/lib/ext \
&& curl -OL4 http://search.maven.org/remotecontent?filepath=kg/apc/jmeter-plugins-manager/$PLUGINMGR_VERSION/jmeter-plugins-manager-$PLUGINMGR_VERSION.jar \
&& java -cp jmeter-plugins-manager-$PLUGINMGR_VERSION.jar org.jmeterplugins.repository.PluginManagerCMDInstaller

# install all available plugins except for those that are deprecated
RUN PluginsManagerCMD.sh install-all-except jpgc-hadoop,jpgc-oauth \
&& sleep 2 \
&& PluginsManagerCMD.sh status

# copy our entrypoint
COPY entrypoint.sh /opt/jmeter/

WORKDIR /logs

EXPOSE 1099 50000 51000 4445/udp

# default command in the entrypoint is 'minion'
ENTRYPOINT ["/opt/jmeter/entrypoint.sh"]
CMD ["minion"]
76 changes: 76 additions & 0 deletions jmeter/5.2/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/bin/sh
#
# Main entrypoint for our Docker image - runs Gru, Minions or other commands

# any .jmx file passed in the command line we act as 'Gru'
if [ ${1##*.} = 'jmx' ]; then

if [ "$MINION_HOSTS" = '' ]; then
echo "MINION_HOSTS must be specified - a command separated list of hostnames or IP addresses"
exit 1
fi
echo "Connecting to $MINION_HOSTS"

# AWS Public HOSTNAME API
echo "Detecting an AWS Environment"
PUBLIC_HOSTNAME=$(curl -s --max-time 5 http://169.254.169.254/latest/meta-data/public-hostname)

if [ "$PUBLIC_HOSTNAME" = '' ]; then
echo "Not running in AWS. Using Gru HOSTNAME $HOSTNAME"
else
HOSTNAME=$PUBLIC_HOSTNAME
echo "Using Gru AWS Public HOSTNAME $HOSTNAME"
fi
# empty the logs directory, or jmeter may fail
rm -rf /logs/report /logs/*.log /logs/*.jtl

# remove setting JAVA heap and use the RUN_IN_DOCKER variable
sed -i 's/-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m//' $JMETER_HOME/bin/jmeter
sed -i 's/# RUN_IN_DOCKER/RUN_IN_DOCKER/' $JMETER_HOME/bin/jmeter

# run jmeter in client (gru) mode
exec jmeter -n $JMETER_FLAGS \
-R $MINION_HOSTS \
-Dclient.rmi.localport=51000 \
-Dserver.rmi.ssl.disable=true \
-Djava.rmi.server.hostname=${PUBLIC_HOSTNAME} \
-l $RESULTS_LOG \
-t $1 \
-e -o /logs/report

fi

# act as a 'Minion'
if [ "$1" = 'minion' ]; then

# AWS Public HOSTNAME API
echo "Detecting an AWS Environment"
PUBLIC_HOSTNAME=$(curl -s --max-time 5 http://169.254.169.254/latest/meta-data/public-hostname)

if [ "$PUBLIC_HOSTNAME" = '' ]; then
echo "Not running in AWS. Using Minion HOSTNAME $HOSTNAME"
else
HOSTNAME=$PUBLIC_HOSTNAME
echo "Using Minion AWS Public HOSTNAME $HOSTNAME"
fi

# remove setting JAVA heap and use the RUN_IN_DOCKER variable
sed -i 's/-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m//' $JMETER_HOME/bin/jmeter
sed -i 's/# RUN_IN_DOCKER/RUN_IN_DOCKER/' $JMETER_HOME/bin/jmeter

# install custom plugin if requested
if [ "$CUSTOM_PLUGIN_URL" != '' ]; then
echo "Installing custom plugin $CUSTOM_PLUGIN_URL"
CUSTOM_PLUGIN_FILE="${CUSTOM_PLUGIN_URL##*/}"
curl -o $JMETER_HOME/lib/ext/$CUSTOM_PLUGIN_FILE $CUSTOM_PLUGIN_URL
fi

# run jmeter in server (minion) mode
exec jmeter-server -n $JMETER_FLAGS \
-Dserver.rmi.localport=50000 \
-Dserver.rmi.ssl.disable=true \
-Djava.rmi.server.hostname=${HOSTNAME}

fi

exec "$@"
26 changes: 14 additions & 12 deletions jmeter/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
FROM openjdk:8-alpine
FROM eclipse-temurin:18-alpine

LABEL maintainer="David Sperling <[email protected]>"

ENV JMETER_VERSION apache-jmeter-5.2
ENV JMETER_HOME /opt/$JMETER_VERSION
ENV PATH $PATH:$JMETER_HOME/bin
ENV CMDRUNNER_VERSION 2.2
ENV PLUGINMGR_VERSION 1.3
ENV JMETER_VERSION=apache-jmeter-5.5
ENV JMETER_HOME=/opt/$JMETER_VERSION
ENV PATH=$PATH:$JMETER_HOME/bin
ENV CMDRUNNER_VERSION=2.3
ENV PLUGINMGR_VERSION=1.8

# overridable environment variables
ENV RESULTS_LOG results.jtl
ENV JMETER_FLAGS=
ENV CUSTOM_PLUGIN_URL=
ENV RESULTS_LOG=results.jtl
ENV JMETER_FLAGS=""
ENV CUSTOM_PLUGIN_URL=""

# Install the required tools for JMeter
RUN apk add --update --no-cache \
curl \
openssh-client
openssh-client \
xmlstarlet

WORKDIR /opt

Expand All @@ -31,8 +32,9 @@ RUN curl -O https://archive.apache.org/dist/jmeter/binaries/$JMETER_VERSION.tgz
&& curl -OL4 http://search.maven.org/remotecontent?filepath=kg/apc/jmeter-plugins-manager/$PLUGINMGR_VERSION/jmeter-plugins-manager-$PLUGINMGR_VERSION.jar \
&& java -cp jmeter-plugins-manager-$PLUGINMGR_VERSION.jar org.jmeterplugins.repository.PluginManagerCMDInstaller

# install all available plugins except for those that are deprecated
RUN PluginsManagerCMD.sh install-all-except jpgc-hadoop,jpgc-oauth \
# install all available plugins except for those that are deprecated, not compatible or under licence
RUN PluginsManagerCMD.sh install-all-except \
jpgc-hadoop,jpgc-oauth,schema-assertion,ulp-jmeter-autocorrelator-plugin,ulp-jmeter-gwt-plugin,ulp-jmeter-videostreaming-plugin,di-kafkameter,tilln-iso8583,jmeter.backendlistener.elasticsearch,jmeter-grpc-request,websocket-sampler,jpgc-graphs-vs \
&& sleep 2 \
&& PluginsManagerCMD.sh status

Expand Down
19 changes: 13 additions & 6 deletions jmeter/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,18 @@ if [ ${1##*.} = 'jmx' ]; then
# empty the logs directory, or jmeter may fail
rm -rf /logs/report /logs/*.log /logs/*.jtl

# remove setting JAVA heap and use the RUN_IN_DOCKER variable
# remove setting JAVA heap
sed -i 's/-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m//' $JMETER_HOME/bin/jmeter
sed -i 's/# RUN_IN_DOCKER/RUN_IN_DOCKER/' $JMETER_HOME/bin/jmeter


# limit thread duration in .jmx if TIME_LIMIT is positive number
if [ "${TIME_LIMIT}" -gt "0" ] 2> /dev/null
then
xml ed --inplace \
--update "//boolProp[@name='ThreadGroup.scheduler']" --value true \
--update "//stringProp[@name='ThreadGroup.duration' and (.='' or .<${TIME_LIMIT})]" --value $TIME_LIMIT \
$1
fi

# run jmeter in client (gru) mode
exec jmeter -n $JMETER_FLAGS \
-R $MINION_HOSTS \
Expand All @@ -54,10 +62,9 @@ if [ "$1" = 'minion' ]; then
echo "Using Minion AWS Public HOSTNAME $HOSTNAME"
fi

# remove setting JAVA heap and use the RUN_IN_DOCKER variable
# remove setting JAVA heap
sed -i 's/-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m//' $JMETER_HOME/bin/jmeter
sed -i 's/# RUN_IN_DOCKER/RUN_IN_DOCKER/' $JMETER_HOME/bin/jmeter


# install custom plugin if requested
if [ "$CUSTOM_PLUGIN_URL" != '' ]; then
echo "Installing custom plugin $CUSTOM_PLUGIN_URL"
Expand Down
3 changes: 2 additions & 1 deletion lucy/lucy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,8 @@ else
echo "Running Docker to start JMeter in Gru mode"
JMX_IN_COMTAINER=/plans/$(basename $INPUT_JMX)
ssh -i $PEM_PATH/$KEY_NAME.pem -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ec2-user@${GRU_HOST} \
"docker run --network host -v /tmp:/plans -v /logs:/logs --env MINION_HOSTS=$MINION_HOSTS --env JMETER_FLAGS=$JMETER_FLAGS smithmicro/jmeter:$JMETER_VERSION $JMX_IN_COMTAINER"
"docker run --network host -v /tmp:/plans -v /logs:/logs --env MINION_HOSTS=$MINION_HOSTS \
--env JMETER_FLAGS=$JMETER_FLAGS --env TIME_LIMIT=$TIME_LIMIT smithmicro/jmeter:$JMETER_VERSION $JMX_IN_COMTAINER"

# Step 8 - Fetch the results from Gru
echo "Copying results from Gru"
Expand Down