| /* |
| * (c) Copyright IBM Corp. 2000, 2001. |
| * All Rights Reserved. |
| */ |
| package org.eclipse.jdt.internal.junit.ui; |
| |
| import java.io.BufferedReader; |
| import java.io.IOException; |
| import java.io.InputStreamReader; |
| import java.io.PrintWriter; |
| import java.net.ServerSocket; |
| import java.net.Socket; |
| import java.net.SocketException; |
| |
| import org.eclipse.jdt.internal.junit.runner.ITestRunListener; |
| import org.eclipse.jdt.internal.junit.runner.MessageIds; |
| |
| /** |
| * The client side of the RemoteTestRunner. Handles the |
| * marshalling of th different messages. |
| */ |
| public class RemoteTestRunnerClient { |
| /** |
| * A listener that is informed about test events. |
| */ |
| private ITestRunListener fListener; |
| /** |
| * The server socket |
| */ |
| private ServerSocket fServerSocket; |
| private Socket fSocket; |
| private int fPort; |
| private PrintWriter fWriter; |
| private BufferedReader fBufferedReader; |
| |
| /** |
| * RemoteTestRunner is sending trace. |
| */ |
| private boolean fInReadTrace= false; |
| /** |
| * RemoteTestRunner is sending the rerun trace. |
| */ |
| private boolean fInReadRerunTrace= false; |
| /** |
| * The currently received failed message |
| */ |
| private boolean fInFailedMessage= false; |
| /** |
| * The failed test that is currently reported from the RemoteTestRunner |
| */ |
| private String fFailedTest; |
| /** |
| * The failed message that is currently reported from the RemoteTestRunner |
| */ |
| private String fFailedMessage; |
| /** |
| * The failed trace that is currently reported from the RemoteTestRunner |
| */ |
| private String fFailedTrace; |
| /** |
| * The failed trace of a reran test |
| */ |
| private String fFailedRerunTrace; |
| /** |
| * The kind of failure of the test that is currently reported as failed |
| */ |
| private int fFailureKind; |
| |
| private boolean fDebug= false; |
| |
| /** |
| * Reads the message stream from the RemoteTestRunner |
| */ |
| private class ServerConnection extends Thread { |
| int fPort; |
| |
| public ServerConnection(int port) { |
| super("ServerConnection"); |
| fPort= port; |
| } |
| |
| public void run() { |
| try { |
| if (fDebug) |
| System.out.println("Creating server socket "+fPort); |
| fServerSocket= new ServerSocket(fPort); |
| fSocket= fServerSocket.accept(); |
| fBufferedReader= new BufferedReader(new InputStreamReader(fSocket.getInputStream())); |
| fWriter= new PrintWriter(fSocket.getOutputStream(), true); |
| String message; |
| while(fBufferedReader != null && (message= readMessage(fBufferedReader)) != null) |
| receiveMessage(message); |
| } catch (SocketException e) { |
| fListener.testRunTerminated(); |
| } catch (IOException e) { |
| System.out.println(e); |
| // fall through |
| } |
| shutDown(); |
| } |
| } |
| |
| /** |
| * Start listening to a test run. Start a server connection that |
| * the RemoteTestRunner can connect to. |
| */ |
| public synchronized void startListening(ITestRunListener listener, int port) { |
| fListener= listener; |
| fPort= port; |
| ServerConnection connection= new ServerConnection(port); |
| connection.start(); |
| } |
| |
| /** |
| * Requests to stop the remote test run. |
| */ |
| public synchronized void stopTest() { |
| if (isRunning()) { |
| fWriter.println(MessageIds.TEST_STOP); |
| fWriter.flush(); |
| } |
| } |
| |
| /** |
| * Requests to rerun a test |
| */ |
| public synchronized void rerunTest(String className, String testName) { |
| if (isRunning()) { |
| fWriter.println(MessageIds.TEST_RERUN+className+" "+testName); |
| fWriter.flush(); |
| } |
| } |
| |
| private synchronized void shutDown() { |
| if (fDebug) |
| System.out.println("shutdown "+fPort); |
| |
| if (fWriter != null) { |
| fWriter.close(); |
| fWriter= null; |
| } |
| try { |
| if (fBufferedReader != null) { |
| fBufferedReader.close(); |
| fBufferedReader= null; |
| } |
| } catch(IOException e) { |
| } |
| try{ |
| if(fSocket != null) { |
| fSocket.close(); |
| fSocket= null; |
| } |
| } catch(IOException e) { |
| } |
| try{ |
| if(fServerSocket != null) { |
| fServerSocket.close(); |
| fServerSocket= null; |
| } |
| } catch(IOException e) { |
| } |
| } |
| |
| public boolean isRunning() { |
| return fSocket != null; |
| } |
| |
| private String readMessage(BufferedReader in) throws IOException { |
| return in.readLine(); |
| } |
| |
| private void receiveMessage(String message) { |
| if (message.startsWith(MessageIds.TRACE_START)) { |
| fInReadTrace= true; |
| fFailedTrace= ""; |
| return; |
| } |
| if (message.startsWith(MessageIds.TRACE_END)) { |
| fInReadTrace= false; |
| fListener.testFailed(fFailureKind, fFailedTest, fFailedTrace); |
| fFailedTrace= ""; |
| return; |
| } |
| if (fInReadTrace) { |
| fFailedTrace+= message + '\n'; |
| return; |
| } |
| |
| if (message.startsWith(MessageIds.RTRACE_START)) { |
| fInReadRerunTrace= true; |
| fFailedRerunTrace= ""; |
| return; |
| } |
| if (message.startsWith(MessageIds.RTRACE_END)) { |
| fInReadRerunTrace= false; |
| return; |
| } |
| if (fInReadRerunTrace) { |
| fFailedRerunTrace+= message + '\n'; |
| return; |
| } |
| |
| String arg= message.substring(MessageIds.MSG_HEADER_LENGTH); |
| if (message.startsWith(MessageIds.TEST_RUN_START)) { |
| int count= Integer.parseInt(arg); |
| fListener.testRunStarted(count); |
| return; |
| } |
| if (message.startsWith(MessageIds.TEST_START)) { |
| fListener.testStarted(arg); |
| return; |
| } |
| if (message.startsWith(MessageIds.TEST_END)) { |
| fListener.testEnded(arg); |
| return; |
| } |
| if (message.startsWith(MessageIds.TEST_ERROR)) { |
| fFailedTest= arg; |
| fFailureKind= ITestRunListener.STATUS_ERROR; |
| return; |
| } |
| if (message.startsWith(MessageIds.TEST_FAILED)) { |
| fFailedTest= arg; |
| fFailureKind= ITestRunListener.STATUS_FAILURE; |
| return; |
| } |
| if (message.startsWith(MessageIds.TEST_RUN_END)) { |
| long elapsedTime= Long.parseLong(arg); |
| fListener.testRunEnded(elapsedTime); |
| return; |
| } |
| if (message.startsWith(MessageIds.TEST_STOPPED)) { |
| long elapsedTime= Long.parseLong(arg); |
| fListener.testRunStopped(elapsedTime); |
| shutDown(); |
| return; |
| } |
| if (message.startsWith(MessageIds.TEST_TREE)) { |
| fListener.testTreeEntry(arg); |
| return; |
| } |
| if (message.startsWith(MessageIds.TEST_RERAN)) { |
| // format: className" "testName" "status |
| // status: FAILURE, ERROR, OK |
| int c= arg.indexOf(" "); |
| int t= arg.indexOf(" ", c+1); |
| String className= arg.substring(0, c); |
| String testName= arg.substring(c+1, t); |
| String status= arg.substring(t+1); |
| int statusCode= ITestRunListener.STATUS_OK; |
| if (status.equals("FAILURE")) |
| statusCode= ITestRunListener.STATUS_FAILURE; |
| else if (status.equals("ERROR")) |
| statusCode= ITestRunListener.STATUS_ERROR; |
| |
| String trace= ""; |
| if (statusCode != ITestRunListener.STATUS_OK) |
| trace= fFailedRerunTrace; // assumption a rerun trace was sent before |
| fListener.testReran(className, testName, statusCode, trace); |
| } |
| } |
| } |