package com.redhat.ceylon.test.eclipse.plugin.model; import static com.redhat.ceylon.test.eclipse.plugin.model.TestElement.State.ERROR; import static com.redhat.ceylon.test.eclipse.plugin.model.TestElement.State.FAILURE; import static com.redhat.ceylon.test.eclipse.plugin.model.TestElement.State.SKIPPED_OR_ABORTED; import static com.redhat.ceylon.test.eclipse.plugin.model.TestElement.State.RUNNING; import static com.redhat.ceylon.test.eclipse.plugin.model.TestElement.State.SUCCESS; import static com.redhat.ceylon.test.eclipse.plugin.model.TestElement.State.UNDEFINED; import java.io.EOFException; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; import org.eclipse.debug.core.ILaunch; import com.redhat.ceylon.test.eclipse.plugin.CeylonTestPlugin; import net.minidev.json.JSONArray; import net.minidev.json.JSONObject; import net.minidev.json.JSONValue; public class TestEventListener { private final static byte EOT = 0x4; public static void startListenerThread(ILaunch launch, int port) { TestEventListenerThread thread = new TestEventListenerThread(launch, port); thread.start(); } private static class TestEventListenerThread extends Thread { private ILaunch launch; private int port; private ServerSocket serverSocket; private Socket socket; public TestEventListenerThread(ILaunch launch, int port) { super("TestEventListenerThread"); this.launch = launch; this.port = port; } public void run() { try { serverSocket = new ServerSocket(port); socket = serverSocket.accept(); InputStream is = socket.getInputStream(); InputStreamReader isr = new InputStreamReader(is, "UTF-8"); StringBuffer buf = new StringBuffer(128); int ch; boolean esc = false; while (true) { ch = isr.read(); if (ch == -1) { break; } if (ch == EOT && esc == false) { JSONObject json = (JSONObject) JSONValue.parse(buf.toString()); TestEventType eventType = parseTestEventType((String) json.get("event")); TestElement element = parseTestElement((JSONObject) json.get("element")); TestRunContainer testRunContainer = CeylonTestPlugin.getDefault().getModel(); TestRun testRun = testRunContainer.getOrCreateTestRun(launch); testRun.processRemoteTestEvent(eventType, element); buf.setLength(0); } else { if (ch == EOT && esc == true) { buf.setCharAt(buf.length() - 1, (char) ch); } else { buf.append((char) ch); } } esc = (ch == '\\'); } } catch (EOFException e) { // noop } catch (IOException e) { CeylonTestPlugin.logError("", e); } finally { dispose(); } } private TestEventType parseTestEventType(String event) { switch (event) { case "testRunStarted": return TestEventType.TEST_RUN_STARTED; case "testRunFinished": return TestEventType.TEST_RUN_FINISHED; case "testStarted": return TestEventType.TEST_STARTED; case "testFinished": case "testError": case "testSkipped": case "testAborted": return TestEventType.TEST_FINISHED; default: throw new IllegalArgumentException(event); } } private TestElement parseTestElement(JSONObject json) { TestElement e = null; if (json != null) { e = new TestElement(); e.setQualifiedName((String) json.get("name")); if( json.containsKey("variant") ) { e.setVariant((String)json.get("variant")); } if( json.containsKey("variantIndex") ) { Number variantIndex = (Number) json.get("variantIndex"); e.setVariantIndex(variantIndex.longValue()); } if (json.containsKey("state")) { String state = (String) json.get("state"); switch (state) { case "running": e.setState(RUNNING); break; case "success": e.setState(SUCCESS); break; case "failure": e.setState(FAILURE); break; case "error": e.setState(ERROR); break; case "skipped": e.setState(SKIPPED_OR_ABORTED); break; case "aborted": e.setState(SKIPPED_OR_ABORTED); break; default: e.setState(UNDEFINED); break; } } if (json.containsKey("children")) { JSONArray children = (JSONArray) json.get("children"); if (children != null) { List<TestElement> childrenList = new ArrayList<TestElement>(); for (Object child : children) { childrenList.add(parseTestElement((JSONObject) child)); } e.setChildren(childrenList); } } if (json.containsKey("elapsedTime")) { Number elapsedTime = (Number) json.get("elapsedTime"); e.setElapsedTimeInMilis(elapsedTime.longValue()); } if (json.containsKey("exception")) { e.setException((String) json.get("exception")); e.setExpectedValue((String) json.get("expectedValue")); e.setActualValue((String) json.get("actualValue")); } } return e; } private void dispose() { if (socket != null) { try { socket.close(); } catch (IOException e) { // noop } socket = null; } if (serverSocket != null) { try { serverSocket.close(); } catch (IOException e) { // noop } socket = null; } } } }