Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JMeter fails to iterate over Controllers that are children of a TransactionController having "Generate parent sample" checked after an assertion error occurs on a Thread Group with "Start Next Thread Loop" #3855

Closed
asfimport opened this issue Feb 25, 2016 · 5 comments

Comments

@asfimport
Copy link
Collaborator

benoit.wiart (Bug 59067):
Test Plan is

Thread Group (1 thread, loop count=2, on error start next loop)
Transaction controller 1 (Generate parent sample = true)
Transaction controller 2 (Generate parent sample = true)
Transaction controller 3 (Generate parent sample = true)
Simple controller
Http sampler 1
Http sampler 2
Http sampler 3
Http sampler 4
Http sampler 5
Http sampler 6

If on first iteration there is an assertion error on sampler 3.
On second iteration the sampler controller starts on sampler 4 and bypass samplers 1,2 and 3.

That's bad and it makes me sad.

Severity: major
OS: SunOS

Duplicates:

@asfimport
Copy link
Collaborator Author

benoit.wiart (migrated from Bugzilla):
Reduced test case

Thread Group (1 thread, loop count=2, on error start next loop)
Transaction controller 1 (Generate parent sample = true)
Simple controller
Http sampler 1
Http sampler 2
Http sampler 3
Http sampler 4
Http sampler 5
Http sampler 6

@asfimport
Copy link
Collaborator Author

benoit.wiart (migrated from Bugzilla):
Broken patch (do not apply) as it doesn't mix well with #3410.
You can use it as a basis for the real correction.

The pb is that in JMeterThread#triggerEndOfLoopOnParentControllers the Sampler used is not always the "real" one, but it can be a TransactionSampler, if there is some Simplecontroller between this TransactionSampler and the http sampler, triggerEndOfLoop will not be called for those controllers.

the idea behind the patch is to always do the tree traversal from the real sampler.

Created attachment 59067-broken-patch.patch: BROKEN PATCH

