You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jmeter.apache.org by pm...@apache.org on 2020/07/06 11:20:11 UTC

[jmeter] 01/01: Bug 64581 - Allow SampleResult#setIgnore to influence behaviour on Sampler Error

This is an automated email from the ASF dual-hosted git repository.

pmouawad pushed a commit to branch fix_64581
in repository https://gitbox.apache.org/repos/asf/jmeter.git

commit 65b75c0e7471a62c388c4212e3a3a731efb877fe
Author: pmouawad <p....@ubik-ingenierie.com>
AuthorDate: Mon Jul 6 13:19:27 2020 +0200

    Bug 64581 - Allow SampleResult#setIgnore to influence behaviour on
    Sampler Error
    
    Fix also misnamed lastSampleInError to lastSampleOk
    When SampleResult#isIgnore() is true, use is for impacting algorithmic
    execution, it will be taken into account to:
    
    - Decide what to do on Error ("Action to be taken after a Sampler error"
    in Thread Group)
    - set JMeterThread.last_sample_ok
---
 .../org/apache/jmeter/threads/JMeterThread.java    | 60 +++++++++++++---------
 xdocs/changes.xml                                  |  1 +
 xdocs/usermanual/component_reference.xml           |  7 +++
 3 files changed, 43 insertions(+), 25 deletions(-)

