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 2018/03/31 10:32:34 UTC
svn commit: r1828095 - in /jmeter/trunk:
src/components/org/apache/jmeter/sampler/
src/components/org/apache/jmeter/sampler/gui/
src/core/org/apache/jmeter/gui/ src/core/org/apache/jmeter/reporters/
src/core/org/apache/jmeter/resources/ src/core/org/ap...
Author: pmouawad
Date: Sat Mar 31 10:32:33 2018
New Revision: 1828095
URL: http://svn.apache.org/viewvc?rev=1828095&view=rev
Log:
Bug 62238 - Add ability to Switch to next iteration of Current Loop
Contributed by Ubik Load Pack
Bugzilla Id: 62238
Modified:
jmeter/trunk/src/components/org/apache/jmeter/sampler/TestAction.java
jmeter/trunk/src/components/org/apache/jmeter/sampler/gui/TestActionGui.java
jmeter/trunk/src/core/org/apache/jmeter/gui/OnErrorPanel.java
jmeter/trunk/src/core/org/apache/jmeter/reporters/ResultAction.java
jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
jmeter/trunk/src/core/org/apache/jmeter/samplers/SampleResult.java
jmeter/trunk/src/core/org/apache/jmeter/testelement/OnErrorTestElement.java
jmeter/trunk/src/core/org/apache/jmeter/threads/AbstractThreadGroup.java
jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterContext.java
jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
jmeter/trunk/xdocs/changes.xml
Modified: jmeter/trunk/src/components/org/apache/jmeter/sampler/TestAction.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/sampler/TestAction.java?rev=1828095&r1=1828094&r2=1828095&view=diff
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/sampler/TestAction.java (original)
+++ jmeter/trunk/src/components/org/apache/jmeter/sampler/TestAction.java Sat Mar 31 10:32:33 2018
@@ -32,6 +32,7 @@ import org.apache.jmeter.testelement.Tes
import org.apache.jmeter.testelement.property.IntegerProperty;
import org.apache.jmeter.testelement.property.StringProperty;
import org.apache.jmeter.threads.JMeterContext;
+import org.apache.jmeter.threads.JMeterContext.TestLogicalAction;
import org.apache.jmeter.threads.JMeterContextService;
import org.apache.jmeter.timers.TimerService;
import org.slf4j.Logger;
@@ -45,10 +46,12 @@ import org.slf4j.LoggerFactory;
public class TestAction extends AbstractSampler implements Interruptible {
private static final Logger log = LoggerFactory.getLogger(TestAction.class);
+
+ private static final String MSG_STOP_CURRENT_THREAD = "Stopping current thread from element {}";
private static final TimerService TIMER_SERVICE = TimerService.getInstance();
- private static final long serialVersionUID = 241L;
+ private static final long serialVersionUID = 242L;
private static final Set<String> APPLIABLE_CONFIG_CLASSES = new HashSet<>(
Arrays.asList("org.apache.jmeter.config.gui.SimpleConfigGui"));
@@ -57,7 +60,18 @@ public class TestAction extends Abstract
public static final int STOP = 0;
public static final int PAUSE = 1;
public static final int STOP_NOW = 2;
+ /**
+ * Start next iteration of Thread Loop
+ */
public static final int RESTART_NEXT_LOOP = 3;
+ /**
+ * Start next iteration of Current Looop
+ */
+ public static final int START_NEXT_ITERATION_CURRENT_LOOP = 4;
+ /**
+ * Break Current Looop
+ */
+ public static final int BREAK_CURRENT_LOOP = 5;
// Action targets
public static final int THREAD = 0;
@@ -87,24 +101,40 @@ public class TestAction extends Abstract
pause(getDurationAsString());
} else if (action == STOP || action == STOP_NOW) {
if (target == THREAD) {
- log.info("Stopping current thread from element {}", getName());
+ if(log.isInfoEnabled()) {
+ log.info(MSG_STOP_CURRENT_THREAD, getName());
+ }
context.getThread().stop();
} else if (target == TEST) {
if (action == STOP_NOW) {
- log.info("Stopping current thread from element {}", getName());
+ if(log.isInfoEnabled()) {
+ log.info(MSG_STOP_CURRENT_THREAD, getName());
+ }
context.getThread().stop();
- log.info("Stopping all threads now from element {}", getName());
+ if(log.isInfoEnabled()) {
+ log.info("Stopping all threads now from element {}", getName());
+ }
context.getEngine().stopTest();
} else {
- log.info("Stopping current thread from element {}", getName());
+ if(log.isInfoEnabled()) {
+ log.info(MSG_STOP_CURRENT_THREAD, getName());
+ }
context.getThread().stop();
- log.info("Stopping all threads from element {}", getName());
+ if(log.isInfoEnabled()) {
+ log.info("Stopping all threads from element {}", getName());
+ }
context.getEngine().askThreadsToStop();
}
}
} else if (action == RESTART_NEXT_LOOP) {
- log.info("Restarting next loop from element {}", getName());
- context.setStartNextThreadLoop(true);
+ log.info("Restarting next thread loop from element {}", getName());
+ context.setTestLogicalAction(TestLogicalAction.START_NEXT_ITERATION_OF_THREAD);
+ } else if (action == START_NEXT_ITERATION_CURRENT_LOOP) {
+ log.info("Switching to next loop iteration from element {}", getName());
+ context.setTestLogicalAction(TestLogicalAction.START_NEXT_ITERATION_OF_CURRENT_LOOP);
+ } else if (action == BREAK_CURRENT_LOOP) {
+ log.info("Breaking current loop from element {}", getName());
+ context.setTestLogicalAction(TestLogicalAction.BREAK_CURRENT_LOOP);
}
return null; // This means no sample is saved
Modified: jmeter/trunk/src/components/org/apache/jmeter/sampler/gui/TestActionGui.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/components/org/apache/jmeter/sampler/gui/TestActionGui.java?rev=1828095&r1=1828094&r2=1828095&view=diff
==============================================================================
--- jmeter/trunk/src/components/org/apache/jmeter/sampler/gui/TestActionGui.java (original)
+++ jmeter/trunk/src/components/org/apache/jmeter/sampler/gui/TestActionGui.java Sat Mar 31 10:32:33 2018
@@ -18,23 +18,26 @@
package org.apache.jmeter.sampler.gui;
+import java.awt.GridLayout;
+
+import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JLabel;
+import javax.swing.JPanel;
import javax.swing.JRadioButton;
-import javax.swing.JTextField;
import org.apache.jmeter.gui.GUIMenuSortOrder;
-import org.apache.jmeter.gui.util.HorizontalPanel;
import org.apache.jmeter.sampler.TestAction;
import org.apache.jmeter.samplers.gui.AbstractSamplerGui;
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.util.JMeterUtils;
+import org.apache.jorphan.gui.JLabeledTextField;
import org.apache.jorphan.gui.layout.VerticalLayout;
@GUIMenuSortOrder(1)
-public class TestActionGui extends AbstractSamplerGui {
+public class TestActionGui extends AbstractSamplerGui { // NOSONAR Ignore hierarchy error
private static final long serialVersionUID = 240L;
// Gui components
@@ -46,9 +49,13 @@ public class TestActionGui extends Abstr
private JRadioButton stopNowButton;
- private JRadioButton restartNextLoopButton;
+ private JRadioButton breakLoopButton;
+
+ private JRadioButton restartNextThreadLoopButton;
+
+ private JRadioButton startNextIterationOfCurrentLoopButton;
- private JTextField durationField;
+ private JLabeledTextField durationField;
// State variables
private int target;
@@ -57,23 +64,29 @@ public class TestActionGui extends Abstr
// String in the panel
// Do not make these static, otherwise language changes don't work
- private final String targetLabel = JMeterUtils.getResString("test_action_target"); // $NON-NLS-1$
+ private static final String TARGET_LABEL = JMeterUtils.getResString("test_action_target"); // $NON-NLS-1$
- private final String threadTarget = JMeterUtils.getResString("test_action_target_thread"); // $NON-NLS-1$
+ private static final String THREAD_TARGET_LABEL = JMeterUtils.getResString("test_action_target_thread"); // $NON-NLS-1$
- private final String testTarget = JMeterUtils.getResString("test_action_target_test"); // $NON-NLS-1$
+ private static final String TEST_TARGET_LABEL = JMeterUtils.getResString("test_action_target_test"); // $NON-NLS-1$
- private final String actionLabel = JMeterUtils.getResString("test_action_action"); // $NON-NLS-1$
+ private static final String ACTION_ON_THREAD_LABEL = JMeterUtils.getResString("test_action_action_thread"); // $NON-NLS-1$
+
+ private static final String ACTION_ON_THREAD_TEST_LABEL = JMeterUtils.getResString("test_action_action_test_thread"); // $NON-NLS-1$
+
+ private static final String PAUSE_ACTION_LABEL = JMeterUtils.getResString("test_action_pause"); // $NON-NLS-1$
- private final String pauseAction = JMeterUtils.getResString("test_action_pause"); // $NON-NLS-1$
+ private static final String STOP_ACTION_LABEL = JMeterUtils.getResString("test_action_stop"); // $NON-NLS-1$
- private final String stopAction = JMeterUtils.getResString("test_action_stop"); // $NON-NLS-1$
+ private static final String STOP_NOW_ACTION_LABEL = JMeterUtils.getResString("test_action_stop_now"); // $NON-NLS-1$
- private final String stopNowAction = JMeterUtils.getResString("test_action_stop_now"); // $NON-NLS-1$
+ private static final String RESTART_NEXT_THREAD_LOOP_LABEL = JMeterUtils.getResString("test_action_restart_next_loop"); // $NON-NLS-1$
+
+ private static final String START_NEXT_ITERATION_CURRENT_LOOP_ACTION = JMeterUtils.getResString("test_action_continue_current_loop"); // $NON-NLS-1$
- private final String restartNextLoopAction = JMeterUtils.getResString("test_action_restart_next_loop"); // $NON-NLS-1$
+ private static final String BREAK_CURRENT_LOOP_ACTION = JMeterUtils.getResString("test_action_break_current_loop"); // $NON-NLS-1$
- private final String durationLabel = JMeterUtils.getResString("test_action_duration"); // $NON-NLS-1$
+ private static final String DURATION_LABEL = JMeterUtils.getResString("test_action_duration"); // $NON-NLS-1$
public TestActionGui() {
super();
@@ -94,19 +107,32 @@ public class TestActionGui extends Abstr
target = ta.getTarget();
if (target == TestAction.THREAD) {
- targetBox.setSelectedItem(threadTarget);
+ targetBox.setSelectedItem(THREAD_TARGET_LABEL);
} else {
- targetBox.setSelectedItem(testTarget);
+ targetBox.setSelectedItem(TEST_TARGET_LABEL);
}
action = ta.getAction();
- if (action == TestAction.PAUSE) {
- pauseButton.setSelected(true);
- } else if (action == TestAction.STOP_NOW) {
- stopNowButton.setSelected(true);
- } else if(action == TestAction.STOP ){
- stopButton.setSelected(true);
- } else {
- restartNextLoopButton.setSelected(true);
+ switch (action) {
+ case TestAction.PAUSE:
+ pauseButton.setSelected(true);
+ break;
+ case TestAction.STOP_NOW:
+ stopNowButton.setSelected(true);
+ break;
+ case TestAction.STOP:
+ stopButton.setSelected(true);
+ break;
+ case TestAction.RESTART_NEXT_LOOP:
+ restartNextThreadLoopButton.setSelected(true);
+ break;
+ case TestAction.START_NEXT_ITERATION_CURRENT_LOOP:
+ startNextIterationOfCurrentLoopButton.setSelected(true);
+ break;
+ case TestAction.BREAK_CURRENT_LOOP:
+ breakLoopButton.setSelected(true);
+ break;
+ default:
+ break;
}
durationField.setText(ta.getDurationAsString());
@@ -156,27 +182,8 @@ public class TestActionGui extends Abstr
setBorder(makeBorder());
add(makeTitlePanel());
- // Target
- HorizontalPanel targetPanel = new HorizontalPanel();
- targetPanel.add(new JLabel(targetLabel));
- DefaultComboBoxModel<String> targetModel = new DefaultComboBoxModel<>();
- targetModel.addElement(threadTarget);
- targetModel.addElement(testTarget);
- targetBox = new JComboBox<>(targetModel);
- targetBox.addActionListener(evt -> {
- if (((String) targetBox.getSelectedItem()).equals(threadTarget)) {
- target = TestAction.THREAD;
- } else {
- target = TestAction.TEST;
- }
- });
- targetPanel.add(targetBox);
- add(targetPanel);
-
- // Action
- HorizontalPanel actionPanel = new HorizontalPanel();
ButtonGroup actionButtons = new ButtonGroup();
- pauseButton = new JRadioButton(pauseAction, true);
+ pauseButton = new JRadioButton(PAUSE_ACTION_LABEL, true);
pauseButton.addChangeListener(evt -> {
if (pauseButton.isSelected()) {
action = TestAction.PAUSE;
@@ -184,7 +191,7 @@ public class TestActionGui extends Abstr
targetBox.setEnabled(false);
}
});
- stopButton = new JRadioButton(stopAction, false);
+ stopButton = new JRadioButton(STOP_ACTION_LABEL, false);
stopButton.addChangeListener(evt -> {
if (stopButton.isSelected()) {
action = TestAction.STOP;
@@ -192,7 +199,7 @@ public class TestActionGui extends Abstr
targetBox.setEnabled(true);
}
});
- stopNowButton = new JRadioButton(stopNowAction, false);
+ stopNowButton = new JRadioButton(STOP_NOW_ACTION_LABEL, false);
stopNowButton.addChangeListener(evt -> {
if (stopNowButton.isSelected()) {
action = TestAction.STOP_NOW;
@@ -201,9 +208,9 @@ public class TestActionGui extends Abstr
}
});
- restartNextLoopButton = new JRadioButton(restartNextLoopAction, false);
- restartNextLoopButton.addChangeListener(evt -> {
- if (restartNextLoopButton.isSelected()) {
+ restartNextThreadLoopButton = new JRadioButton(RESTART_NEXT_THREAD_LOOP_LABEL, false);
+ restartNextThreadLoopButton.addChangeListener(evt -> {
+ if (restartNextThreadLoopButton.isSelected()) {
action = TestAction.RESTART_NEXT_LOOP;
durationField.setEnabled(false);
targetBox.setSelectedIndex(TestAction.THREAD);
@@ -211,25 +218,69 @@ public class TestActionGui extends Abstr
}
});
+ startNextIterationOfCurrentLoopButton = new JRadioButton(START_NEXT_ITERATION_CURRENT_LOOP_ACTION, false);
+ startNextIterationOfCurrentLoopButton.addChangeListener(evt -> {
+ if (startNextIterationOfCurrentLoopButton.isSelected()) {
+ action = TestAction.START_NEXT_ITERATION_CURRENT_LOOP;
+ durationField.setEnabled(false);
+ targetBox.setSelectedIndex(TestAction.THREAD);
+ targetBox.setEnabled(false);
+ }
+ });
+
+ breakLoopButton = new JRadioButton(BREAK_CURRENT_LOOP_ACTION, false);
+ breakLoopButton.addChangeListener(evt -> {
+ if (breakLoopButton.isSelected()) {
+ action = TestAction.BREAK_CURRENT_LOOP;
+ durationField.setEnabled(false);
+ targetBox.setSelectedIndex(TestAction.THREAD);
+ targetBox.setEnabled(false);
+ }
+ });
+
+ // Duration
+ durationField = new JLabeledTextField(DURATION_LABEL, 15);
+ durationField.setText(""); // $NON-NLS-1$
+
+
actionButtons.add(pauseButton);
actionButtons.add(stopButton);
actionButtons.add(stopNowButton);
- actionButtons.add(restartNextLoopButton);
+ actionButtons.add(restartNextThreadLoopButton);
+ actionButtons.add(startNextIterationOfCurrentLoopButton);
+ actionButtons.add(breakLoopButton);
- actionPanel.add(new JLabel(actionLabel));
- actionPanel.add(pauseButton);
- actionPanel.add(stopButton);
- actionPanel.add(stopNowButton);
- actionPanel.add(restartNextLoopButton);
- add(actionPanel);
+ // Action
+ JPanel actionOnThreadPanel = new JPanel(new GridLayout(3, 2));
+ actionOnThreadPanel.setBorder(BorderFactory.createTitledBorder(ACTION_ON_THREAD_LABEL)); //$NON-NLS-1$
+ actionOnThreadPanel.add(pauseButton);
+ actionOnThreadPanel.add(durationField);
+ actionOnThreadPanel.add(restartNextThreadLoopButton);
+ actionOnThreadPanel.add(startNextIterationOfCurrentLoopButton);
+ actionOnThreadPanel.add(breakLoopButton);
+
+
+ // Action
+ JPanel actionOnTestOrThreadPanel = new JPanel(new GridLayout(2, 2));
+ actionOnTestOrThreadPanel.setBorder(BorderFactory.createTitledBorder(ACTION_ON_THREAD_TEST_LABEL)); //$NON-NLS-1$
+ actionOnTestOrThreadPanel.add(stopButton);
+ actionOnTestOrThreadPanel.add(stopNowButton);
+ actionOnTestOrThreadPanel.add(new JLabel(TARGET_LABEL));
+ DefaultComboBoxModel<String> targetModel = new DefaultComboBoxModel<>();
+ targetModel.addElement(THREAD_TARGET_LABEL);
+ targetModel.addElement(TEST_TARGET_LABEL);
+ targetBox = new JComboBox<>(targetModel);
+ targetBox.addActionListener(evt -> {
+ if (((String) targetBox.getSelectedItem()).equals(THREAD_TARGET_LABEL)) {
+ target = TestAction.THREAD;
+ } else {
+ target = TestAction.TEST;
+ }
+ });
+ actionOnTestOrThreadPanel.add(targetBox);
- // Duration
- HorizontalPanel durationPanel = new HorizontalPanel();
- durationField = new JTextField(15);
- durationField.setText(""); // $NON-NLS-1$
- durationPanel.add(new JLabel(durationLabel));
- durationPanel.add(durationField);
- add(durationPanel);
+ add(actionOnThreadPanel);
+ add(actionOnTestOrThreadPanel);
}
}
Modified: jmeter/trunk/src/core/org/apache/jmeter/gui/OnErrorPanel.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/gui/OnErrorPanel.java?rev=1828095&r1=1828094&r2=1828095&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/gui/OnErrorPanel.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/gui/OnErrorPanel.java Sat Mar 31 10:32:33 2018
@@ -19,6 +19,7 @@
package org.apache.jmeter.gui;
import java.awt.BorderLayout;
+import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
@@ -34,44 +35,44 @@ public class OnErrorPanel extends JPanel
// Sampler error action buttons
private JRadioButton continueBox;
+ private JRadioButton breakLoopBox;
+
private JRadioButton startNextThreadLoopBox;
+ private JRadioButton startNextIterationOfCurrentLoopBox;
+
private JRadioButton stopThrdBox;
private JRadioButton stopTestBox;
private JRadioButton stopTestNowBox;
+
private JPanel createOnErrorPanel() {
- JPanel panel = new JPanel();
+ JPanel panel = new JPanel(new GridLayout(4, 2));
panel.setBorder(BorderFactory.createTitledBorder(JMeterUtils.getResString("sampler_on_error_action"))); //$NON-NLS-1$
ButtonGroup group = new ButtonGroup();
- continueBox = new JRadioButton(JMeterUtils.getResString("sampler_on_error_continue")); //$NON-NLS-1$
- group.add(continueBox);
+ continueBox = addRadioButton("sampler_on_error_continue", group, panel); //$NON-NLS-1$
+ breakLoopBox = addRadioButton("sampler_on_error_break_loop", group, panel); //$NON-NLS-1$
+ startNextThreadLoopBox = addRadioButton("sampler_on_error_start_next_loop", group, panel); //$NON-NLS-1$
+ startNextIterationOfCurrentLoopBox = addRadioButton("sampler_on_error_start_next_iteration_current_loop", group, panel); //$NON-NLS-1$
+ stopTestBox = addRadioButton("sampler_on_error_stop_test", group, panel); //$NON-NLS-1$
+ stopTestNowBox = addRadioButton("sampler_on_error_stop_test_now", group, panel); //$NON-NLS-1$
+ stopThrdBox = addRadioButton("sampler_on_error_stop_thread", group, panel); //$NON-NLS-1$
+
continueBox.setSelected(true);
- panel.add(continueBox);
-
- startNextThreadLoopBox = new JRadioButton(JMeterUtils.getResString("sampler_on_error_start_next_loop")); //$NON-NLS-1$
- group.add(startNextThreadLoopBox);
- panel.add(startNextThreadLoopBox);
-
- stopThrdBox = new JRadioButton(JMeterUtils.getResString("sampler_on_error_stop_thread")); //$NON-NLS-1$
- group.add(stopThrdBox);
- panel.add(stopThrdBox);
-
- stopTestBox = new JRadioButton(JMeterUtils.getResString("sampler_on_error_stop_test")); //$NON-NLS-1$
- group.add(stopTestBox);
- panel.add(stopTestBox);
-
- stopTestNowBox = new JRadioButton(JMeterUtils.getResString("sampler_on_error_stop_test_now")); //$NON-NLS-1$
- group.add(stopTestNowBox);
- panel.add(stopTestNowBox);
-
return panel;
}
+ private JRadioButton addRadioButton(String labelKey, ButtonGroup group, JPanel panel) {
+ JRadioButton radioButton = new JRadioButton(JMeterUtils.getResString(labelKey));
+ group.add(radioButton);
+ panel.add(radioButton);
+ return radioButton;
+ }
+
/**
* Create a new NamePanel with the default name.
*/
@@ -90,9 +91,11 @@ public class OnErrorPanel extends JPanel
public void configure(int errorAction) {
stopTestNowBox.setSelected(errorAction == OnErrorTestElement.ON_ERROR_STOPTEST_NOW);
startNextThreadLoopBox.setSelected(errorAction == OnErrorTestElement.ON_ERROR_START_NEXT_THREAD_LOOP);
+ startNextIterationOfCurrentLoopBox.setSelected(errorAction == OnErrorTestElement.ON_ERROR_START_NEXT_ITERATION_OF_CURRENT_LOOP);
stopTestBox.setSelected(errorAction == OnErrorTestElement.ON_ERROR_STOPTEST);
stopThrdBox.setSelected(errorAction == OnErrorTestElement.ON_ERROR_STOPTHREAD);
continueBox.setSelected(errorAction == OnErrorTestElement.ON_ERROR_CONTINUE);
+ breakLoopBox.setSelected(errorAction == OnErrorTestElement.ON_ERROR_BREAK_CURRENT_LOOP);
}
public int getOnErrorSetting() {
@@ -108,6 +111,12 @@ public class OnErrorPanel extends JPanel
if (startNextThreadLoopBox.isSelected()) {
return OnErrorTestElement.ON_ERROR_START_NEXT_THREAD_LOOP;
}
+ if (startNextIterationOfCurrentLoopBox.isSelected()) {
+ return OnErrorTestElement.ON_ERROR_START_NEXT_ITERATION_OF_CURRENT_LOOP;
+ }
+ if(breakLoopBox.isSelected()) {
+ return OnErrorTestElement.ON_ERROR_BREAK_CURRENT_LOOP;
+ }
// Defaults to continue
return OnErrorTestElement.ON_ERROR_CONTINUE;
Modified: jmeter/trunk/src/core/org/apache/jmeter/reporters/ResultAction.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/reporters/ResultAction.java?rev=1828095&r1=1828094&r2=1828095&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/reporters/ResultAction.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/reporters/ResultAction.java Sat Mar 31 10:32:33 2018
@@ -24,6 +24,7 @@ import org.apache.jmeter.samplers.Sample
import org.apache.jmeter.samplers.SampleListener;
import org.apache.jmeter.samplers.SampleResult;
import org.apache.jmeter.testelement.OnErrorTestElement;
+import org.apache.jmeter.threads.JMeterContext.TestLogicalAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -33,7 +34,7 @@ import org.slf4j.LoggerFactory;
*/
public class ResultAction extends OnErrorTestElement implements Serializable, SampleListener {
- private static final long serialVersionUID = 241L;
+ private static final long serialVersionUID = 242L;
private static final Logger log = LoggerFactory.getLogger(ResultAction.class);
@@ -61,15 +62,16 @@ public class ResultAction extends OnErro
if (!s.isSuccessful()) {
if (isStopTestNow()) {
s.setStopTestNow(true);
- }
- if (isStopTest()) {
+ } else if (isStopTest()) {
s.setStopTest(true);
- }
- if (isStopThread()) {
+ } else if (isStopThread()) {
s.setStopThread(true);
- }
- if (isStartNextThreadLoop()) {
- s.setStartNextThreadLoop(true);
+ } else if (isStartNextThreadLoop()) {
+ s.setTestLogicalAction(TestLogicalAction.START_NEXT_ITERATION_OF_THREAD);
+ } else if(isStartNextIterationOfCurrentLoop()) {
+ s.setTestLogicalAction(TestLogicalAction.START_NEXT_ITERATION_OF_CURRENT_LOOP);
+ } else if(isBreakCurrentLoop()) {
+ s.setTestLogicalAction(TestLogicalAction.BREAK_CURRENT_LOOP);
}
}
}
Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties?rev=1828095&r1=1828094&r2=1828095&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages.properties Sat Mar 31 10:32:33 2018
@@ -975,7 +975,9 @@ sample_scope_parent=Main sample only
sample_scope_variable=JMeter Variable Name to use
sampler_label=Label
sampler_on_error_action=Action to be taken after a Sampler error
+sampler_on_error_break_loop=Break Current Loop
sampler_on_error_continue=Continue
+sampler_on_error_start_next_iteration_current_loop=Start Next Iteration of Current Loop
sampler_on_error_start_next_loop=Start Next Thread Loop
sampler_on_error_stop_test=Stop Test
sampler_on_error_stop_test_now=Stop Test Now
@@ -1204,13 +1206,16 @@ template_merge_from=Merge
template_reload=Reload templates
template_title=Templates
test=Test
-test_action_action=Action
-test_action_duration=Duration (milliseconds)
+test_action_action_thread=Logical Action on Thread
+test_action_action_test_thread=Logical Action on Thread/Test
+test_action_break_current_loop=Break Current Loop
+test_action_continue_current_loop=Switch to next iteration of Current Loop
+test_action_duration=Duration (milliseconds)\:
test_action_pause=Pause
test_action_restart_next_loop=Start Next Thread Loop
test_action_stop=Stop
test_action_stop_now=Stop Now
-test_action_target=Target
+test_action_target=Target\:
test_action_target_test=All Threads
test_action_target_thread=Current Thread
test_action_title=Test Action
Modified: jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties?rev=1828095&r1=1828094&r2=1828095&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/resources/messages_fr.properties Sat Mar 31 10:32:33 2018
@@ -967,8 +967,10 @@ sample_timeout_timeout=D\u00E9lai d'atte
sample_timeout_title=Compteur Interruption
sampler_label=Libell\u00E9
sampler_on_error_action=Action \u00E0 suivre apr\u00E8s une erreur d'\u00E9chantillon
+sampler_on_error_break_loop=Quitter la boucle courante
sampler_on_error_continue=Continuer
-sampler_on_error_start_next_loop=D\u00E9marrer it\u00E9ration suivante
+sampler_on_error_start_next_iteration_current_loop=D\u00E9marrer it\u00E9ration suivante de la boucle courante
+sampler_on_error_start_next_loop=D\u00E9marrer it\u00E9ration suivante du Thread
sampler_on_error_stop_test=Arr\u00EAter le test
sampler_on_error_stop_test_now=Arr\u00EAter le test imm\u00E9diatement
sampler_on_error_stop_thread=Arr\u00EAter l'unit\u00E9
@@ -1194,9 +1196,11 @@ template_reload=Recharger les mod\u00E8l
template_title=Mod\u00E8les
test=Test
test_action_action=Action \:
+test_action_break_current_loop=Quitter la boucle courante
+test_action_continue_current_loop=Passer \u00e0 It\u00E9ration suivante de la Boucle courante
test_action_duration=Dur\u00E9e (millisecondes) \:
test_action_pause=Mettre en pause
-test_action_restart_next_loop=D\u00E9marrer it\u00E9ration suivante
+test_action_restart_next_loop=D\u00E9marrer it\u00E9ration suivante du Thread
test_action_stop=Arr\u00EAter
test_action_stop_now=Arr\u00EAter imm\u00E9diatement
test_action_target=Cible \:
Modified: jmeter/trunk/src/core/org/apache/jmeter/samplers/SampleResult.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/samplers/SampleResult.java?rev=1828095&r1=1828094&r2=1828095&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/samplers/SampleResult.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/samplers/SampleResult.java Sat Mar 31 10:32:33 2018
@@ -32,6 +32,7 @@ import java.util.concurrent.TimeUnit;
import org.apache.jmeter.assertions.AssertionResult;
import org.apache.jmeter.gui.Searchable;
+import org.apache.jmeter.threads.JMeterContext.TestLogicalAction;
import org.apache.jmeter.util.JMeterUtils;
import org.apache.jorphan.util.JOrphanUtils;
import org.slf4j.Logger;
@@ -228,9 +229,9 @@ public class SampleResult implements Ser
/** time to end connecting */
private long connectTime = 0;
- /** Should thread start next iteration ? */
- private boolean startNextThreadLoop = false;
-
+ /** Way to signal what to do on Test */
+ private TestLogicalAction testLogicalAction = TestLogicalAction.CONTINUE;
+
/** Should thread terminate? */
private boolean stopThread = false;
@@ -331,7 +332,7 @@ public class SampleResult implements Ser
stopTest = res.stopTest;
stopTestNow = res.stopTestNow;
stopThread = res.stopThread;
- startNextThreadLoop = res.startNextThreadLoop;
+ testLogicalAction = res.testLogicalAction;
subResults = res.subResults;
success = res.success;//OK
threadName = res.threadName;//OK
@@ -1466,16 +1467,24 @@ public class SampleResult implements Ser
/**
* @return the startNextThreadLoop
+ * @deprecated use {@link SampleResult#getTestLogicalAction()}
*/
+ @Deprecated
public boolean isStartNextThreadLoop() {
- return startNextThreadLoop;
+ return testLogicalAction == TestLogicalAction.START_NEXT_ITERATION_OF_THREAD;
}
/**
+ * @deprecated use {@link SampleResult#setTestLogicalAction(TestLogicalAction)}
* @param startNextThreadLoop the startNextLoop to set
*/
+ @Deprecated
public void setStartNextThreadLoop(boolean startNextThreadLoop) {
- this.startNextThreadLoop = startNextThreadLoop;
+ if(startNextThreadLoop) {
+ testLogicalAction = TestLogicalAction.START_NEXT_ITERATION_OF_THREAD;
+ } else {
+ testLogicalAction = TestLogicalAction.CONTINUE;
+ }
}
/**
@@ -1536,4 +1545,18 @@ public class SampleResult implements Ser
}
return message;
}
+
+ /**
+ * @return the testLogicalAction
+ */
+ public TestLogicalAction getTestLogicalAction() {
+ return testLogicalAction;
+ }
+
+ /**
+ * @param testLogicalAction the testLogicalAction to set
+ */
+ public void setTestLogicalAction(TestLogicalAction testLogicalAction) {
+ this.testLogicalAction = testLogicalAction;
+ }
}
Modified: jmeter/trunk/src/core/org/apache/jmeter/testelement/OnErrorTestElement.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/testelement/OnErrorTestElement.java?rev=1828095&r1=1828094&r2=1828095&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/testelement/OnErrorTestElement.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/testelement/OnErrorTestElement.java Sat Mar 31 10:32:33 2018
@@ -39,6 +39,10 @@ public abstract class OnErrorTestElement
public static final int ON_ERROR_STOPTEST_NOW = 3;
public static final int ON_ERROR_START_NEXT_THREAD_LOOP = 4;
+
+ public static final int ON_ERROR_START_NEXT_ITERATION_OF_CURRENT_LOOP = 5;
+
+ public static final int ON_ERROR_BREAK_CURRENT_LOOP = 6;
/* Property name */
public static final String ON_ERROR_ACTION = "OnError.action";
@@ -70,8 +74,16 @@ public abstract class OnErrorTestElement
public boolean isStopTestNow() {
return getErrorAction() == ON_ERROR_STOPTEST_NOW;
}
-
+
public boolean isStartNextThreadLoop() {
return getErrorAction() == ON_ERROR_START_NEXT_THREAD_LOOP;
}
+
+ public boolean isStartNextIterationOfCurrentLoop() {
+ return getErrorAction() == ON_ERROR_START_NEXT_ITERATION_OF_CURRENT_LOOP;
+ }
+
+ public boolean isBreakCurrentLoop() {
+ return getErrorAction() == ON_ERROR_BREAK_CURRENT_LOOP;
+ }
}
Modified: jmeter/trunk/src/core/org/apache/jmeter/threads/AbstractThreadGroup.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/threads/AbstractThreadGroup.java?rev=1828095&r1=1828094&r2=1828095&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/threads/AbstractThreadGroup.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/threads/AbstractThreadGroup.java Sat Mar 31 10:32:33 2018
@@ -295,4 +295,8 @@ public abstract class AbstractThreadGrou
* This gracefully stops threads of Group
*/
public abstract void stop();
+
+ public void breakThreadLoop() {
+ ((LoopController) getSamplerController()).breakLoop();
+ }
}
Modified: jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterContext.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterContext.java?rev=1828095&r1=1828094&r2=1828095&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterContext.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterContext.java Sat Mar 31 10:32:33 2018
@@ -34,6 +34,13 @@ import org.apache.jmeter.util.JMeterUtil
* The class is not thread-safe - it is only intended for use within a single thread.
*/
public class JMeterContext {
+
+ public enum TestLogicalAction {
+ CONTINUE,
+ START_NEXT_ITERATION_OF_THREAD,
+ START_NEXT_ITERATION_OF_CURRENT_LOOP,
+ BREAK_CURRENT_LOOP
+ }
private JMeterVariables variables;
private SampleResult previousResult;
@@ -44,7 +51,7 @@ public class JMeterContext {
private JMeterThread thread;
private AbstractThreadGroup threadGroup;
private int threadNum;
- private boolean restartNextLoop = false;
+ private TestLogicalAction testLogicalAction = TestLogicalAction.CONTINUE;
private ConcurrentHashMap<String, Object> samplerContext = new ConcurrentHashMap<>(5);
private boolean recording;
@@ -199,19 +206,43 @@ public class JMeterContext {
public void setSamplingStarted(boolean b) {
samplingStarted = b;
}
+
/**
+ * @param startNextIterationOfCurrentLoop start next iteration of current loop in which this component is present
+ */
+ public void setTestLogicalAction(TestLogicalAction actionOnExecution) {
+ this.testLogicalAction = actionOnExecution;
+ }
+
+ /**
+ * @return TestLogicalAction to start next iteration of current loop in which this component is present
+ */
+ public TestLogicalAction getTestLogicalAction() {
+ return testLogicalAction;
+ }
+
+ /**
+ * @deprecated
* @param restartNextLoop if set to <code>true</code> a restart of the loop will occur
+ * @deprecated use {@link JMeterContext#setTestLogicalAction(TestLogicalAction)}
*/
+ @Deprecated
public void setStartNextThreadLoop(boolean restartNextLoop) {
- this.restartNextLoop = restartNextLoop;
+ if(restartNextLoop) {
+ this.testLogicalAction = TestLogicalAction.START_NEXT_ITERATION_OF_THREAD;
+ } else {
+ this.testLogicalAction = TestLogicalAction.CONTINUE;
+ }
}
/**
- * @return {@code true} when current loop iteration will be interrupted and JMeter will go to next iteration
+ * @return {@code true} when current loop iteration of Thread Group will be interrupted and JMeter will go to next iteration of the Thread Group loop
+ * @deprecated use {@link JMeterContext#isTestLogicalAction()}
*/
+ @Deprecated
public boolean isStartNextThreadLoop() {
- return restartNextLoop;
+ return this.testLogicalAction == TestLogicalAction.START_NEXT_ITERATION_OF_THREAD;
}
/**
Modified: jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java
URL: http://svn.apache.org/viewvc/jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java?rev=1828095&r1=1828094&r2=1828095&view=diff
==============================================================================
--- jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java (original)
+++ jmeter/trunk/src/core/org/apache/jmeter/threads/JMeterThread.java Sat Mar 31 10:32:33 2018
@@ -23,10 +23,12 @@ import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
+import java.util.function.Consumer;
import org.apache.jmeter.assertions.Assertion;
import org.apache.jmeter.assertions.AssertionResult;
import org.apache.jmeter.control.Controller;
+import org.apache.jmeter.control.IteratingController;
import org.apache.jmeter.control.TransactionSampler;
import org.apache.jmeter.engine.StandardJMeterEngine;
import org.apache.jmeter.engine.event.LoopIterationEvent;
@@ -46,6 +48,7 @@ import org.apache.jmeter.testelement.Abs
import org.apache.jmeter.testelement.TestElement;
import org.apache.jmeter.testelement.TestIterationListener;
import org.apache.jmeter.testelement.ThreadListener;
+import org.apache.jmeter.threads.JMeterContext.TestLogicalAction;
import org.apache.jmeter.timers.Timer;
import org.apache.jmeter.timers.TimerService;
import org.apache.jmeter.util.JMeterUtils;
@@ -141,7 +144,7 @@ public class JMeterThread implements Run
private volatile boolean onErrorStartNextLoop;
- private volatile Sampler currentSampler;
+ private volatile Sampler currentSamplerForInterruption;
private final ReentrantLock interruptLock = new ReentrantLock(); // ensure that interrupt cannot overlap with shutdown
@@ -253,23 +256,36 @@ public class JMeterThread implements Run
// restart of the next loop
// - was requested through threadContext
// - or the last sample failed AND the onErrorStartNextLoop option is enabled
- if (threadContext.isStartNextThreadLoop()
+ if (threadContext.getTestLogicalAction() != TestLogicalAction.CONTINUE
|| (onErrorStartNextLoop
&& !TRUE.equals(threadContext.getVariables().get(LAST_SAMPLE_OK)))) {
- if (log.isDebugEnabled() && onErrorStartNextLoop && !threadContext.isStartNextThreadLoop()) {
- log.debug("StartNextLoop option is on, Last sample failed, starting next loop");
+ if (log.isDebugEnabled() && onErrorStartNextLoop
+ && threadContext.getTestLogicalAction() != TestLogicalAction.CONTINUE) {
+ log.debug("Start Next Thread Loop option is on, Last sample failed, starting next thread loop");
}
-
- triggerEndOfLoopOnParentControllers(sam, threadContext);
+ switch (threadContext.getTestLogicalAction()) {
+ case BREAK_CURRENT_LOOP:
+ triggerLoopLogicalActionOnParentControllers(sam, threadContext, JMeterThread::breakOnCurrentLoop);
+ break;
+ case START_NEXT_ITERATION_OF_THREAD:
+ triggerLoopLogicalActionOnParentControllers(sam, threadContext, JMeterThread::continueOnThreadLoop);
+ break;
+ case START_NEXT_ITERATION_OF_CURRENT_LOOP:
+ triggerLoopLogicalActionOnParentControllers(sam, threadContext, JMeterThread::continueOnCurrentLoop);
+ break;
+ default:
+ break;
+ }
+ threadContext.setTestLogicalAction(TestLogicalAction.CONTINUE);
sam = null;
threadContext.getVariables().put(LAST_SAMPLE_OK, TRUE);
- threadContext.setStartNextThreadLoop(false);
}
else {
sam = threadGroupLoopController.next();
}
}
-
+
+ // It would be possible to add finally for Thread Loop here
if (threadGroupLoopController.isDone()) {
running = false;
log.info("Thread is done: {}", threadName);
@@ -297,7 +313,7 @@ public class JMeterThread implements Run
} catch (ThreadDeath e) {
throw e; // Must not ignore this one
} finally {
- currentSampler = null; // prevent any further interrupts
+ currentSamplerForInterruption = null; // prevent any further interrupts
try {
interruptLock.lock(); // make sure current interrupt is finished, prevent another starting yet
threadContext.clear();
@@ -312,44 +328,94 @@ public class JMeterThread implements Run
}
/**
- * Trigger end of loop on parent controllers up to Thread Group
- * @param sam Sampler Base sampler
+ * Trigger break/continue/switch to next thread Loop depending on consumer implementation
+ * @param sampler Sampler Base sampler
* @param threadContext
+ * @param consumer Consumer that will process the tree of elements up to root node
*/
- private void triggerEndOfLoopOnParentControllers(Sampler sam, JMeterContext threadContext) {
+ private void triggerLoopLogicalActionOnParentControllers(Sampler sampler, JMeterContext threadContext,
+ Consumer<FindTestElementsUpToRootTraverser> consumer) {
TransactionSampler transactionSampler = null;
- if (sam instanceof TransactionSampler) {
- transactionSampler = (TransactionSampler) sam;
+ if (sampler instanceof TransactionSampler) {
+ transactionSampler = (TransactionSampler) sampler;
}
- Sampler realSampler = findRealSampler(sam);
+ Sampler realSampler = findRealSampler(sampler);
if (realSampler == null) {
throw new IllegalStateException(
"Got null subSampler calling findRealSampler for:" +
- (sam != null ? sam.getName() : "null") + ", sam:" + sam);
+ (sampler != null ? sampler.getName() : "null") + ", sampler:" + sampler);
}
// Find parent controllers of current sampler
FindTestElementsUpToRootTraverser pathToRootTraverser = new FindTestElementsUpToRootTraverser(realSampler);
testTree.traverse(pathToRootTraverser);
- // Trigger end of loop condition on all parent controllers of current sampler
+ consumer.accept(pathToRootTraverser);
+
+ // bug 52968
+ // When using Start Next Loop option combined to TransactionController.
+ // if an error occurs in a Sample (child of TransactionController)
+ // then we still need to report the Transaction in error (and create the sample result)
+ if (transactionSampler != null) {
+ SamplePackage transactionPack = compiler.configureTransactionSampler(transactionSampler);
+ doEndTransactionSampler(transactionSampler, null, transactionPack, threadContext);
+ }
+ }
+
+ /**
+ * Executes a continue of current loop, equivalent of "continue" in algorithm.
+ * As a consequence it ends the first loop it finds on the path to root
+ * @param pathToRootTraverser {@link FindTestElementsUpToRootTraverser}
+ */
+ private static void continueOnCurrentLoop(FindTestElementsUpToRootTraverser pathToRootTraverser) {
List<Controller> controllersToReinit = pathToRootTraverser.getControllersToRoot();
for (Controller parentController : controllersToReinit) {
if (parentController instanceof AbstractThreadGroup) {
AbstractThreadGroup tg = (AbstractThreadGroup) parentController;
tg.startNextLoop();
+ } else if (parentController instanceof IteratingController) {
+ ((IteratingController) parentController).startNextLoop();
+ break;
} else {
parentController.triggerEndOfLoop();
}
}
+ }
+
+ /**
+ * Executes a break of current loop, equivalent of "break" in algorithm.
+ * As a consequence it ends the first loop it finds on the path to root
+ * @param pathToRootTraverser {@link FindTestElementsUpToRootTraverser}
+ */
+ private static void breakOnCurrentLoop(FindTestElementsUpToRootTraverser pathToRootTraverser) {
+ List<Controller> controllersToReinit = pathToRootTraverser.getControllersToRoot();
+ for (Controller parentController : controllersToReinit) {
+ if (parentController instanceof AbstractThreadGroup) {
+ AbstractThreadGroup tg = (AbstractThreadGroup) parentController;
+ tg.breakThreadLoop();
+ } else if (parentController instanceof IteratingController) {
+ ((IteratingController) parentController).breakLoop();
+ break;
+ } else {
+ parentController.triggerEndOfLoop();
+ }
+ }
+ }
- // bug 52968
- // When using Start Next Loop option combined to TransactionController.
- // if an error occurs in a Sample (child of TransactionController)
- // then we still need to report the Transaction in error (and create the sample result)
- if (transactionSampler != null) {
- SamplePackage transactionPack = compiler.configureTransactionSampler(transactionSampler);
- doEndTransactionSampler(transactionSampler, null, transactionPack, threadContext);
+ /**
+ * Executes a restart of Thread loop, equivalent of "continue" in algorithm but on Thread Loop.
+ * As a consequence it ends all loop on the path to root
+ * @param pathToRootTraverser {@link FindTestElementsUpToRootTraverser}
+ */
+ private static void continueOnThreadLoop(FindTestElementsUpToRootTraverser pathToRootTraverser) {
+ List<Controller> controllersToReinit = pathToRootTraverser.getControllersToRoot();
+ for (Controller parentController : controllersToReinit) {
+ if (parentController instanceof AbstractThreadGroup) {
+ AbstractThreadGroup tg = (AbstractThreadGroup) parentController;
+ tg.startNextLoop();
+ } else {
+ parentController.triggerEndOfLoop();
+ }
}
}
@@ -452,7 +518,7 @@ public class JMeterThread implements Run
return transactionResult;
}
- /*
+ /**
* Execute the sampler with its pre/post processors, timers, assertions
* Broadcast the result to the sample listeners
*/
@@ -473,29 +539,7 @@ public class JMeterThread implements Run
SampleResult result = null;
if (running) {
Sampler sampler = pack.getSampler();
- sampler.setThreadContext(threadContext);
- // TODO should this set the thread names for all the subsamples?
- // might be more efficient than fetching the name elsewhere
- sampler.setThreadName(threadName);
- TestBeanHelper.prepare(sampler);
-
- // Perform the actual sample
- currentSampler = sampler;
- if (!sampleMonitors.isEmpty()) {
- for (SampleMonitor sampleMonitor : sampleMonitors) {
- sampleMonitor.sampleStarting(sampler);
- }
- }
- try {
- result = sampler.sample(null);
- } finally {
- if (!sampleMonitors.isEmpty()) {
- for (SampleMonitor sampleMonitor : sampleMonitors) {
- sampleMonitor.sampleEnded(sampler);
- }
- }
- }
- currentSampler = null;
+ result = doSampling(threadContext, sampler);
}
// If we got any results, then perform processing on the result
if (result != null && !result.isIgnore()) {
@@ -536,14 +580,49 @@ public class JMeterThread implements Run
if (result.isStopTestNow() || (!result.isSuccessful() && onErrorStopTestNow)) {
stopTestNow();
}
- if(result.isStartNextThreadLoop()) {
- threadContext.setStartNextThreadLoop(true);
- }
+ threadContext.setTestLogicalAction(result.getTestLogicalAction());
} else {
compiler.done(pack); // Finish up
}
}
+ /**
+ * Call sample on Sampler handling:
+ * <ul>
+ * <li>setting up ThreadContext</li>
+ * <li>initializing sampler if needed</li>
+ * <li>positionning currentSamplerForInterruption for potential interruption</li>
+ * <li>Playing SampleMonitor before and after sampling</li>
+ * <li>resetting currentSamplerForInterruption</li>
+ * </ul>
+ * @param threadContext {@link JMeterContext}
+ * @param sampler {@link Sampler}
+ * @return {@link SampleResult}
+ */
+ private SampleResult doSampling(JMeterContext threadContext, Sampler sampler) {
+ sampler.setThreadContext(threadContext);
+ sampler.setThreadName(threadName);
+ TestBeanHelper.prepare(sampler);
+
+ // Perform the actual sample
+ currentSamplerForInterruption = sampler;
+ if (!sampleMonitors.isEmpty()) {
+ for (SampleMonitor sampleMonitor : sampleMonitors) {
+ sampleMonitor.sampleStarting(sampler);
+ }
+ }
+ try {
+ return sampler.sample(null);
+ } finally {
+ if (!sampleMonitors.isEmpty()) {
+ for (SampleMonitor sampleMonitor : sampleMonitors) {
+ sampleMonitor.sampleEnded(sampler);
+ }
+ }
+ currentSamplerForInterruption = null;
+ }
+ }
+
private SampleResult doEndTransactionSampler(
TransactionSampler transactionSampler, Sampler parent,
SamplePackage transactionPack, JMeterContext threadContext) {
@@ -716,7 +795,7 @@ public class JMeterThread implements Run
public boolean interrupt(){
try {
interruptLock.lock();
- Sampler samp = currentSampler; // fetch once; must be done under lock
+ Sampler samp = currentSamplerForInterruption; // fetch once; must be done under lock
if (samp instanceof Interruptible){ // (also protects against null)
if (log.isWarnEnabled()) {
log.warn("Interrupting: {} sampler: {}", threadName, samp.getName());
@@ -738,7 +817,7 @@ public class JMeterThread implements Run
}
}
} finally {
- interruptLock.unlock();
+ interruptLock.unlock();
}
return false;
}
Modified: jmeter/trunk/xdocs/changes.xml
URL: http://svn.apache.org/viewvc/jmeter/trunk/xdocs/changes.xml?rev=1828095&r1=1828094&r2=1828095&view=diff
==============================================================================
--- jmeter/trunk/xdocs/changes.xml [utf-8] (original)
+++ jmeter/trunk/xdocs/changes.xml [utf-8] Sat Mar 31 10:32:33 2018
@@ -127,6 +127,7 @@ this behaviour, set <code>httpclient.res
<li><bug>62155</bug>Search Feature: Make Search text field get focus</li>
<li><bug>62156</bug>Search Feature : Distinguish between node that matches search and node that contains a child that matches search</li>
<li><bug>62234</bug>Search/Replace Feature : Enhance UX and add Replace/Next/Previous/Replace & Find features. Contributed by Ubik Load Pack (support at ubikloadpack.com)</li>
+ <li><bug>62238</bug>Add ability to Switch to next iteration of Current Loop. Contributed by Ubik Load Pack (support at ubikloadpack.com)</li>
<li><bug>62065</bug>Use Maven artifact for JAF Module instead of embedded module</li>
<li><pr>379</pr> Improve chinese translations. Contributed by XmeterNet</li>
</ul>