59067-broken-patch.patch
diff --git a/src/core/org/apache/jmeter/threads/JMeterThread.java b/src/core/org/apache/jmeter/threads/JMeterThread.java
index fc2f018..b00a4f8 100644
--- a/src/core/org/apache/jmeter/threads/JMeterThread.java
+++ b/src/core/org/apache/jmeter/threads/JMeterThread.java
@@ -308,27 +308,20 @@ public class JMeterThread implements Runnable, Interruptible {
      * @param threadContext 
      */
     private void triggerEndOfLoopOnParentControllers(Sampler sam, JMeterContext threadContext) {
-        
+        // Find parent controllers of current sampler
+        FindTestElementsUpToRootTraverser pathToRootTraverser = null;
         TransactionSampler transactionSampler = null;
         if(sam instanceof TransactionSampler) {
             transactionSampler = (TransactionSampler) sam;
-        }
-
-        Sampler realSampler = findRealSampler(sam);
-        
-        // Find parent controllers of current sampler
-        FindTestElementsUpToRootTraverser pathToRootTraverser = null;
-        if(realSampler instanceof TransactionSampler) {
-            pathToRootTraverser = new FindTestElementsUpToRootTraverser(((TransactionSampler) realSampler).getTransactionController());
+            pathToRootTraverser = new FindTestElementsUpToRootTraverser(transactionSampler.getTransactionController());
         } else {
-            pathToRootTraverser = new FindTestElementsUpToRootTraverser(realSampler);
+            pathToRootTraverser = new FindTestElementsUpToRootTraverser(sam);
         }
         testTree.traverse(pathToRootTraverser);
         
         // Trigger end of loop condition on all parent controllers of current sampler
         List<Controller> controllersToReinit = pathToRootTraverser.getControllersToRoot();
         for (Controller parentController : controllersToReinit) {
-            System.out.println("Will trigger " + parentController.getName());
             if(parentController instanceof AbstractThreadGroup) {
                 AbstractThreadGroup tg = (AbstractThreadGroup) parentController;
                 tg.startNextLoop();
@@ -347,16 +340,6 @@ public class JMeterThread implements Runnable, Interruptible {
         }
     }
 
-    private Sampler findRealSampler(Sampler sam) {
-        Sampler realSampler = sam;
-
-        while(realSampler instanceof TransactionSampler) {
-            realSampler = ((TransactionSampler) realSampler).getSubSampler();
-        }
-       
-        return realSampler;
-    }
-
     /**
      * Process the current sampler, handling transaction samplers.
      *

@asfimport
Copy link
Collaborator Author

benoit.wiart (migrated from Bugzilla):
PR #141

Please review carefully as it may break the world...

@asfimport
Copy link
Collaborator Author

@pmouawad (migrated from Bugzilla):
Author: pmouawad
Date: Fri Feb 26 16:38:10 2016
New Revision: 1732514

URL: http://svn.apache.org/viewvc?rev=1732514&view=rev
Log:
#3855 - JMeter fails to iterate over Controllers that are children of a TransactionController having "Generate parent sample" checked after an assertion error occurs on a Thread Group with "Start Next Thread Loop"
#3855

Modified:
jmeter/trunk/src/core/org/apache/jmeter/control/TransactionController.java
jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
jmeter/trunk/xdocs/changes.xml

@asfimport
Copy link
Collaborator Author

@pmouawad (migrated from Bugzilla):
Created attachment BUG_59067.jmx: Test Plan showing issue

BUG_59067.jmx
From c866e4279031364f76e2f34cf3165253b1cdc9e5 Mon Sep 17 00:00:00 2001
From: benoit <b.wiart@ubik-ingenierie.com>
Date: Thu, 25 Feb 2016 16:15:09 +0100
Subject: [PATCH] Bug 59067 JMeter fail to iterate over SimpleController after
 an assertion error. The controller does not restart at the first sampler The
 pb is that in JMeterThread#triggerEndOfLoopOnParentControllers the Sampler
 used is not always the "real" one, but it can be a TransactionSampler, if
 there are some other controllers (Simplecontroller) between this
 TransactionSampler and the http sampler, triggerEndOfLoop will not be called
 for those controllers.

the idea behind the patch is to always do the tree traversal from the
real sampler.
---
 .../jmeter/control/TransactionController.java      |  1 -
 .../org/apache/jmeter/threads/JMeterThread.java    | 29 +++++++++++++++++++---
 2 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/src/core/org/apache/jmeter/control/TransactionController.java b/src/core/org/apache/jmeter/control/TransactionController.java
index 9634655..7a86211 100644
--- a/src/core/org/apache/jmeter/control/TransactionController.java
+++ b/src/core/org/apache/jmeter/control/TransactionController.java
@@ -283,7 +283,6 @@ public void triggerEndOfLoop() {
             // update them with SubSamplerResult
             if(subSampler instanceof TransactionSampler) {
                 TransactionSampler tc = (TransactionSampler) subSampler;
-                tc.getTransactionController().triggerEndOfLoop();
                 transactionSampler.addSubSamplerResult(tc.getTransactionResult());
             }
             transactionSampler.setTransactionDone();
diff --git a/src/core/org/apache/jmeter/threads/JMeterThread.java b/src/core/org/apache/jmeter/threads/JMeterThread.java
index b00a4f8..7d6e4f2 100644
--- a/src/core/org/apache/jmeter/threads/JMeterThread.java
+++ b/src/core/org/apache/jmeter/threads/JMeterThread.java
@@ -308,14 +308,25 @@ public void run() {
      * @param threadContext 
      */
     private void triggerEndOfLoopOnParentControllers(Sampler sam, JMeterContext threadContext) {
-        // Find parent controllers of current sampler
-        FindTestElementsUpToRootTraverser pathToRootTraverser = null;
+        
         TransactionSampler transactionSampler = null;
         if(sam instanceof TransactionSampler) {
             transactionSampler = (TransactionSampler) sam;
-            pathToRootTraverser = new FindTestElementsUpToRootTraverser(transactionSampler.getTransactionController());
+        }
+
+        // Bug 59067
+        // the Sampler provided is not always the "real" one, but it can be a TransactionSampler, 
+        //   if there are some other controllers (SimpleController) between this TransactionSampler and the real sampler, 
+        //   triggerEndOfLoop will not be called for those controllers.
+        // the following method will try to find the sampler that really generate an error
+        Sampler realSampler = findRealSampler(sam);
+        
+        // Find parent controllers of current sampler
+        FindTestElementsUpToRootTraverser pathToRootTraverser = null;
+        if(realSampler instanceof TransactionSampler) {
+            pathToRootTraverser = new FindTestElementsUpToRootTraverser(((TransactionSampler) realSampler).getTransactionController());
         } else {
-            pathToRootTraverser = new FindTestElementsUpToRootTraverser(sam);
+            pathToRootTraverser = new FindTestElementsUpToRootTraverser(realSampler);
         }
         testTree.traverse(pathToRootTraverser);
         
@@ -340,6 +351,16 @@ private void triggerEndOfLoopOnParentControllers(Sampler sam, JMeterContext thre
         }
     }
 
+    private Sampler findRealSampler(Sampler sam) {
+        Sampler realSampler = sam;
+
+        while(realSampler instanceof TransactionSampler) {
+            realSampler = ((TransactionSampler) realSampler).getSubSampler();
+        }
+       
+        return realSampler;
+    }
+
     /**
      * Process the current sampler, handling transaction samplers.
      *

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant