55import com .blazemeter .jmeter .threads .arrivals .ArrivalsThreadGroup ;
66import com .blazemeter .jmeter .threads .concurrency .ConcurrencyThreadGroup ;
77import org .apache .jmeter .control .GenericController ;
8+ import org .apache .jmeter .control .IteratingController ;
89import org .apache .jmeter .control .NextIsNullException ;
10+ import org .apache .jmeter .engine .event .LoopIterationEvent ;
911import org .apache .jmeter .samplers .Sampler ;
1012import org .apache .jmeter .threads .JMeterContextService ;
1113import org .apache .jmeter .threads .JMeterThread ;
1214import org .slf4j .LoggerFactory ;
1315import org .slf4j .Logger ;
1416
15- public class VirtualUserController extends GenericController {
17+ public class VirtualUserController extends GenericController implements IteratingController {
1618 private static final Logger log = LoggerFactory .getLogger (VirtualUserController .class );
1719 private boolean hasArrived = false ;
1820 protected AbstractDynamicThreadGroup owner ;
19-
21+ private boolean breakLoop ;
2022 private long iterationNo = 0 ;
2123
2224 @ Override
2325 public Sampler next () {
24- if (owner .isLimitReached ()) {
25- setDone (true );
26- } else if (!hasArrived ) {
27- if (owner .isLimitReached ()) {
28- throw new IllegalStateException ("Should not have more iterations" );
29- }
30- hasArrived = true ;
31- iterationNo ++;
32- if (owner instanceof ArrivalsThreadGroup ) {
33- getOwnerAsArrivals ().arrivalFact (JMeterContextService .getContext ().getThread (), iterationNo );
34- if (!owner .isRunning ()) {
35- setDone (true );
36- return null ;
26+ updateIterationIndex (owner .getName (), (int ) iterationNo );
27+ try {
28+ if (breakLoop || owner .isLimitReached ()) {
29+ setDone (true );
30+ } else if (!hasArrived ) {
31+ if (owner .isLimitReached ()) {
32+ throw new IllegalStateException ("Should not have more iterations" );
33+ }
34+ hasArrived = true ;
35+ incrementLoopCount ();
36+ updateIterationIndex (owner .getName (), (int ) iterationNo );
37+ if (owner instanceof ArrivalsThreadGroup ) {
38+ getOwnerAsArrivals ().arrivalFact (JMeterContextService .getContext ().getThread (), iterationNo );
39+ if (!owner .isRunning ()) {
40+ setDone (true );
41+ return null ;
42+ }
3743 }
3844 }
45+ return super .next ();
46+ } finally {
47+ updateIterationIndex (owner .getName (), (int ) iterationNo );
3948 }
40-
41- return super .next ();
4249 }
4350
4451 private boolean moveToPool (JMeterThread thread ) {
@@ -57,6 +64,12 @@ protected void reInitialize() {
5764 hasArrived = false ;
5865 }
5966
67+ @ Override
68+ protected void setDone (boolean done ) {
69+ resetBreakLoop ();
70+ super .setDone (done );
71+ }
72+
6073 @ Override
6174 protected Sampler nextIsNull () throws NextIsNullException {
6275 JMeterThread thread = JMeterContextService .getContext ().getThread ();
@@ -87,10 +100,23 @@ protected Sampler nextIsNull() throws NextIsNullException {
87100 }
88101 }
89102
103+ protected void incrementLoopCount () {
104+ iterationNo ++;
105+ }
106+
107+ protected void resetLoopCount () {
108+ iterationNo = 0 ;
109+ }
110+
90111 public void setOwner (AbstractDynamicThreadGroup owner ) {
91112 this .owner = owner ;
92113 }
93114
115+ @ Override
116+ protected int getIterCount () {
117+ return (int ) (iterationNo + 1 );
118+ }
119+
94120 public void startNextLoop () {
95121 JMeterThread thread = JMeterContextService .getContext ().getThread ();
96122 if (owner instanceof ArrivalsThreadGroup ) {
@@ -104,7 +130,37 @@ public void startNextLoop() {
104130 }
105131 }
106132
133+ @ Override
134+ public void breakLoop () {
135+ breakLoop = true ;
136+ setFirst (true );
137+ resetCurrent ();
138+ resetLoopCount ();
139+ recoverRunningVersion ();
140+ }
141+
142+ private void resetBreakLoop () {
143+ if (breakLoop ) {
144+ breakLoop = false ;
145+ }
146+ }
147+
107148 private ArrivalsThreadGroup getOwnerAsArrivals () {
108149 return (ArrivalsThreadGroup ) owner ;
109150 }
151+
152+ @ Override
153+ public void removed () {
154+ super .removed ();
155+ }
156+
157+ @ Override
158+ public void iterationStart (LoopIterationEvent loopIterationEvent ) {
159+ if (log .isDebugEnabled ()) {
160+ log .debug ("iterationStart called on {} with source {} and iteration {}" , owner .getName (),
161+ loopIterationEvent .getSource (), loopIterationEvent .getIteration ());
162+ }
163+ reInitialize ();
164+ resetLoopCount ();
165+ }
110166}
0 commit comments