package org.opentrafficsim.sim0mq.publisher;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.rmi.RemoteException;
import java.util.List;
import java.util.Scanner;
import javax.naming.NamingException;
import org.djunits.value.vdouble.scalar.Length;
import org.djutils.event.EventInterface;
import org.djutils.event.EventListenerInterface;
import org.djutils.serialization.SerializationException;
import org.junit.Test;
import org.opentrafficsim.core.dsol.AbstractOTSModel;
import org.opentrafficsim.core.dsol.OTSModelInterface;
import org.opentrafficsim.core.dsol.OTSSimulator;
import org.opentrafficsim.core.dsol.OTSSimulatorInterface;
import org.opentrafficsim.core.geometry.OTSGeometryException;
import org.opentrafficsim.core.gtu.GTUType;
import org.opentrafficsim.core.network.NetworkException;
import org.opentrafficsim.core.network.OTSNetwork;
import org.opentrafficsim.road.network.OTSRoadNetwork;
import org.opentrafficsim.road.network.factory.xml.parser.XmlNetworkLaneParser;
import org.opentrafficsim.road.network.lane.conflict.ConflictBuilder;
import org.opentrafficsim.road.network.lane.conflict.LaneCombinationList;
import org.sim0mq.Sim0MQException;
import nl.tudelft.simulation.dsol.SimRuntimeException;
import nl.tudelft.simulation.dsol.model.inputparameters.InputParameterMap;
import nl.tudelft.simulation.dsol.model.outputstatistics.OutputStatistic;
/**
* Unit tests. This requires half of OTS in the imports because it sets up a simulation and runs that for a couple of seconds.
*
* 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 PublisherTest implements OTSModelInterface
{
/** ... */
private static final long serialVersionUID = 20200505L;
/** Storage for the last result submitted to the ReturnWrapper. */
@SuppressWarnings("checkstyle:visibilitymodifier")
Object[] lastResult = null;
/**
* Test the Publisher class.
* @throws RemoteException when that happens this test has failed
* @throws NetworkException if that happens uncaught; this test has failed
* @throws OTSGeometryException if that happens uncaught; this test has failed
* @throws NamingException on context error
* @throws SimRuntimeException on DSOL error
* @throws SerializationException - when encoding an error message fails
* @throws Sim0MQException - when encoding an error message fails
*/
@Test
public void testPublisher() throws RemoteException, NetworkException, OTSGeometryException, SimRuntimeException,
NamingException, Sim0MQException, SerializationException
{
ReturnWrapper storeLastResult = new ReturnWrapper()
{
@Override
public void encodeReplyAndTransmit(final Boolean ackNack, final Object[] payload)
{
PublisherTest.this.lastResult = payload;
}
};
OTSSimulatorInterface simulator = new OTSSimulator("test simulator for PublisherTest");
OTSRoadNetwork network = new OTSRoadNetwork("test network for PublisherTest", true, simulator);
Publisher publisher = new Publisher(network);
assertTrue("id of publisher contains id of network", publisher.getId().contains(network.getId()));
TransceiverInterface transceiverInterface = publisher.getIdSource(0, storeLastResult);
assertNotNull("result of getIdSource should not be null", transceiverInterface);
Object[] transceiverNames = transceiverInterface.get(null, storeLastResult);
assertTrue("result of getIdSource should not be empty", transceiverNames.length > 0);
for (Object o : transceiverNames)
{
assertTrue("transceiver name is a String", o instanceof String);
// System.out.println("transceiver: " + o);
}
// See if we can obtain the GTUIdTransceiver
Object[] subscriptionHandler = publisher.get(new Object[] { "GTUs in network" }, storeLastResult);
assertNotNull("result of get should not be null", subscriptionHandler);
assertEquals("result should contain one elements", 1, subscriptionHandler.length);
System.out.println(subscriptionHandler[0]);
assertTrue("Result should contain a String", subscriptionHandler[0] instanceof SubscriptionHandler);
this.lastResult = null;
assertNull("request for non existent transceiver should return null",
publisher.get(new Object[] { "No such transceiver" }, storeLastResult));
checkLastResult("No transceiver with name \"No such transceiver\"");
assertNull("getIdSource with wrong index returns null", publisher.getIdSource(1, storeLastResult));
checkLastResult("Address should be 0");
assertNull("getIdSource with wrong index returns null", publisher.getIdSource(-1, storeLastResult));
checkLastResult("Address should be 0");
}
/**
* Verify that lastResult
is not null, an Object array of length 1 and the one and only element is a String
* with the expected text.
* @param expectedText String; the expected text
*/
public void checkLastResult(final String expectedText)
{
assertNotNull("returnWrapper has stored something", this.lastResult);
assertEquals("returnWrapper has stored one object error message", 1, this.lastResult.length);
assertEquals("Stored result is expected string", expectedText, this.lastResult[0]);
this.lastResult = null;
}
@Override
public void constructModel() throws SimRuntimeException
{
// Ignore
}
@Override
public final OTSSimulatorInterface getSimulator()
{
return null;
}
@Override
public final InputParameterMap getInputParameterMap()
{
return null;
}
@Override
public final List> getOutputStatistics()
{
return null;
}
@Override
public final OTSNetwork getNetwork()
{
return null;
}
@Override
public final String getShortName()
{
return null;
}
@Override
public final String getDescription()
{
return null;
}
/**
* Open an URL, read it and store the contents in a string. Adapted from
* https://stackoverflow.com/questions/4328711/read-url-to-string-in-few-lines-of-java-code
* @param url URL; the URL
* @return String
* @throws IOException when reading the file fails
*/
public static String readStringFromURL(final URL url) throws IOException
{
try (Scanner scanner = new Scanner(url.openStream(), StandardCharsets.UTF_8.toString()))
{
scanner.useDelimiter("\\A");
return scanner.hasNext() ? scanner.next() : "";
}
}
/**
* The Model.
*/
class TestModel extends AbstractOTSModel implements EventListenerInterface
{
/** */
private static final long serialVersionUID = 20170419L;
/** The network. */
private OTSRoadNetwork network;
/** The XML. */
private final String xml;
/**
* @param simulator OTSSimulatorInterface; the simulator
* @param shortName String; the model name
* @param description String; the model description
* @param xml String; the XML description of the simulation model
*/
TestModel(final OTSSimulatorInterface simulator, final String shortName, final String description, final String xml)
{
super(simulator, shortName, description);
this.xml = xml;
}
/** {@inheritDoc} */
@Override
public void notify(final EventInterface event) throws RemoteException
{
System.err.println("Received event " + event);
}
/** {@inheritDoc} */
@Override
public void constructModel() throws SimRuntimeException
{
this.network = new OTSRoadNetwork(getShortName(), true, getSimulator());
try
{
XmlNetworkLaneParser.build(new ByteArrayInputStream(this.xml.getBytes(StandardCharsets.UTF_8)), this.network,
false);
LaneCombinationList ignoreList = new LaneCombinationList();
LaneCombinationList permittedList = new LaneCombinationList();
ConflictBuilder.buildConflictsParallel(this.network, this.network.getGtuType(GTUType.DEFAULTS.VEHICLE),
getSimulator(), new ConflictBuilder.FixedWidthGenerator(Length.instantiateSI(2.0)), ignoreList,
permittedList);
}
catch (Exception e)
{
e.printStackTrace();
}
}
/** {@inheritDoc} */
@Override
public OTSNetwork getNetwork()
{
return this.network;
}
/** {@inheritDoc} */
@Override
public Serializable getSourceId()
{
return "Sim0MQOTSModel";
}
}
/** The test network. */
// @formatter:off
static final String TEST_NETWORK_XML = "\r\n"
+ "\r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " 2m \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " 3.3m \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " -6.2m \r\n"
+ " 3.3m \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " 3.3m \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " 2m \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " -6.2m \r\n"
+ " -9.5m \r\n"
+ " 3.3m \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " -7.85m \r\n"
+ " \r\n"
+ " \r\n"
+ " -6.2m \r\n"
+ " 3.3m \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " -4.55m \r\n"
+ " \r\n"
+ " \r\n"
+ " -6.2m \r\n"
+ " -2.9m \r\n"
+ " 3.3m \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " -8.8m \r\n"
+ " 2m \r\n"
+ " \r\n"
+ " \r\n"
+ " -7.8m \r\n"
+ " \r\n"
+ " \r\n"
+ " -6.2m \r\n"
+ " 3.3m \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " -4.6m \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " -8.8m \r\n"
+ " 2m \r\n"
+ " \r\n"
+ " \r\n"
+ " -7.8m \r\n"
+ " \r\n"
+ " \r\n"
+ " -6.2m \r\n"
+ " 3.3m \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " -4.6m \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " -4.6m \r\n"
+ " \r\n"
+ " \r\n"
+ " -6.2m \r\n"
+ " 3.3m \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " -7.8m \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " -4.6m \r\n"
+ " \r\n"
+ " \r\n"
+ " -6.2m \r\n"
+ " 3.3m \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " -7.8m \r\n"
+ " \r\n"
+ " \r\n"
+ " -8.8m \r\n"
+ " 2m \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r2l \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r1g \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r1 \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r2l \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r1g \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r1 \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r2l \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r1g \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r1 \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r2l \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r1g \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r1 \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r2r \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r2l \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r2r \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r2l \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r2l \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r2l \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r2l \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r2l \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r3 \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r3 \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r3 \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r3 \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r4 \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r4 \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r4 \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " r4 \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " 200.00veh/h \r\n"
+ " 200.00veh/h \r\n"
+ " \r\n"
+ " \r\n"
+ " 300.00veh/h \r\n"
+ " 300.00veh/h \r\n"
+ " \r\n"
+ " \r\n"
+ " 200.00veh/h \r\n"
+ " 200.00veh/h \r\n"
+ " \r\n"
+ " \r\n"
+ " 200.00veh/h \r\n"
+ " 200.00veh/h \r\n"
+ " \r\n"
+ " \r\n"
+ " 300.00veh/h \r\n"
+ " 300.00veh/h \r\n"
+ " \r\n"
+ " \r\n"
+ " 200.00veh/h \r\n"
+ " 200.00veh/h \r\n"
+ " \r\n"
+ " \r\n"
+ " 200.00veh/h \r\n"
+ " 200.00veh/h \r\n"
+ " \r\n"
+ " \r\n"
+ " 300.00veh/h \r\n"
+ " 300.00veh/h \r\n"
+ " \r\n"
+ " \r\n"
+ " 200.00veh/h \r\n"
+ " 200.00veh/h \r\n"
+ " \r\n"
+ " \r\n"
+ " 200.00veh/h \r\n"
+ " 200.00veh/h \r\n"
+ " \r\n"
+ " \r\n"
+ " 300.00veh/h \r\n"
+ " 300.00veh/h \r\n"
+ " \r\n"
+ " \r\n"
+ " 200.00veh/h \r\n"
+ " 200.00veh/h \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " 3600s \r\n"
+ " 1 \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ " \r\n"
+ "\r\n"
+ " \r\n";
// @formatter:on
}