Testing Java Sockets - java

I'm developing a network application and I want to get unit testing right. THIS time we'll do it, you know? :)
I'm have trouble testing network connections, though.
In my application I use plain java.net.Sockets.
For example:
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.net.UnknownHostException;
public class Message {
byte[] payload;
public Message(byte[] payload) {
this.payload = payload;
}
public boolean sendTo(String hostname, int port) {
boolean sent = false;
try {
Socket socket = new Socket(hostname, port);
OutputStream out = socket.getOutputStream();
out.write(payload);
socket.close();
sent = true;
} catch (UnknownHostException e) {
} catch (IOException e) {
}
return sent;
}
}
I read about mocking but am not sure how to apply it.

If I was to test the code, I'd do the following.
Firstly, refactor the code so that the Socket isn't directly instantiated in the method you want to test. The example below shows the smallest change I can think of to make that happen. Future changes might factor out the Socket creation to a completely separate class, but I like small steps and I don't like making big changes on untested code.
public boolean sendTo(String hostname, int port) {
boolean sent = false;
try {
Socket socket = createSocket();
OutputStream out = socket.getOutputStream();
out.write(payload);
socket.close();
sent = true;
} catch (UnknownHostException e) {
// TODO
} catch (IOException e) {
// TODO
}
return sent;
}
protected Socket createSocket() {
return new Socket();
}
Now that the socket creation logic is outside of the method you are trying to test, you can start to mock things up and hook into the creation the socket.
public class MessageTest {
#Test
public void testSimplePayload() () {
byte[] emptyPayload = new byte[1001];
// Using Mockito
final Socket socket = mock(Socket.class);
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
when(socket.getOutputStream()).thenReturn(byteArrayOutputStream);
Message text = new Message(emptyPayload) {
#Override
protected Socket createSocket() {
return socket;
}
};
Assert.assertTrue("Message sent successfully", text.sendTo("localhost", "1234"));
Assert.assertEquals("whatever you wanted to send".getBytes(), byteArrayOutputStream.toByteArray());
}
}
Overriding individual methods on units you want to test is really useful for testing, especially in ugly code with horrible dependencies. Obviously the best solution is sorting out dependencies (in this case I would think that a Message not depend on a Socket, maybe there is a Messager interface as glowcoder suggests), but it's nice to move towards the solution in the smallest possible steps.

I'm going to answer your question as asked instead of redesigning your class (others have that covered, but the basic question on the class as written is stil valid).
Unit testing never tests anything outside the class being tested. This hurt my brain for a while--it means unit test does not in any way prove that your code works! What it does is prove that your code works the same way it did when you wrote the test.
So that said you want a unit test for this class but you also want a functional test.
For the unit test you have to be able to "Mock out" the communications. To do this instead of creating your own socket, fetch one from a "Socket factory", then make yourself a socket factory. The factory should be passed in to the constructor of this class you are testing. This is actually not a bad design strategy--you can set the hostname and port in the factory so you don't have to know about them in your communication class--more abstract.
Now in testing you just pass in a mock factory that creates mock sockets and everything is roses.
Don't forget the functional test though! Set up a "test server" that you can connect to, send some messages to the server and test the responses you get back.
For that matter, you probably want to do even deeper functional tests where you write a client that sends the REAL server some scripted commands and tests the results. You probably even want to create a "Reset state" command just for functional testing. Functional tests actually ensure that entire "Functional units" work together as you expect--something that many unit testing advocates forget.

