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" + " \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 }