Skip to content

Commit

Permalink
Merge pull request #35 from smithmicro/feature-24
Browse files Browse the repository at this point in the history
Pass contents of /plans directory to Gru and Minions
  • Loading branch information
dsperling authored Jan 26, 2019
2 parents 09ead8d + 97d7af3 commit f9f4459
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 8 deletions.
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,10 @@ This Docker image replaces the JMeter master/slave nomenclature with *Gru*, *Min
* Step 3 - Run a Minion Task with the requested instance count
* Step 4 - Get Gru and Minion's instance ID's
* Step 5 - Get IP addresses from Gru and Minions
* Step 6 - Run Gru with the specified JMX
* Step 7 - Fetch the results from Gru
* Step 8 - Delete the cluster
* Step 6 - Copy all files to Minions/Gru, or just the JMX
* Step 7 - Run Gru with the specified JMX
* Step 8 - Fetch the results from Gru
* Step 9 - Delete the cluster

### Volumes
The `lucy` container uses 3 volumes:
Expand Down Expand Up @@ -112,6 +113,7 @@ The following required and optional environment variables are supported:
|JMETER_FLAGS||None|Custom JMeter command line options. For example, passing `-X` will tell the Minion to exit at the end of the test|
|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/...`|

## Notes
All current JMeter Plugins are installed via the Plugins Manager.
Expand Down
23 changes: 18 additions & 5 deletions lucy/lucy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -138,21 +138,34 @@ else
# uncomment if you want to pause Lucy to inspect Gru or a Minion
#read -p "Press enter to start Gru setup: "

# Step 6 - Run Gru with the specified JMX
echo "Copying $INPUT_JMX to Gru"
scp -i $PEM_PATH/$KEY_NAME.pem -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $INPUT_JMX ec2-user@${GRU_HOST}:/tmp
# Step 6 - Copy all files to Minions/Gru, or just the JMX
if [ "$COPY_DIR" == '' ]; then
echo "Copying $INPUT_JMX to Gru"
scp -i $PEM_PATH/$KEY_NAME.pem -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $INPUT_JMX ec2-user@${GRU_HOST}:/tmp
else
# Get Gru and Minion public hosts (space delimited) so Lucy can reach them for scp.
PUBLIC_HOSTS=$(aws ec2 describe-instances --instance-ids $GRU_INSTANCE_ID $MINION_INSTANCE_IDS \
--query 'Reservations[*].Instances[*].[PublicIpAddress]' --output text | tr '\n' ' ')
JMX_DIR=$(dirname $INPUT_JMX)

for HOST in $PUBLIC_HOSTS; do
echo "Copying $INPUT_JMX and test files to $HOST"
scp -i $PEM_PATH/$KEY_NAME.pem -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $JMX_DIR/* ec2-user@${HOST}:/tmp
done
fi

# Step 7 - Run Gru with the specified JMX
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"

# Step 6 - Fetch the results from Gru
# Step 8 - Fetch the results from Gru
echo "Copying results from Gru"
scp -r -i $PEM_PATH/$KEY_NAME.pem -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no ec2-user@${GRU_HOST}:/logs/* /logs
fi

# Step 7 - Delete the cluster
# Step 9 - Delete the cluster
if [ "$RETAIN_CLUSTER" == '' ]; then
echo "Deleting cluster/$CLUSTER_NAME"
ecs-cli down --cluster $CLUSTER_NAME --force
Expand Down
1 change: 1 addition & 0 deletions lucy/lucy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ services:
- 50000:50000
volumes:
- /logs:/logs
- /tmp:/plans
environment:
- CUSTOM_PLUGIN_URL=
113 changes: 113 additions & 0 deletions plans/demo-csv.jmx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.0 r1840935">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan" enabled="true">
<stringProp name="TestPlan.comments"></stringProp>
<boolProp name="TestPlan.functional_mode">false</boolProp>
<boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="searchStringsCSVPath" elementType="Argument">
<stringProp name="Argument.name">searchStringsCSVPath</stringProp>
<stringProp name="Argument.value">${__P(searchStringsCSVPath,/plans/searchStrings.csv)}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
</elementProp>
</collectionProp>
</elementProp>
<stringProp name="TestPlan.user_define_classpath"></stringProp>
</TestPlan>
<hashTree>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group" enabled="true">
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
<boolProp name="LoopController.continue_forever">false</boolProp>
<stringProp name="LoopController.loops">10</stringProp>
</elementProp>
<stringProp name="ThreadGroup.num_threads">1</stringProp>
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
<boolProp name="ThreadGroup.scheduler">false</boolProp>
<stringProp name="ThreadGroup.duration"></stringProp>
<stringProp name="ThreadGroup.delay"></stringProp>
</ThreadGroup>
<hashTree>
<CSVDataSet guiclass="TestBeanGUI" testclass="CSVDataSet" testname="CSV Data Set Config" enabled="true">
<stringProp name="delimiter">,</stringProp>
<stringProp name="fileEncoding">utf-8</stringProp>
<stringProp name="filename">/plans/search-strings.csv</stringProp>
<boolProp name="ignoreFirstLine">false</boolProp>
<boolProp name="quotedData">false</boolProp>
<boolProp name="recycle">true</boolProp>
<stringProp name="shareMode">shareMode.all</stringProp>
<boolProp name="stopThread">false</boolProp>
<stringProp name="variableNames">searchString</stringProp>
</CSVDataSet>
<hashTree/>
<HTTPSamplerProxy guiclass="HttpTestSampleGui" testclass="HTTPSamplerProxy" testname="HTTP Request" enabled="true">
<elementProp name="HTTPsampler.Arguments" elementType="Arguments" guiclass="HTTPArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
<collectionProp name="Arguments.arguments">
<elementProp name="q" elementType="HTTPArgument">
<boolProp name="HTTPArgument.always_encode">false</boolProp>
<stringProp name="Argument.value">${searchString}</stringProp>
<stringProp name="Argument.metadata">=</stringProp>
<boolProp name="HTTPArgument.use_equals">true</boolProp>
<stringProp name="Argument.name">q</stringProp>
</elementProp>
</collectionProp>
</elementProp>
<stringProp name="HTTPSampler.domain">www.google.com</stringProp>
<stringProp name="HTTPSampler.port">80</stringProp>
<stringProp name="HTTPSampler.protocol"></stringProp>
<stringProp name="HTTPSampler.contentEncoding"></stringProp>
<stringProp name="HTTPSampler.path">/search</stringProp>
<stringProp name="HTTPSampler.method">GET</stringProp>
<boolProp name="HTTPSampler.follow_redirects">true</boolProp>
<boolProp name="HTTPSampler.auto_redirects">false</boolProp>
<boolProp name="HTTPSampler.use_keepalive">true</boolProp>
<boolProp name="HTTPSampler.DO_MULTIPART_POST">false</boolProp>
<stringProp name="HTTPSampler.embedded_url_re"></stringProp>
<stringProp name="HTTPSampler.connect_timeout"></stringProp>
<stringProp name="HTTPSampler.response_timeout"></stringProp>
</HTTPSamplerProxy>
<hashTree/>
</hashTree>
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
<boolProp name="ResultCollector.error_logging">false</boolProp>
<objProp>
<name>saveConfig</name>
<value class="SampleSaveConfiguration">
<time>true</time>
<latency>true</latency>
<timestamp>true</timestamp>
<success>true</success>
<label>true</label>
<code>true</code>
<message>false</message>
<threadName>false</threadName>
<dataType>false</dataType>
<encoding>false</encoding>
<assertions>true</assertions>
<subresults>true</subresults>
<responseData>false</responseData>
<samplerData>false</samplerData>
<xml>false</xml>
<fieldNames>true</fieldNames>
<responseHeaders>true</responseHeaders>
<requestHeaders>true</requestHeaders>
<responseDataOnError>false</responseDataOnError>
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
<assertionsResultsToSave>2</assertionsResultsToSave>
<bytes>true</bytes>
<sentBytes>true</sentBytes>
<url>true</url>
<threadCounts>true</threadCounts>
<idleTime>true</idleTime>
<connectTime>true</connectTime>
</value>
</objProp>
<stringProp name="filename"></stringProp>
</ResultCollector>
<hashTree/>
</hashTree>
</hashTree>
</jmeterTestPlan>
18 changes: 18 additions & 0 deletions plans/search-strings.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
Niwuryik
DronFet3
VegNudBoth
Tejyiajcy
jobWamRac
recuvNab
gomLakik5
byWremirOk
Ikhecec9
roamosIpMo
BijHonFatt
TrakIsvew
Avthudro
Dacfowokuc
KochutNad
Thanoisp
Lacnuop3
dudoalRi

0 comments on commit f9f4459

Please sign in to comment.