I'm not going to say this is a bad idea.
I am going to say it can be improved upon.
If you're sending across a raw byte[] over your socket, the other side can do whatever it wants with it. Now, if you're not connecting to a Java server, then you might NEED to do that. If you're willing to say "I'm always working with a Java server" then you can use serialization to your advantage.
When you do this, you can mock it by just creating your own Sendable objects as if they came across the wire.
Create one socket, not one for every message.
interface Sendable {
void callback(Engine engine);
}
So how does this work in practice?
Messenger class:
/**
* Class is not thread-safe. Synchronization left as exercise to the reader
*/
class Messenger { // on the client side
Socket socket;
ObjectOutputStream out;
Messenger(String host, String port) {
socket = new Socket(host,port);
out = new ObjectOutputStream(socket.getOutputStream());
}
void sendMessage(Sendable message) {
out.writeObject(message);
}
}
Receiver class:
class Receiver extends Thread { // on the server side
Socket socket;
ObjectInputStream in;
Engine engine; // whatever does your logical data
Receiver(Socket socket, Engine engine) { // presumable from new Receiver(serverSocket.accept());
this.socket = socket;
this.in = new ObjectInputStream(socket.getInputStream());
}
#Override
public void run() {
while(true) {
// we know only Sendables ever come across the wire
Sendable message = in.readObject();
message.callback(engine); // message class has behavior for the engine
}
}
}

It's difficult testing connection and server interactions.
Tipically, I isolate business logic from communication logic.
I create scenarios for unit tests on business logic, these tests are automatic (use JUni,t and Maven) and i create other scenarios to test real connections, I don't use framework like JUnit for these tests.
In last year I've used Spring Mocks to test logic with HttpResponse HttpRequest, but I think this is not useful.
I follow this question.
Bye

Related

java.lang.ClassCastException exception using ObjectInputStream, when sending a class as an object

