package org.jgroups.blocks;
import org.jgroups.Address;
import org.jgroups.Global;
import org.jgroups.JChannel;
import org.jgroups.tests.ChannelTestBase;
import org.jgroups.util.*;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.io.*;
import java.util.Iterator;
import java.util.List;
@Test(groups=Global.STACK_DEPENDENT,singleThreaded=true)
public class RpcDispatcherSerializationTest extends ChannelTestBase {
private JChannel channel, channel2;
private RpcDispatcher disp, disp2;
private final Target target=new Target();
@BeforeClass
protected void setUp() throws Exception {
channel=createChannel(true);
disp=new RpcDispatcher(channel, target);
channel.connect("RpcDispatcherSerializationTest");
channel2=createChannel(channel);
disp2=new RpcDispatcher(channel2, target);
channel2.connect("RpcDispatcherSerializationTest");
}
@AfterClass
protected void tearDown() throws Exception {
Util.close(disp2, channel2, disp, channel);
}
public void testNonSerializableArgument() throws Exception {
try {
disp.callRemoteMethods(null, "foo", new Object[]{new NonSerializable()}, new Class[]{NonSerializable.class},
new RequestOptions(ResponseMode.GET_ALL, 5000));
throw new IllegalStateException("should throw NotSerializableException");
}
catch(Exception t) {
assert t instanceof NotSerializableException : "exception is not of expected type: " + t;
}
}
public void testTargetMethodNotFound() throws Exception {
List<Address> members=channel.getView().getMembers();
System.out.println("members are: " + members);
RspList<Object> rsps=disp.callRemoteMethods(members, "foo", null, new Class[]{String.class, String.class},
new RequestOptions(ResponseMode.GET_ALL, 8000));
System.out.println("responses:\n" + rsps + ", channel.view: " + channel.getView() + ", channel2.view: " + channel2.getView());
assert members.size() == rsps.size() : "expected " + members.size() + " responses, but got " + rsps + " (" + rsps.size() + ")";
for(Rsp rsp: rsps.values())
assert rsp.getException() instanceof NoSuchMethodException;
}
public void testMarshaller() throws Exception {
Marshaller m=new MyMarshaller();
disp.setMarshaller(m);
disp2.setMarshaller(m);
RspList rsps;
rsps=disp.callRemoteMethods(null, "methodA", new Object[]{Boolean.TRUE, new Long(322649)},
new Class[]{boolean.class, long.class},
new RequestOptions(ResponseMode.GET_ALL, 0));
assert rsps.size() == 2;
for(Iterator<Rsp> it=rsps.values().iterator(); it.hasNext();) {
Rsp rsp=it.next();
assert rsp.getValue() == null;
assertTrue(rsp.wasReceived());
assertFalse(rsp.wasSuspected());
}
rsps=disp.callRemoteMethods(null, "methodB", null, null, new RequestOptions(ResponseMode.GET_ALL, 0));
assertEquals(2, rsps.size());
for(Iterator<Rsp> it=rsps.values().iterator(); it.hasNext();) {
Rsp rsp=it.next();
assertNotNull(rsp.getValue());
assertEquals(Boolean.TRUE, rsp.getValue());
assertTrue(rsp.wasReceived());
assertFalse(rsp.wasSuspected());
}
rsps=disp.callRemoteMethods(null, "methodC", null, null, new RequestOptions(ResponseMode.GET_ALL, 0));
assertEquals(2, rsps.size());
for(Iterator<Rsp> it=rsps.values().iterator(); it.hasNext();) {
Rsp rsp=it.next();
assertNull(rsp.getValue());
assertNotNull(rsp.getException());
assertTrue(rsp.wasReceived());
assertFalse(rsp.wasSuspected());
}
disp.setMarshaller(null);
disp2.setMarshaller(null);
}
static class MyMarshaller implements Marshaller {
static final byte NULL = 0;
static final byte BOOL = 1;
static final byte LONG = 2;
static final byte OBJ = 3;
public void objectToStream(Object obj, DataOutput out) throws Exception {
if(obj == null)
out.writeByte(NULL);
else if(obj instanceof Boolean) {
out.writeByte(BOOL);
out.writeBoolean((Boolean)obj);
}
else if(obj instanceof Long) {
out.writeByte(LONG);
out.writeLong((Long)obj);
}
else {
out.writeByte(OBJ);
Buffer buf=Util.objectToBuffer(obj);
out.write(buf.getBuf(), buf.getOffset(), buf.getLength());
}
}
public Object objectFromStream(DataInput in) throws Exception {
int type=in.readByte();
switch(type) {
case NULL:
return null;
case BOOL:
return in.readBoolean();
case LONG:
return in.readLong();
case OBJ:
return Util.objectFromStream(in);
default:
throw new IllegalArgumentException("incorrect type " + type);
}
}
}
static class Target {
@SuppressWarnings("UnusedParameters")
public static void methodA(boolean b, long l) {
;
}
public static boolean methodB() {
return true;
}
public static void methodC() {
throw new IllegalArgumentException("dummy exception - for testing only");
}
}
static class NonSerializable {
@SuppressWarnings("unused") int i;
}
}