Ok, so here's the thing.  If you have a controller that does nothing but return null, 
a loop 
controller is going to continue searching for a sub-controller with a sampler to 
return.  If you're 
controller returned a sampler, then null, then a sampler, then null, etc (like a 
normal controller 
does), then this problem doesn't show up.  It's when you have a sampler that insists 
on never 
providing a sampler, yet also insists it's got samplers to provide (ie, it's not 
"done").

So, here you are trying to make a triggered controller that could reasonably have no 
samplers 
to provide, but insists that it might at some point in the future.  It's sort of a new 
situation not 
anticipated by the current code.  You could create a NullSampler that returns a dummy 
ResponseData object to get around this, though that's a substandard solution since 
your 
listeners will get a lot of these things.  But, I'm not sure I see a better solution 
until JMeter 
learns about this new possibility.

-Mike

On 24 Jan 2004 at 16:00, Jerry Pulley wrote:

> I recently encountered some problems with the design of a controller,
> and discussed them with M. Stover in the "TriggeredController design"
> thread on jmeter-user.  Here's what Mike said about
> GenericController.next(): 
> 
> > The semantics of the "next()" method are supposed to be like so: 
> > 
> > returns Sampler - sampler is intended to be executed. 
> > 
> > returns null, isDone() = false: This should indicate the controller 
> > has finished a full round of iteration, and the test should move on to
> > the next controller.  If the test runs another iteration, the 
> > controller should be ready for everything to begin again.  This is why
> > the "nextIsNull()" method calls reinitialize(). 
> > 
> > returns null, isDone() = true; The controller has finished entirely, 
> > and should not be run again.  Indeed, it is generally dropped from the
> > test entirely.  
> 
> The current version of JMeter fails to behave in the manner described in
> the second case.  If a subclass of GenericController is an immediate
> child of a LoopController (e.g. the one in the ThreadGroup) and its
> next() method returns null without setting "done", an infinite chain of
> recursive calls results.  The attached test case demonstrates the
> problem.
> 
> It's interesting that the "loops" property of some LoopController in the
> tree needs to be set to -1 for this problem to surface.  (That's what
> ThreadGroupGui does when creating the loop controller for a thread
> group.)  What's even more interesting is that if the test tree contains
> an explicit loop controller with "loops" set to a positive value, and
> that loop controller contains the controller that returns null, then it
> still fails.  These observations might be of interest to someone who
> knows JMeter internals. In the absence of any Javadoc I can't really
> determine a firm definition of the "loops" property, so I'm leaving this
> to the experts.
> 
> jp
> 
> package net.jpulley.jmeter19.controller;
> 
> import junit.framework.Test;
> import junit.framework.TestCase;
> import junit.framework.TestSuite;
> import org.apache.jmeter.control.GenericController;
> import org.apache.jmeter.control.LoopController;
> import org.apache.jmeter.samplers.Sampler;
> import org.apache.jmeter.threads.ThreadGroup;
> import org.apache.log.Hierarchy;
> import org.apache.log.Priority;
> 
> public class LoopControllerTest2 extends TestCase {
>     public LoopControllerTest2(String name) {
>         super(name);
>     }
>     
>     public static Test suite() {
>         return new TestSuite(LoopControllerTest2.class);
>     }
>     
>     public static void main(String[] args) {
>         junit.textui.TestRunner.run(suite());
>     }
>     
>     protected void setUp() {
>         Hierarchy.getDefaultHierarchy()
>                 .setDefaultPriority(Priority.NONE);
>     }
>     
>     public void testInThreadGroup() throws Exception {
>         //set up a ThreadGroup like ThreadGroupGui does
>         ThreadGroup threadGroup = new ThreadGroup();
>         LoopController threadGroupLoopCtlr = new LoopController();
>         threadGroupLoopCtlr.setLoops(-1);
>         threadGroup.setSamplerController(threadGroupLoopCtlr);
> 
>         NullController nullCtlr = new NullController(false, 0);
>         threadGroup.addTestElement(nullCtlr);
>         
>         //test
>         try {
>             Sampler smplr = threadGroup.next();
>         } catch (java.lang.StackOverflowError err) {
>             fail("Stack overflow");
>         }
>     }
>     
>     public void testAsSubcontroller() throws Exception {
>         //set up a ThreadGroup like ThreadGroupGui does
>         ThreadGroup threadGroup = new ThreadGroup();
>         LoopController threadGroupLoopCtlr = new LoopController();
>         threadGroupLoopCtlr.setLoops(-1);
>         threadGroup.setSamplerController(threadGroupLoopCtlr);
>         
>         //add a loop controller to the thread group
>         LoopController loopCtlr = new LoopController();
>         loopCtlr.setLoops(10);
>         threadGroup.addTestElement(loopCtlr);
>         
>         //add a test controller to the loop controller
>         NullController nullCtlr = new NullController(false, 0);
>         loopCtlr.addTestElement(nullCtlr);
>         
>         //test
>         try {
>             Sampler smplr = threadGroup.next();
>         } catch (java.lang.StackOverflowError err) {
>             fail("Stack overflow");
>         }
>     }
>     
>     public void testStandaloneFinite() throws Exception {
>         LoopController loopCtlr = new LoopController();
>         loopCtlr.setLoops(10);
> 
>         NullController nullCtlr = new NullController(false, 0);
>         loopCtlr.addTestElement(nullCtlr);
>         
>         //test
>         try {
>             Sampler smplr = loopCtlr.next();
>         } catch (java.lang.StackOverflowError err) {
>             fail("Stack overflow");
>         }
>     }
>     
>     public void testStandaloneInfinite() throws Exception {
>         LoopController loopCtlr = new LoopController();
>         loopCtlr.setLoops(-1);
> 
>         NullController nullCtlr = new NullController(false, 0);
>         loopCtlr.addTestElement(nullCtlr);
>         
>         //test
>         try {
>             Sampler smplr = loopCtlr.next();
>         } catch (java.lang.StackOverflowError err) {
>             fail("Stack overflow");
>         }
>     }
>     
>     //A simple controller that's never done and always
>     //returns null.  Create it with (true, n) to get a
>     //stack dump at the nth call.
>     public static class NullController extends GenericController {
>         private int callCount;
>         private boolean dumpStack;
>         private int whichIter;
>         
>         public NullController(boolean dumpStack, int whichIter) {
>             super();
>             this.dumpStack = dumpStack;
>             this.whichIter = whichIter;
>         }
>         
>         public NullController() {
>             this(true, 5);
>         }
>         
>         public Sampler next() {
>             if (dumpStack && ++callCount == whichIter) {
>                 Thread.dumpStack();
>             }
>             return null;
>         }
>     }
> }
> 
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
> 




--
Michael Stover
[EMAIL PROTECTED]
Yahoo IM: mstover_ya
ICQ: 152975688
AIM: mstover777

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to