diff --git a/src/core/src/main/java/org/apache/jmeter/threads/JMeterThread.java b/src/core/src/main/java/org/apache/jmeter/threads/JMeterThread.java
index af8e8bf..0276b5e 100644
--- a/src/core/src/main/java/org/apache/jmeter/threads/JMeterThread.java
+++ b/src/core/src/main/java/org/apache/jmeter/threads/JMeterThread.java
@@ -256,17 +256,17 @@ public class JMeterThread implements Runnable, Interruptible {
                     processSampler(sam, null, threadContext);
                     threadContext.cleanAfterSample();
 
-                    boolean lastSampleInError = TRUE.equals(threadContext.getVariables().get(LAST_SAMPLE_OK));
+                    boolean lastSampleOk = TRUE.equals(threadContext.getVariables().get(LAST_SAMPLE_OK));
                     // restart of the next loop
                     // - was requested through threadContext
                     // - or the last sample failed AND the onErrorStartNextLoop option is enabled
                     if (threadContext.getTestLogicalAction() != TestLogicalAction.CONTINUE
-                            || (onErrorStartNextLoop && !lastSampleInError)) {
+                            || (onErrorStartNextLoop && !lastSampleOk)) {
                         if (log.isDebugEnabled() && onErrorStartNextLoop
                                 && threadContext.getTestLogicalAction() != TestLogicalAction.CONTINUE) {
                             log.debug("Start Next Thread Loop option is on, Last sample failed, starting next thread loop");
                         }
-                        if(onErrorStartNextLoop && !lastSampleInError){
+                        if(onErrorStartNextLoop && !lastSampleOk){
                             triggerLoopLogicalActionOnParentControllers(sam, threadContext, JMeterThread::continueOnThreadLoop);
                         } else {
                             switch (threadContext.getTestLogicalAction()) {
@@ -285,7 +285,7 @@ public class JMeterThread implements Runnable, Interruptible {
                         }
                         threadContext.setTestLogicalAction(TestLogicalAction.CONTINUE);
                         sam = null;
-                        threadContext.getVariables().put(LAST_SAMPLE_OK, TRUE);
+                        setLastSampleOk(threadContext.getVariables(), true);
                     }
                     else {
                         sam = threadGroupLoopController.next();
@@ -558,30 +558,33 @@ public class JMeterThread implements Runnable, Interruptible {
             result = doSampling(threadContext, sampler);
         }
         // If we got any results, then perform processing on the result
-        if (result != null && !result.isIgnore()) {
-            int nbActiveThreadsInThreadGroup = threadGroup.getNumberOfThreads();
-            int nbTotalActiveThreads = JMeterContextService.getNumberOfThreads();
-            fillThreadInformation(result, nbActiveThreadsInThreadGroup, nbTotalActiveThreads);
-            SampleResult[] subResults = result.getSubResults();
-            if (subResults != null) {
-                for (SampleResult subResult : subResults) {
-                    fillThreadInformation(subResult, nbActiveThreadsInThreadGroup, nbTotalActiveThreads);
-                }
-            }
-            threadContext.setPreviousResult(result);
-            runPostProcessors(pack.getPostProcessors());
-            checkAssertions(pack.getAssertions(), result, threadContext);
+        if (result != null) {
             if (!result.isIgnore()) {
+                int nbActiveThreadsInThreadGroup = threadGroup.getNumberOfThreads();
+                int nbTotalActiveThreads = JMeterContextService.getNumberOfThreads();
+                fillThreadInformation(result, nbActiveThreadsInThreadGroup, nbTotalActiveThreads);
+                SampleResult[] subResults = result.getSubResults();
+                if (subResults != null) {
+                    for (SampleResult subResult : subResults) {
+                        fillThreadInformation(subResult, nbActiveThreadsInThreadGroup, nbTotalActiveThreads);
+                    }
+                }
+                threadContext.setPreviousResult(result);
+                runPostProcessors(pack.getPostProcessors());
+                checkAssertions(pack.getAssertions(), result, threadContext);
                 // Do not send subsamples to listeners which receive the transaction sample
                 List<SampleListener> sampleListeners = getSampleListeners(pack, transactionPack, transactionSampler);
                 notifyListeners(sampleListeners, result);
+                compiler.done(pack);
+                // Add the result as subsample of transaction if we are in a transaction
+                if (transactionSampler != null && !result.isIgnore()) {
+                    transactionSampler.addSubSamplerResult(result);
+                }
+            } else {
+                // This call is done by checkAssertions() , as we don't call it
+                // for isIgnore, we explictely call it here
+                setLastSampleOk(threadContext.getVariables(), result.isSuccessful());
             }
-            compiler.done(pack);
-            // Add the result as subsample of transaction if we are in a transaction
-            if (transactionSampler != null && !result.isIgnore()) {
-                transactionSampler.addSubSamplerResult(result);
-            }
-
             // Check if thread or test should be stopped
             if (result.isStopThread() || (!result.isSuccessful() && onErrorStopThread)) {
                 stopThread();
@@ -690,6 +693,13 @@ public class JMeterThread implements Runnable, Interruptible {
     }
 
     /**
+     * Store {@link JMeterThread#LAST_SAMPLE_OK} in JMeter Variables context
+     */
+    private void setLastSampleOk(JMeterVariables variables, boolean value) {
+        variables.put(LAST_SAMPLE_OK, Boolean.toString(value));
+    }
+
+    /**
      * @param threadContext
      * @return the iteration listener
      */
@@ -697,7 +707,7 @@ public class JMeterThread implements Runnable, Interruptible {
         threadVars.putObject(JMeterVariables.VAR_IS_SAME_USER_KEY, isSameUserOnNextIteration);
         threadContext.setVariables(threadVars);
         threadContext.setThreadNum(getThreadNum());
-        threadContext.getVariables().put(LAST_SAMPLE_OK, TRUE);
+        setLastSampleOk(threadVars, true);
         threadContext.setThread(this);
         threadContext.setThreadGroup(threadGroup);
         threadContext.setEngine(engine);
@@ -885,7 +895,7 @@ public class JMeterThread implements Runnable, Interruptible {
                 processAssertion(parent, assertion);
             }
         }
-        threadContext.getVariables().put(LAST_SAMPLE_OK, Boolean.toString(parent.isSuccessful()));
+        setLastSampleOk(threadContext.getVariables(), parent.isSuccessful());
     }
 
     private void recurseAssertionChecks(SampleResult parent, Assertion assertion, int level) {
diff --git a/xdocs/changes.xml b/xdocs/changes.xml
index a7a1a81..5d0ffae 100644
--- a/xdocs/changes.xml
+++ b/xdocs/changes.xml
@@ -112,6 +112,7 @@ Summary
 <ul>
   <li><bug>64446</bug>Better parse curl commands with backslash at line endings and support <code>PUT</code> method with data arguments</li>
   <li><pr>599</pr>Ensure all buttons added to the toolbar behave/look consistently. Contributed by Jannis Weis</li>
+  <li><bug>64581</bug>Allow SampleResult#setIgnore to influence behaviour on Sampler Error</li>
 </ul>
 
 <ch_section>Non-functional changes</ch_section>
diff --git a/xdocs/usermanual/component_reference.xml b/xdocs/usermanual/component_reference.xml
index 4b54cdd..7a60c75 100644
--- a/xdocs/usermanual/component_reference.xml
+++ b/xdocs/usermanual/component_reference.xml
@@ -1119,6 +1119,13 @@ The JSR223 Sampler allows JSR223 script code to be used to perform a sample or s
 <note>
 If you don't want to generate a <apilink href="org/apache/jmeter/samplers/SampleResult.html">SampleResult</apilink> when this sampler is run, call the following method:
 <source>SampleResult.setIgnore();</source>
+This call will have the following impact:
+<ul>
+    <li>SampleResult will not be delivered to SampleListeners like View Results Tree, Summariser ...</li>
+    <li>SampleResult will not be evaluated in Assertions nor PostProcessors</li>
+    <li>SampleResult will be evaluated to computing last sample status (${JMeterThread.last_sample_ok}),
+    and ThreadGroup "Action to be taken after a Sampler error" (since JMeter 5.4)</li>
+</ul>
 </note>
 </p>
 <p>