# 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
/**
* A trace happened, show it.
* <p>
- * 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
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;
+ }
}
import be.nikiroo.utils.Version;
+/**
+ * Base class used for the client/server basic handling.
+ * <p>
+ * 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.
+ * <p>
+ * Thus, it is only called on the server.
+ * <p>
+ * 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;
} 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(),
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 ")) {
}
}
- // (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) {
}
}
- 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.
+ * <p>
+ * Also used internally for the client (only do something if there is
+ * contentToSend).
+ * <p>
+ * 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");
}
}
- // 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.
+ * <p>
+ * Also used internally for the client (only do something if there is
+ * contentToSend).
+ * <p>
+ * 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) {
// "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();
}
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.
+ * <p>
+ * 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.
+ * <p>
+ * 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
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.
+ * <p>
+ * 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.
+ * <p>
+ * 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.
+ * <p>
+ * 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
private Map<Integer, Object> map;
private StringBuilder builder;
+ /**
+ * Create a new {@link Exporter}.
+ */
public Exporter() {
map = new HashMap<Integer, Object>();
builder = new StringBuilder();
}
+ /**
+ * Serialise the given object and add it to the list.
+ * <p>
+ * <b>Important: </b>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;
}
/**
- * 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() {
private String currentFieldName;
+ /**
+ * Create a new {@link Importer}.
+ */
public Importer() {
map = new HashMap<String, Object>();
map.put("NULL", null);
/**
* Return the assigned port.
+ *
+ * @return the assigned port
*/
public int getPort() {
return port;
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);
@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);
}
} catch (NullPointerException e) {
// Client has no data any more, we quit
+ tracer.trace("Client has data no more, stopping connection");
}
}
count(-1);
}
}
-
- @Override
- protected void onClientVersionReceived(Version clientVersion) {
- this.clientVersion = clientVersion;
- }
}.connectAsync();
}
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;
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