Search code examples
jmeterload-testing

JMeter While Controller upon exit does not run Flow Control Action


I have a while controller in jmeter test plan within a thread group. I want to run Flow Control action when while loop is exited. But despite trying several different configs, Flow Control Action never runs. In one thread group Flow Control is used to repeatedly call API after every 10 minutes, in another thread group it is used to exit the jmeter test.

Flow Control Action is just below the while controller i.e. it is immediate sibling of while controller.

How to solve this problem?


Solution

    1. Add a While Controller configured like:

      enter image description here

    2. Put the CSV Data Set Config inside the While Controller and set it up like:

      enter image description here

    3. Add the If Controller after the CSV Data Set Config and use the same condition as in the While Controller

      ${__jexl3("${variableFromCSV}" != "<EOF>",)}
      

      enter image description here

    4. Put your Sampler(s) under the If Controller

    5. Add Flow Control Action sampler after the While Controller and configure it like:

      enter image description here

    6. That's it, when your CSV file ends the test will be stopped:

      enter image description here

    CSV file used in the exercise looks like:

    line1
    line2
    line3
    

    And the whole test plan:

    <?xml version="1.0" encoding="UTF-8"?>
    <jmeterTestPlan version="1.2" properties="5.0" jmeter="5.5">
      <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>
          <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>
              <intProp name="LoopController.loops">-1</intProp>
            </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>
            <boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
          </ThreadGroup>
          <hashTree>
            <DebugSampler guiclass="TestBeanGUI" testclass="DebugSampler" testname="Sampler from Thread Group 1" enabled="true">
              <boolProp name="displayJMeterProperties">false</boolProp>
              <boolProp name="displayJMeterVariables">true</boolProp>
              <boolProp name="displaySystemProperties">false</boolProp>
            </DebugSampler>
            <hashTree>
              <ConstantTimer guiclass="ConstantTimerGui" testclass="ConstantTimer" testname="Constant Timer" enabled="true">
                <stringProp name="ConstantTimer.delay">100</stringProp>
              </ConstantTimer>
              <hashTree/>
            </hashTree>
          </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">1</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>
            <boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
          </ThreadGroup>
          <hashTree>
            <WhileController guiclass="WhileControllerGui" testclass="WhileController" testname="While Controller" enabled="true">
              <stringProp name="WhileController.condition">${__jexl3(&quot;${variableFromCSV}&quot; != &quot;&lt;EOF&gt;&quot;,)}</stringProp>
            </WhileController>
            <hashTree>
              <CSVDataSet guiclass="TestBeanGUI" testclass="CSVDataSet" testname="CSV Data Set Config" enabled="true">
                <stringProp name="delimiter">,</stringProp>
                <stringProp name="fileEncoding"></stringProp>
                <stringProp name="filename">test.csv</stringProp>
                <boolProp name="ignoreFirstLine">false</boolProp>
                <boolProp name="quotedData">false</boolProp>
                <boolProp name="recycle">false</boolProp>
                <stringProp name="shareMode">shareMode.all</stringProp>
                <boolProp name="stopThread">false</boolProp>
                <stringProp name="variableNames">variableFromCSV</stringProp>
              </CSVDataSet>
              <hashTree/>
              <IfController guiclass="IfControllerPanel" testclass="IfController" testname="If Controller" enabled="true">
                <stringProp name="IfController.condition">${__jexl3(&quot;${variableFromCSV}&quot; != &quot;&lt;EOF&gt;&quot;,)}</stringProp>
                <boolProp name="IfController.evaluateAll">false</boolProp>
                <boolProp name="IfController.useExpression">true</boolProp>
              </IfController>
              <hashTree>
                <DebugSampler guiclass="TestBeanGUI" testclass="DebugSampler" testname="Sampler From Thread Group 2 - ${variableFromCSV}" enabled="true">
                  <boolProp name="displayJMeterProperties">false</boolProp>
                  <boolProp name="displayJMeterVariables">true</boolProp>
                  <boolProp name="displaySystemProperties">false</boolProp>
                </DebugSampler>
                <hashTree>
                  <ConstantTimer guiclass="ConstantTimerGui" testclass="ConstantTimer" testname="Constant Timer" enabled="true">
                    <stringProp name="ConstantTimer.delay">500</stringProp>
                  </ConstantTimer>
                  <hashTree/>
                </hashTree>
              </hashTree>
            </hashTree>
            <DebugSampler guiclass="TestBeanGUI" testclass="DebugSampler" testname="Reached the end of the CSV file, ending the test" enabled="true">
              <boolProp name="displayJMeterProperties">false</boolProp>
              <boolProp name="displayJMeterVariables">true</boolProp>
              <boolProp name="displaySystemProperties">false</boolProp>
            </DebugSampler>
            <hashTree/>
            <TestAction guiclass="TestActionGui" testclass="TestAction" testname="Flow Control Action" enabled="true">
              <intProp name="ActionProcessor.action">0</intProp>
              <intProp name="ActionProcessor.target">2</intProp>
              <stringProp name="ActionProcessor.duration">0</stringProp>
            </TestAction>
            <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>true</message>
                <threadName>true</threadName>
                <dataType>true</dataType>
                <encoding>false</encoding>
                <assertions>true</assertions>
                <subresults>true</subresults>
                <responseData>false</responseData>
                <samplerData>false</samplerData>
                <xml>false</xml>
                <fieldNames>true</fieldNames>
                <responseHeaders>false</responseHeaders>
                <requestHeaders>false</requestHeaders>
                <responseDataOnError>false</responseDataOnError>
                <saveAssertionResultsFailureMessage>true</saveAssertionResultsFailureMessage>
                <assertionsResultsToSave>0</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>