jdk/test/sanity/client/lib/jemmy/src/org/netbeans/jemmy/Test.java
changeset 36744 a00905527ec2
equal deleted inserted replaced
36743:bdc3f1b79fb7 36744:a00905527ec2
       
     1 /*
       
     2  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 package org.netbeans.jemmy;
       
    24 
       
    25 import java.io.PrintStream;
       
    26 import java.io.PrintWriter;
       
    27 import java.lang.reflect.InvocationTargetException;
       
    28 
       
    29 /**
       
    30  *
       
    31  * Jemmy itself provides a way to create tests. Test should implement
       
    32  * org.netbeans.jemmy.Scenario interface.
       
    33  *
       
    34  * Test can be executed from command line:<BR>
       
    35  * {@code java [application options] [jemmy options] org.netbeans.jemmy.Test [full name of test class] [test args]}<BR>
       
    36  * Test elso can be executed by one of the run(...) methods or by <BR>
       
    37  * {@code new Test([test class name]).startTest([test args]);}<BR>
       
    38  *
       
    39  * <BR><BR>Timeouts used: <BR>
       
    40  * Test.WholeTestTimeout - time for the whole test<BR>
       
    41  *
       
    42  * @author Alexandre Iline (alexandre.iline@oracle.com)
       
    43  */
       
    44 public class Test extends ActionProducer<Object, Object>
       
    45         implements Timeoutable, Outputable, Scenario {
       
    46 
       
    47     private final static long WHOLE_TEST_TIMEOUT = 3600000;
       
    48 
       
    49     /**
       
    50      * Status returned by test if wrong parameter was passed.
       
    51      */
       
    52     public static int WRONG_PARAMETERS_STATUS = 101;
       
    53 
       
    54     /**
       
    55      * Status returned by test if exception appeared inside scenario.
       
    56      */
       
    57     public static int SCENARIO_EXCEPTION_STATUS = 102;
       
    58 
       
    59     /**
       
    60      * Positive test status.
       
    61      */
       
    62     public static int TEST_PASSED_STATUS = 0;
       
    63 
       
    64     /**
       
    65      * Test timeouts.
       
    66      */
       
    67     protected Timeouts timeouts;
       
    68 
       
    69     /**
       
    70      * Test output.
       
    71      */
       
    72     protected TestOut output;
       
    73 
       
    74     private Scenario scenario;
       
    75 
       
    76     /**
       
    77      * Constructor for tests requiring only a class instance. Creates a subclass
       
    78      * of {@code ActionProducer} and {@code java.lang.Thread} that
       
    79      * runs in a separate thread of execution and waits for execution to finish.
       
    80      * The current output stream assignments and timeouts are used.
       
    81      *
       
    82      * @param testClassName Full test class name
       
    83      */
       
    84     public Test(String testClassName) {
       
    85         super(true);
       
    86         setOutput(JemmyProperties.getCurrentOutput());
       
    87         setTimeouts(JemmyProperties.getCurrentTimeouts());
       
    88         scenario = testForName(testClassName);
       
    89     }
       
    90 
       
    91     /**
       
    92      * Constructor for scenarios that require an instance and might require an
       
    93      * argument. Creates a subclass of {@code ActionProducer} and
       
    94      * {@code java.lang.Thread} that runs in a separate thread of execution
       
    95      * and waits for execution to finish. The current output stream assignments
       
    96      * and timeouts are used.
       
    97      *
       
    98      * @param scenario a test scenario
       
    99      * @see org.netbeans.jemmy.Scenario
       
   100      */
       
   101     public Test(Scenario scenario) {
       
   102         super(true);
       
   103         setOutput(JemmyProperties.getCurrentOutput());
       
   104         setTimeouts(JemmyProperties.getCurrentTimeouts());
       
   105         this.scenario = scenario;
       
   106     }
       
   107 
       
   108     /**
       
   109      * No argument constructor. Used by subclasses of this {@code Test}
       
   110      * class. Creates a subclass of {@code ActionProducer} and
       
   111      * {@code java.lang.Thread} that runs in a separate thread of execution
       
   112      * and waits for execution to finish. The current output stream assignments
       
   113      * and timeouts are used.
       
   114      */
       
   115     protected Test() {
       
   116         super(true);
       
   117         setOutput(JemmyProperties.getCurrentOutput());
       
   118         setTimeouts(JemmyProperties.getCurrentTimeouts());
       
   119     }
       
   120 
       
   121     /**
       
   122      * Throws TestCompletedException exception. The exception thrown contains a
       
   123      * pass/fail status and a short status {@code java.lang.String}. Can by
       
   124      * invoked from test to abort test execution.
       
   125      *
       
   126      * @param status If 0 - test passed, otherwise failed.
       
   127      * @throws TestCompletedException all of the time.
       
   128      */
       
   129     public static void closeDown(int status) {
       
   130         if (status == 0) {
       
   131             throw (new TestCompletedException(status, "Test passed"));
       
   132         } else {
       
   133             throw (new TestCompletedException(status, "Test failed with status "
       
   134                     + Integer.toString(status)));
       
   135         }
       
   136     }
       
   137 
       
   138     /**
       
   139      * Executes a test.
       
   140      *
       
   141      * @param argv First element should be a test class name, all others - test
       
   142      * args.
       
   143      * @return test status.
       
   144      */
       
   145     public static int run(String[] argv) {
       
   146         String[] args = argv;
       
   147         JemmyProperties.getProperties().init();
       
   148         if (argv.length < 1) {
       
   149             JemmyProperties.getCurrentOutput().
       
   150                     printErrLine("First element of String array should be test classname");
       
   151             return WRONG_PARAMETERS_STATUS;
       
   152         }
       
   153         JemmyProperties.getCurrentOutput().printLine("Executed test " + argv[0]);
       
   154         Test test = new Test(argv[0]);
       
   155         if (argv.length >= 1) {
       
   156             args = shiftArray(args);
       
   157         }
       
   158         if (argv.length >= 2) {
       
   159             JemmyProperties.getCurrentOutput().printLine("Work directory: " + argv[1]);
       
   160             System.setProperty("user.dir", argv[1]);
       
   161             args = shiftArray(args);
       
   162         }
       
   163         int status;
       
   164         status = test.startTest(args);
       
   165         JemmyProperties.getCurrentOutput().flush();
       
   166         return status;
       
   167     }
       
   168 
       
   169     /**
       
   170      * Executes a test.
       
   171      *
       
   172      * @param argv First element should be a test class name, all others - test
       
   173      * args.
       
   174      * @param output Stream to put test output and errput into.
       
   175      * @return test status.
       
   176      */
       
   177     public static int run(String[] argv, PrintStream output) {
       
   178         JemmyProperties.setCurrentOutput(new TestOut(System.in, output, output));
       
   179         return run(argv);
       
   180     }
       
   181 
       
   182     /**
       
   183      * Executes a test.
       
   184      *
       
   185      * @param argv First element should be a test class name, all others - test
       
   186      * args.
       
   187      * @param output Stream to put test output into.
       
   188      * @param errput Stream to put test errput into.
       
   189      * @return test status.
       
   190      */
       
   191     public static int run(String[] argv, PrintStream output, PrintStream errput) {
       
   192         JemmyProperties.setCurrentOutput(new TestOut(System.in, output, errput));
       
   193         return run(argv);
       
   194     }
       
   195 
       
   196     /**
       
   197      * Executes a test.
       
   198      *
       
   199      * @param argv First element should be a test class name, all others - test
       
   200      * args.
       
   201      * @param output Writer to put test output and errput into.
       
   202      * @return test status.
       
   203      */
       
   204     public static int run(String[] argv, PrintWriter output) {
       
   205         JemmyProperties.setCurrentOutput(new TestOut(System.in, output, output));
       
   206         return run(argv);
       
   207     }
       
   208 
       
   209     /**
       
   210      * Executes a test.
       
   211      *
       
   212      * @param argv First element should be a test class name, all others - test
       
   213      * args.
       
   214      * @param output Writer to put test output into.
       
   215      * @param errput Writer to put test errput into.
       
   216      * @return test status.
       
   217      */
       
   218     public static int run(String[] argv, PrintWriter output, PrintWriter errput) {
       
   219         JemmyProperties.setCurrentOutput(new TestOut(System.in, output, errput));
       
   220         return run(argv);
       
   221     }
       
   222 
       
   223     /**
       
   224      * Invoke this {@code Test}. The call might be directly from the
       
   225      * command line.
       
   226      *
       
   227      * @param argv First element should be a test class name, all others - test
       
   228      * args.
       
   229      */
       
   230     public static void main(String[] argv) {
       
   231         System.exit(run(argv, System.out));
       
   232     }
       
   233 
       
   234     static {
       
   235         Timeouts.initDefault("Test.WholeTestTimeout", WHOLE_TEST_TIMEOUT);
       
   236     }
       
   237 
       
   238     /**
       
   239      * Creates an instance of a class named by the parameter.
       
   240      *
       
   241      * @param testName Full test class name
       
   242      * @return an instance of the test {@code Scenario} to launch.
       
   243      * @see org.netbeans.jemmy.Scenario
       
   244      */
       
   245     public Scenario testForName(String testName) {
       
   246         try {
       
   247             return ((Scenario) (Class.forName(testName).
       
   248                     getConstructor(new Class<?>[0]).
       
   249                     newInstance()));
       
   250         } catch (ClassNotFoundException e) {
       
   251             output.printErrLine("Class " + testName + " does not exist!");
       
   252             output.printStackTrace(e);
       
   253         } catch (NoSuchMethodException e) {
       
   254             output.printErrLine("Class " + testName + " has not constructor!");
       
   255             output.printStackTrace(e);
       
   256         } catch (InvocationTargetException e) {
       
   257             output.printErrLine("Exception inside " + testName + " constructor:");
       
   258             output.printStackTrace(e.getTargetException());
       
   259         } catch (IllegalAccessException e) {
       
   260             output.printErrLine("Cannot access to " + testName + " constructor!");
       
   261             output.printStackTrace(e);
       
   262         } catch (InstantiationException e) {
       
   263             output.printErrLine("Cannot instantiate " + testName + " class!");
       
   264             output.printStackTrace(e);
       
   265         }
       
   266         return null;
       
   267     }
       
   268 
       
   269     /**
       
   270      * Set the timeouts used by this {@code Test}.
       
   271      *
       
   272      * @param timeouts A collection of timeout assignments.
       
   273      * @see org.netbeans.jemmy.Timeoutable
       
   274      * @see org.netbeans.jemmy.Timeouts
       
   275      * @see #getTimeouts
       
   276      */
       
   277     @Override
       
   278     public void setTimeouts(Timeouts timeouts) {
       
   279         this.timeouts = timeouts;
       
   280         Timeouts times = timeouts.cloneThis();
       
   281         times.setTimeout("ActionProducer.MaxActionTime",
       
   282                 timeouts.getTimeout("Test.WholeTestTimeout"));
       
   283         super.setTimeouts(times);
       
   284     }
       
   285 
       
   286     /**
       
   287      * Get the timeouts used by this {@code Test}.
       
   288      *
       
   289      * @see org.netbeans.jemmy.Timeoutable
       
   290      * @see org.netbeans.jemmy.Timeouts
       
   291      * @see #setTimeouts
       
   292      */
       
   293     @Override
       
   294     public Timeouts getTimeouts() {
       
   295         return timeouts;
       
   296     }
       
   297 
       
   298     /**
       
   299      * Set the streams or writers used for print output.
       
   300      *
       
   301      * @param out An object used to identify both output and error print
       
   302      * streams.
       
   303      * @see org.netbeans.jemmy.Outputable
       
   304      * @see org.netbeans.jemmy.TestOut
       
   305      * @see #getOutput
       
   306      */
       
   307     @Override
       
   308     public void setOutput(TestOut out) {
       
   309         output = out;
       
   310         super.setOutput(out);
       
   311     }
       
   312 
       
   313     /**
       
   314      * Get the streams or writers used for print output.
       
   315      *
       
   316      * @return an object containing references to both output and error print
       
   317      * streams.
       
   318      * @see org.netbeans.jemmy.Outputable
       
   319      * @see org.netbeans.jemmy.TestOut
       
   320      * @see #setOutput
       
   321      */
       
   322     @Override
       
   323     public TestOut getOutput() {
       
   324         return output;
       
   325     }
       
   326 
       
   327     /**
       
   328      * Executes test.
       
   329      *
       
   330      * @param param Object to be passed into this test's launch(Object) method.
       
   331      * @return test status.
       
   332      */
       
   333     public int startTest(Object param) {
       
   334         if (scenario != null) {
       
   335             output.printLine("Test " + scenario.getClass().getName()
       
   336                     + " has been started");
       
   337         } else {
       
   338             output.printLine("Test " + getClass().getName()
       
   339                     + " has been started");
       
   340         }
       
   341         try {
       
   342             return ((Integer) produceAction(param, "Test.WholeTestTimeout")).intValue();
       
   343         } catch (InterruptedException e) {
       
   344             output.printErrLine("Test was interrupted.");
       
   345             output.printStackTrace(e);
       
   346         } catch (TimeoutExpiredException e) {
       
   347             output.printErrLine("Test was not finished in "
       
   348                     + Long.toString(timeouts.getTimeout("Test.WholeTestTimeout"))
       
   349                     + " milliseconds");
       
   350             output.printStackTrace(e);
       
   351         } catch (Exception e) {
       
   352             output.printStackTrace(e);
       
   353         }
       
   354         return 1;
       
   355     }
       
   356 
       
   357     /**
       
   358      * Launch an action. Pass arguments to and execute a test
       
   359      * {@code Scenario}.
       
   360      *
       
   361      * @param obj An argument object that controls test execution. This might be
       
   362      * a {@code java.lang.String[]} containing command line arguments.
       
   363      * @see org.netbeans.jemmy.Action
       
   364      * @return an Integer containing test status.
       
   365      */
       
   366     @Override
       
   367     public final Object launch(Object obj) {
       
   368         setTimeouts(timeouts);
       
   369         try {
       
   370             if (scenario != null) {
       
   371                 closeDown(scenario.runIt(obj));
       
   372             } else {
       
   373                 closeDown(runIt(obj));
       
   374             }
       
   375         } catch (TestCompletedException e) {
       
   376             output.printStackTrace(e);
       
   377             return e.getStatus();
       
   378         } catch (Throwable e) {
       
   379             output.printStackTrace(e);
       
   380             return SCENARIO_EXCEPTION_STATUS;
       
   381         }
       
   382         return TEST_PASSED_STATUS;
       
   383     }
       
   384 
       
   385     /**
       
   386      * Supposed to be overridden to print a synopsys into test output.
       
   387      */
       
   388     public void printSynopsis() {
       
   389         output.printLine("Here should be a test synopsis.");
       
   390     }
       
   391 
       
   392     /**
       
   393      * @see org.netbeans.jemmy.Action
       
   394      */
       
   395     @Override
       
   396     public final String getDescription() {
       
   397         return "Test " + scenario.getClass().getName() + " finished";
       
   398     }
       
   399 
       
   400     @Override
       
   401     public String toString() {
       
   402         return "Test{" + "scenario=" + scenario + '}';
       
   403     }
       
   404 
       
   405     /**
       
   406      * Defines a way to execute this {@code Test}.
       
   407      *
       
   408      * @param param An object passed to configure the test scenario execution.
       
   409      * For example, this parameter might be a      <code>java.lang.String[]<code> object that lists the
       
   410      * command line arguments to the Java application corresponding
       
   411      * to a test.
       
   412      * @return an int that tells something about the execution. For, example, a
       
   413      * status code.
       
   414      * @see org.netbeans.jemmy.Scenario
       
   415      */
       
   416     @Override
       
   417     public int runIt(Object param) {
       
   418         return 0;
       
   419     }
       
   420 
       
   421     /**
       
   422      * Sleeps.
       
   423      *
       
   424      * @param time The sleep time in milliseconds.
       
   425      */
       
   426     protected void doSleep(long time) {
       
   427         try {
       
   428             Thread.sleep(time);
       
   429         } catch (InterruptedException e) {
       
   430         }
       
   431     }
       
   432 
       
   433     private static String[] shiftArray(String[] orig) {
       
   434         String[] result = new String[orig.length - 1];
       
   435         for (int i = 0; i < result.length; i++) {
       
   436             result[i] = orig[i + 1];
       
   437         }
       
   438         return result;
       
   439     }
       
   440 
       
   441 }