From b227f5c04b05ebbac3a16584cd3eaa36b3c6b34d Mon Sep 17 00:00:00 2001 From: Martin Prikryl Date: Tue, 8 Nov 2022 12:16:12 +0100 Subject: [PATCH 1/2] Add JMeter 5.5 with Java 18 --- jmeter/5.2/Dockerfile | 48 +++++++++++++++++++++++++ jmeter/5.2/entrypoint.sh | 76 ++++++++++++++++++++++++++++++++++++++++ jmeter/Dockerfile | 23 ++++++------ jmeter/entrypoint.sh | 10 +++--- 4 files changed, 140 insertions(+), 17 deletions(-) create mode 100644 jmeter/5.2/Dockerfile create mode 100755 jmeter/5.2/entrypoint.sh diff --git a/jmeter/5.2/Dockerfile b/jmeter/5.2/Dockerfile new file mode 100644 index 0000000..bd5a971 --- /dev/null +++ b/jmeter/5.2/Dockerfile @@ -0,0 +1,48 @@ +FROM openjdk:8-alpine + +LABEL maintainer="David Sperling " + +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"] diff --git a/jmeter/5.2/entrypoint.sh b/jmeter/5.2/entrypoint.sh new file mode 100755 index 0000000..af154f6 --- /dev/null +++ b/jmeter/5.2/entrypoint.sh @@ -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 "$@" diff --git a/jmeter/Dockerfile b/jmeter/Dockerfile index bd5a971..145a825 100644 --- a/jmeter/Dockerfile +++ b/jmeter/Dockerfile @@ -1,17 +1,17 @@ -FROM openjdk:8-alpine +FROM eclipse-temurin:18-alpine LABEL maintainer="David Sperling " -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 \ @@ -31,8 +31,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-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 \ && sleep 2 \ && PluginsManagerCMD.sh status diff --git a/jmeter/entrypoint.sh b/jmeter/entrypoint.sh index af154f6..906c3cd 100755 --- a/jmeter/entrypoint.sh +++ b/jmeter/entrypoint.sh @@ -24,10 +24,9 @@ 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 - + # run jmeter in client (gru) mode exec jmeter -n $JMETER_FLAGS \ -R $MINION_HOSTS \ @@ -54,10 +53,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" From 98a57c1cfb06bcc819a54a3fdd13f00e5982f0e7 Mon Sep 17 00:00:00 2001 From: Martin Prikryl Date: Tue, 22 Nov 2022 11:12:11 +0100 Subject: [PATCH 2/2] Limit thread lifetime --- README.md | 1 + jmeter/Dockerfile | 5 +++-- jmeter/entrypoint.sh | 9 +++++++++ lucy/lucy.sh | 3 ++- 4 files changed, 15 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d868c7f..adf80b0 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/jmeter/Dockerfile b/jmeter/Dockerfile index 145a825..557fc71 100644 --- a/jmeter/Dockerfile +++ b/jmeter/Dockerfile @@ -16,7 +16,8 @@ ENV CUSTOM_PLUGIN_URL="" # Install the required tools for JMeter RUN apk add --update --no-cache \ curl \ - openssh-client + openssh-client \ + xmlstarlet WORKDIR /opt @@ -33,7 +34,7 @@ RUN curl -O https://archive.apache.org/dist/jmeter/binaries/$JMETER_VERSION.tgz # install all available plugins except for those that are deprecated, not compatible or under licence RUN PluginsManagerCMD.sh install-all-except \ - 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-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 diff --git a/jmeter/entrypoint.sh b/jmeter/entrypoint.sh index 906c3cd..c5507bf 100755 --- a/jmeter/entrypoint.sh +++ b/jmeter/entrypoint.sh @@ -27,6 +27,15 @@ if [ ${1##*.} = 'jmx' ]; then # remove setting JAVA heap sed -i 's/-Xms1g -Xmx1g -XX:MaxMetaspaceSize=256m//' $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 \ diff --git a/lucy/lucy.sh b/lucy/lucy.sh index 1b05344..8d2090d 100755 --- a/lucy/lucy.sh +++ b/lucy/lucy.sh @@ -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"