apache / jmeter

Apache JMeter open-source load testing tool for analyzing and measuring the performance of a variety of services
https://jmeter.apache.org/
Apache License 2.0
8.3k stars 2.09k forks source link

While-contoller's seems to check the condition at the end, rather than beginning of the loop #2923

Closed asfimport closed 12 years ago

asfimport commented 12 years ago

Mikhail T. (Bug 53856): As illustrated by the attached sample, the While-controller may enter the loop "one last time" even when the specified condition is false.

In my example, the loop goes through a CSV-file with three lines invoking a Debug Sampler. However, the Debug Sampler is shown in the results tree not three times, but four -- in the last, fourth, invocation all variables are set "<EOF>".

The work-around is to put an If-controller inside the loop and hang everything off of it. This should not be necessary.

Created attachment while-eof-bug-sample.jmx: Illustrating sample

while-eof-bug-sample.jmx ````xml false false continue false 1 1 1 1347395230000 1347395230000 false ${__jexl("${greek}" != "<EOF>")} , sample.csv false false All threads false greek,english true true true false saveConfig true true true true true true true false true true false false true false false false false false 0 true ````

Severity: normal OS: All

asfimport commented 12 years ago

Mikhail T. (migrated from Bugzilla): Created attachment sample.csv: Sample CSV-file refered to by the sample test-plan

sample.csv ```` alpha,A beta,B gamma,G ````
asfimport commented 12 years ago

Sebb (migrated from Bugzilla): The CSV dataset entry is only updated within the While Loop, so of course the debug sampler will show <EOF> before the loop exits.

asfimport commented 12 years ago

Mikhail T. (migrated from Bugzilla): I am sorry, but the current behavior makes no sense. What possible use-case is there for iterating through a CSV-file, that has N rows, N+1 times?

All this does is necessitates the use of an If-controller with the same condition repeated -- so as to skip the last iteration.

I did some research before filing this bug-report. At least one other user -- a lot more seasoned with JMeter than myself -- sees no other way to use While-controller with the CSV Dataset. And that's a shame...

asfimport commented 12 years ago

Sebb (migrated from Bugzilla): It's impossible to fix this, as the condition can only be checked after the CSV file entry has been read, and the CSV entry is only read if the loop is entered.

Note that CSV DataSet has an option to stop the thread on reaching EOF.

asfimport commented 12 years ago

Mikhail T. (migrated from Bugzilla): (In reply to comment 4)

It's impossible to fix this, as the condition can only be checked after the CSV file entry has been read, and the CSV entry is only read if the loop is entered.

What, then, happens the first time, the condition is evaluated? Before the CSV file is read at all?

Note that CSV DataSet has an option to stop the thread on reaching EOF.

Yes, but this is of no help, if one wants to nest While-controllers -- and does not wish an inner one to end the entire thread.

asfimport commented 12 years ago

Mikhail T. (migrated from Bugzilla): Ok, some deeper debugging -- after enhancing the log.debug messages inside WhileController.java a little -- reveal, that the controller's condition is checked twice per CSV-file row. The endOfLoop() method is invoked twice: first with the loopEnd-argument set to false, and then -- to true.

At the end, when the CSV Dataset sets all variables to "<EOF>", the function is called one more time -- with loopEnd set to false. For brevity, I removed the 3rd row from the sample.csv:

2012/09/11 23:38:31 INFO - jmeter.threads.JMeterThread: Thread started: Thread Group 1-1 2012/09/11 23:38:31 DEBUG - org.apache.commons.jexl.ScriptFactory: Parsing script: "${greek}" != "<EOF>"; 2012/09/11 23:38:31 DEBUG - jmeter.control.WhileController: Condition string at loop-end true. (Called from next) 2012/09/11 23:38:31 DEBUG - jmeter.control.WhileController: Condition value: false 2012/09/11 23:38:31 INFO - jmeter.services.FileServer: Stored: sample.csv 2012/09/11 23:38:31 DEBUG - org.apache.commons.jexl.ScriptFactory: Parsing script: "alpha" != "<EOF>"; 2012/09/11 23:38:31 DEBUG - jmeter.control.WhileController: Condition string at loop-beginning true. (Called from nextIsNull) 2012/09/11 23:38:31 DEBUG - jmeter.control.WhileController: Condition value: false 2012/09/11 23:38:31 DEBUG - org.apache.commons.jexl.ScriptFactory: Parsing script: "alpha" != "<EOF>"; 2012/09/11 23:38:31 DEBUG - jmeter.control.WhileController: Condition string at loop-end true. (Called from next) 2012/09/11 23:38:31 DEBUG - jmeter.control.WhileController: Condition value: false 2012/09/11 23:38:31 DEBUG - org.apache.commons.jexl.ScriptFactory: Parsing script: "beta" != "<EOF>"; 2012/09/11 23:38:31 DEBUG - jmeter.control.WhileController: Condition string at loop-beginning true. (Called from nextIsNull) 2012/09/11 23:38:31 DEBUG - jmeter.control.WhileController: Condition value: false 2012/09/11 23:38:31 DEBUG - org.apache.commons.jexl.ScriptFactory: Parsing script: "beta" != "<EOF>"; 2012/09/11 23:38:31 DEBUG - jmeter.control.WhileController: Condition string at loop-end true. (Called from next) 2012/09/11 23:38:31 DEBUG - jmeter.control.WhileController: Condition value: false 2012/09/11 23:38:31 DEBUG - org.apache.commons.jexl.ScriptFactory: Parsing script: "<EOF>" != "<EOF>"; 2012/09/11 23:38:31 DEBUG - jmeter.control.WhileController: Condition string at loop-beginning false. (Called from nextIsNull) 2012/09/11 23:38:31 DEBUG - jmeter.control.WhileController: Condition value: true 2012/09/11 23:38:31 INFO - jmeter.threads.JMeterThread: Thread finished: Thread Group 1-1

The above output tells me: a. This bug report is not at all "INVALID" b. It is possible to fix the problem...

Created attachment WhileController-enhanced-logging.patch: Enhance the logging output of WhiteController's endOfLoop() method (not for production use)

WhileController-enhanced-logging.patch ````diff Index: src/core/org/apache/jmeter/control/WhileController.java =================================================================== --- src/core/org/apache/jmeter/control/WhileController.java (revision 1383743) +++ src/core/org/apache/jmeter/control/WhileController.java (working copy) @@ -54,7 +54,7 @@ */ private boolean endOfLoop(boolean loopEnd) { String cnd = getCondition().trim(); - log.debug("Condition string:" + cnd+"."); + log.debug("Condition string at loop-" + (loopEnd ? "beginning " : "end ") + cnd+". (Called from " + (new Exception("Debug")).getStackTrace()[1].getMethodName() + ")"); boolean res; // If blank, only check previous sample when at end of loop if ((loopEnd && cnd.length() == 0) || "LAST".equalsIgnoreCase(cnd)) {// $NON-NLS-1$ ````