Skip to content

Commit 5a35437

Browse files
andiemontoyeahandiem-bq
and
andiem-bq
authored
[AD-250] Add POC jmeter test plan (#34)
* [AD-250] Add POC jmeter test plan * [AD-250] Add POC jmeter test plan * Commit Code Coverage Badge * [AD-250] Add documentation * Commit Code Coverage Badge * [AD-250] Remove setup info unrelated to DocumentDb + use only 1 query format * Commit Code Coverage Badge * [AD-250] Removed hardcoded password * [AD-250] Update instructions * Commit Code Coverage Badge * [AD-250] Improvements from code review * Commit Code Coverage Badge * Commit Code Coverage Badge * [AD-250] Fix typo * Commit Code Coverage Badge Co-authored-by: andiem-bq <[email protected]>
1 parent efc06be commit 5a35437

File tree

4 files changed

+286
-0
lines changed

4 files changed

+286
-0
lines changed

JMeter/DocumentDb_Test_Plan.jmx

+182
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.4.1">
3+
<hashTree>
4+
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="DocumentDb Test Plan" enabled="true">
5+
<stringProp name="TestPlan.comments"></stringProp>
6+
<boolProp name="TestPlan.functional_mode">true</boolProp>
7+
<boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
8+
<boolProp name="TestPlan.serialize_threadgroups">false</boolProp>
9+
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables" enabled="true">
10+
<collectionProp name="Arguments.arguments">
11+
<elementProp name="CONNECTION_STRING" elementType="Argument">
12+
<stringProp name="Argument.name">CONNECTION_STRING</stringProp>
13+
<stringProp name="Argument.value">${__P(connectionString, jdbc:documentdb://localhost:27017/jmeter?tlsAllowInvalidHostnames=true)}</stringProp>
14+
<stringProp name="Argument.metadata">=</stringProp>
15+
</elementProp>
16+
<elementProp name="USERNAME" elementType="Argument">
17+
<stringProp name="Argument.name">USERNAME</stringProp>
18+
<stringProp name="Argument.value">${__P(username, documentdb)}</stringProp>
19+
<stringProp name="Argument.metadata">=</stringProp>
20+
</elementProp>
21+
<elementProp name="PASSWORD" elementType="Argument">
22+
<stringProp name="Argument.name">PASSWORD</stringProp>
23+
<stringProp name="Argument.value">${__P(password)}</stringProp>
24+
<stringProp name="Argument.metadata">=</stringProp>
25+
</elementProp>
26+
</collectionProp>
27+
</elementProp>
28+
<stringProp name="TestPlan.user_define_classpath"></stringProp>
29+
</TestPlan>
30+
<hashTree>
31+
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Query ThreadGroup" enabled="true">
32+
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
33+
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller" enabled="true">
34+
<boolProp name="LoopController.continue_forever">false</boolProp>
35+
<stringProp name="LoopController.loops">4</stringProp>
36+
</elementProp>
37+
<stringProp name="ThreadGroup.num_threads">1</stringProp>
38+
<stringProp name="ThreadGroup.ramp_time">1</stringProp>
39+
<boolProp name="ThreadGroup.scheduler">false</boolProp>
40+
<stringProp name="ThreadGroup.duration"></stringProp>
41+
<stringProp name="ThreadGroup.delay"></stringProp>
42+
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
43+
</ThreadGroup>
44+
<hashTree>
45+
<CSVDataSet guiclass="TestBeanGUI" testclass="CSVDataSet" testname="Test Plan CSV" enabled="true">
46+
<stringProp name="delimiter">,</stringProp>
47+
<stringProp name="fileEncoding"></stringProp>
48+
<stringProp name="filename">./Test_Plan.csv</stringProp>
49+
<boolProp name="ignoreFirstLine">false</boolProp>
50+
<boolProp name="quotedData">true</boolProp>
51+
<boolProp name="recycle">true</boolProp>
52+
<stringProp name="shareMode">shareMode.all</stringProp>
53+
<boolProp name="stopThread">false</boolProp>
54+
<stringProp name="variableNames"></stringProp>
55+
</CSVDataSet>
56+
<hashTree/>
57+
<JDBCDataSource guiclass="TestBeanGUI" testclass="JDBCDataSource" testname="JDBC Connection Configuration" enabled="true">
58+
<boolProp name="autocommit">true</boolProp>
59+
<stringProp name="checkQuery"></stringProp>
60+
<stringProp name="connectionAge">5000</stringProp>
61+
<stringProp name="connectionProperties"></stringProp>
62+
<stringProp name="dataSource">DocumentDB</stringProp>
63+
<stringProp name="dbUrl">${CONNECTION_STRING}</stringProp>
64+
<stringProp name="driver"></stringProp>
65+
<stringProp name="initQuery"></stringProp>
66+
<boolProp name="keepAlive">true</boolProp>
67+
<stringProp name="password">${PASSWORD}</stringProp>
68+
<stringProp name="poolMax">0</stringProp>
69+
<boolProp name="preinit">false</boolProp>
70+
<stringProp name="timeout">10000</stringProp>
71+
<stringProp name="transactionIsolation">DEFAULT</stringProp>
72+
<stringProp name="trimInterval">60000</stringProp>
73+
<stringProp name="username">${USERNAME}</stringProp>
74+
</JDBCDataSource>
75+
<hashTree/>
76+
<JDBCSampler guiclass="TestBeanGUI" testclass="JDBCSampler" testname="${__V(${test_name})}" enabled="true">
77+
<stringProp name="dataSource">DocumentDB</stringProp>
78+
<stringProp name="query">${query}</stringProp>
79+
<stringProp name="queryArguments"></stringProp>
80+
<stringProp name="queryArgumentsTypes"></stringProp>
81+
<stringProp name="queryTimeout"></stringProp>
82+
<stringProp name="queryType">Select Statement</stringProp>
83+
<stringProp name="resultSetHandler">Store as String</stringProp>
84+
<stringProp name="resultSetMaxRows"></stringProp>
85+
<stringProp name="resultVariable"></stringProp>
86+
<stringProp name="variableNames"></stringProp>
87+
</JDBCSampler>
88+
<hashTree>
89+
<DurationAssertion guiclass="DurationAssertionGui" testclass="DurationAssertion" testname="Duration Assertion" enabled="true">
90+
<stringProp name="DurationAssertion.duration">20000</stringProp>
91+
</DurationAssertion>
92+
<hashTree/>
93+
<ResponseAssertion guiclass="AssertionGui" testclass="ResponseAssertion" testname="Response Assertion" enabled="true">
94+
<collectionProp name="Asserion.test_strings">
95+
<stringProp name="71001929">${result}</stringProp>
96+
</collectionProp>
97+
<stringProp name="Assertion.custom_message"></stringProp>
98+
<stringProp name="Assertion.test_field">Assertion.response_data</stringProp>
99+
<boolProp name="Assertion.assume_success">false</boolProp>
100+
<intProp name="Assertion.test_type">8</intProp>
101+
</ResponseAssertion>
102+
<hashTree/>
103+
</hashTree>
104+
<ResultCollector guiclass="ViewResultsFullVisualizer" testclass="ResultCollector" testname="View Results Tree" enabled="true">
105+
<boolProp name="ResultCollector.error_logging">false</boolProp>
106+
<objProp>
107+
<name>saveConfig</name>
108+
<value class="SampleSaveConfiguration">
109+
<time>true</time>
110+
<latency>true</latency>
111+
<timestamp>true</timestamp>
112+
<success>true</success>
113+
<label>true</label>
114+
<code>true</code>
115+
<message>true</message>
116+
<threadName>true</threadName>
117+
<dataType>true</dataType>
118+
<encoding>false</encoding>
119+
<assertions>true</assertions>
120+
<subresults>true</subresults>
121+
<responseData>false</responseData>
122+
<samplerData>false</samplerData>
123+
<xml>false</xml>
124+
<fieldNames>true</fieldNames>
125+
<responseHeaders>false</responseHeaders>
126+
<requestHeaders>false</requestHeaders>
127+
<responseDataOnError>false</responseDataOnError>
128+
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
129+
<assertionsResultsToSave>0</assertionsResultsToSave>
130+
<bytes>true</bytes>
131+
<sentBytes>true</sentBytes>
132+
<url>true</url>
133+
<threadCounts>true</threadCounts>
134+
<idleTime>true</idleTime>
135+
<connectTime>true</connectTime>
136+
</value>
137+
</objProp>
138+
<stringProp name="filename"></stringProp>
139+
</ResultCollector>
140+
<hashTree/>
141+
<ResultCollector guiclass="SummaryReport" testclass="ResultCollector" testname="Summary Report" enabled="true">
142+
<boolProp name="ResultCollector.error_logging">false</boolProp>
143+
<objProp>
144+
<name>saveConfig</name>
145+
<value class="SampleSaveConfiguration">
146+
<time>true</time>
147+
<latency>true</latency>
148+
<timestamp>true</timestamp>
149+
<success>true</success>
150+
<label>true</label>
151+
<code>true</code>
152+
<message>true</message>
153+
<threadName>true</threadName>
154+
<dataType>true</dataType>
155+
<encoding>false</encoding>
156+
<assertions>true</assertions>
157+
<subresults>true</subresults>
158+
<responseData>false</responseData>
159+
<samplerData>false</samplerData>
160+
<xml>false</xml>
161+
<fieldNames>true</fieldNames>
162+
<responseHeaders>false</responseHeaders>
163+
<requestHeaders>false</requestHeaders>
164+
<responseDataOnError>false</responseDataOnError>
165+
<saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
166+
<assertionsResultsToSave>0</assertionsResultsToSave>
167+
<bytes>true</bytes>
168+
<sentBytes>true</sentBytes>
169+
<url>true</url>
170+
<threadCounts>true</threadCounts>
171+
<idleTime>true</idleTime>
172+
<connectTime>true</connectTime>
173+
</value>
174+
</objProp>
175+
<stringProp name="filename"></stringProp>
176+
<boolProp name="saveHeaders">false</boolProp>
177+
</ResultCollector>
178+
<hashTree/>
179+
</hashTree>
180+
</hashTree>
181+
</hashTree>
182+
</jmeterTestPlan>

JMeter/JMeter.md

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# JMeter Tests
2+
3+
## Set-Up
4+
5+
### Install & Set Up JMeter
6+
7+
- Download [JMeter](http://jmeter.apache.org/download_jmeter.cgi) (should be >= version 5.4.1).
8+
9+
- Add the latest DocumentDbDriver `.jar` to `/lib` folder of your JMeter installation.
10+
11+
### Set Up a Test Cluster
12+
13+
If targeting a cluster that has not been used for JMeter testing before,
14+
you will need to insert the relevant test data beforehand.
15+
Use `mongoimport` to insert the data from `/testData`, using the name of each file as the collection name and “jmeter” as the database.
16+
17+
A potential enhancement could be to automate this.
18+
19+
## Run Tests
20+
21+
### Run Test Plan with DocumentDb Driver
22+
23+
#### GUI
24+
25+
1. Open the `DocumentDb_Test_Plan.jmx` file in JMeter.
26+
27+
1. Start an SSH tunnel for the target cluster.
28+
29+
1. Click on the `DocumentDb Test Plan` element.
30+
Change user variables `CONNECTION_STRING`, `USERNAME`, and `PASSWORD` depending on SSH tunnel setup and target cluster.
31+
32+
1. Run the test plan.
33+
34+
#### Command-line
35+
36+
1. Start an SSH tunnel for target cluster.
37+
38+
1. Run the `DocumentDb_Test_Plan.jmx` file.
39+
Pass connection string (`-JconnectionString`), username(`-Jusername`), and password(`-Jpassword`) as parameters. Connection string and username
40+
may be omitted as they have default values but password is required.
41+
Example:
42+
43+
```
44+
./jmeter.sh -n -t DocumentDb_Test_Plan.jmx -Jpassword=<password>
45+
```
46+
47+
### Run Test Plan with Other JDBC Driver
48+
49+
- It may be useful to run the tests against another data source to confirm expected functionality.
50+
The user variables `CONNECTION_STRING`, `USERNAME`, and `PASSWORD`
51+
can be changed to be used with another driver.
52+
53+
- Dependencies of the other driver may need to be setup and/or added to the JMeter `/lib` folder.
54+
Refer to [JMeter documentation](https://jmeter.apache.org/usermanual/get-started.html#opt_jdbc)
55+
and documentation of the specific database vendor for more information.
56+
57+
## Add Tests
58+
59+
### Add Test Data
60+
61+
- Add test data as a `JSON` file under the `/testData` folder.
62+
Use [MongoDB Extended JSON syntax](https://docs.mongodb.com/manual/reference/mongodb-extended-json/)
63+
to explicitly specify types.
64+
65+
### Add Test Cases
66+
67+
- To add a query, you need to add a new row in `Test_Plan.csv`.
68+
69+
- Populate the `query` column with the query to be executed, the `result` column with the
70+
expected result set, and the `test_name` column with a descriptive name for the query.
71+
72+
- To keep results uniform across different data sources for easier comparisons:
73+
74+
- Columns are ordered explicitly instead of using `SELECT *` so column order is deterministic.
75+
76+
- Rows are ordered explicitly with `ORDER BY` so row order is deterministic.
77+
78+
- Calculated fields are named explicitly with `AS` so they always use same name.

JMeter/Test_Plan.csv

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
query,result,test_name
2+
"SELECT int0, int1, string1 FROM jmeter.test ORDER BY int1 LIMIT 5","int0 int1 string1
3+
50 10 Hop
4+
40 20 Hip
5+
30 30 Hop
6+
20 40 Hip
7+
10 50 Hop
8+
",SELECT *
9+
"SELECT int0, int1, string1 FROM jmeter.test WHERE int0 < 40 ORDER BY int1 LIMIT 5","int0 int1 string1
10+
30 30 Hop
11+
20 40 Hip
12+
10 50 Hop
13+
",SELECT WHERE
14+
SELECT SUM(int0) AS expr FROM jmeter.test GROUP BY string1 ORDER BY expr ASC LIMIT 5,"expr
15+
60
16+
90
17+
",SELECT SUM
18+
SELECT CASE WHEN (int0) < 30 THEN 'yes' ELSE 'no' END AS expr FROM jmeter.test GROUP BY CASE WHEN (int0) < 30 THEN 'yes' ELSE 'no' END ORDER BY expr,"expr
19+
no
20+
yes
21+
",SELECT CASE

JMeter/testData/test.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{ "_id" : {"$numberLong": "1"}, "int0": {"$numberLong": "50"}, "int1": {"$numberLong": "10"}, "string1" : "Hop" }
2+
{ "_id" : {"$numberLong": "2"}, "int0": {"$numberLong": "40"}, "int1": {"$numberLong": "20"}, "string1" : "Hip" }
3+
{ "_id" : {"$numberLong": "3"}, "int0": {"$numberLong": "30"}, "int1": {"$numberLong": "30"}, "string1" : "Hop" }
4+
{ "_id" : {"$numberLong": "4"}, "int0": {"$numberLong": "20"}, "int1": {"$numberLong": "40"}, "string1" : "Hip" }
5+
{ "_id" : {"$numberLong": "5"}, "int0": {"$numberLong": "10"}, "int1": {"$numberLong": "50"}, "string1" : "Hop" }

0 commit comments

Comments
 (0)