/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.jmeter.control; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNull; import static org.junit.Assert.fail; import org.apache.jmeter.engine.util.ValueReplacer; import org.apache.jmeter.junit.JMeterTestCase; import org.apache.jmeter.junit.stubs.TestSampler; import org.apache.jmeter.samplers.Sampler; import org.apache.jmeter.testelement.TestElement; import org.apache.jmeter.testelement.property.PropertyIterator; import org.apache.jmeter.threads.JMeterContext; import org.apache.jmeter.threads.JMeterContextService; import org.apache.jmeter.threads.JMeterThread; import org.apache.jmeter.threads.JMeterVariables; import org.junit.Before; import org.junit.Test; public class TestWhileController extends JMeterTestCase { private JMeterContext jmctx; private JMeterVariables jmvars; @Before public void setUp() { jmctx = JMeterContextService.getContext(); jmctx.setVariables(new JMeterVariables()); jmvars = jmctx.getVariables(); } private void setLastSampleStatus(boolean status){ jmvars.put(JMeterThread.LAST_SAMPLE_OK,Boolean.toString(status)); } private void setRunning(TestElement el){ PropertyIterator pi = el.propertyIterator(); while(pi.hasNext()){ pi.next().setRunningVersion(true); } } // Get next sample and its name private String nextName(GenericController c) { Sampler s = c.next(); if (s == null) { return null; } return s.getName(); } // While (blank), previous sample OK - should loop until false @Test public void testBlankPrevOK() throws Exception { // log.info("testBlankPrevOK"); runtestPrevOK(""); } // While (LAST), previous sample OK - should loop until false @Test public void testLastPrevOK() throws Exception { // log.info("testLASTPrevOK"); runtestPrevOK("LAST"); } private static final String OTHER = "X"; // Dummy for testing functions // While (LAST), previous sample OK - should loop until false @Test public void testOtherPrevOK() throws Exception { // log.info("testOtherPrevOK"); runtestPrevOK(OTHER); } private void runtestPrevOK(String type) throws Exception { GenericController controller = new GenericController(); WhileController while_cont = new WhileController(); setLastSampleStatus(true); while_cont.setCondition(type); while_cont.addTestElement(new TestSampler("one")); while_cont.addTestElement(new TestSampler("two")); while_cont.addTestElement(new TestSampler("three")); controller.addTestElement(while_cont); controller.addTestElement(new TestSampler("four")); controller.initialize(); assertEquals("one", nextName(controller)); assertEquals("two", nextName(controller)); assertEquals("three", nextName(controller)); assertEquals("one", nextName(controller)); assertEquals("two", nextName(controller)); assertEquals("three", nextName(controller)); assertEquals("one", nextName(controller)); setLastSampleStatus(false); if (type.equals(OTHER)){ while_cont.setCondition("false"); } assertEquals("two", nextName(controller)); assertEquals("three", nextName(controller)); setLastSampleStatus(true); if (type.equals(OTHER)) { while_cont.setCondition(OTHER); } assertEquals("one", nextName(controller)); assertEquals("two", nextName(controller)); assertEquals("three", nextName(controller)); setLastSampleStatus(false); if (type.equals(OTHER)) { while_cont.setCondition("false"); } assertEquals("four", nextName(controller)); assertNull(nextName(controller)); setLastSampleStatus(true); if (type.equals(OTHER)) { while_cont.setCondition(OTHER); } assertEquals("one", nextName(controller)); } // While (blank), previous sample failed - should run once @Test public void testBlankPrevFailed() throws Exception { // log.info("testBlankPrevFailed"); GenericController controller = new GenericController(); controller.setRunningVersion(true); WhileController while_cont = new WhileController(); setLastSampleStatus(false); while_cont.setCondition(""); while_cont.addTestElement(new TestSampler("one")); while_cont.addTestElement(new TestSampler("two")); controller.addTestElement(while_cont); controller.addTestElement(new TestSampler("three")); controller.initialize(); assertEquals("one", nextName(controller)); assertEquals("two", nextName(controller)); assertEquals("three", nextName(controller)); assertNull(nextName(controller)); // Run entire test again assertEquals("one", nextName(controller)); assertEquals("two", nextName(controller)); assertEquals("three", nextName(controller)); assertNull(nextName(controller)); } /* * Generic Controller * - before * - While Controller ${VAR} * - - one * - - two * - - Simple Controller * - - - three * - - - four * - after */ @Test public void testVariable1() throws Exception { GenericController controller = new GenericController(); WhileController while_cont = new WhileController(); setLastSampleStatus(false); while_cont.setCondition("${VAR}"); jmvars.put("VAR", ""); ValueReplacer vr = new ValueReplacer(); vr.replaceValues(while_cont); setRunning(while_cont); controller.addTestElement(new TestSampler("before")); controller.addTestElement(while_cont); while_cont.addTestElement(new TestSampler("one")); while_cont.addTestElement(new TestSampler("two")); GenericController simple = new GenericController(); while_cont.addTestElement(simple); simple.addTestElement(new TestSampler("three")); simple.addTestElement(new TestSampler("four")); controller.addTestElement(new TestSampler("after")); controller.initialize(); for (int i = 1; i <= 3; i++) { assertEquals("Loop: "+i,"before", nextName(controller)); assertEquals("Loop: "+i,"one", nextName(controller)); assertEquals("Loop: "+i,"two", nextName(controller)); assertEquals("Loop: "+i,"three", nextName(controller)); assertEquals("Loop: "+i,"four", nextName(controller)); assertEquals("Loop: "+i,"after", nextName(controller)); assertNull("Loop: "+i,nextName(controller)); } jmvars.put("VAR", "LAST"); // Should not enter the loop for (int i = 1; i <= 3; i++) { assertEquals("Loop: "+i,"before", nextName(controller)); assertEquals("Loop: "+i,"after", nextName(controller)); assertNull("Loop: "+i,nextName(controller)); } jmvars.put("VAR", ""); for (int i = 1; i <= 3; i++) { assertEquals("Loop: "+i,"before", nextName(controller)); if (i==1) { assertEquals("Loop: "+i,"one", nextName(controller)); assertEquals("Loop: "+i,"two", nextName(controller)); assertEquals("Loop: "+i,"three", nextName(controller)); jmvars.put("VAR", "LAST"); // Should not enter the loop next time assertEquals("Loop: "+i,"four", nextName(controller)); } assertEquals("Loop: "+i,"after", nextName(controller)); assertNull("Loop: "+i,nextName(controller)); } } // Test with SimpleController as first item @Test public void testVariable2() throws Exception { GenericController controller = new GenericController(); WhileController while_cont = new WhileController(); setLastSampleStatus(false); while_cont.setCondition("${VAR}"); jmvars.put("VAR", ""); ValueReplacer vr = new ValueReplacer(); vr.replaceValues(while_cont); setRunning(while_cont); controller.addTestElement(new TestSampler("before")); controller.addTestElement(while_cont); GenericController simple = new GenericController(); while_cont.addTestElement(simple); simple.addTestElement(new TestSampler("one")); simple.addTestElement(new TestSampler("two")); while_cont.addTestElement(new TestSampler("three")); while_cont.addTestElement(new TestSampler("four")); controller.addTestElement(new TestSampler("after")); controller.initialize(); for (int i = 1; i <= 3; i++) { assertEquals("Loop: "+i,"before", nextName(controller)); assertEquals("Loop: "+i,"one", nextName(controller)); assertEquals("Loop: "+i,"two", nextName(controller)); assertEquals("Loop: "+i,"three", nextName(controller)); assertEquals("Loop: "+i,"four", nextName(controller)); assertEquals("Loop: "+i,"after", nextName(controller)); assertNull("Loop: "+i,nextName(controller)); } jmvars.put("VAR", "LAST"); // Should not enter the loop for (int i = 1; i <= 3; i++) { assertEquals("Loop: "+i,"before", nextName(controller)); assertEquals("Loop: "+i,"after", nextName(controller)); assertNull("Loop: "+i,nextName(controller)); } jmvars.put("VAR", ""); for (int i = 1; i <= 3; i++) { assertEquals("Loop: "+i,"before", nextName(controller)); if (i==1){ assertEquals("Loop: "+i,"one", nextName(controller)); assertEquals("Loop: "+i,"two", nextName(controller)); jmvars.put("VAR", "LAST"); // Should not enter the loop next time // But should continue to the end of the loop assertEquals("Loop: "+i,"three", nextName(controller)); assertEquals("Loop: "+i,"four", nextName(controller)); } assertEquals("Loop: "+i,"after", nextName(controller)); assertNull("Loop: "+i,nextName(controller)); } } // While LAST, previous sample failed - should not run @Test public void testLASTPrevFailed() throws Exception { // log.info("testLastPrevFailed"); runTestPrevFailed("LAST"); } // While False, previous sample failed - should not run @Test public void testfalsePrevFailed() throws Exception { // log.info("testFalsePrevFailed"); runTestPrevFailed("False"); } private void runTestPrevFailed(String s) throws Exception { GenericController controller = new GenericController(); WhileController while_cont = new WhileController(); setLastSampleStatus(false); while_cont.setCondition(s); while_cont.addTestElement(new TestSampler("one")); while_cont.addTestElement(new TestSampler("two")); controller.addTestElement(while_cont); controller.addTestElement(new TestSampler("three")); controller.initialize(); assertEquals("three", nextName(controller)); assertNull(nextName(controller)); assertEquals("three", nextName(controller)); assertNull(nextName(controller)); } @Test public void testLastFailedBlank() throws Exception{ runTestLastFailed(""); } @Test public void testLastFailedLast() throws Exception{ runTestLastFailed("LAST"); } // Should behave the same for blank and LAST because success on input private void runTestLastFailed(String s) throws Exception { GenericController controller = new GenericController(); controller.addTestElement(new TestSampler("1")); WhileController while_cont = new WhileController(); controller.addTestElement(while_cont); while_cont.setCondition(s); GenericController sub = new GenericController(); while_cont.addTestElement(sub); sub.addTestElement(new TestSampler("2")); sub.addTestElement(new TestSampler("3")); controller.addTestElement(new TestSampler("4")); setLastSampleStatus(true); controller.initialize(); assertEquals("1", nextName(controller)); assertEquals("2", nextName(controller)); setLastSampleStatus(false); assertEquals("3", nextName(controller)); assertEquals("4", nextName(controller)); assertNull(nextName(controller)); } // Tests for Stack Overflow (bug 33954) @Test public void testAlwaysFailOK() throws Exception { runTestAlwaysFail(true); // Should be OK } @Test public void testAlwaysFailBAD() throws Exception { runTestAlwaysFail(false); } private void runTestAlwaysFail(boolean other) { LoopController controller = new LoopController(); controller.setContinueForever(true); controller.setLoops(-1); WhileController while_cont = new WhileController(); setLastSampleStatus(false); while_cont.setCondition("false"); while_cont.addTestElement(new TestSampler("one")); while_cont.addTestElement(new TestSampler("two")); controller.addTestElement(while_cont); if (other) { controller.addTestElement(new TestSampler("three")); } controller.initialize(); try { if (other) { assertEquals("three", nextName(controller)); } else { assertNull(nextName(controller)); } } catch (StackOverflowError e) { // e.printStackTrace(); fail(e.toString()); } } }