package org.dcache.xdr;
import java.io.EOFException;
import java.io.IOException;
import java.nio.channels.CompletionHandler;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
/**
*
*/
public class ClientServerTest {
private static final int PROGNUM = 100017;
private static final int PROGVER = 1;
private static final int ECHO = 1;
private static final int UPPER = 2;
private static final int SHUTDOWN = 3;
private OncRpcSvc svc;
private OncRpcSvc clnt;
private RpcCall clntCall;
@Before
public void setUp() throws IOException {
RpcDispatchable echo = (RpcCall call) -> {
switch (call.getProcedure()) {
case ECHO: {
XdrString s = new XdrString();
call.retrieveCall(s);
call.reply(s);
break;
}
case UPPER: {
RpcCall cb = new RpcCall(PROGNUM, PROGVER, new RpcAuthTypeNone(), call.getTransport());
XdrString s = new XdrString();
call.retrieveCall(s);
cb.call(ECHO, s, s);
call.reply(s);
break;
}
case SHUTDOWN: {
svc.stop();
}
}
};
RpcDispatchable upper = (RpcCall call) -> {
XdrString s = new XdrString();
call.retrieveCall(s);
XdrString u = new XdrString(s.stringValue().toUpperCase());
call.reply(u);
};
svc = new OncRpcSvcBuilder()
.withoutAutoPublish()
.withTCP()
.withWorkerThreadIoStrategy()
.withRpcService(new OncRpcProgram(PROGNUM, PROGVER), echo)
.build();
svc.start();
clnt = new OncRpcSvcBuilder()
.withoutAutoPublish()
.withTCP()
.withClientMode()
.withWorkerThreadIoStrategy()
.withRpcService(new OncRpcProgram(PROGNUM, PROGVER), upper)
.build();
clnt.start();
XdrTransport t = clnt.connect(svc.getInetSocketAddress(IpProtocolType.TCP));
clntCall = new RpcCall(PROGNUM, PROGVER, new RpcAuthTypeNone(), t);
}
@After
public void tearDown() throws IOException {
if (svc != null) {
svc.stop();
}
if (clnt != null) {
clnt.stop();
}
}
@Test
public void shouldCallCorrectProcedure() throws IOException {
XdrString s = new XdrString("hello");
XdrString reply = new XdrString();
clntCall.call(ECHO, s, reply);
assertEquals("reply mismatch", s, reply);
}
@Test
public void shouldTriggerClientCallback() throws IOException {
XdrString s = new XdrString("hello");
XdrString reply = new XdrString();
clntCall.call(UPPER, s, reply);
assertEquals("reply mismatch", s.stringValue().toUpperCase(), reply.stringValue());
}
@Test(expected = EOFException.class, timeout = 5000)
public void shouldFailClientCallWhenServerStopped() throws IOException, InterruptedException {
XdrString s = new XdrString("hello");
try {
// stop the server
clntCall.call(SHUTDOWN, s, XdrVoid.XDR_VOID);
} catch (EOFException e) {
// ignore disconnect error
}
clntCall.call(ECHO, s, (CompletionHandler) null);
}
@Test(expected = EOFException.class, timeout = 5000)
public void shouldFailClientCallWhileWaitingWhenServerStopped() throws IOException, InterruptedException {
XdrString s = new XdrString("hello");
clntCall.call(SHUTDOWN, s, s);
}
@Test
public void shouldTriggerClientCallbackEvenIfOtherClientDisconnected() throws IOException {
OncRpcSvc clnt2 = new OncRpcSvcBuilder()
.withTCP()
.withClientMode()
.withWorkerThreadIoStrategy()
.build();
clnt2.start();
clnt2.connect(svc.getInetSocketAddress(IpProtocolType.TCP));
clnt2.stop();
XdrString s = new XdrString("hello");
XdrString reply = new XdrString();
clntCall.call(UPPER, s, reply);
assertEquals("reply mismatch", s.stringValue().toUpperCase(), reply.stringValue());
}
}