https://github.com/IshayKom/RCProject
Classes As Shown in the eclipse package manager
(I don't really deal with github so I don't know how to upload classes correctly)
I got an error running my project.
I use VMWare to work on my project but I don't think that this specific error requires the use of multiple PCs or VMs.
It basically should receive ClientInformation from the InitiHandler class and start the process of matching two clients together. (Security isn't required in this project at the moment)
The steps to recreate this issue as follows: Enabling the "server" with the required information. After that go on "controlled client" mode, write the required information, and attempt to send info to the server.
I tried searching for a solution and looking at what mistake I did this time but I just can't get my mind into it. If anyone can spot my mistake it'll super helpful.
The following is the class which the error happened in:
package Server;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class ServerInitializer extends Thread {
private int port;
private ClientInformation[] ci = null;
private ClientInformation c = null;
private boolean run = true;
ServerSocket serversocket;
ObjectInputStream ois;
Socket client;
public ServerInitializer(int port, int clientlimit) {
this.port = port;
ci = new ClientInformation[clientlimit];
start();
}
#Override
public void run() {
try
{
serversocket = new ServerSocket(port);
while(run)
{
client = serversocket.accept();
System.out.println("New Client Has Been Connected, ip:" + client.getInetAddress().getHostAddress());
ois = new ObjectInputStream(client.getInputStream());
c = (ClientInformation) ois.readObject();
new ServerThread(ci,c, client, run);
}
serversocket.close();
}
catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
public void terminate()
{
this.run = false;
}
public boolean getrun()
{
return run;
}
}
The error itself:
"Exception in thread "Thread-0" java.lang.ClassCastException: class Startup.ClientInformation cannot be cast to class Server.ClientInformation (Startup.ClientInformation and Server.ClientInformation are in unnamed module of loader 'app')
at Server.ServerInitializer.run(ServerInitializer.java:35)"
If it's too much of a pain to see my mistake based on what I currently wrote let me know what to do to make it easier for you to spot it.
Another Question: How can I use the terminate function to basically disable any while loops that are happening in other classes/threads? or what I wrote is good enough? I couldn't test this because of my error. (This can apply to the server itself in my project or the client-side)
You have a class named ClientConfiguration, which has package Server; on the top. You have a completely different, totally unrelated class which by pure coincidence is also named ClientConfiguration, but has package Startup; at the top, which is why I say it is unrelated. Because that's what that means. You are then sending an instance of one of these, and upon receiving it, you assume it is the other. It isn't, hence, CCEx.
If you intended to have 2 different classes with the same name, stop confusing them; if this sounds difficult (I think it'd have some issues with this, too!), then rename one.
If you never intended to have 2 separate classes, then fix that problem. Possibly you already did and simply replaced the package statement (and moved the source file to another folder) for the only ClientConfiguration you ever had, but then one of the two (client or server) is running old code.

How to test method that internally creates and uses a ServerSocket

My server code looks something like this:
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
public class Server implements Runnable {
private ServerSocket serverSocket;
public Server(int port) throws IOException {
serverSocket = new ServerSocket(port);
}
#Override
public void run() {
try {
Socket client = serverSocket.accept();
// do stuff
} catch (IOException e) {
e.printStackTrace();
}
}
}
My plan was to write a mock client that connects to the server socket, and verifies the result, but in order to do that I need to know which port to connect to. However, this information is private.
None of the options I was thinking about are good practice I think:
If I use a predefined port number for the tests, I have no guarantee that it will be available. Even if it's available just before the test, it might be, theoretically snatched by the time I try to use it.
If I pass 0 as port number (so that ServerSocket will atomically provide a free port), I still have no access to it.
I could add a getServerPort() method to the interface or create a constructor that accepts a ServerSocket object, but changing the interface only for the sake of testing is considered bad practice.
As written, your class is not really suited for unit test.
The problem is that your direct call to new ServerSocket() basically deprives your ability to control what the socket object will be doing.
So, what you can do:
interface SocketFactory {
public ServerSocket createSocketFor(int port);
}
class SocketFactoryImpl implements SocketFactory {
...
public class Server implements Runnable {
public Server(int port) {
this(port, new SocketFactoryImpl());
}
Server(int port, SocketFactory socketFactory) {
...
In other words: you use dependency injection in order to provide a mean to your "class under test" to create those objects that it needs to do its work.
From there: you can use a mocking framework such as EasyMock in order to control what a mocked SocketFactory object will return (probably a mocked ServerSocket object). And now that you have full control over the ServerSocket used by your production code ... you can test whatever situation you want.
Long story short: don't call new; instead use dependency injection to gain full control over your class under test.
(and maybe watch these videos to really understand what writing testable code is about).

How do I design a program that does completely different tasks concurrently?

I've just got my feet wet with multi-threading and its really awesome. I find myself trying to figure out new ways I can use it make things better and I think I found one but I'm unsure how to design the program for this.
Here's the situation. I have a queue server that multiple clients consume and produce data to but to kick start the process I run a java program on to put some initial data for them to start. then my program is done and I have excess capacity on the queue server but nothing is really running on it. So I want to try to do some maintenance tasks, run a service, and do low priority stuff.I'm not sure how do that though. How do I design a program that does completely different tasks concurrently?
Typically I just wrap my programs in a while (true) loop and it does a single task and I realize I cannot do two while loops at the same time in the same process(maybe nested?). To show a simplified example, I put a bunch of code that runs a runnable(maybe it'll process a low priority queue) and a service that monitors a socket and replies back(I might want to add more depending on cpu usage). How do I get them all to work together? Is there a better way to design it(I know long term its probably better to run multiple java processes but right now I am just trying to manage a single file and I suspect there's a way to give the socket service a higher priority than processing the queue within the file but if they are both running in different files I don't know how to lower one over the other instead of them fighting for resources)?
Thanks and I'll edit this question if it turns out I'm explaining this totally wrong. But in a nutshell, I want it to provide a service to other systems(server socket, in the example) and when its idle I want it to do a few other tasks.
Example(if you understand what I'm asking this code may not be necessary to read):
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class multipleThreads {
private ServerSocket server;
private int port = 7777;
public void ServerSocketExample() {
try {
server = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("starting");
ServerSocketExample example = new ServerSocketExample();
example.handleConnection();
while (true) {
//monitor low low priority queue
}
}
public void handleConnection() {
System.out.println("Waiting for client message...");
//
// The server do a loop here to accept all connection initiated by the
// client application.
//
while (true) {
try {
Socket socket = server.accept();
new ConnectionHandler(socket);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
class ConnectionHandler implements Runnable {
private Socket socket;
public ConnectionHandler(Socket socket) {
this.socket = socket;
Thread t = new Thread(this);
t.start();
}
public void run() {
try
{
//
// Read a message sent by client application
//
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
String message = (String) ois.readObject();
System.out.println("Message Received: " + message);
//
// Send a response information to the client application
//
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject("Hi...");
ois.close();
oos.close();
socket.close();
System.out.println("Waiting for client message...");
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
class MonitorQueue implements Runnable{
#Override
public void run() {
// TODO Auto-generated method stub
//do work when stuff comes in the queue
}
}
I strongly recommend you take a look at this project: Java Concurrent Animated. I found this probably the best way to get my head around concurrency concepts in Java: it's animated, interactive, and you can just take one concept at a time and get a good understanding.
http://sourceforge.net/projects/javaconcurrenta/
Take a look at the java.util.concurrent package. It's full off goodies for doing exactly the kinds of things you describe.
In particular, check out the Executors factory class which lets you build Thread Pools that allow multiple tasks to be scheduled and run concurrently on any number of Threads you specify.
Oracle has some great tutorials on using Executors:
http://docs.oracle.com/javase/tutorial/essential/concurrency/executors.html
http://docs.oracle.com/javase/tutorial/essential/concurrency/exinter.html
Concurrency is hard, you can read Java Concurrency in Practice, but even the experts have difficulties.
Look for a training course in your area.
I would like to recommend Concurrency Specialist Courses which is based on Java Concurrency in Practice and endorsed by the author, Brian Goetz

Java: how to compare object in different threads

I have a server listening data from clients. Once a client sends data, it will go into a thread. Thus, each thread has a data. revFeaturePoints is the data which the server receives from clients.
Each revFeaturePoints has a float array, I want to compute the Euclidean distance between different revFeaturePoints in different thread?
I do not know how can let one thread to access another revFeaturePoints in other threads?
Here is the code:
public class MyServer {
public static void main(String[] args) throws IOException{
ServerSocket serverSocket = null;
//bind a serverSocket to the port and listen
try{
serverSocket = new ServerSocket(8888);
System.out.println("Listening: 8888");
}catch(IOException e){
e.printStackTrace();
}
while(true)
new MyServerThread(serverSocket.accept()).start();
}
}
public class MyServerThread extends Thread{
//Create a socket for each client
private Socket socket = null;
private ObjectInputStream dataInputStream = null;
private ObjectOutputStream dataOutputStream = null;
private ArrayList<FeaturePointList> revFeaturePoints = null;
//constructor
public MyServerThread(Socket socket){
super("MyServerThread");
this.socket = socket;
}
#SuppressWarnings("unchecked")
public void run(){
try{
dataOutputStream = new ObjectOutputStream(socket.getOutputStream());
dataInputStream = new ObjectInputStream(socket.getInputStream());
System.out.println("ip: "+ socket.getInetAddress());
revFeaturePoints = (ArrayList<FeaturePointList>) dataInputStream.readObject();
}catch(IOException e){
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
if(socket!=null){
try{
socket.close();
}catch(IOException e){
e.printStackTrace();
}
}
if(dataInputStream!=null){
try{
dataInputStream.close();
}catch(IOException e){
e.printStackTrace();
}
}
if(dataOutputStream!=null){
try{
dataOutputStream.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
}
A simple way would be putting a synchronized method in MyServerThread that returns the data.
Another way of doing it would be to use a BlockingQueue and place the data result in a queue and taking the results from this as a producer-consumer pattern. See here for a way of doing this.
If your MyServerThread class stashes the data into a field, you can access that field from multiple instances of MyServerThread.
You can share the data among threads by using a shared structure and correct synchronization. For example, you could have a ConcurrentHashMap<'threadname', data> in MyServerThread where each thread puts its data and search for data in other threads.
That said, you should evaluate your architecture. If N threads have to check what the other N-1 threads are doing with data, you are preparing a recipe for performance disaster. Probably, what you would like to do is to create some layering in your architecture, where a number of ServerThreads are gathering the request and placing them in a concurrent shared structure (e.g queues). Then another set of workers are comparing and processing the data and producing results in a collaborative system. Have a look at the producer-consumer pattern.
[really a comment but won't fit ;)]
maasg's answer is quite correct in the general sense, but I believe you are right now looking at design difficulties and not Java threaded implementation per se.
You server (as is) fires off a disposable thread on each connect request, and this thread simply reads one object from the client and then closes the connection. The passed object is put in a (server thread) instance scoped object (which is duly garbage collected after you exit run()).
It is completely unclear -- and thus the impression that this is a design problem -- how you determine which 2 threads to compare, or for that matter, what guarantees you have that there will be (always) 2 concurrent threads to begin with.
Logically, you clearly have some domain specific association between a server thread and some meaningful matter in your domain. This relationship needs to be embodied in code, but first we need to understand what is this distinction and relationship.
Objects aren't 'in different threads'. Objects are members of other different objects, usually referenced via 'get' methods. Forget about the thread issue entirely, it is irrelevant. You just want to compare a member of object A with a member of object B. This is just business as usual.

What is the best way to manage text-based client-server connections?

I'm looking to write a small client-server-based text game that handles multiple client connections and persistently affects a game state. I'm wondering what the best way would be to handle multiple connects such that commands are processed in the order they arrive at the server.
Ideally I'm not looking to take advantage of multi-threading, at least on the command processing level. I would be okay with each client having a separate thread (in order to have blocking IO on each thread), as long as I could unify the processing in a single thread thereafter.
Since the only communication between the client and server will be text, I'm not sure how best to go about setting up the communication. If I chose blocking IO, how would I get queue the processing to occur in a single thread?
Alternatively, if I choose non-blocking IO and use a selector to query for when clients have written to the server, how can I get read a String of unknown/unlimited length without using a set-size ByteBuffer? Non-blocking also favours keeping the processing in a single thread as it can just read from the client connections as and when they send new data. However, when I tried to implement it with read/writeUTF I came up against the IllegalBlockingModeException heh.
Any answers to the questions or suggestions on how to do this in a way I haven't mentioned would be sincerely appreciated! I'm fairly new to clients and servers so I don't know whether java.io or java.nio would be most appropriate.
Sorry for the convoluted question. I think I ran away with myself.
Opinions differ, but I'd definitely go with a single thread per client. The communication to the single processing thread could then go via a LinkedBlockingQueue, or just a synchronized LinkedList.
Something like this on the per-client thread:
public class Client implements Runnable, ResponseOutput {
private final BufferedReader br;
private final PrintWriter pw;
public Client(Socket s) {
br = new BufferedReader(new InputStreamReader(s.getInputStream()));
pw = new PrintWriter(s.getOutputStream());
}
// defined by the ResponseOutput interface
public void sendReply(String reply) {
pw.println(reply);
}
public void run() {
try {
while (true) {
String s = br.readLine();
if (s==null)
break;
Processor.queue(new Processor.InputItem(this, s));
}
} catch (IOException ioe) {
... error handling ...
}
}
}
Then this for the processing:
public class Processor implements Runnable {
static public class InputItem {
final ResponseOutput client;
final String command;
public InputItem(ResponseOutput client, String command) {
this.client = client;
this.command = command;
}
}
static private Processor instance;
static public void queue(InputItem item) {
instance.commandQueue.add(item);
}
private BlockingQueue<InputItem> commandQueue;
public void run() {
try {
while (true) {
InputItem item = commandQueue.take();
String reply = doStuff(item.command);
item.client.sendReply(reply);
}
} catch (InterruptedException ie) {
... error handling ....
}
}
}
Within the InputItem class, you can also include a reference to any game state that needs updating. Since there's only the processing thread changing it, you get to do that without any synchronization.
i'm no expert in sever client systems but I'll share a couple of tips
Depending on your need you could simply set up a Tomcat server and do http request, its fairly straight forwards and of course all in Java.
the downside is that the request might be a bit slow.
The Second option you can check out is RMI.
The concept is simple you connect to another computer and when that is done you call methods on the other computer from a local object in you code.
http://java.sun.com/developer/onlineTraining/rmi/RMI.html
it might look a bit complicated (and sometimes debbuging a stack through multiple computer is a bit tricky) but I recommend because it keeps your code clear.
Finally you can try sockets but there your on your own :P

Categories