< prev index next >

tools/FxTestRunner/src/client/test/runner/TestScript.java

Print this page
rev 319 : 8160349: [TEST BUG] Hanged test blocks port and breaks following tests
Summary: Now each test uses random free port and test runner correctly handles interrupts from javatest.

@@ -47,10 +47,12 @@
 import java.lang.reflect.Method;
 import java.net.ServerSocket;
 import java.net.Socket;
 import java.net.URL;
 import java.net.UnknownHostException;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 import org.junit.runner.RunWith;
 import test.javaclient.shared.CanvasRunner;
 import test.javaclient.shared.Utils;

@@ -59,10 +61,11 @@
  *
  * @author shura, mrkam, Sergey Grinev, Victor Shubov
  */
 public class TestScript extends htmltestrunner.TestScript {
 
+    private static final int FORCED_TERMINATION_TIMEOUT = 5000;
     private static final boolean verbose = true; //TODO: use real logger
     private volatile Process process = null;
     private volatile ServerSocket cmdServer = null;
     private volatile Socket cmdSocket;
     private volatile ObjectOutputStream commandStream;

@@ -91,16 +94,16 @@
         System.out.println("Mode:" + runMode);
         System.out.println("Result Dir:" + resultDir);
         if (needToRun(testClassName, testName, runMode)) {
 
             try {
-                startServer();
+                int masterPort = startServer();
 
                 if (runMode.equals(BasicFXInterview.RUN_MODE_DESKTOP)
                         || runMode.equals(BasicFXInterview.RUN_MODE_DESKTOP_SWING_INTEROPERABILITY)
                         || runMode.equals(BasicFXInterview.RUN_MODE_DESKTOP_SWT_INTEROPERABILITY)) {
-                    runTd(description, resultDir);
+                    runTd(description, resultDir, masterPort);
                 } else {
                     runPlugin(td, resultDir, BasicFXInterview.RUN_MODE_JNLP.equals(runMode));
                 }
             } catch (Throwable e) {
                 e.printStackTrace(System.err);

@@ -130,10 +133,11 @@
                 }
                 commandStream.close();
                 interrupt(Status.error(e.toString()));
             }
 
+            Semaphore s = new Semaphore(0);
             resultThread = new Thread(new Runnable() {
                 @Override
                 public void run() {
                     try {
                         System.err.println("Waiting for exit");

@@ -189,14 +193,23 @@
 //                        }
 //
 //                        jemmyProcess.destroy();
 //                    }
                         System.out.println("DONE");
+                        s.release();
                     }
                 }
             }, "I'm waiting for test's result");
             resultThread.start();
+            try {
+                s.acquire();
+            } catch (InterruptedException ex) {
+                System.out.println("Interrupt from test runner: " + ex);
+                resultThread.interrupt();
+                process.destroyForcibly();
+                process.waitFor(FORCED_TERMINATION_TIMEOUT, TimeUnit.MILLISECONDS);
+            }            
         }
     }
 
     @Override
     protected void showTestDialog(TestDescription td, TestEnvironment env) {

@@ -285,11 +298,11 @@
      * @param resultDir
      * @return
      * @throws IOException
      * @throws Fault
      */
-    protected String[] tdCmdArgs(TestDescription td, String resultDir) throws IOException, Fault {
+    protected String[] tdCmdArgs(TestDescription td, String resultDir, int port) throws IOException, Fault {
         String testClassName = td.getParameter(RunUITestFinder.UNIT_TEST_CLASS_NAME);
 
         boolean isJunit = Boolean.parseBoolean(td.getParameter(RunUITestFinder.TYPE_JUNIT));
 
         //String fxSdkHome = td.getParameter(BasicFXInterview.FX_SDK_HOME_PARAM_NAME);

@@ -381,10 +394,11 @@
         command = addToArray(command, ipV4);
         command = addToArray(command, jvmArgPrismOrder, jvmArgLibraryPath, jvmArgImageUtils);
         command = addToArray(command, additionalOptions);
         command = addToArray(command, jvmArgNoDesc, jvmProxyHost, jvmProxyPort, jvmInterop, swtTestOpt);
         command = addToArray(command, jvmArgClientTestRoot);
+        command = addToArray(command, "-DmasterPort=" + port);        
         command = addToArray(command, "-classpath", System.getProperty("java.class.path"));
 //        command = addToArray(command, "-Xdebug", "-Xnoagent", "-Djava.compiler=NONE", "-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5858");
         command = addToArray(command, isJunit ? JUnit2TestRunner.class.getName() : TestRunner.class.getName(), testClassName);
         return command;
     }

@@ -406,31 +420,33 @@
      */
     protected void doRunTd(String[] command) throws IOException {
         process = Runtime.getRuntime().exec(deleteEmptyElements(command));
     }
 
-    private void startServer() throws IOException {
-        System.out.println("Starting server at " + CommonTestRunnerWorker.PORT);
+    private int startServer() throws IOException {
+        System.out.println("Starting server." );
         int iRetryCount = 3;
         boolean bindDone = false;
         while ( (iRetryCount > 0) && (false==bindDone) ) {
             iRetryCount = iRetryCount - 1;
             
             try {
-                cmdServer = new ServerSocket(CommonTestRunnerWorker.PORT);
+                cmdServer = new ServerSocket(0);
+                System.out.println("Started server at port " + cmdServer.getLocalPort());
                 bindDone = true;
             } catch (java.net.BindException be) {
                 bindDone = false;
                 System.out.println("  === bind exception ===");
-                Socket socket = new Socket( "127.0.0.1", CommonTestRunnerWorker.PORT);
+                Socket socket = new Socket("127.0.0.1", cmdServer.getLocalPort());
                 commandStream = new ObjectOutputStream(socket.getOutputStream());
                 sendCommand(CommandType.ABORT);
                 try {Thread.sleep(100);} catch(Exception e){}
             }
         
         }// retry loop end
         cmdServer.setSoTimeout(60000); // we need to be generous for plugin mode, it gets to "download" runnable
+        return cmdServer.getLocalPort();
     }
 
     private void waitForConnection() throws IOException {
         System.out.println("Waiting for connection...");
         cmdSocket = cmdServer.accept();

@@ -479,12 +495,12 @@
             ex.printStackTrace(System.err);
         }
         return result;
     }
 
-    private void runTd(TestDescription td, String resultDir) throws IOException, InterruptedException, Fault {
-        String[] command = tdCmdArgs(td, resultDir);
+    private void runTd(TestDescription td, String resultDir, int port) throws IOException, InterruptedException, Fault {
+        String[] command = tdCmdArgs(td, resultDir, port);
         dumpProcessExecution(resultDir, command, null);
         doRunTd(command);
         System.out.println("Logs: " + resultDir + File.separator);
 
         if (process != null) {

@@ -520,11 +536,12 @@
         writer.flush();
     }
     private static final String pluginPath = "./dist-plugin/";
     private static final String pluginFile = "JavaClientPluginTest";
 
-    private void runPlugin(TestDescription td, String resultDir, boolean isJnlp) throws IOException, Fault {
+    private void runPlugin(TestDescription td, String resultDir, boolean isJnlp)
+            throws IOException, Fault {
         String testClassName = td.getParameter(RunUITestFinder.UNIT_TEST_CLASS_NAME);
         String testName = td.getParameter(RunUITestFinder.TEST_NAME);
 
         //TODO: add non-junit tests support
         boolean isJunit = Boolean.parseBoolean(td.getParameter(RunUITestFinder.TYPE_JUNIT));
< prev index next >