/*****************************************************************************
* Copyright [2013] [Jules White] *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. *
* You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
****************************************************************************/
package org.magnum.soda.test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.Test;
import org.magnum.soda.MsgBus;
import org.magnum.soda.ObjRegistry;
import org.magnum.soda.msg.LocalAddress;
import org.magnum.soda.proxy.JavaReflectionProxyCreator;
import org.magnum.soda.proxy.ObjRef;
import org.magnum.soda.proxy.ProxyFactory;
import org.magnum.soda.svc.InvocationInfo;
import org.magnum.soda.svc.InvocationInfoBuilder;
import org.magnum.soda.svc.ObjInvocationMsg;
import org.magnum.soda.svc.ObjInvocationMsgBuilder;
import org.magnum.soda.svc.ObjInvocationRespMsg;
import org.magnum.soda.svc.ObjInvoker;
import org.magnum.soda.svc.Session;
import org.magnum.soda.svc.SessionData;
import org.mockito.ArgumentCaptor;
public class ObjInvokerTest {
public static interface TestMe {
public void run();
public Object foo(String a);
public TestMe bar(String[] a, int c, Integer[] b, TestMe d);
}
@Test
public void testNoArgNoReturn() {
ObjRegistry reg = mock(ObjRegistry.class);
MsgBus bus = mock(MsgBus.class);
LocalAddress addr = new LocalAddress();
ProxyFactory factory = new ProxyFactory(reg, new JavaReflectionProxyCreator(getClass().getClassLoader()), addr, bus);
TestMe testme = mock(TestMe.class);
ObjRef ref = addr.createObjRef(testme);
when(reg.get(ref)).thenReturn(testme);
ObjInvoker invoker = new ObjInvoker(bus, reg, factory, true);
InvocationInfo target = InvocationInfoBuilder.invocationInfo()
.withMethod("run")
.withParameters(new Object[]{})
.build();
ObjInvocationMsg invoke = ObjInvocationMsgBuilder.objInvocationMsg()
.withInvocation(target)
.withTargetObjectId(ref)
.withSource(addr.toString())
.build();
invoker.handleInvocation(invoke);
verify(testme).run();
ArgumentCaptor<ObjInvocationRespMsg> respc = ArgumentCaptor.forClass(ObjInvocationRespMsg.class);
verify(bus).publish(respc.capture());
ObjInvocationRespMsg resp = respc.getValue();
assertEquals(addr.toString(), resp.getDestination());
assertNull(resp.getResult());
assertNull(resp.getException());
assertEquals(invoke.getId(),resp.getResponseTo());
}
@Test
public void testSingleArgAndReturn() {
ObjRegistry reg = mock(ObjRegistry.class);
MsgBus bus = mock(MsgBus.class);
LocalAddress addr = new LocalAddress();
ProxyFactory factory = new ProxyFactory(reg, new JavaReflectionProxyCreator(getClass().getClassLoader()), addr, bus);
TestMe testme = mock(TestMe.class);
ObjRef ref = addr.createObjRef(testme);
when(reg.get(ref)).thenReturn(testme);
when(testme.foo("a")).thenReturn("b");
ObjInvoker invoker = new ObjInvoker(bus, reg, factory, true);
InvocationInfo target = InvocationInfoBuilder.invocationInfo()
.withMethod("foo")
.withParameterTypes(new Class[]{String.class})
.withParameters(new Object[]{"a"})
.build();
ObjInvocationMsg invoke = ObjInvocationMsgBuilder.objInvocationMsg()
.withInvocation(target)
.withTargetObjectId(ref)
.withSource(addr.toString())
.build();
invoker.handleInvocation(invoke);
verify(testme).foo("a");
ArgumentCaptor<ObjInvocationRespMsg> respc = ArgumentCaptor.forClass(ObjInvocationRespMsg.class);
verify(bus).publish(respc.capture());
ObjInvocationRespMsg resp = respc.getValue();
assertEquals(addr.toString(), resp.getDestination());
assertEquals("b",resp.getResult());
assertNull(resp.getException());
assertEquals(invoke.getId(),resp.getResponseTo());
}
//bar(String[] a, int c, Integer[] b, TestMe d);
@Test
public void testMultiArgAndReturn() {
ObjRegistry reg = mock(ObjRegistry.class);
MsgBus bus = mock(MsgBus.class);
LocalAddress addr = new LocalAddress();
ProxyFactory factory = new ProxyFactory(reg, new JavaReflectionProxyCreator(getClass().getClassLoader()), addr, bus);
TestMe testme = mock(TestMe.class);
ObjRef ref = addr.createObjRef(testme);
when(reg.get(ref)).thenReturn(testme);
when(reg.publish(testme)).thenReturn(ref);
ObjInvoker invoker = new ObjInvoker( bus, reg, factory, true);
Object[] args = new Object[]{new String[]{"a","b"},2,new Integer[]{4,5},testme};
when(testme.bar((String[])args[0],(Integer)args[1],(Integer[])args[2],(TestMe)args[3])).thenReturn(testme);
InvocationInfo target = InvocationInfoBuilder.invocationInfo()
.withMethod("bar")
.withParameterTypes(new Class[]{String[].class,int.class,Integer[].class,TestMe.class})
.withParameters(args)
.build();
ObjInvocationMsg invoke = ObjInvocationMsgBuilder.objInvocationMsg()
.withInvocation(target)
.withTargetObjectId(ref)
.withSource(addr.toString())
.build();
SessionData.forClient(addr.toString()).put("foo", "bar");
invoker.handleInvocation(invoke);
assertEquals("bar",Session.get().get("foo"));
verify(testme).bar((String[])args[0],(Integer)args[1],(Integer[])args[2],(TestMe)args[3]);
ArgumentCaptor<ObjInvocationRespMsg> respc = ArgumentCaptor.forClass(ObjInvocationRespMsg.class);
verify(bus).publish(respc.capture());
ObjInvocationRespMsg resp = respc.getValue();
assertEquals(addr.toString(), resp.getDestination());
assertEquals(ref,resp.getResult());
assertNull(resp.getException());
assertEquals(invoke.getId(),resp.getResponseTo());
}
//bar(String[] a, int c, Integer[] b, TestMe d);
@Test
public void testMultiArgWithObjRefAndReturn() {
ObjRegistry reg = mock(ObjRegistry.class);
MsgBus bus = mock(MsgBus.class);
LocalAddress addr = new LocalAddress();
ProxyFactory factory = new ProxyFactory(reg, new JavaReflectionProxyCreator(getClass().getClassLoader()), addr, bus);
TestMe testme = mock(TestMe.class);
ObjRef ref = addr.createObjRef(testme);
when(reg.get(ref)).thenReturn(testme);
when(reg.publish(testme)).thenReturn(ref);
ObjInvoker invoker = new ObjInvoker(bus, reg, factory, true);
//Note that rather than directly passing "testme" we pass a reference
//to it as the last arg that must be dynamically converted back to
//the right object
Object[] args = new Object[]{new String[]{"a","b"},2,new Integer[]{4,5},ref};
when(testme.bar((String[])args[0],(Integer)args[1],(Integer[])args[2],testme)).thenReturn(testme);
InvocationInfo target = InvocationInfoBuilder.invocationInfo()
.withMethod("bar")
.withParameterTypes(new Class[]{String[].class,int.class,Integer[].class,TestMe.class})
.withParameters(args)
.build();
ObjInvocationMsg invoke = ObjInvocationMsgBuilder.objInvocationMsg()
.withInvocation(target)
.withTargetObjectId(ref)
.withSource(addr.toString())
.build();
invoker.handleInvocation(invoke);
verify(testme).bar((String[])args[0],(Integer)args[1],(Integer[])args[2],testme);
ArgumentCaptor<ObjInvocationRespMsg> respc = ArgumentCaptor.forClass(ObjInvocationRespMsg.class);
verify(bus).publish(respc.capture());
ObjInvocationRespMsg resp = respc.getValue();
assertEquals(addr.toString(), resp.getDestination());
assertEquals(ref,resp.getResult());
assertNull(resp.getException());
assertEquals(invoke.getId(),resp.getResponseTo());
}
}