Skip to content

Commit 9cf9f05

Browse files
Enhancements Jmeter autostop plugin (undera#729)
* Enhancments for AS Plugin * Update JAutoStopPanel.form * update version * Update Contributors.wiki * Update AutoStop.java * Updated Review comments
1 parent 259ad4f commit 9cf9f05

6 files changed

Lines changed: 426 additions & 9 deletions

File tree

plugins/autostop/pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
</parent>
1111
<groupId>kg.apc</groupId>
1212
<artifactId>jmeter-plugins-autostop</artifactId>
13-
<version>0.2</version>
13+
<version>0.3</version>
1414

1515
<name>Autostop plugin</name>
1616
<description>Autostop plugin</description>
@@ -68,4 +68,4 @@
6868
<scope>test</scope>
6969
</dependency>
7070
</dependencies>
71-
</project>
71+
</project>

plugins/autostop/src/main/java/kg/apc/jmeter/reporters/AutoStop.java

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,25 @@
88
import org.apache.jmeter.samplers.Remoteable;
99
import org.apache.jmeter.samplers.SampleEvent;
1010
import org.apache.jmeter.samplers.SampleListener;
11+
import org.apache.jmeter.samplers.SampleResult;
1112
import org.apache.jmeter.testelement.TestStateListener;
13+
import org.apache.jmeter.threads.JMeterContext;
1214
import org.apache.jmeter.threads.JMeterContextService;
15+
import org.apache.jmeter.threads.JMeterThread;
1316
import org.apache.jmeter.util.JMeterUtils;
17+
import org.apache.jmeter.visualizers.SamplingStatCalculator;
1418
import org.slf4j.Logger;
1519
import org.slf4j.LoggerFactory;
1620

21+
22+
23+
import org.apache.jmeter.engine.util.CompoundVariable;
24+
import org.apache.jmeter.threads.JMeterVariables;
25+
import org.apache.jmeter.functions.AbstractFunction;
26+
27+
28+
29+
1730
import java.io.Serializable;
1831
import java.net.DatagramPacket;
1932
import java.net.DatagramSocket;
@@ -32,13 +45,20 @@ public class AutoStop
3245
private final static String ERROR_RATE_SECS = "error_rate_length";
3346
private final static String RESPONSE_LATENCY = "avg_response_latency";
3447
private final static String RESPONSE_LATENCY_SECS = "avg_response_latency_length";
48+
private final static String PERCENTILE_RESPONSE_TIME = "percentile_response_time";
49+
private final static String PERCENTILE_RESPONSE_TIME_SECS ="percentile_response_time_secs";
50+
private final static String PERCENTILE_VALUE = "percentile_value";
51+
private final static String CUSTOM_VALIDATION_DURATION = "custom_validation_duration";
3552
private long curSec = 0L;
3653
private GraphPanelChartAverageElement avgRespTime = new GraphPanelChartAverageElement();
3754
private GraphPanelChartAverageElement avgRespLatency = new GraphPanelChartAverageElement();
3855
private GraphPanelChartAverageElement errorRate = new GraphPanelChartAverageElement();
56+
SamplingStatCalculator statCalc = new SamplingStatCalculator();
3957
private long respTimeExceededStart = 0;
4058
private long errRateExceededStart = 0;
4159
private long respLatencyExceededStart = 0;
60+
private long percentileRespTimeExceededStart = 0;
61+
private long customValidationExceededStart = 0;
4262
private int stopTries = 0;
4363
//optimization: not convert String to number for each sample
4464
private int testValueRespTime = 0;
@@ -47,6 +67,15 @@ public class AutoStop
4767
private int testValueRespLatencySec = 0;
4868
private float testValueError = 0;
4969
private int testValueErrorSec = 0;
70+
private int testValuePercentileRespTime = 0;
71+
private int testValuePercentileRespTimeSec = 0;
72+
private float testPercentileValue = 0;
73+
private int percentileResponseTime = 0;
74+
private String testExpectedValue = "true";
75+
private String testActualValue = "false";
76+
private int testValueCustomSec = 180;
77+
private boolean skipIter = false;
78+
5079

5180
public AutoStop() {
5281
super();
@@ -74,7 +103,7 @@ public void sampleOccurred(SampleEvent se) {
74103
if (testValueRespLatency > 0) {
75104
//log.debug("Avg resp time: "+avgRespTime.getValue());
76105
if (avgRespLatency.getValue() > testValueRespLatency) {
77-
//log.debug((sec - respTimeExceededStart)+" "+getResponseTimeSecsAsInt());
106+
//log.debug((sec - respTimeExceededStart)+" "+getResponseLatencySecsAsInt());
78107
if (sec - respLatencyExceededStart >= testValueRespLatencySec) {
79108
log.info("Average Latency Time is more than " + getResponseLatency() + " for " + getResponseLatencySecs() + "s. Auto-shutdown test...");
80109
System.out.println("AutoStop - Average Latency Time is more than " + getResponseLatency() + " for " + getResponseLatencySecs() + "s. Auto-shutdown test...");
@@ -99,10 +128,27 @@ public void sampleOccurred(SampleEvent se) {
99128
}
100129
}
101130

131+
if(testValuePercentileRespTime > 0) {
132+
SampleResult sr = se.getResult();
133+
statCalc.addSample(sr);
134+
// log.debug(testPercentileValue+"Percentile Response >"+testValuePercentileRespTime+"until"+testValuePercentileRespTimeSec+"currentValue"+percentileResponseTime);
135+
// log.debug(testActualValue+">>"+testExpectedValue+">>"+skipIter+">>"+testValueCustomSec);
136+
if(percentileResponseTime > testValuePercentileRespTime) {
137+
//log.debug((sec - percentileRespTimeExceededStart)+" "+getPercentileResponseTimeSecsAsInt());
138+
if (sec - percentileRespTimeExceededStart >= testValuePercentileRespTimeSec) {
139+
log.info(testPercentileValue+"Percentile Response more than " + getPercentileResponseTime() + " for " + getPercentileResponseTimeSecs() + "s. Auto-shutdown test...");
140+
stopTest();
141+
}
142+
} else {
143+
percentileRespTimeExceededStart = sec;
144+
}
145+
}
146+
102147
curSec = sec;
103148
avgRespTime = new GraphPanelChartAverageElement();
104149
avgRespLatency = new GraphPanelChartAverageElement();
105150
errorRate = new GraphPanelChartAverageElement();
151+
percentileResponseTime = statCalc.getPercentPoint(testPercentileValue).intValue();
106152
}
107153

108154
avgRespTime.add(se.getResult().getTime());
@@ -130,6 +176,8 @@ public void testStarted() {
130176
errRateExceededStart = 0;
131177
respTimeExceededStart = 0;
132178
respLatencyExceededStart = 0;
179+
percentileRespTimeExceededStart = 0;
180+
customValidationExceededStart = 0;
133181

134182
//init test values
135183
testValueError = getErrorRateAsFloat();
@@ -138,6 +186,11 @@ public void testStarted() {
138186
testValueRespLatencySec = getResponseLatencySecsAsInt();
139187
testValueRespTime = getResponseTimeAsInt();
140188
testValueRespTimeSec = getResponseTimeSecsAsInt();
189+
testValuePercentileRespTime = getPercentileResponseTimeAsInt();
190+
testValuePercentileRespTimeSec = getPercentileResponseTimeSecsAsInt();
191+
testPercentileValue = getPercentileValueAsFloat();
192+
testValueCustomSec = getCustomValidationDurationAsInt();
193+
141194
}
142195

143196
@Override
@@ -153,6 +206,14 @@ public void testEnded() {
153206
public void testEnded(String string) {
154207
}
155208

209+
void setPercentileResponseTime(String text) { setProperty(PERCENTILE_RESPONSE_TIME, text); }
210+
211+
void setPercentileResponseTimeSecs(String text) { setProperty(PERCENTILE_RESPONSE_TIME_SECS, text); }
212+
213+
void setPercentileValue(String text) { setProperty(PERCENTILE_VALUE, text); }
214+
215+
void setCustomValidationDuration(String text) { setProperty(CUSTOM_VALIDATION_DURATION, text); }
216+
156217
void setResponseTime(String text) {
157218
setProperty(RESPONSE_TIME, text);
158219
}
@@ -177,6 +238,14 @@ void setErrorRateSecs(String text) {
177238
setProperty(ERROR_RATE_SECS, text);
178239
}
179240

241+
String getPercentileResponseTime() { return getPropertyAsString(PERCENTILE_RESPONSE_TIME); }
242+
243+
String getPercentileResponseTimeSecs() { return getPropertyAsString(PERCENTILE_RESPONSE_TIME_SECS); }
244+
245+
String getPercentileValue() { return getPropertyAsString(PERCENTILE_VALUE); }
246+
247+
String getCustomValidationDuration() { return getPropertyAsString(CUSTOM_VALIDATION_DURATION); }
248+
180249
String getResponseTime() {
181250
return getPropertyAsString(RESPONSE_TIME);
182251
}
@@ -201,6 +270,50 @@ String getErrorRateSecs() {
201270
return getPropertyAsString(ERROR_RATE_SECS);
202271
}
203272

273+
private int getPercentileResponseTimeAsInt() {
274+
int res = 0;
275+
try {
276+
res = Integer.parseInt(getPercentileResponseTime());
277+
} catch (NumberFormatException e) {
278+
log.error("Wrong response time: " + getPercentileResponseTime(), e);
279+
setPercentileResponseTime("0");
280+
}
281+
return res;
282+
}
283+
284+
private int getPercentileResponseTimeSecsAsInt() {
285+
int res = 0;
286+
try {
287+
res = Integer.parseInt(getPercentileResponseTimeSecs());
288+
} catch (NumberFormatException e) {
289+
log.error("Wrong response time period: " + getPercentileResponseTimeSecs(), e);
290+
setPercentileResponseTimeSecs("1");
291+
}
292+
return res > 0 ? res : 1;
293+
}
294+
295+
private int getCustomValidationDurationAsInt() {
296+
int res = 0;
297+
try {
298+
res = Integer.parseInt(getCustomValidationDuration());
299+
} catch (NumberFormatException e) {
300+
log.error("Wrong time period: " + getCustomValidationDuration(), e);
301+
setCustomValidationDuration("1");
302+
}
303+
return res > 0 ? res : 1;
304+
}
305+
306+
private float getPercentileValueAsFloat() {
307+
float res = 0;
308+
try {
309+
res = Float.parseFloat(getPercentileValue()) / 100;
310+
} catch (NumberFormatException e) {
311+
log.error("Wrong Percentile Value: " + getPercentileValue(), e);
312+
setPercentileValue("1");
313+
}
314+
return res > 0 ? res : 1;
315+
}
316+
204317
private int getResponseTimeAsInt() {
205318
int res = 0;
206319
try {

plugins/autostop/src/main/java/kg/apc/jmeter/reporters/JAutoStopPanel.form

Lines changed: 153 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<AuxValue name="FormSettings_listenerGenerationStyle" type="java.lang.Integer" value="0"/>
1919
<AuxValue name="FormSettings_variablesLocal" type="java.lang.Boolean" value="false"/>
2020
<AuxValue name="FormSettings_variablesModifier" type="java.lang.Integer" value="2"/>
21-
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,0,-14,0,0,2,-75"/>
21+
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,38,0,0,2,-68"/>
2222
</AuxValues>
2323

2424
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
@@ -193,7 +193,7 @@
193193
<Container class="javax.swing.JPanel" name="jPanel3">
194194
<Constraints>
195195
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
196-
<GridBagConstraints gridX="0" gridY="6" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
196+
<GridBagConstraints gridX="0" gridY="10" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
197197
</Constraint>
198198
</Constraints>
199199

@@ -225,5 +225,156 @@
225225
</Constraint>
226226
</Constraints>
227227
</Component>
228+
<Component class="javax.swing.JLabel" name="jLabel13">
229+
<Properties>
230+
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
231+
<Font name="Tahoma" size="10" style="0"/>
232+
</Property>
233+
<Property name="text" type="java.lang.String" value="OR"/>
234+
</Properties>
235+
<Constraints>
236+
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
237+
<GridBagConstraints gridX="0" gridY="6" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="10" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
238+
</Constraint>
239+
</Constraints>
240+
</Component>
241+
<Component class="javax.swing.JLabel" name="jLabel20">
242+
<Properties>
243+
<Property name="font" type="java.awt.Font" editor="org.netbeans.beaninfo.editors.FontEditor">
244+
<Font name="Tahoma" size="10" style="0"/>
245+
</Property>
246+
<Property name="text" type="java.lang.String" value="OR"/>
247+
</Properties>
248+
<Constraints>
249+
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
250+
<GridBagConstraints gridX="0" gridY="8" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="10" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
251+
</Constraint>
252+
</Constraints>
253+
</Component>
254+
<Container class="javax.swing.JPanel" name="jPanel5">
255+
<Constraints>
256+
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
257+
<GridBagConstraints gridX="0" gridY="7" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
258+
</Constraint>
259+
</Constraints>
260+
261+
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
262+
<SubComponents>
263+
<Component class="javax.swing.JLabel" name="jLabelBulletPercentile">
264+
<Properties>
265+
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
266+
<Image iconType="3" name="/kg/apc/jmeter/reporters/bulletGreen.png"/>
267+
</Property>
268+
</Properties>
269+
</Component>
270+
<Component class="javax.swing.JTextField" name="jTextFieldPercentileValue">
271+
<Properties>
272+
<Property name="columns" type="int" value="2"/>
273+
<Property name="horizontalAlignment" type="int" value="4"/>
274+
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
275+
<Dimension value="[100, 20]"/>
276+
</Property>
277+
</Properties>
278+
</Component>
279+
<Component class="javax.swing.JLabel" name="jLabel14">
280+
<Properties>
281+
<Property name="text" type="java.lang.String" value="th Percentile Response time is greater than"/>
282+
</Properties>
283+
</Component>
284+
<Component class="javax.swing.JTextField" name="jTextFieldPercentileRespTime">
285+
<Properties>
286+
<Property name="columns" type="int" value="7"/>
287+
<Property name="horizontalAlignment" type="int" value="4"/>
288+
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
289+
<Dimension value="[100, 20]"/>
290+
</Property>
291+
</Properties>
292+
</Component>
293+
<Component class="javax.swing.JLabel" name="jLabel15">
294+
<Properties>
295+
<Property name="text" type="java.lang.String" value="ms for"/>
296+
</Properties>
297+
</Component>
298+
<Component class="javax.swing.JTextField" name="jTextFieldPercentileRespTimeSec">
299+
<Properties>
300+
<Property name="columns" type="int" value="5"/>
301+
<Property name="horizontalAlignment" type="int" value="4"/>
302+
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
303+
<Dimension value="[100, 20]"/>
304+
</Property>
305+
</Properties>
306+
</Component>
307+
<Component class="javax.swing.JLabel" name="jLabel16">
308+
<Properties>
309+
<Property name="text" type="java.lang.String" value="seconds"/>
310+
</Properties>
311+
</Component>
312+
</SubComponents>
313+
</Container>
314+
<Container class="javax.swing.JPanel" name="jPanel6">
315+
<Constraints>
316+
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
317+
<GridBagConstraints gridX="0" gridY="9" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
318+
</Constraint>
319+
</Constraints>
320+
321+
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignFlowLayout"/>
322+
<SubComponents>
323+
<Component class="javax.swing.JLabel" name="jLabelBulletCustomValidation">
324+
<Properties>
325+
<Property name="icon" type="javax.swing.Icon" editor="org.netbeans.modules.form.editors2.IconEditor">
326+
<Image iconType="3" name="/kg/apc/jmeter/reporters/bulletGreen.png"/>
327+
</Property>
328+
</Properties>
329+
</Component>
330+
<Component class="javax.swing.JLabel" name="jLabel17">
331+
<Properties>
332+
<Property name="text" type="java.lang.String" value="Custom Validation ( Expected = Actual)"/>
333+
</Properties>
334+
</Component>
335+
<Component class="javax.swing.JTextField" name="jTextFieldExpectedValue">
336+
<Properties>
337+
<Property name="columns" type="int" value="5"/>
338+
<Property name="horizontalAlignment" type="int" value="4"/>
339+
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
340+
<Dimension value="[30, 20]"/>
341+
</Property>
342+
</Properties>
343+
</Component>
344+
<Component class="javax.swing.JLabel" name="jLabel18">
345+
<Properties>
346+
<Property name="text" type="java.lang.String" value="="/>
347+
</Properties>
348+
</Component>
349+
<Component class="javax.swing.JTextField" name="jTextFieldActualValue">
350+
<Properties>
351+
<Property name="columns" type="int" value="5"/>
352+
<Property name="horizontalAlignment" type="int" value="4"/>
353+
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
354+
<Dimension value="[100, 20]"/>
355+
</Property>
356+
</Properties>
357+
</Component>
358+
<Component class="javax.swing.JLabel" name="jLabel19">
359+
<Properties>
360+
<Property name="text" type="java.lang.String" value="observed for"/>
361+
</Properties>
362+
</Component>
363+
<Component class="javax.swing.JTextField" name="jTextFieldCustomDuration">
364+
<Properties>
365+
<Property name="columns" type="int" value="5"/>
366+
<Property name="horizontalAlignment" type="int" value="4"/>
367+
<Property name="maximumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
368+
<Dimension value="[100, 20]"/>
369+
</Property>
370+
</Properties>
371+
</Component>
372+
<Component class="javax.swing.JLabel" name="jLabel21">
373+
<Properties>
374+
<Property name="text" type="java.lang.String" value="seconds"/>
375+
</Properties>
376+
</Component>
377+
</SubComponents>
378+
</Container>
228379
</SubComponents>
229380
</Form>

0 commit comments

Comments
 (0)