/*
* Copyright (c) 2012 Diamond Light Source Ltd.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*/
package uk.ac.diamond.scisoft.analysis.rpc;
import org.eclipse.dawnsci.analysis.api.rpc.AnalysisRpcException;
import org.eclipse.dawnsci.analysis.api.rpc.AnalysisRpcRemoteException;
import org.eclipse.dawnsci.analysis.api.rpc.IAnalysisRpcHandler;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
public class AnalysisRpcExceptionsTest {
private static final class CatStringsHandler implements IAnalysisRpcHandler {
@Override
public Object run(Object[] unflattened) {
return (String)unflattened[0] + (String)unflattened[1];
}
}
private static final int PORT = 8614;
private static final String CAT_TWO_STRINGS = "cat";
private static AnalysisRpcServer analysisRpcServer;
private static AnalysisRpcClient analysisRpcClient;
@BeforeClass
public static void setupBeforeClass() throws AnalysisRpcException {
analysisRpcServer = new AnalysisRpcServer(PORT);
analysisRpcServer.start();
analysisRpcServer.addHandler(CAT_TWO_STRINGS, new CatStringsHandler());
analysisRpcClient = new AnalysisRpcClient(PORT);
}
@AfterClass
public static void tearDownAfterClass() {
analysisRpcServer.shutdown();
}
@Test
public void testBasicOperation() throws AnalysisRpcException {
String result = (String)analysisRpcClient.request(CAT_TWO_STRINGS, new Object[] {"Hello, ", "World!"});
Assert.assertEquals("Hello, World!", result);
}
@Test
public void testHandlerExceptionOperation() {
// force an ArrayIndexOutOfBoundsException in the handler and make sure it is raised rather than returned
// due to flattening, it will be raised as an Exception wrapped in an AnalysisRpcException
try {
analysisRpcClient.request(CAT_TWO_STRINGS, new Object[] {"Hello, "});
Assert.fail("No exception raised");
} catch (AnalysisRpcException e) {
// The exception type is lost, but we preserve it in the message string
Assert.assertFalse(e.getCause() instanceof ArrayIndexOutOfBoundsException);
Assert.assertTrue(e.getCause() instanceof AnalysisRpcRemoteException);
Assert.assertTrue(e.getCause().getMessage().startsWith("java.lang.ArrayIndexOutOfBoundsException:"));
}
}
@Test
public void testInternalExceptionOperation() {
// force a flattening exception on the call side
try {
analysisRpcClient.request(CAT_TWO_STRINGS, new Object[] {new Object()});
Assert.fail("No exception raised");
} catch (AnalysisRpcException e) {
Assert.assertEquals(UnsupportedOperationException.class, e.getCause().getClass());
}
}
@Test
public void testNoMatchingHandlerException() {
// force a not found on the call side error
try {
analysisRpcClient.request(CAT_TWO_STRINGS + " invalid", new Object[] {"Hello, ", "World!"});
Assert.fail("No exception raised");
} catch (AnalysisRpcException e) {
Assert.assertTrue(e.getCause() instanceof AnalysisRpcRemoteException);
Assert.assertEquals("org.eclipse.dawnsci.analysis.api.rpc.AnalysisRpcException: No handler registered for " + CAT_TWO_STRINGS + " invalid", e.getCause().getMessage());
}
}
@Test
public void testRemoteRaisesException() {
// have remote code raise an exception and make sure that the stack trace is preserved
// we don this by forcing a class cast exception (ie cat String + Integer
try {
analysisRpcClient.request(CAT_TWO_STRINGS, new Object[] {"Hello, ", 2});
Assert.fail("No exception raised");
} catch (AnalysisRpcException e) {
Assert.assertTrue(e.getCause().getMessage().startsWith("java.lang.ClassCastException:"));
StackTraceElement[] remoteStackTrace = e.getCause().getStackTrace();
Assert.assertEquals(CatStringsHandler.class.getName(), remoteStackTrace[0].getClassName());
Assert.assertEquals("run", remoteStackTrace[0].getMethodName());
}
}
}