From: Niki Roo Date: Mon, 27 Nov 2017 21:44:35 +0000 (+0100) Subject: jDoc, tests, Server fixes X-Git-Url: https://git.nikiroo.be/?a=commitdiff_plain;h=f157aed840bdd5b8ef04902d2326d916f71139da;p=fanfix-jexer.git jDoc, tests, Server fixes --- diff --git a/changelog.md b/changelog.md index ab1be9e..34046e8 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,11 @@ # nikiroo-utils +## Version WIP + +- jDoc +- Fix bugs in Server (it was not possible to send objects back to client) +- Improve code in Server (including tests) + ## Version 2.2.3 - Fix in readSmallStream diff --git a/src/be/nikiroo/utils/TraceHandler.java b/src/be/nikiroo/utils/TraceHandler.java index d7f6046..309e8af 100644 --- a/src/be/nikiroo/utils/TraceHandler.java +++ b/src/be/nikiroo/utils/TraceHandler.java @@ -67,7 +67,7 @@ public class TraceHandler { /** * A trace happened, show it. *

- * Will only be effective if {@link TraceHandler#isShowTraces()} is true. + * Will only be effective if {@link TraceHandler#showTraces} is true. * * @param message * the trace message @@ -77,4 +77,28 @@ public class TraceHandler { System.out.println(message); } } + + // old stuff: + + /** + * Use the parameters in the constructor instead. + * + * @param showTraces + * show the traces + */ + @Deprecated + public void setShowTraces(boolean showTraces) { + this.showTraces = showTraces; + } + + /** + * Use the parameters in the constructor instead. + * + * @param showErrorDetails + * show the details on errors + */ + @Deprecated + public void setShowErrorDetails(boolean showErrorDetails) { + this.showErrorDetails = showErrorDetails; + } } diff --git a/src/be/nikiroo/utils/serial/ConnectAction.java b/src/be/nikiroo/utils/serial/ConnectAction.java index 2a25c5b..dfc1a2b 100644 --- a/src/be/nikiroo/utils/serial/ConnectAction.java +++ b/src/be/nikiroo/utils/serial/ConnectAction.java @@ -8,20 +8,71 @@ import java.net.Socket; import be.nikiroo.utils.Version; +/** + * Base class used for the client/server basic handling. + *

+ * It represents a single action: a client is expected to only execute one + * action, while a server is expected to execute one action for each client + * action. + * + * @author niki + */ abstract class ConnectAction { private Socket s; private boolean server; private Version version; + private Version clientVersion; private Object lock = new Object(); private BufferedReader in; private OutputStreamWriter out; private boolean contentToSend; - // serverVersion = null on server (or bad clients) - abstract public void action(Version serverVersion) throws Exception; + /** + * Method that will be called when an action is performed on either the + * client or server this {@link ConnectAction} represent. + * + * @param version + * the counter part version + * + * @throws Exception + * in case of I/O error + */ + abstract protected void action(Version version) throws Exception; + + /** + * Method called when we negotiate the version with the client. + *

+ * Thus, it is only called on the server. + *

+ * Will return the actual server version by default. + * + * @param clientVersion + * the client version + * + * @return the version to send to the client + */ + abstract protected Version negotiateVersion(Version clientVersion); + + /** + * Handler called when an unexpected error occurs in the code. + * + * @param e + * the exception that occurred + */ + abstract protected void onError(Exception e); - // server = version NULL + /** + * Create a new {@link ConnectAction}. + * + * @param s + * the socket to bind to + * @param server + * TRUE for a server action, FALSE for a client action (will + * impact the process) + * @param version + * the version of this client-or-server + */ protected ConnectAction(Socket s, boolean server, Version version) { this.s = s; this.server = server; @@ -31,18 +82,22 @@ abstract class ConnectAction { } else { this.version = version; } + + clientVersion = new Version(); } - public void connectAsync() { - new Thread(new Runnable() { - @Override - public void run() { - connect(); - } - }).start(); + /** + * The version of this client-or-server. + * + * @return the version + */ + public Version getVersion() { + return version; } - // connect, do the action (sync) + /** + * Actually start the process (this is synchronous). + */ public void connect() { try { in = new BufferedReader(new InputStreamReader(s.getInputStream(), @@ -51,7 +106,7 @@ abstract class ConnectAction { out = new OutputStreamWriter(s.getOutputStream(), "UTF-8"); try { if (server) { - action(version); + action(clientVersion); } else { String v = sendString("VERSION " + version.toString()); if (v != null && v.startsWith("VERSION ")) { @@ -77,9 +132,30 @@ abstract class ConnectAction { } } - // (also, server never get anything) - public Object send(Object data) throws IOException, NoSuchFieldException, - NoSuchMethodException, ClassNotFoundException { + /** + * Serialise and send the given object to the counter part (and, only for + * client, return the deserialised answer -- the server will always receive + * NULL). + * + * @param data + * the data to send + * + * @return the answer (which can be NULL) if this action is a client, always + * NULL if it is a server + * + * @throws IOException + * in case of I/O error + * @throws NoSuchFieldException + * if the serialised data contains information about a field + * which does actually not exist in the class we know of + * @throws NoSuchMethodException + * if a class described in the serialised data cannot be created + * because it is not compatible with this code + * @throws ClassNotFoundException + * if a class described in the serialised data cannot be found + */ + protected Object send(Object data) throws IOException, + NoSuchFieldException, NoSuchMethodException, ClassNotFoundException { synchronized (lock) { String rep = sendString(new Exporter().append(data).toString(true)); if (rep != null) { @@ -90,37 +166,55 @@ abstract class ConnectAction { } } - public Object flush() throws NoSuchFieldException, NoSuchMethodException, - ClassNotFoundException, IOException, java.lang.NullPointerException { + /** + * Reserved for the server: flush the data to the client and retrieve its + * answer. + *

+ * Also used internally for the client (only do something if there is + * contentToSend). + *

+ * Will only flush the data if there is contentToSend. + * + * @return the deserialised answer (which can actually be NULL) + * + * @throws IOException + * in case of I/O error + * @throws NoSuchFieldException + * if the serialised data contains information about a field + * which does actually not exist in the class we know of + * @throws NoSuchMethodException + * if a class described in the serialised data cannot be created + * because it is not compatible with this code + * @throws ClassNotFoundException + * if a class described in the serialised data cannot be found + * @throws java.lang.NullPointerException + * if the counter part has no data to send + */ + protected Object rec() throws IOException, NoSuchFieldException, + NoSuchMethodException, ClassNotFoundException, + java.lang.NullPointerException { String str = flushString(); if (str == null) { - throw new NullPointerException("No more data from client"); + throw new NullPointerException("No more data available"); } return new Importer().read(str).getValue(); } /** - * Handler called when the client {@link Version} is received. + * Send the given string to the counter part (and, only for client, return + * the answer -- the server will always receive NULL). * - * @param clientVersion - * the client {@link Version} - */ - protected void onClientVersionReceived( - @SuppressWarnings("unused") Version clientVersion) { - } - - /** - * Handler called when an unexpected error occurs in the code. + * @param line + * the data to send (we will add a line feed) * - * @param e - * the exception that occurred + * @return the answer if this action is a client (without the added line + * feed), NULL if it is a server + * + * @throws IOException + * in case of I/O error */ - protected void onError(@SuppressWarnings("unused") Exception e) { - } - - // \n included in line, but not in rep (also, server never get anything) - private String sendString(String line) throws IOException { + protected String sendString(String line) throws IOException { synchronized (lock) { out.write(line); out.write("\n"); @@ -135,8 +229,21 @@ abstract class ConnectAction { } } - // server can receive something even without pending content - private String flushString() throws IOException { + /** + * Reserved for the server (externally): flush the data to the client and + * retrieve its answer. + *

+ * Also used internally for the client (only do something if there is + * contentToSend). + *

+ * Will only flush the data if there is contentToSend. + * + * @return the answer (which can be NULL) + * + * @throws IOException + * in case of I/O error + */ + protected String flushString() throws IOException { synchronized (lock) { if (server || contentToSend) { if (contentToSend) { @@ -149,8 +256,12 @@ abstract class ConnectAction { // "VERSION client-version" (VERSION 1.0.0) Version clientVersion = new Version( line.substring("VERSION ".length())); - onClientVersionReceived(clientVersion); - sendString("VERSION " + version.toString()); + this.clientVersion = clientVersion; + Version v = negotiateVersion(clientVersion); + if (v == null) { + v = new Version(); + } + sendString("VERSION " + v.toString()); line = in.readLine(); } diff --git a/src/be/nikiroo/utils/serial/ConnectActionClient.java b/src/be/nikiroo/utils/serial/ConnectActionClient.java index 5b98202..8353702 100644 --- a/src/be/nikiroo/utils/serial/ConnectActionClient.java +++ b/src/be/nikiroo/utils/serial/ConnectActionClient.java @@ -5,27 +5,181 @@ import java.net.Socket; import be.nikiroo.utils.Version; -public class ConnectActionClient extends ConnectAction { - protected ConnectActionClient(Socket s) { - super(s, false, Version.getCurrentVersion()); - } +/** + * Base class used for the client basic handling. + *

+ * It represents a single action: a client is expected to only execute one + * action. + * + * @author niki + */ +public class ConnectActionClient { + private ConnectAction action; - protected ConnectActionClient(Socket s, Version version) { - super(s, false, version); + /** + * Create a new {@link ConnectActionClient} with the current application + * version (see {@link Version#getCurrentVersion()}) as the client version. + * + * @param s + * the socket to bind to + */ + public ConnectActionClient(Socket s) { + this(s, Version.getCurrentVersion()); } - protected ConnectActionClient(String host, int port, boolean ssl) + /** + * Create a new {@link ConnectActionClient} with the current application + * version (see {@link Version#getCurrentVersion()}) as the client version. + * + * @param host + * the host to bind to + * @param port + * the port to bind to + * @param ssl + * TRUE for an SSL connection, FALSE for plain text + * + * @throws IOException + * in case of I/O error when creating the socket + */ + public ConnectActionClient(String host, int port, boolean ssl) throws IOException { - super(Server.createSocket(host, port, ssl), false, Version - .getCurrentVersion()); + this(Server.createSocket(host, port, ssl), Version.getCurrentVersion()); } - protected ConnectActionClient(String host, int port, boolean ssl, + /** + * Create a new {@link ConnectActionClient}. + * + * @param host + * the host to bind to + * @param port + * the port to bind to + * @param ssl + * TRUE for an SSL connection, FALSE for plain text + * @param version + * the client version + * + * @throws IOException + * in case of I/O error when creating the socket + */ + public ConnectActionClient(String host, int port, boolean ssl, Version version) throws IOException { - super(Server.createSocket(host, port, ssl), false, version); + this(Server.createSocket(host, port, ssl), version); + } + + /** + * Create a new {@link ConnectActionClient}. + * + * @param s + * the socket to bind to + * @param version + * the client version + */ + public ConnectActionClient(Socket s, Version version) { + action = new ConnectAction(s, false, version) { + @Override + protected void action(Version serverVersion) throws Exception { + ConnectActionClient.this.action(serverVersion); + } + + @Override + protected void onError(Exception e) { + ConnectActionClient.this.onError(e); + } + + @Override + protected Version negotiateVersion(Version clientVersion) { + new Exception("Should never be called on a client") + .printStackTrace(); + return null; + } + }; + } + + /** + * Actually start the process and call the action (synchronous). + */ + public void connect() { + action.connect(); + } + + /** + * Actually start the process and call the action (asynchronous). + */ + public void connectAsync() { + new Thread(new Runnable() { + @Override + public void run() { + connect(); + } + }).start(); } - @Override + /** + * Method that will be called when an action is performed on the client. + * + * @param serverVersion + * the server version + * + * @throws Exception + * in case of I/O error + */ + @SuppressWarnings("unused") public void action(Version serverVersion) throws Exception { } + + /** + * Serialise and send the given object to the server (and return the + * deserialised answer). + * + * @param data + * the data to send + * + * @return the answer, which can be NULL + * + * @throws IOException + * in case of I/O error + * @throws NoSuchFieldException + * if the serialised data contains information about a field + * which does actually not exist in the class we know of + * @throws NoSuchMethodException + * if a class described in the serialised data cannot be created + * because it is not compatible with this code + * @throws ClassNotFoundException + * if a class described in the serialised data cannot be found + */ + public Object send(Object data) throws IOException, NoSuchFieldException, + NoSuchMethodException, ClassNotFoundException { + return action.send(data); + } + + /** + * Handler called when an unexpected error occurs in the code. + *

+ * Will just ignore the error by default. + * + * @param e + * the exception that occurred + */ + protected void onError(@SuppressWarnings("unused") Exception e) { + } + + // old stuff: + + /** + * Do not use. Will never be called. + */ + @SuppressWarnings({ "unused", "javadoc" }) + @Deprecated + protected void onClientVersionReceived(Version clientVersion) { + } + + /** + * Do not use, it is not supposed to be called from the outside. + */ + @SuppressWarnings({ "unused", "javadoc" }) + @Deprecated + public Object flush() throws NoSuchFieldException, NoSuchMethodException, + ClassNotFoundException, IOException, java.lang.NullPointerException { + return null; + } } \ No newline at end of file diff --git a/src/be/nikiroo/utils/serial/ConnectActionServer.java b/src/be/nikiroo/utils/serial/ConnectActionServer.java index 7c04065..2d85c79 100644 --- a/src/be/nikiroo/utils/serial/ConnectActionServer.java +++ b/src/be/nikiroo/utils/serial/ConnectActionServer.java @@ -1,19 +1,180 @@ package be.nikiroo.utils.serial; +import java.io.IOException; import java.net.Socket; import be.nikiroo.utils.Version; -public class ConnectActionServer extends ConnectAction { - protected ConnectActionServer(Socket s) { - super(s, true, Version.getCurrentVersion()); +/** + * Base class used for the server basic handling. + *

+ * It represents a single action: a server is expected to execute one action for + * each client action. + * + * @author niki + */ +public class ConnectActionServer { + private ConnectAction action; + + /** + * Create a new {@link ConnectActionServer} with the current application + * version (see {@link Version#getCurrentVersion()}) as the server version. + * + * @param s + * the socket to bind to + */ + public ConnectActionServer(Socket s) { + this(s, Version.getCurrentVersion()); + } + + /** + * Create a new {@link ConnectActionServer}. + * + * @param s + * the socket to bind to + * @param version + * the server version + */ + public ConnectActionServer(Socket s, Version version) { + action = new ConnectAction(s, true, version) { + @Override + protected void action(Version clientVersion) throws Exception { + ConnectActionServer.this.action(clientVersion); + } + + @Override + protected void onError(Exception e) { + ConnectActionServer.this.onError(e); + } + + @Override + protected Version negotiateVersion(Version clientVersion) { + return ConnectActionServer.this.negotiateVersion(clientVersion); + } + }; + } + + /** + * Actually start the process and call the action (synchronous). + */ + public void connect() { + action.connect(); + } + + /** + * Actually start the process and call the action (asynchronous). + */ + public void connectAsync() { + new Thread(new Runnable() { + @Override + public void run() { + connect(); + } + }).start(); + } + + /** + * Method that will be called when an action is performed on the server. + * + * @param clientVersion + * the client version + * + * @throws Exception + * in case of I/O error + */ + @SuppressWarnings("unused") + public void action(Version clientVersion) throws Exception { + } + + /** + * Serialise and send the given object to the client. + * + * @param data + * the data to send + * + * @throws IOException + * in case of I/O error + * @throws NoSuchFieldException + * if the serialised data contains information about a field + * which does actually not exist in the class we know of + * @throws NoSuchMethodException + * if a class described in the serialised data cannot be created + * because it is not compatible with this code + * @throws ClassNotFoundException + * if a class described in the serialised data cannot be found + */ + public void send(Object data) throws IOException, NoSuchFieldException, + NoSuchMethodException, ClassNotFoundException { + action.send(data); + } + + /** + * (Flush the data to the client if needed and) retrieve its answer. + * + * @return the deserialised answer (which can actually be NULL) + * + * @throws IOException + * in case of I/O error + * @throws NoSuchFieldException + * if the serialised data contains information about a field + * which does actually not exist in the class we know of + * @throws NoSuchMethodException + * if a class described in the serialised data cannot be created + * because it is not compatible with this code + * @throws ClassNotFoundException + * if a class described in the serialised data cannot be found + * @throws java.lang.NullPointerException + * if the counter part has no data to send + */ + public Object rec() throws NoSuchFieldException, NoSuchMethodException, + ClassNotFoundException, IOException, java.lang.NullPointerException { + return action.rec(); } - protected ConnectActionServer(Socket s, Version version) { - super(s, true, version); + /** + * Handler called when an unexpected error occurs in the code. + *

+ * Will just ignore the error by default. + * + * @param e + * the exception that occurred + */ + protected void onError(@SuppressWarnings("unused") Exception e) { + } + + /** + * Method called when we negotiate the version with the client. + *

+ * Will return the actual server version by default. + * + * @param clientVersion + * the client version + * + * @return the version to send to the client + */ + protected Version negotiateVersion( + @SuppressWarnings("unused") Version clientVersion) { + return action.getVersion(); + } + + // old stuff: + + /** + * Not used anymore. See {@link ConnectActionServer#rec()}. + */ + @SuppressWarnings("javadoc") + @Deprecated + public Object flush() throws NoSuchFieldException, NoSuchMethodException, + ClassNotFoundException, IOException, java.lang.NullPointerException { + return rec(); } - @Override - public void action(Version serverVersion) throws Exception { + /** + * Not used anymore. See + * {@link ConnectActionServer#negotiateVersion(Version)}. + */ + @SuppressWarnings({ "unused", "javadoc" }) + @Deprecated + protected void onClientVersionReceived(Version clientVersion) { } } \ No newline at end of file diff --git a/src/be/nikiroo/utils/serial/Exporter.java b/src/be/nikiroo/utils/serial/Exporter.java index 8b522e9..9093988 100644 --- a/src/be/nikiroo/utils/serial/Exporter.java +++ b/src/be/nikiroo/utils/serial/Exporter.java @@ -18,22 +18,52 @@ public class Exporter { private Map map; private StringBuilder builder; + /** + * Create a new {@link Exporter}. + */ public Exporter() { map = new HashMap(); builder = new StringBuilder(); } + /** + * Serialise the given object and add it to the list. + *

+ * Important: If the operation fails (with a + * {@link NotSerializableException}), the {@link Exporter} will be corrupted + * (will contain bad, most probably not importable data). + * + * @param o + * the object to serialise + * @return this (for easier appending of multiple values) + * + * @throws NotSerializableException + * if the object cannot be serialised (in this case, the + * {@link Exporter} can contain bad, most probably not + * importable data) + */ public Exporter append(Object o) throws NotSerializableException { SerialUtils.append(builder, o, map); return this; } + /** + * Clear the current content. + */ public void clear() { builder.setLength(0); map.clear(); } - // null = auto + /** + * The exported items in a serialised form. + * + * @param zip + * TRUE to have zipped content, FALSE to have raw content, NULL + * to let the system decide + * + * @return the items currently in this {@link Exporter} + */ public String toString(Boolean zip) { if (zip == null) { zip = builder.length() > 128; @@ -47,9 +77,9 @@ public class Exporter { } /** - * The exported items in a serialised form. + * The exported items in a serialised form (possibly zipped). * - * @return the items currently in this {@link Exporter}. + * @return the items currently in this {@link Exporter} */ @Override public String toString() { diff --git a/src/be/nikiroo/utils/serial/Importer.java b/src/be/nikiroo/utils/serial/Importer.java index d21f1dd..a159dde 100644 --- a/src/be/nikiroo/utils/serial/Importer.java +++ b/src/be/nikiroo/utils/serial/Importer.java @@ -26,6 +26,9 @@ public class Importer { private String currentFieldName; + /** + * Create a new {@link Importer}. + */ public Importer() { map = new HashMap(); map.put("NULL", null); diff --git a/src/be/nikiroo/utils/serial/Server.java b/src/be/nikiroo/utils/serial/Server.java index e15680e..f2a01c5 100644 --- a/src/be/nikiroo/utils/serial/Server.java +++ b/src/be/nikiroo/utils/serial/Server.java @@ -114,6 +114,8 @@ abstract public class Server implements Runnable { /** * Return the assigned port. + * + * @return the assigned port */ public int getPort() { return port; @@ -189,13 +191,8 @@ abstract public class Server implements Runnable { exiting = true; try { - new ConnectActionClient(createSocket(null, port, ssl)) { - @Override - public void action(Version serverVersion) - throws Exception { - } - }.connect(); - + new ConnectActionClient(createSocket(null, port, ssl)) + .connect(); long time = 0; while (ss != null && timeout > 0 && timeout > time) { Thread.sleep(10); @@ -222,17 +219,14 @@ abstract public class Server implements Runnable { @Override public void run() { try { - tracer.trace(name + ": server starting on port " + port); while (started && !exiting) { count(1); Socket s = ss.accept(); new ConnectActionServer(s) { - private Version clientVersion = new Version(); - @Override - public void action(Version dummy) throws Exception { + public void action(Version clientVersion) throws Exception { try { - for (Object data = flush(); true; data = flush()) { + for (Object data = rec(); true; data = rec()) { Object rep = null; try { rep = onRequest(this, clientVersion, data); @@ -243,6 +237,7 @@ abstract public class Server implements Runnable { } } catch (NullPointerException e) { // Client has no data any more, we quit + tracer.trace("Client has data no more, stopping connection"); } } @@ -254,11 +249,6 @@ abstract public class Server implements Runnable { count(-1); } } - - @Override - protected void onClientVersionReceived(Version clientVersion) { - this.clientVersion = clientVersion; - } }.connectAsync(); } diff --git a/src/be/nikiroo/utils/test/SerialTest.java b/src/be/nikiroo/utils/test/SerialTest.java index 4233a7b..e66bda8 100644 --- a/src/be/nikiroo/utils/test/SerialTest.java +++ b/src/be/nikiroo/utils/test/SerialTest.java @@ -1,5 +1,6 @@ package be.nikiroo.utils.test; +import be.nikiroo.utils.TraceHandler; import be.nikiroo.utils.Version; import be.nikiroo.utils.serial.ConnectActionClient; import be.nikiroo.utils.serial.ConnectActionServer; @@ -8,230 +9,212 @@ import be.nikiroo.utils.serial.Importer; import be.nikiroo.utils.serial.Server; class SerialTest extends TestLauncher { - @SuppressWarnings("unused") - private void not_used() { - // TODO: test Server ; but this will at least help dependency checking - try { - Server server = new Server(0, false) { - @Override - protected Object onRequest(ConnectActionServer action, - Version clientVersion, Object data) throws Exception { - return null; - } - }; - } catch (Exception e) { - } - } - private SerialTest() { super("Serial test", null); } - private TestCase[] createServerTestCases(final boolean ssl) { + private TestLauncher createServerTestCases(final String[] args, + final boolean ssl) { final String ssls = (ssl ? "(ssl)" : "(plain text)"); - return new TestCase[] { - new TestCase("Client/Server simple connection " + ssls) { + TestLauncher series = new TestLauncher("Client/Server " + ssls, args); + + series.addTest(new TestCase("Simple connection " + ssls) { + @Override + public void test() throws Exception { + final Object[] rec = new Object[1]; + + Server server = new Server(this.getName(), 0, ssl) { @Override - public void test() throws Exception { - final Object[] rec = new Object[1]; - - Server server = new Server("testy", 0, ssl) { - @Override - protected Object onRequest( - ConnectActionServer action, - Version clientVersion, Object data) - throws Exception { - return null; - } - }; - - assertEquals("A port should have been assigned", true, - server.getPort() > 0); - - server.start(); - - try { - new ConnectActionClient(null, server.getPort(), ssl) { - @Override - public void action(Version serverVersion) - throws Exception { - rec[0] = true; - } - }.connect(); - } finally { - server.stop(); + protected Object onRequest(ConnectActionServer action, + Version clientVersion, Object data) + throws Exception { + return null; + } + }; + + assertEquals("A port should have been assigned", true, + server.getPort() > 0); + + // TODO: remove + server.setTraceHandler(new TraceHandler(true, true, true)); + + server.start(); + + try { + new ConnectActionClient(null, server.getPort(), ssl) { + @Override + public void action(Version serverVersion) + throws Exception { + rec[0] = true; } + }.connect(); + } finally { + server.stop(); + } - assertNotNull("The client action was not run", rec[0]); - assertEquals(true, (boolean) ((Boolean) rec[0])); + assertNotNull("The client action was not run", rec[0]); + assertEquals(true, (boolean) ((Boolean) rec[0])); + } + }); + + series.addTest(new TestCase("Simple exchange " + ssls) { + final Object[] sent = new Object[1]; + final Object[] recd = new Object[1]; + final Exception[] err = new Exception[1]; + + @Override + public void test() throws Exception { + Server server = new Server(this.getName(), 0, ssl) { + @Override + protected Object onRequest(ConnectActionServer action, + Version clientVersion, Object data) + throws Exception { + sent[0] = data; + return "pong"; } - }, // - new TestCase("Client/Server simple exchange " + ssls) { - final Object[] rec = new Object[3]; @Override - public void test() throws Exception { - Server server = new Server("testy", 0, ssl) { - @Override - protected Object onRequest( - ConnectActionServer action, - Version clientVersion, Object data) - throws Exception { - rec[0] = data; - return "pong"; - } + protected void onError(Exception e) { + super.onError(e); + err[0] = e; + } + }; - @Override - protected void onError(Exception e) { - super.onError(e); - rec[2] = e; - } - }; - - assertEquals("A port should have been assigned", true, - server.getPort() > 0); - - server.start(); - - try { - new ConnectActionClient(null, server.getPort(), ssl) { - @Override - public void action(Version serverVersion) - throws Exception { - rec[1] = send("ping"); - } - }.connect(); - } finally { - server.stop(); - } + server.start(); - if (rec[2] != null) { - fail("An exception was thrown: " - + ((Exception) rec[2]).getMessage()); + try { + new ConnectActionClient(null, server.getPort(), ssl) { + @Override + public void action(Version serverVersion) + throws Exception { + recd[0] = send("ping"); } + }.connect(); + } finally { + server.stop(); + } - assertEquals("ping", rec[0]); - assertEquals("pong", rec[1]); + if (err[0] != null) { + fail("An exception was thrown: " + err[0].getMessage()); + } + + assertEquals("ping", sent[0]); + assertEquals("pong", recd[0]); + } + }); + + series.addTest(new TestCase("Multiple exchanges " + ssls) { + final Object[] sent = new Object[3]; + final Object[] recd = new Object[3]; + final Exception[] err = new Exception[1]; + + @Override + public void test() throws Exception { + Server server = new Server(this.getName(), 0, ssl) { + @Override + protected Object onRequest(ConnectActionServer action, + Version clientVersion, Object data) + throws Exception { + sent[0] = data; + action.send("pong"); + sent[1] = action.flush(); + return "pong2"; } - }, // - new TestCase("Client/Server multiple exchanges " + ssls) { - final Object[] sent = new Object[3]; - final Object[] recd = new Object[3]; - final Exception[] err = new Exception[1]; @Override - public void test() throws Exception { - Server server = new Server("testy", 0, ssl) { - @Override - protected Object onRequest( - ConnectActionServer action, - Version clientVersion, Object data) - throws Exception { - sent[0] = data; - action.send("pong"); - sent[1] = action.flush(); - return "pong2"; - } + protected void onError(Exception e) { + super.onError(e); + err[0] = e; + } + }; - @Override - protected void onError(Exception e) { - super.onError(e); - err[0] = e; - } - }; - - server.start(); - - try { - new ConnectActionClient(null, server.getPort(), ssl) { - @Override - public void action(Version serverVersion) - throws Exception { - recd[0] = send("ping"); - recd[1] = send("ping2"); - } - }.connect(); - } finally { - server.stop(); - } + server.start(); - if (err[0] != null) { - fail("An exception was thrown: " - + err[0].getMessage()); + try { + new ConnectActionClient(null, server.getPort(), ssl) { + @Override + public void action(Version serverVersion) + throws Exception { + recd[0] = send("ping"); + recd[1] = send("ping2"); } + }.connect(); + } finally { + server.stop(); + } + + if (err[0] != null) { + fail("An exception was thrown: " + err[0].getMessage()); + } + + assertEquals("ping", sent[0]); + assertEquals("pong", recd[0]); + assertEquals("ping2", sent[1]); + assertEquals("pong2", recd[1]); + } + }); + + series.addTest(new TestCase("Multiple call from client " + ssls) { + final Object[] sent = new Object[3]; + final Object[] recd = new Object[3]; + final Exception[] err = new Exception[1]; - assertEquals("ping", sent[0]); - assertEquals("pong", recd[0]); - assertEquals("ping2", sent[1]); - assertEquals("pong2", recd[1]); + @Override + public void test() throws Exception { + Server server = new Server(this.getName(), 0, ssl) { + @Override + protected Object onRequest(ConnectActionServer action, + Version clientVersion, Object data) + throws Exception { + sent[(Integer) data] = data; + return ((Integer) data) * 2; } - }, // - new TestCase("Client/Server multiple call from client " + ssls) { - final Object[] sent = new Object[3]; - final Object[] recd = new Object[3]; - final Exception[] err = new Exception[1]; @Override - public void test() throws Exception { - Server server = new Server("testy", 0, ssl) { - @Override - protected Object onRequest( - ConnectActionServer action, - Version clientVersion, Object data) - throws Exception { - sent[(Integer) data] = data; - return ((Integer) data) * 2; - } + protected void onError(Exception e) { + super.onError(e); + err[0] = e; + } + }; + + server.start(); - @Override - protected void onError(Exception e) { - super.onError(e); - err[0] = e; + try { + new ConnectActionClient(null, server.getPort(), ssl) { + @Override + public void action(Version serverVersion) + throws Exception { + for (int i = 0; i < 3; i++) { + recd[i] = send(i); } - }; - - server.start(); - - try { - new ConnectActionClient(null, server.getPort(), ssl) { - @Override - public void action(Version serverVersion) - throws Exception { - for (int i = 0; i < 3; i++) { - recd[i] = send(i); - } - } - }.connect(); - } finally { - server.stop(); } + }.connect(); + } finally { + server.stop(); + } - if (err[0] != null) { - fail("An exception was thrown: " - + err[0].getMessage()); - } + if (err[0] != null) { + fail("An exception was thrown: " + err[0].getMessage()); + } - assertEquals(0, sent[0]); - assertEquals(0, recd[0]); - assertEquals(1, sent[1]); - assertEquals(2, recd[1]); - assertEquals(2, sent[2]); - assertEquals(4, recd[2]); - } - }, // - }; + assertEquals(0, sent[0]); + assertEquals(0, recd[0]); + assertEquals(1, sent[1]); + assertEquals(2, recd[1]); + assertEquals(2, sent[2]); + assertEquals(4, recd[2]); + } + }); + + return series; } public SerialTest(String[] args) { super("Serial test", args); - for (TestCase test : createServerTestCases(false)) { - addTest(test); - } + addSeries(createServerTestCases(args, false)); - for (TestCase test : createServerTestCases(true)) { - addTest(test); - } + addSeries(createServerTestCases(args, true)); addTest(new TestCase("Simple class Import/Export") { @Override