package org.jacorb.test.orb.policies;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import junit.framework.AssertionFailedError;
import org.jacorb.test.AMI_TimingServerHandler;
import org.jacorb.test.AMI_TimingServerHandlerOperations;
import org.jacorb.test.AMI_TimingServerHandlerPOATie;
import org.jacorb.test.EmptyException;
import org.jacorb.test.TimingServer;
import org.jacorb.test.TimingServerHelper;
import org.jacorb.test._TimingServerStub;
import org.jacorb.test.harness.CallbackTestCase;
import org.jacorb.test.harness.ClientServerSetup;
import org.jacorb.util.Time;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.omg.CORBA.Policy;
import org.omg.CORBA.PolicyError;
import org.omg.CORBA.SetOverrideType;
import org.omg.Messaging.ExceptionHolder;
import org.omg.Messaging.RELATIVE_REQ_TIMEOUT_POLICY_TYPE;
import org.omg.Messaging.RELATIVE_RT_TIMEOUT_POLICY_TYPE;
import org.omg.Messaging.REPLY_END_TIME_POLICY_TYPE;
import org.omg.Messaging.REPLY_START_TIME_POLICY_TYPE;
import org.omg.Messaging.REQUEST_END_TIME_POLICY_TYPE;
import org.omg.Messaging.REQUEST_START_TIME_POLICY_TYPE;
import org.omg.TimeBase.UtcT;
import org.omg.TimeBase.UtcTHelper;
/**
* @author Andre Spiegel spiegel@gnu.org
*/
public class TimingTest extends CallbackTestCase
{
private TimingServer server = null;
@Before
public void setUp() throws Exception
{
server = TimingServerHelper.narrow (setup.getServerObject());
}
private class ReplyHandler
extends CallbackTestCase.ReplyHandler
implements AMI_TimingServerHandlerOperations
{
public void ex_op_excep(ExceptionHolder excep_holder)
{
wrong_exception ("ex_op_excep", excep_holder);
}
public void ex_op(char ami_return_val)
{
wrong_reply ("ex_op");
}
public void operation_excep(ExceptionHolder excep_holder)
{
wrong_exception ("operation_excep", excep_holder);
}
public void operation(int ami_return_val)
{
wrong_reply ("operation");
}
public void server_time_excep(ExceptionHolder excep_holder)
{
wrong_exception ("server_time_excep", excep_holder);
}
public void server_time(long ami_return_val)
{
wrong_reply ("server_time");
}
}
private AMI_TimingServerHandler ref ( ReplyHandler handler )
{
AMI_TimingServerHandlerPOATie tie =
new AMI_TimingServerHandlerPOATie( handler )
{
@Override
public org.omg.CORBA.portable.OutputStream
_invoke( String method,
org.omg.CORBA.portable.InputStream _input,
org.omg.CORBA.portable.ResponseHandler handler )
throws org.omg.CORBA.SystemException
{
try
{
return super._invoke( method, _input, handler );
}
catch( AssertionFailedError e )
{
return null;
}
}
};
return tie._this( setup.getClientOrb() );
}
@BeforeClass
public static void beforeClassSetUp() throws Exception
{
setup = new ClientServerSetup
(
"org.jacorb.test.orb.policies.TimingServerImpl");
// some tests are disabled below (no test prefix)
// because it is impossible
// to make them succeed on a fast machine where the Java
// clock has only millisecond resolution
}
/**
* Do a few synchronous invocations as a sanity check
* and to get all the necessary classes loaded.
*/
@Test
public void test_sync_no_timing() throws Exception
{
int result = server.operation (1, 0);
assertEquals (1, result);
result = server.operation (2, 10);
assertEquals (2, result);
result = server.operation (3, 100);
assertEquals (3, result);
try
{
server.ex_op('e', 50);
fail ("should have raised EmptyException");
}
catch (EmptyException ex)
{
// ok
}
try
{
server.ex_op('$', 50);
fail ("should have raised DATA_CONVERSION");
}
catch (org.omg.CORBA.DATA_CONVERSION ex)
{
// ok
}
}
/**
* Do a few asynchronous invocations as a sanity check
* and to get all the necessary classes loaded.
*/
@Test
public void test_async_no_timing()
{
ReplyHandler handler = new ReplyHandler()
{
@Override
public void operation (int ami_return_val)
{
this.assertEquals (7, ami_return_val);
pass();
}
};
((_TimingServerStub)server).sendc_operation (ref (handler), 7, 50);
handler.wait_for_reply(400);
handler = new ReplyHandler()
{
@Override
public void ex_op_excep (ExceptionHolder excep_holder)
{
this.assertEquals (EmptyException.class,
getException (excep_holder).getClass());
pass();
}
};
((_TimingServerStub)server).sendc_ex_op (ref (handler), 'e', 50);
handler.wait_for_reply(400);
handler = new ReplyHandler()
{
@Override
public void ex_op_excep (ExceptionHolder excep_holder)
{
this.assertEquals (org.omg.CORBA.DATA_CONVERSION.class,
getException (excep_holder).getClass());
pass();
}
};
((_TimingServerStub)server).sendc_ex_op (ref (handler), '$', 50);
handler.wait_for_reply(400);
}
/**
* Set all timing policies to values that will be met by the invocation.
*/
@Test
public void test_all_policies_sync_ok() throws Exception
{
server = clearPolicies (server);
server = setRequestStartTime (server, System.currentTimeMillis());
server = setRequestEndTime (server, System.currentTimeMillis() + 2000);
server = setRelativeRequestTimeout (server, System.currentTimeMillis() + 3000);
server = setReplyStartTime (server, System.currentTimeMillis());
server = setReplyEndTime (server, System.currentTimeMillis() + 5000);
server = setRelativeRoundtripTimeout(server, System.currentTimeMillis() + 6000);
assertEquals(434, server.operation (434, 500));
}
/**
* Sets a RequestStartTime which will already have expired
* when the request arrives.
*/
@Test
public void test_request_start_time_sync_expired()
{
server = clearPolicies (server);
long start = System.currentTimeMillis();
server = setRequestStartTime (server, start);
server.server_time (10);
long delta = System.currentTimeMillis() - start;
if (delta > 200)
{
fail ("reply too late (" + delta + "ms)");
}
}
/**
* Sets a RequestStartTime which will not have been reached
* when the request arrives.
*/
@Test
public void test_request_start_time_sync_wait()
{
server = clearPolicies (server);
long start = System.currentTimeMillis();
server = setRequestStartTime (server, start + 200);
long time = server.server_time (100);
long delta = time - start;
if (delta < 200)
{
fail ("request started too early (" + delta + "ms)");
}
else if (delta > 250)
{
fail ("request started too late (" + delta + "ms)");
}
}
/**
* Sets a RequestEndTime which will
* be met by the invocation.
*/
@Test
public void test_request_end_time_sync_ok() throws Exception
{
server = clearPolicies (server);
server = setRequestEndTime (server, System.currentTimeMillis() + 400);
server.operation (434, 500);
}
/**
* Sets a RequestEndTime which will have expired prior
* to the invocation.
*/
@Test
public void test_request_end_time_sync_pre_expired()
{
server = clearPolicies (server);
server = setRequestEndTime (server, System.currentTimeMillis() - 200);
try
{
server.operation (121, 50);
fail ("should have been a TIMEOUT");
}
catch (org.omg.CORBA.TIMEOUT t)
{
// ok
}
}
/**
* Sets a RequestEndTime which will have expired prior to the invocation.
*/
@Test
public void test_request_end_time_async_pre_expired()
{
ReplyHandler handler = new ReplyHandler();
server = clearPolicies (server);
server = setRequestEndTime (server, System.currentTimeMillis() - 5);
try
{
((_TimingServerStub)server).sendc_operation (ref (handler), 765, 50);
fail ("should have been a TIMEOUT");
}
catch (org.omg.CORBA.TIMEOUT e)
{
// ok
}
}
/**
* Sets a RequestEndTime which will expire during the invocation.
*/
@Test
public void test_request_end_time_sync_expired() throws Exception
{
server = clearPolicies (server);
server = setRequestEndTime (server, System.currentTimeMillis() - 200);
try
{
server.operation (121, 50);
fail ("should have been a TIMEOUT");
}
catch (org.omg.CORBA.TIMEOUT t)
{
// ok
}
}
/**
* Sets a RelativeRequestTimeout which will
* be met by the invocation.
*/
@Test
public void test_request_timeout_sync_ok()
{
server = clearPolicies (server);
server = setRelativeRequestTimeout (server, 200);
try
{
server.operation (434, 300);
}
catch (org.omg.CORBA.TIMEOUT t)
{
fail ("should not have been a TIMEOUT");
}
}
/**
* Sets a RelativeRequestTimeout which will expire during the invocation.
*/
@Ignore ("### Ignore pre-junit4 disabled test")
@Test
public void test_request_timeout_sync_expired()
{
server = clearPolicies (server);
server = setRelativeRequestTimeout (server, 1);
try
{
server.operation (121, 50);
fail ("should have been a TIMEOUT");
}
catch (org.omg.CORBA.TIMEOUT t)
{
// ok
}
}
/**
* Sets a RelativeRequestTimeout which will
* expire during the invocation.
*/
@Ignore ("### Ignore pre-junit4 disabled test")
@Test
public void test_request_timeout_async_expired()
{
ReplyHandler handler = new ReplyHandler()
{
@Override
public void operation (int ami_return_val)
{
this.fail ("should have raised TIMEOUT");
}
@Override
public void operation_excep (ExceptionHolder excep_holder)
{
this.assertEquals (org.omg.CORBA.TIMEOUT.class,
getException (excep_holder).getClass());
pass();
}
};
server = clearPolicies (server);
server = setRelativeRequestTimeout (server, -100);
((_TimingServerStub)server).sendc_operation (ref (handler), 767, 200);
handler.wait_for_reply (400);
}
/**
* Sets a ReplyStartTime which will already have expired
* when the reply arrives.
*/
@Test
public void test_reply_start_time_sync_expired()
{
server = clearPolicies (server);
long start = System.currentTimeMillis();
server = setReplyStartTime (server, start);
server.operation (18, 10);
long delta = System.currentTimeMillis() - start;
if (delta > 200)
{
fail ("reply too late (" + delta + "ms)");
}
}
/**
* Sets a ReplyStartTime which will not have been reached
* when the reply arrives.
*/
@Test
public void test_reply_start_time_sync_wait()
{
server = clearPolicies (server);
long start = System.currentTimeMillis();
server = setReplyStartTime (server, start + 2000);
int result = server.operation (18, 1000);
assertEquals (18, result);
long delta = System.currentTimeMillis() - start;
if (delta < 2000)
{
fail ("reply too early (" + delta + "ms)");
}
else if (delta > 2500)
{
fail ("reply too late (" + delta + "ms)");
}
}
/**
* Sets a ReplyStartTime which will already have expired
* when the reply arrives.
*/
@Test
public void test_reply_start_time_async_expired()
{
ReplyHandler handler = new ReplyHandler()
{
@Override
public void operation (int ami_return_val)
{
this.assertEquals (19, ami_return_val);
pass();
}
};
server = clearPolicies (server);
long start = System.currentTimeMillis();
server = setReplyStartTime (server, start);
((_TimingServerStub)server).sendc_operation (ref (handler), 19, 500);
handler.wait_for_reply (1000);
long delta = System.currentTimeMillis() - start;
if (delta > 2000)
{
fail ("reply too late (" + delta + "ms)");
}
}
/**
* Sets a ReplyStartTime which will not have been reached
* when the reply arrives.
*/
@Test
public void test_reply_start_time_async_wait()
{
ReplyHandler handler = new ReplyHandler()
{
@Override
public void operation (int ami_return_val)
{
this.assertEquals (19, ami_return_val);
pass();
}
};
server = clearPolicies (server);
long start = System.currentTimeMillis();
server = setReplyStartTime (server, start + 200);
((_TimingServerStub)server).sendc_operation (ref (handler), 19, 100);
handler.wait_for_reply (250);
long delta = System.currentTimeMillis() - start;
if (delta < 200)
{
fail ("reply too early (" + delta + "ms)");
}
}
/**
* Sets a ReplyEndTime which will
* be met by the invocation.
*/
@Test
public void test_reply_end_time_async_ok()
{
ReplyHandler handler = new ReplyHandler()
{
@Override
public void operation (int ami_return_val)
{
this.assertEquals (765, ami_return_val);
pass();
}
};
server = clearPolicies (server);
server = setReplyEndTime (server, System.currentTimeMillis() + 500);
((_TimingServerStub)server).sendc_operation (ref (handler), 765, 50);
handler.wait_for_reply (450);
}
/**
* Sets a ReplyEndTime which will
* expire during the invocation.
*/
@Test
public void test_reply_end_time_async_expired()
{
ReplyHandler handler = new ReplyHandler()
{
@Override
public void operation (int ami_return_val)
{
this.fail ("should have raised TIMEOUT");
}
@Override
public void operation_excep (ExceptionHolder excep_holder)
{
this.assertEquals (org.omg.CORBA.TIMEOUT.class,
getException (excep_holder).getClass());
pass();
}
};
server = clearPolicies (server);
server = setReplyEndTime (server, System.currentTimeMillis() + 1000);
((_TimingServerStub)server).sendc_operation (ref (handler), 767, 2000);
handler.wait_for_reply (4000);
}
/**
* Sets a ReplyEndTime which will
* be met by the invocation.
*/
@Test
public void test_reply_end_time_sync_ok()
{
server = clearPolicies (server);
server = setReplyEndTime (server, System.currentTimeMillis() + 2000);
server.operation (434, 500);
}
/**
* Sets a ReplyEndTime which has expired prior to invocation.
*/
@Test
public void test_reply_end_time_sync_pre_expired()
{
server = clearPolicies (server);
server = setReplyEndTime (server, System.currentTimeMillis() - 100);
try
{
server.operation (44, 100);
fail ("should have raised TIMEOUT");
}
catch (org.omg.CORBA.TIMEOUT t)
{
// ok
}
}
/**
* Sets a ReplyEndTime which will
* expire during invocation.
*/
@Test
public void test_reply_end_time_sync_expired()
{
server = clearPolicies (server);
server = setReplyEndTime (server, System.currentTimeMillis() + 200);
try
{
server.operation (343, 300);
fail ("should have raised TIMEOUT");
}
catch (org.omg.CORBA.TIMEOUT t)
{
// ok
}
}
/**
* Sets a RelativeRoundtripTimeout which will
* be met by the invocation.
*/
@Test
public void test_relative_roundtrip_sync_ok()
{
server = clearPolicies (server);
server = setRelativeRoundtripTimeout (server, 200);
server.operation (434, 50);
}
/**
* Sets a RelativeRoundtripTimeout which will
* expire during invocation.
*/
@Test
public void test_relative_roundtrip_sync_expired()
{
server = clearPolicies (server);
server = setRelativeRoundtripTimeout (server, 200);
try
{
server.operation (343, 300);
fail ("should have raised TIMEOUT");
}
catch (org.omg.CORBA.TIMEOUT t)
{
// ok
}
}
/**
* Sets a RelativeRoundtripTimeout which will
* be met by the invocation.
*/
@Test
public void test_relative_roundtrip_async_ok()
{
ReplyHandler handler = new ReplyHandler()
{
@Override
public void operation (int ami_return_val)
{
this.assertEquals (765, ami_return_val);
pass();
}
};
server = clearPolicies (server);
server = setRelativeRoundtripTimeout (server, 200);
((_TimingServerStub)server).sendc_operation (ref (handler), 765, 50);
handler.wait_for_reply (150);
}
/**
* Sets a RelativeRoundtripTimeout which will
* expire during the invocation.
*/
@Test
public void test_relative_roundtrip_async_expired()
{
ReplyHandler handler = new ReplyHandler()
{
@Override
public void operation (int ami_return_val)
{
this.fail ("should have raised TIMEOUT");
}
@Override
public void operation_excep (ExceptionHolder excep_holder)
{
this.assertEquals (org.omg.CORBA.TIMEOUT.class,
getException (excep_holder).getClass());
pass();
}
};
server = clearPolicies (server);
server = setRelativeRoundtripTimeout (server, 50);
((_TimingServerStub)server).sendc_operation (ref (handler), 767, 100);
handler.wait_for_reply (400);
}
/**
* Test multiple combined policies.
* Sets a Request- and ReplyStartTime which will not have been
* reached. Server needs to wait for both policies.
*/
@Test
public void test_request_reply_start_time_sync_wait()
{
server = clearPolicies (server);
long start = System.currentTimeMillis();
server = setRequestStartTime(server, start + 2000);
server = setReplyStartTime(server, start + 6000);
long serverStart = server.server_time(2000);
long rtTime = System.currentTimeMillis() - start;
// check server starts immediately
assertTrue(serverStart >= start + 2000);
assertTrue(serverStart <= start + 2000 + 500); // 500 ms latency
// check roundtrip time takes 1000 ms
assertTrue(rtTime >= 6000);
assertTrue(rtTime <= 6000 + 500); // 500 ms latency
}
// convenience methods for policy manipulation
// These methods create policies in the really cumbersome way
// via the ORB, so that the mechanism gets tested. Each of the
// policy types in org.jacorb.orb.policies also has a convenience
// constructor that makes it much easier.
private TimingServer clearPolicies (TimingServer server)
{
org.omg.CORBA.Object r = server._set_policy_override (new Policy[]{}, SetOverrideType.SET_OVERRIDE);
server._release();
return TimingServerHelper.narrow (r);
}
private TimingServer setRequestStartTime (TimingServer server, long unixTime)
{
UtcT corbaTime = Time.corbaTime (unixTime);
org.omg.CORBA.ORB orb = setup.getClientOrb();
org.omg.CORBA.Any any = orb.create_any();
UtcTHelper.insert (any, corbaTime);
try
{
Policy policy =
orb.create_policy (REQUEST_START_TIME_POLICY_TYPE.value, any);
org.omg.CORBA.Object r = server._set_policy_override (new Policy[]{ policy },
SetOverrideType.ADD_OVERRIDE);
server._release();
return TimingServerHelper.narrow (r);
}
catch (PolicyError e)
{
throw new RuntimeException ("policy error: " + e);
}
}
private TimingServer setRequestEndTime (TimingServer server, long unixTime)
{
UtcT corbaTime = Time.corbaTime (unixTime);
org.omg.CORBA.ORB orb = setup.getClientOrb();
org.omg.CORBA.Any any = orb.create_any();
UtcTHelper.insert (any, corbaTime);
try
{
Policy policy =
orb.create_policy (REQUEST_END_TIME_POLICY_TYPE.value, any);
org.omg.CORBA.Object r = server._set_policy_override (new Policy[]{ policy },
SetOverrideType.ADD_OVERRIDE);
server._release();
return TimingServerHelper.narrow (r);
}
catch (PolicyError e)
{
throw new RuntimeException ("policy error: " + e);
}
}
private TimingServer setRelativeRequestTimeout (TimingServer server,
long millis)
{
org.omg.CORBA.ORB orb = setup.getClientOrb();
org.omg.CORBA.Any any = orb.create_any();
any.insert_ulonglong (millis * 10000);
try
{
Policy policy =
orb.create_policy (RELATIVE_REQ_TIMEOUT_POLICY_TYPE.value, any);
org.omg.CORBA.Object r = server._set_policy_override (new Policy[]{ policy },
SetOverrideType.ADD_OVERRIDE);
server._release();
return TimingServerHelper.narrow (r);
}
catch (PolicyError e)
{
throw new RuntimeException ("policy error: " + e);
}
}
private TimingServer setReplyStartTime (TimingServer server, long unixTime)
{
UtcT corbaTime = Time.corbaTime (unixTime);
org.omg.CORBA.ORB orb = setup.getClientOrb();
org.omg.CORBA.Any any = orb.create_any();
UtcTHelper.insert (any, corbaTime);
try
{
Policy policy =
orb.create_policy (REPLY_START_TIME_POLICY_TYPE.value, any);
org.omg.CORBA.Object r = server._set_policy_override (new Policy[]{ policy },
SetOverrideType.ADD_OVERRIDE);
server._release();
return TimingServerHelper.narrow (r);
}
catch (PolicyError e)
{
throw new RuntimeException ("policy error: " + e);
}
}
private TimingServer setReplyEndTime (TimingServer server, long unixTime)
{
UtcT corbaTime = Time.corbaTime (unixTime);
org.omg.CORBA.ORB orb = setup.getClientOrb();
org.omg.CORBA.Any any = orb.create_any();
UtcTHelper.insert (any, corbaTime);
try
{
Policy policy =
orb.create_policy (REPLY_END_TIME_POLICY_TYPE.value, any);
org.omg.CORBA.Object r = server._set_policy_override (new Policy[]{ policy },
SetOverrideType.ADD_OVERRIDE);
server._release();
return TimingServerHelper.narrow (r);
}
catch (PolicyError e)
{
throw new RuntimeException ("policy error: " + e);
}
}
private TimingServer setRelativeRoundtripTimeout (TimingServer server,
long millis)
{
org.omg.CORBA.ORB orb = setup.getClientOrb();
org.omg.CORBA.Any any = orb.create_any();
any.insert_ulonglong (millis * 10000);
try
{
Policy policy =
orb.create_policy (RELATIVE_RT_TIMEOUT_POLICY_TYPE.value, any);
org.omg.CORBA.Object r = server._set_policy_override (new Policy[]{ policy },
SetOverrideType.ADD_OVERRIDE);
server._release();
return TimingServerHelper.narrow (r);
}
catch (PolicyError e)
{
throw new RuntimeException ("policy error: " + e);
}
}
}