Path: blob/master/test/functional/cmdline_options_tester/src/TestIterator.java
6004 views
/*******************************************************************************1* Copyright (c) 2004, 2018 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/2122import java.util.*;2324public class TestIterator {25private TestSuite _suite;2627private String _loopIndex;28private String _loopFrom;29private String _loopUntil;30private String _loopInc;3132private boolean _singleIterationOnly;33private boolean _loopIndexIncremented;3435private boolean _isInnerLoopOpen;36private ArrayList _subItems;3738/**39* This constructor creates a standard TestIterator object, which runs a given set of tests/variable assignments/etc.40* a number of times. The number of times that the stuff is run depends on the <code>from</code>, <code>until</code>,41* and <code>inc</code> parameters.42* The <code>index</code> variable is started at <code>from</code>, and incremented by <code>inc</code> after each43* iteration. Before each iteration is started, if <code>index</code> is equal to <code>until</code>, the run is44* terminated.45* The effect is the equivalent of <code>for (index = from; index != until; index += inc) { dostuff }</code>, where46* <code>dostuff</code> is determined by what is added to this TestIterator using the addXXX methods.47* The <code>from</code>, <code>until</code>, and <code>inc</code> strings may have variables in them, but after48* variable substitution, must evaluate to integers.49*/50TestIterator( TestSuite suite, String index, String from, String until, String inc ) {51_suite = suite;5253_loopIndex = index;54_loopFrom = from;55_loopUntil = until;56_loopInc = inc;5758_isInnerLoopOpen = false;59_subItems = new ArrayList();6061TestSuite.putVariable( _loopIndex, TestSuite.evaluateVariables( _loopFrom ) );62}6364/**65* This constructor creates a single-iteration version of this iterator. It will run everything passed66* to it (by the addXXX methods) exactly once.67*/68TestIterator( TestSuite suite ) {69_suite = suite;7071_singleIterationOnly = true;7273_isInnerLoopOpen = false;74_subItems = new ArrayList();75}7677void addTest( Test t ) {78if (_isInnerLoopOpen) {79getLastSubIterator().addTest( t );80} else {81_subItems.add( t );82if (canRunTest()) {83_suite.runTest( t );84}85}86}8788void addSubIterator( TestIterator it ) {89if (_isInnerLoopOpen) {90getLastSubIterator().addSubIterator( it );91} else {92_subItems.add( it );93_isInnerLoopOpen = true;94}95}9697void addCommand( Command c ) {98if (_isInnerLoopOpen) {99getLastSubIterator().addCommand( c );100} else {101_subItems.add( c );102c.executeSelf();103}104}105106boolean closeInnerLoop() {107if (_isInnerLoopOpen) {108if (getLastSubIterator().closeInnerLoop()) {109return true;110}111_isInnerLoopOpen = false;112return true;113}114// end of this TestIterator's corresponding <loop> element, so now we actually run the remaining115// iterations of the loop116incrementLoopIndex();117while (canRunTest()) {118runIteration();119}120return false;121}122123private void incrementLoopIndex() {124if (_singleIterationOnly) {125_loopIndexIncremented = true;126return;127}128129try {130int increment = (_loopInc == null ? 1 : Integer.parseInt( TestSuite.evaluateVariables( _loopInc ).trim() ));131String value = TestSuite.getVariable( _loopIndex );132value = Integer.toString( Integer.parseInt( value.trim() ) + increment );133TestSuite.putVariable( _loopIndex, value );134} catch (Exception e) {135notifyInfiniteLoop(e);136System.exit(1);137}138}139140private void runEntireLoop() {141TestSuite.putVariable( _loopIndex, TestSuite.evaluateVariables( _loopFrom ) );142while (canRunTest()) {143runIteration();144}145}146147private void runIteration() {148for (int i = 0; i < _subItems.size(); i++) {149Object o = _subItems.get(i);150if (o instanceof Test && canRunTest()) {151_suite.runTest( (Test)o );152} else if (o instanceof TestIterator) {153( (TestIterator)o ).runEntireLoop();154} else if (o instanceof Command) {155( (Command)o ).executeSelf();156}157}158incrementLoopIndex();159}160161private boolean canRunTest() {162if (_singleIterationOnly) {163return !_loopIndexIncremented;164}165try {166return ! (Integer.parseInt(TestSuite.getVariable(_loopIndex)) == Integer.parseInt(TestSuite.evaluateVariables(_loopUntil)));167} catch (Exception e) {168notifyInfiniteLoop(e);169System.exit(1);170}171return false; // dead code, to satisfy compiler only172}173174private TestIterator getLastSubIterator() {175return (TestIterator)_subItems.get( _subItems.size() - 1 );176}177178private void notifyInfiniteLoop( Exception e ) {179// if there is an exception here, it's an accidental infinite loop. tell user to fix!180System.err.println( "The test file passed to the cmdLineTester application contained an invalid loop" );181System.err.println( "of " + _loopIndex + " from " + _loopFrom + " until " + _loopUntil + ", with increment " + _loopInc + ". This loop" );182System.err.println( "contains an error that will get it stuck in an infinite cycle. Please fix it.. or" );183System.err.println( "modify the cmdLineTester application to deal with it, if it really is what you" );184System.err.println( "want to do. The cmdLineTester application will now terminate." );185e.printStackTrace();186}187}188189190