* Copyright (c) 2020-2020 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved.
* BSD-style license. See OpenTrafficSim License.
*
* $LastChangedDate: 2020-02-13 11:08:16 +0100 (Thu, 13 Feb 2020) $, @version $Revision: 6383 $, by $Author: pknoppers $,
* @author Peter Knoppers
*/
public class TransceiverTest
{
/** Storage for the last ACK or NACK value submitted to the ReturnWrapper. */
@SuppressWarnings("checkstyle:visibilitymodifier")
Boolean lastAckNack = null;
/** Storage for the last payload submitted to the ReturnWrapper. */
@SuppressWarnings("checkstyle:visibilitymodifier")
Object[] lastPayload = null;
/** Storage for last content submitted to notify method in EventListenerInterface. */
@SuppressWarnings("checkstyle:visibilitymodifier")
Serializable lastContent = null;
/** Time stamp of last notify event. */
@SuppressWarnings("checkstyle:visibilitymodifier")
Time lastTime = null;
/**
* Test the GTUIdTransceiver and the GTUTransceiver.
* @throws RemoteException if the happens, this test has failed
* @throws SerializationException on error
* @throws Sim0MQException on error
* @throws NetworkException on error
* @throws OTSGeometryException on error
* @throws NamingException on error
* @throws SimRuntimeException on error
* @throws GTUException on error
*/
@Test
public void testGTUIdTransceiver() throws RemoteException, Sim0MQException, SerializationException, NetworkException,
OTSGeometryException, SimRuntimeException, NamingException, GTUException
{
ReturnWrapper storeLastResult = new ReturnWrapper()
{
@Override
public void encodeReplyAndTransmit(final Boolean ackNack, final Object[] payload)
{
TransceiverTest.this.lastAckNack = ackNack;
TransceiverTest.this.lastPayload = payload;
}
};
try
{
new GTUIdTransceiver(null);
fail("null argument should have thrown an exception");
}
catch (NullPointerException npe)
{
// Ignore expected exception
}
OTSSimulatorInterface simulator = MockDEVSSimulator.createMock();
OTSRoadNetwork network = new OTSRoadNetwork("test network for TransceiverTest", true, simulator);
GTUIdTransceiver gtuIdTransceiver = new GTUIdTransceiver(network);
assertEquals("getId returns correct id", "GTU id transceiver", gtuIdTransceiver.getId());
assertEquals("address has 0 entries", 0, gtuIdTransceiver.getAddressFields().size());
assertEquals("result has one field", 1, gtuIdTransceiver.getResultFields().size());
assertEquals("type of the result field is String", String[].class,
gtuIdTransceiver.getResultFields().getObjectClass(0));
assertEquals("description of the result field", "String array filled with all currently valid GTU ids",
gtuIdTransceiver.getResultFields().getObjectDescription(0));
try
{
gtuIdTransceiver.getResultFields().getObjectClass(1);
fail("Bad index should have thrown an IndexOutOfBoundsException");
}
catch (IndexOutOfBoundsException ioobe)
{
// Ignore expected exception
}
try
{
gtuIdTransceiver.getResultFields().getObjectClass(-1);
fail("Bad index should have thrown an IndexOutOfBoundsException");
}
catch (IndexOutOfBoundsException ioobe)
{
// Ignore expected exception
}
try
{
gtuIdTransceiver.getResultFields().getObjectDescription(1);
fail("Bad index should have thrown an IndexOutOfBoundsException");
}
catch (IndexOutOfBoundsException ioobe)
{
// Ignore expected exception
}
try
{
gtuIdTransceiver.getResultFields().getObjectDescription(-1);
fail("Bad index should have thrown an IndexOutOfBoundsException");
}
catch (IndexOutOfBoundsException ioobe)
{
// Ignore expected exception
}
for (int i = -1; i <= 1; i++)
{
try
{
gtuIdTransceiver.getIdSource(i, storeLastResult);
fail("any address level should have thrown an IndexOutOfBoundsException");
}
catch (IndexOutOfBoundsException ioobe)
{
// Ignore expected exception
}
}
Object[] result = gtuIdTransceiver.get(null, storeLastResult);
assertNotNull("result should not be null", result);
assertEquals("length of result should be 0", 0, result.length);
assertNull("Bad address",
checkAckNack(gtuIdTransceiver, new Object[] {"this is a bad address"}, false, "wrong length"));
GTUType gtuType = new GTUType("gtuType 1", network);
LaneBasedGTU gtu1 =
new MyMockGTU("gtu 1", gtuType, new DirectedPoint(1, 10, 100, 1, 1, 1), new Speed(1, SpeedUnit.KM_PER_HOUR),
new Acceleration(1, AccelerationUnit.METER_PER_SECOND_2), simulator).getMock();
network.addGTU(gtu1);
result = gtuIdTransceiver.get(null, storeLastResult);
assertEquals("length of result is now 1", 1, result.length);
assertTrue("result contains a string", result[0] instanceof String);
assertEquals("result[0] is name of our mocked GTU", "gtu 1", result[0]);
LaneBasedGTU gtu2 =
new MyMockGTU("gtu 2", gtuType, new DirectedPoint(2, 20, 200, 2, 2, 2), new Speed(2, SpeedUnit.KM_PER_HOUR),
new Acceleration(2, AccelerationUnit.METER_PER_SECOND_2), simulator).getMock();
network.addGTU(gtu2);
result = gtuIdTransceiver.get(new Object[0], storeLastResult);
assertEquals("length of result is now 2", 2, result.length);
for (int i = 0; i < 2; i++)
{
assertTrue("result contains a string", result[i] instanceof String);
// Order is not guaranteed; the network maintains the GTUs in a LinkedHashMap
int count = 0;
String lookingFor = String.format("gtu %d", i + 1);
for (int j = 0; j < 2; j++)
{
if (lookingFor.equals(result[j]))
{
count++;
}
}
assertEquals("found gtu i once", 1, count);
}
// Make the GTUTransceiver
GTUTransceiver gtuTransceiver = new GTUTransceiver(network, gtuIdTransceiver);
assertEquals("GTUTransceiver returns correct id", "GTU transceiver", gtuTransceiver.getId());
assertEquals("getIdSource returns gtuIdTransceiver", gtuIdTransceiver, gtuTransceiver.getIdSource(0, null));
try
{
gtuTransceiver.getIdSource(1, storeLastResult);
fail("Invalid index should have thrown an IndexOutOfBoundsException");
}
catch (IndexOutOfBoundsException ioobe)
{
// Ignore expected exception
}
try
{
gtuTransceiver.getIdSource(-1, storeLastResult);
fail("Invalid index should have thrown an IndexOutOfBoundsException");
}
catch (IndexOutOfBoundsException ioobe)
{
// Ignore expected exception
}
assertEquals("address field 0", "GTU id", gtuTransceiver.getAddressFields().getObjectDescription(0));
try
{
gtuTransceiver.getAddressFields().getObjectDescription(1);
fail("Invalid index should have thrown an IndexOutOfBoundsException");
}
catch (IndexOutOfBoundsException ioobe)
{
// Ignore expected exception
}
try
{
gtuTransceiver.getAddressFields().getObjectDescription(-1);
fail("Invalid index should have thrown an IndexOutOfBoundsException");
}
catch (IndexOutOfBoundsException ioobe)
{
// Ignore expected exception
}
assertEquals("address field class", String.class, gtuTransceiver.getAddressFields().getObjectClass(0));
try
{
gtuTransceiver.getAddressFields().getObjectClass(1);
fail("Invalid index should have thrown an IndexOutOfBoundsException");
}
catch (IndexOutOfBoundsException ioobe)
{
// Ignore expected exception
}
try
{
gtuTransceiver.getAddressFields().getObjectClass(-1);
fail("Invalid index should have thrown an IndexOutOfBoundsException");
}
catch (IndexOutOfBoundsException ioobe)
{
// Ignore expected exception
}
for (int i = 0; i < 2; i++)
{
Object[] gtuResult = gtuTransceiver.get(new Object[] {result[i]}, storeLastResult);
assertNotNull("result is not null", gtuResult);
assertEquals("result has 6 fields", 6, gtuResult.length);
assertEquals("first field is a String", String.class, gtuResult[0].getClass());
assertEquals("gtuResult is gtu with expected id", result[i], gtuResult[0]);
LaneBasedGTU gtu = (LaneBasedGTU) network.getGTU(((String) gtuResult[0]));
assertNotNull("GTU is in the network", gtu);
assertTrue("field 1 is id of a GTUType", gtuResult[1] instanceof String);
assertEquals("gtu type matches", gtuType.getId(), gtuResult[1]);
assertEquals("x matches", gtu.getLocation().x, ((PositionVector) gtuResult[2]).get(0).si, 0.0000);
assertEquals("y matches", gtu.getLocation().y, ((PositionVector) gtuResult[2]).get(1).si, 0.0000);
assertEquals("z matches", gtu.getLocation().z, ((PositionVector) gtuResult[2]).get(2).si, 0.0000);
assertEquals("direction matches", new Direction(gtu.getLocation().getRotZ(), DirectionUnit.EAST_DEGREE).si,
((Direction) gtuResult[3]).si, 0.0001);
assertEquals("speed", gtu.getSpeed(), gtuResult[4]);
assertEquals("acceleration", gtu.getAcceleration(), gtuResult[5]);
}
assertNull("gtuTransceiver returns null for non-existend ID",
gtuTransceiver.get(new Object[] {"NONEXISTENTGTU"}, storeLastResult));
gtuTransceiver.get(new Object[] {123}, storeLastResult);
assertTrue("toString returns something descriptive", gtuTransceiver.toString().contains("Transceiver"));
NodeIdTransceiver nit = new NodeIdTransceiver(network);
assertTrue("toString of node id transceiver returns something descriptive",
nit.toString().startsWith("NodeIdTransceiver"));
LinkIdTransceiver lit = new LinkIdTransceiver(network);
assertTrue("toString of link id transceiver returns something descriptive",
lit.toString().startsWith("LinkIdTransceiver"));
// Give the network two nodes and a link with a lane - A lot of code is required to create a lane :-(
OTSPoint3D node1Point = new OTSPoint3D(10, 20, 30);
OTSRoadNode node1 = new OTSRoadNode(network, "node 1", node1Point, Direction.ZERO);
OTSRoadNode node2 = new OTSRoadNode(network, "node 2", new OTSPoint3D(110, 20, 30), Direction.ZERO);
LinkType roadLinkType = network.getLinkType(LinkType.DEFAULTS.ROAD);
CrossSectionLink link = new CrossSectionLink(network, "1 to 2", node1, node2, roadLinkType,
new OTSLine3D(node1.getPoint(), node2.getPoint()), LaneKeepingPolicy.KEEPRIGHT);
LaneType laneType = network.getLaneType(LaneType.DEFAULTS.RESIDENTIAL_ROAD_LANE);
OTSReplication replication = Mockito.mock(OTSReplication.class);
HistoryManagerDEVS hmd = Mockito.mock(HistoryManagerDEVS.class);
Mockito.when(hmd.now()).thenReturn(Time.ZERO);
Mockito.when(replication.getHistoryManager(simulator)).thenReturn(hmd);
Mockito.when(simulator.getReplication()).thenReturn(replication);
Lane lane = new Lane(link, "lane", Length.ZERO, Length.ZERO, new Length(3, LengthUnit.METER),
new Length(3, LengthUnit.METER), laneType, new Speed(50, SpeedUnit.KM_PER_HOUR));
Stripe stripe = new Stripe(link, Length.ZERO, Length.ZERO, new Length(20, LengthUnit.DECIMETER));
String stripeId = stripe.getId();
LinkGTUIdTransceiver linkgit = new LinkGTUIdTransceiver(network);
assertTrue("toString of LinkGTUIdTransceiver returns something descriptive",
linkgit.toString().startsWith("LinkGTUIdTransceiver"));
assertFalse("LinkGTUIdTransceiver does not have an id source", linkgit.hasIdSource());
assertNull("Bad address", checkAckNack(linkgit, new Object[] {"bad", "address"}, false, "need id of a link"));
assertNull("Non existing link",
checkAckNack(linkgit, new Object[] {"Non existing link"}, false, "Network does not contain a link with id"));
this.lastAckNack = null;
result = linkgit.get(new Object[] {"1 to 2"}, storeLastResult);
assertNotNull(result);
assertEquals("result is empty array", 0, result.length);
assertNull(this.lastAckNack);
LaneGTUIdTransceiver lanegit = new LaneGTUIdTransceiver(network);
assertTrue("toString of LaneGTUIdTransceiver returns something descriptive",
lanegit.toString().startsWith("LaneGTUIdTransceiver"));
assertFalse("LaneGTUIdTransceiver does not have an Id source", lanegit.hasIdSource());
assertNull("Bad address", checkAckNack(lanegit, new Object[] {"this", "is", "a", "bad", "address"}, false,
"need id of a link and id of a CrossSectionElement"));
assertNull("Non existing link", checkAckNack(lanegit, new Object[] {"Non existing link", "Non existing lane"}, false,
"Network does not contain a link with id"));
assertNull("Existing link but non existing lane", checkAckNack(lanegit, new Object[] {"1 to 2", "Non existing lane"},
false, "does not contain a cross section element with id"));
assertNull("Existing link, but non a lane",
checkAckNack(lanegit, new Object[] {"1 to 2", stripeId}, false, "is not a lane"));
this.lastAckNack = null;
result = lanegit.get(new Object[] {"1 to 2", "lane"}, storeLastResult);
assertNull("Existing link and lane should not have sent a NACK or ACK", this.lastAckNack);
assertEquals("Existing link and lane should have sent empty array", 0, result.length);
// Put one of the GTUs on the lane
lane.addGTU(gtu1, 0.3);
this.lastAckNack = null;
result = linkgit.get(new Object[] {"1 to 2"}, storeLastResult);
assertNotNull(result);
assertEquals("result is array with one entry", 1, result.length);
assertEquals("content of entry is id of gtu1", gtu1.getId(), result[0]);
assertNull(this.lastAckNack);
result = lanegit.get(new Object[] {"1 to 2", "lane"}, storeLastResult);
assertNull("Existing link and lane should not have sent a NACK or ACK", this.lastAckNack);
assertEquals("Existing link and lane should have sent empty array", 1, result.length);
assertEquals("content of entry is id of gtu1", gtu1.getId(), result[0]);
assertNull(this.lastAckNack);
Mockito.when(simulator.isInitialized()).thenReturn(false);
SimulatorStateTransceiver sst = new SimulatorStateTransceiver(simulator);
result = sst.get(null, storeLastResult);
assertEquals("get returned one element Object array", 1, result.length);
assertEquals("Mock simulator pretends not to have been initialized", "Not (yet) initialized", result[0]);
Mockito.when(simulator.isInitialized()).thenReturn(true);
// Next statement is not really needed; just making sure
Mockito.when(simulator.isStartingOrRunning()).thenReturn(false);
result = sst.get(null, storeLastResult);
assertEquals("get returned one element Object array", 1, result.length);
assertEquals("Mock simulator pretends be in stopped state", "Stopping or stopped", result[0]);
Mockito.when(simulator.isStartingOrRunning()).thenReturn(true);
result = sst.get(null, storeLastResult);
assertEquals("get returned one element Object array", 1, result.length);
assertEquals("Mock simulator pretends be in stopped state", "Starting or running", result[0]);
LookupEventProducerInterface lepi = sst.getLookupEventProducerInterface();
EventProducerInterface epi = lepi.lookup(null, storeLastResult);
TimedEvent