001/* JUnit test that exports the demos.
002
003   Copyright (c) 2012-2018 The Regents of the University of California.
004   All rights reserved.
005   Permission is hereby granted, without written agreement and without
006   license or royalty fees, to use, copy, modify, and distribute this
007   software and its documentation for any purpose, provided that the above
008   copyright notice and the following two paragraphs appear in all copies
009   of this software.
010
011   IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
012   FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
013   ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
014   THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
015   SUCH DAMAGE.
016
017   THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
018   INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
019   MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
020   PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
021   CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
022   ENHANCEMENTS, OR MODIFICATIONS.
023
024   PT_COPYRIGHT_VERSION_2
025   COPYRIGHTENDKEY
026
027 */
028
029package ptolemy.vergil.basic.export.test.junit;
030
031import java.io.BufferedReader;
032import java.io.DataInputStream;
033import java.io.File;
034import java.io.FileInputStream;
035import java.io.IOException;
036import java.io.InputStreamReader;
037import java.util.Date;
038import java.util.LinkedList;
039import java.util.List;
040
041import org.junit.Assert;
042import org.junit.Test;
043import org.junit.runner.RunWith;
044
045import junitparams.JUnitParamsRunner;
046import junitparams.Parameters;
047import ptolemy.actor.Manager;
048import ptolemy.actor.gui.ConfigurationApplication;
049import ptolemy.kernel.util.KernelException;
050import ptolemy.util.StringUtilities;
051import ptolemy.util.test.junit.AutoTests;
052import ptolemy.vergil.basic.export.ExportModel;
053
054///////////////////////////////////////////////////////////////////
055//// ExportModelJUnitTest
056/**
057 * JUnit test that exports the demos.
058 *
059 * <p>To run these tests, use:
060 * <pre>
061 * cd $PTII
062 * ./configure
063 * ant test.single -Dtest.name=ptolemy.vergil.basic.export.test.junit.ExportModelJUnitTest -Djunit.formatter=plain
064 * </pre>
065 * or
066 * <pre>
067 * cd $PTII/ptolemy/vergil/basic/export/test/junit/;
068 * export CLASSPATH=${PTII}:${PTII}/lib/junit-4.8.2.jar:${PTII}/lib/JUnitParams-0.3.0.jar${PTII}:${PTII}/lib/junit-4.8.2.jar:${PTII}/lib/JUnitParams-0.3.0.jar;
069 * export JAVAFLAGS="-Dptolemy.ptII.exportHTML.linkToJNLP=true -Dptolemy.ptII.exportHTML.usePtWebsite=true"
070 * $PTII/bin/ptinvoke org.junit.runner.JUnitCore ptolemy.vergil.basic.export.test.junit.ExportModelJUnitTest
071 * </pre>
072 * <p>Or, if you want to debug this to find leaks, try removing most of the models from $PTII/ptolemy/configs/doc/models.txt
073 * and then running the above exports followed by $PTII/bin/ptjacl and then:
074 * <pre>
075 * set cmdArgs [java::new {java.lang.String[]} 1 {ptolemy.vergil.basic.export.test.junit.ExportModelJUnitTest}]
076 * java::call org.junit.runner.JUnitCore main $cmdArgs
077 * </pre>
078 * <p>Then a few models will export and leaks can be checked.</p>
079 * <p>
080 * This test uses JUnitParams from <a
081 * href="http://code.google.com/p/junitparams/#in_browser"
082 * >http://code.google.com/p/junitparams/</a>, which is released under <a
083 * href="http://www.apache.org/licenses/LICENSE-2.0#in_browser">Apache License
084 * 2.0</a>.
085 * </p>
086 *
087 * @author Christopher Brooks
088 * @version $Id$
089 * @since Ptolemy II 10.0
090 * @Pt.ProposedRating Green (cxh)
091 * @Pt.AcceptedRating Red (cxh)
092 */
093@RunWith(JUnitParamsRunner.class)
094public class ExportModelJUnitTest {
095    /** Export a model.
096     *  @param modelPath The model to be exported. The code is exported to
097     *  the directory contained by the model.
098     *  @exception Throwable If there is a problem reading or exporting the model.
099     */
100    @Test
101    @Parameters(method = "demos")
102    public void RunExportModel(String modelPath) throws Throwable {
103        String modelFile = modelPath.substring(modelPath.lastIndexOf("/") + 1);
104        String modelName = modelFile.substring(0, modelFile.lastIndexOf("."));
105
106        String ptolemyPtIIDir = StringUtilities.getProperty("ptolemy.ptII.dir");
107        String fullModelPath = ptolemyPtIIDir + "/" + modelPath;
108
109        String modelDirectory = modelPath.substring(0,
110                modelPath.lastIndexOf("/"));
111        // A directory inside the current directory that contains the model because
112        // we remove the contents of the outputDirectory with the force parameter.
113        String outputDirectory = ptolemyPtIIDir + "/" + modelDirectory + "/"
114                + modelName;
115
116        boolean openComposites = _openComposites(modelPath);
117        boolean run = _runDemo(modelPath);
118        long timeOut = _timeOut(modelPath);
119
120        Date date = new Date();
121        ExportModelJUnitTest._incrementCount();
122        System.out.println("####### " + ExportModelJUnitTest._getCount() + " "
123                + date + " $PTII/bin/ptinvoke "
124                + "ptolemy.vergil.basic.export.ExportModel -force htm "
125                + (run ? "-run " : " ")
126                + (openComposites ? "-openComposites " : " ") + "-timeOut "
127                + timeOut + " -whiteBackground " + modelPath + " $PTII/"
128                + modelDirectory + "/" + modelName);
129
130        if (!openComposites) {
131            System.out.println("Warning: not opening composites for "
132                    + modelPath
133                    + ". See ptolemy/vergil/basic/export/test/junit/ExportModelJUnitTest.java");
134        }
135
136        if (!run) {
137            System.out.println("Warning: not running " + modelPath
138                    + ". See ptolemy/vergil/basic/export/test/junit/ExportModelJUnitTest.java");
139        }
140        // ExportModel.exportModel() calls System.exit() unless we set this property.
141        System.setProperty("ptolemy.ptII.doNotExit", "true");
142
143        // Delay if the model is a hlacerti or accessor.
144        AutoTests.delayIfNecessary(fullModelPath);
145
146        ExportModel exportModel = new ExportModel();
147        try {
148            // Set ptolemy.ptII.batchMode so that MessageHandler does
149            // not hang on dialogs.
150            System.setProperty("ptolemy.ptII.batchMode", "true");
151
152            long startTime = new Date().getTime();
153            exportModel.exportModel(false /* copyJavaScriptFiles */,
154                    true /* force */, "htm", fullModelPath, run, openComposites,
155                    false /* open results */, outputDirectory, false /* save */,
156                    timeOut, true /* whitebackground */);
157            System.out.println(Manager.timeAndMemory(startTime));
158        } catch (Throwable throwable) {
159            throwable.printStackTrace();
160            // If exporting html throws an exception, then that is a
161            // test failure, not a test error.
162            Assert.fail("Exporting HTML for " + modelPath + " failed: \n"
163                    + KernelException.stackTraceToString(throwable));
164        }
165    }
166
167    /**
168     * Return a two dimensional array of arrays of strings that name the model
169     * to be exported.
170     *
171     * @return a two dimension array of arrays of strings that name the
172     * models to be exported.
173     * @exception IOException If there is a problem accessing the directory.
174     */
175    public Object[] demos() throws IOException {
176        // Read the contents of $PTII/ptolemy/configs/doc/models.txt
177        String ptolemyPtIIDir = StringUtilities.getProperty("ptolemy.ptII.dir");
178        String modelsFile = ptolemyPtIIDir + "/ptolemy/configs/doc/models.txt";
179        FileInputStream fileInputStream = null;
180        DataInputStream dataInputStream = null;
181        BufferedReader reader = null;
182
183        // If the full configuration exists, use ptolemy/configs/doc/models.txt.
184        // If the full configuration does not exist, then use the *Models.txt
185        // file for the configuration that does exist.  In this way, we can
186        // export the Cape Code models.
187
188        try {
189            File configurationDirectory = ConfigurationApplication
190                    .configurationDirectoryFullOrFirst();
191            if (!configurationDirectory.getCanonicalPath()
192                    .endsWith("configs/full")) {
193                String configurationDirectoryName = configurationDirectory
194                        .getName();
195                File configurationModelsFile = new File(configurationDirectory,
196                        configurationDirectoryName + "Models.txt");
197                if (configurationModelsFile.exists()) {
198                    modelsFile = configurationModelsFile.getCanonicalPath();
199                    System.err.println(
200                            "ExportModelJUnitTest: configurationDirectory is "
201                                    + configurationDirectory + " Using "
202                                    + modelsFile + ".");
203                } else {
204                    System.err.println(
205                            "ExportModelJUnitTest: Warning: configurationDirectory is "
206                                    + configurationDirectory + ", yet "
207                                    + configurationModelsFile
208                                    + " does not exist?  Using " + modelsFile
209                                    + ".");
210                }
211            }
212        } catch (Throwable throwable) {
213            IOException exception = new IOException(
214                    "Failed to get the configuration");
215            exception.initCause(throwable);
216            throw exception;
217        }
218
219        List<String> demos = new LinkedList<String>();
220        try {
221            fileInputStream = new FileInputStream(modelsFile);
222            dataInputStream = new DataInputStream(fileInputStream);
223            reader = new BufferedReader(new InputStreamReader(dataInputStream,
224                    java.nio.charset.Charset.defaultCharset()));
225            String line;
226            while ((line = reader.readLine()) != null) {
227                // Lines in models.txt look like
228                // $CLASSPATH/lbnl/demo/CRoom/CRoom.xml
229                String prefix = "$CLASSPATH/";
230                if (!line.startsWith(prefix)) {
231                    throw new IOException("Line in \"" + modelsFile
232                            + "\" does not start with \"" + prefix
233                            + "\".  Line was:\n" + line);
234                }
235                String modelPath = line.substring(prefix.length());
236                if (_openModel(modelPath)) {
237                    demos.add(modelPath);
238                }
239            }
240        } catch (Exception ex) {
241            IOException exception = new IOException(
242                    "Failed to read \"" + modelsFile + "\"");
243            exception.initCause(ex);
244            throw exception;
245        } finally {
246            if (reader != null) {
247                reader.close();
248            }
249        }
250
251        int i = 0;
252        Object[][] data = new Object[demos.size()][1];
253        for (String demo : demos) {
254            data[i++][0] = demo;
255        }
256        return data;
257    }
258
259    /** Get the number of times RunExportModel has been invoked.
260     *  @return the number of times RunExportModel has been invoked.
261     */
262    protected static int _getCount() {
263        // To avoid FindBugs: Write to static field from instance method.
264        return _count;
265    }
266
267    /** Increment the count of the number of times RunExportModel has been invoked.
268     */
269    protected static void _incrementCount() {
270        // To avoid FindBugs: Write to static field from instance method.
271        _count++;
272    }
273
274    /** Return true if we should open the composites.
275     */
276    private boolean _openComposites(String modelPath) {
277        // Pathnames that should be skipped
278        String[] skip = {
279                // Fails with: Cannot render to more than 32 Canvas3Ds
280                "Gravitation.xml", "GravitationWithCollisionDetection.xml",
281                // PtinyOS is probably not installed and if it is not installed,
282                // the loading the demos will report missing classes.
283                "ptolemy/actor/ptalon/demo/ptinyos",
284                "ptolemy/domains/ptinyos/demo", };
285        for (String element : skip) {
286            if (modelPath.indexOf(element) != -1) {
287                return false;
288            }
289        }
290        return true;
291    }
292
293    /** Return true if we should open the model.
294     */
295    private boolean _openModel(String modelPath) {
296        // Pathnames that should be skipped
297        String[] skip = {
298            "jai/demo", // Skip jai demos because the don't run in JDK9 and later.
299            "ModularCG.xml", // Prompted for save of unamed on close?
300            "pthales/demo/FFT/FFT.xml", // Skip JAI demo.
301            "ptolemy/actor/ptalon/demo/ptinyos/", // PtinyOS is probably not installed.
302            "ptolemy/domains/ptinyos/demo",
303            "ScaleWithEmbeddedCFileActor", // Only works on 32-bit
304            "SimplePassPointer", // Only works on 32-bit
305        };
306        for (String element : skip) {
307            if (modelPath.indexOf(element) != -1) {
308                return false;
309            }
310        }
311        return true;
312    }
313
314    /** Return true if we should run the demo.
315     *  It does not make sense to run some demos.
316     *  This method returns false for those demos.
317     */
318    private boolean _runDemo(String modelPath) {
319        // Pathnames that should be skipped
320        String[] skip = { "ptalon/gt/demo/Adder/Adder.xml", // gt does not have a run button: "Channel index 0 is out of range, because width is only 0."
321                "2Billes2Fed.xml", // Has links to other models
322                "AirManagementSystem.xml", // Assert is thrown.
323                "AirManagementSystemCausalityLoop", // Deliberately brings up message on run.
324                "AMS_AMSSim", // FMU does not reliably build everywhere.
325                "wireless/demo/AntennaPattern/AntennaModel.xml", // Used by other models.
326                "AntennaPattern.xml", // Has links to other models
327                "jjs/modules/audio/demo/Audio/Audio.xml", // Has links to other models.
328                "AudioCapture.xml", // Wrong Audio Hardware on the test machine.
329                "AudioClipPlayer.xml", // Wrong Audio Hardware on the test machine. (ClipPlayer2: Error in ClipPlayer: [] ERROR_MEDIA_AUDIO_FORMAT_UNSUPPORTED: ERROR_MEDIA_AUDIO_FORMAT_UNSUPPORTED)
330                "AudioFFT.xml", // Wrong Audio Hardware on the test machine.
331                "AudioRecorder.xml", // Wrong Audio Hardware on the test machine.
332                "AudioSynthesis.xml", // Wrong Audio Hardware on the test machine.
333                "BouncingBall.xml", // Java3d internal error
334                "AugmentedReality.xml", // Has links to other models.
335                "org/terraswarm/accessor/demo/Audio/Audio.xml", // Wrong Audio Hardware on the test machine.
336                "ConstScaleZeroDemoProductLattice.xml", // Lattice, used by other models.
337                // CRoom, MatlabRoom, SystemCommand
338                "lbnl/demo/", // FIXME: hangs, probably because the log window is not closed.
339                "g4ltl/demo/", // These demos require wiring.
340                "Gravitation.xml", // Java3d internal error
341                "gt/demo/BouncingBallX2/BouncingBallX2.xml", //Hangs during wrapup, probably a threading bug with Java3D/jogamp.
342                // If hlacerti models are hanging, see
343                // AutoTests.delayIfNecessary() and consider
344                // increasing the amount of delay time
345                "org/hlacerti",
346                //"BrockAckerman.xml", // FIXME: Seems to hang when runnning under code coverage.
347                "ConstAbstractInterpretationObservable.xml", // Has links to other models
348                "ConstNonconst/Const.xml", // Has links to other models
349                "data/ontologies/demo/ConstPropagation/ConstPropagation.xml", // Has links to other models
350                "jjs/modules/contextAware/demo/ContextAware/ContextAware.xml", // Need to have the user selecte which service to use before running.
351
352                "jjs/modules/discovery/demo/Discovery/Discovery.xml", // Has links to other models
353                // HLA Models that have links to other demos.
354                "2Billes1Fed.xml", // Has links to other models
355                "2Billes2Fed.xml", // Has links to other models
356                "Billard.xml", // Has links to other models
357                "BillardHit.xml", // Has links to other models
358                "IntegrationTests.xml", // Has links to other models
359                "Others.xml", // Has links to other models
360                "TimeAdvancing1Federate.xml", // Has links to other models
361                "TimeAdvancing2FederatesIntervalEvents", // Has links to other models
362                "org/hlacerti/demo/BillardHit/BillardHit.xml", // Has links to other models
363                "org/hlacerti/demo/legacy/CoSimulationFunctional/CoSimulationFunctional.xml", // Has links to other demos and does not work
364                "org/hlacerti/demo/legacy/CoSimulationNetwork1/CoSimulationNetwork1.xml", // Has links to other demos and does not work
365                "org/hlacerti/demo/legacy/f14HLA/f14HLA.xml", // Has links to other demos and does not work
366                "org/hlacerti/demo/f14HLA/f14HLA.xml", // Has links to other demos.
367                "org/hlacerti/demo/legacy/MultiProducerConsumer/MultiProducerConsumer.xml", // Has links to other demos and does not work
368                "org/hlacerti/demo/MicrostepReset/MicrostepReset.xml", // Has Links to other models.
369                "org/hlacerti/demo/MicrostepReset/DistributedReceiver", // Links.
370                "org/hlacerti/demo/legacy/SimpleProducerConsumer/SimpleProducerConsumer.xml", // Has links to other demos and does not work
371                "org/hlacerti/demo/IntegrationTests/TimeAdvancing2Federates/TimeAdvancing2Federates.xml", // Has links to other demos.
372
373                "DimensionSystemExample.xml", // Has links to other models.
374                "distributed/demo/Sleep/Sleep.xml", // Requires jini.
375                "DECG.xml", // This has links to the DE demos and is not runnable in itself.
376                "de/demo/Clock/Clock.xml", // "Audio Device Unavailable"
377                //"domains/gr", // FIXME: need to close ViewScreen3D by adding a ViewScreen3D Tableau.
378                "ExportExamples.xml", // Has links to other models
379                "f14HLAr74766.xml", // Has links to other models
380                "GeneratorRegulatorProtectorSimXRhapsodyFMU", //SimX only works under 32-bits.
381                "PhysicalPlantCausalityLoop", // Deliberately brings up message on run.  AMS
382                //"GravitationWithCollisionDetection.xml", // "Cannot render to more than 32 Canvas3Ds."
383                //"demo/ExecDemo/Demos/BouncingBall.xml", // "Cannot render to more than 32 Canvas3Ds."
384                "EPlus70Actuator.xml", // Hangs in a strange way after running.o
385                "ElectricPowerSystem.xml", // Just has links to other demos.
386                "ExecDemos", // hangs
387                "FMUSimulationX", // 32-bit only
388                "FourInFourOutsDymola.xml", // Only runs under Ubuntu, not RHEL because of GLIBC problems.
389                "FourInFourOutsDymolaJNI.xml", // Only runs under Ubuntu, not RHEL because of GLIBC problems.
390                "FourInFourOutsDymolaWindows.xml", // Only runs under Windows.
391                "GeneratorContactorLoad.xml", // The GeneratorContactorLoad file is a component used inElectricPowerSystem models.
392                "GeneratorRegulatorProtectorSimXRhapsodyFMU.xml", // 32-bit Windows only.
393                "HappySadStock.xml", // Run only if there is a Hue on the local network.
394                "HierarchyFlattening.xml", // gt
395                "org/terraswarm/accessor/demo/Hue/Hue.xml", // Has links to other demos.
396                "IMUSensor.xml", // Uses the serial port.
397                "actor/lib/io", // Don't run the demos in actor/lib/io, some read from stdin and never exit.
398                "ImageFilters.xml", // Has links to other demos.
399                "iRobotCreateVerification.xml", // Annotation says that it does not simulate.
400                "JMFJAI.xml", // Requires a video camera
401                "KarplusStrong.xml", // "Audio Device Unavailable"
402                "LatticeComposition.xml", // Intentionally throws an error.
403                "LineFault.xml", // Intentionally throws an error.
404                "LongRuns.xml", // Produces almost 1 million lines on stdout.
405                "matlab/demo", // Matlab is not installed on the Travis-ci machine.
406                "MatlabRoom.xml", // Matlab message: Error: Too many inputs passed to SimpleFunctionThunk.
407                "MapReduceDDF.xml", // Hangs.
408                "MoC.xml", // "No line matching interface Clip supporting format PCM_SIGNED unknown sample rate, 16 bit, stereo, 4 bytes/frame, big-endian is supported."
409                "ModularCG.xml", // cg model fails to run while exporting.
410                "data/ontologies/demo/ProductLattices/ProductLattices.xml", // Has links to other models
411                "PageAssembler.xml", // Has links to other models.
412                "ProbabilisticModels.xml", // Has links to other models.
413                "PtidesBasicOnePlatform.xml", // Annotation says not to run.
414                "ptolemy/actor/ptalon/demo/ptinyos/", // PtinyOS is probably not installed.
415                "ptolemy/actor/lib/vertx/demo/PubSub/PubSub.xml", // Has links to pub and sub
416                "ptolemy/actor/lib/vertx/demo/PubSub/Publisher.xml", // Subscriber needs to run
417                "ptolemy/actor/lib/vertx/demo/PubSub/Subscriber.xml", // Publisher needs to run.
418                "PublisherTest", // gt
419                "actor/lib/r", // R is probably not installed.
420                "RealTimeComposite.xml", // "Audio Device Unavailable"
421                "jjs/modules/audio/demo/Audio/Audio.xml", // Has links to other models.
422                "TokenTransmissionTime/Sender.xml", // Requires that Receiver be running.
423                "RecordManipulation", // Python demo pops up a dialog.
424                "jjs/modules/httpClient/demo/REST/REST.xml", // Has links to other demos.
425                "ptolemy/demo/Robot/Robot.xml", // Has links to other demos.
426                "ros/demo/Ros", // Need a robot.
427                "ptolemy/domains/ptinyos/demo", // Ptinyos is probably not installed.
428                "RobotMPC", // Has links to other demos.
429                "RobotOnCircleKV.xml", // Needs the KeyValue model running.
430                "RobotPFChase.xml", // Needs the KeyValue model running.
431                "Ros.xml", // This demo has links to the demo that are to run
432                "RosPublisher.xml", // RosSubscriber needs to run.
433                "RosSubscriber.xml", // RosPublisher needs to run.
434                "RijndaelEncryption.xml", // FIXME: Hangs during wrapup.
435                "cg/lib/demo/Scale/Scale.xml", // Contains links to other demos.
436                "ScaleC.xml", // FIXME: the JVM crashes while running.
437                "SemanticYelpSensorUpdateExample.xml", // Needs a Yelp key
438                "SequencedActors.xml", // Has links to other models
439                "SecureCommServerClientJS.xml", // Does not run under Travis.
440                "actor/lib/io/comm/demo", // Requires serial port.
441                "Signature.xml", // Throws an exception in the normal course of operations.
442                "SimpleTrafficLightSMVModule.xml", // "PedestrianLightSMV can not run in simulation mode."
443                "SmartChaseWithSmartIntruder.xml", // Needs the KeyValue model running.
444                "SmartIntruder.xml", // Needs the KeyValue model running.
445                "SoundSpectrum.xml", // "Audio Device Unavailable"
446                "ptolemy/actor/lib/jjs/modules/speechRecognition/demo/SpeechRecognition/SpeechRecognition.xml", // Audio Device Unavailable
447                "ptolemy/domains/ptides/demo/Speaker/Speaker.xml", // Luminary demo, Annotation says not to run.
448
449                "SwarmAcousticService.xml", // Times out while connecting to a port
450                "SynthesizedVoice.xml", // "Audio Device Unavailable"
451                "SystemLevelType", // The SystemLevelType demos are not meant to be run.
452                "TCPSocket.xml", // Has links to other demos.
453                "ThreadedComposite.xml", // Has links to other demos.
454                "TokenTransmissionTime.xml", // This demo has links to the demo that are to run
455                "TunnelingBallDevice", // Annotation says that it cannot be run.
456                "Ultrasonic.xml", // Arduino only
457                "ptolemy/actor/lib/jjs/modules/vertxEventBus/demo/VertxBus/ReadFromVertxBus.xml", // Requires that other demos run.
458                "ptolemy/actor/lib/jjs/modules/vertxEventBus/demo/VertxBus/VertxBus.xml", // Requires that other demos run.
459                "ptolemy/actor/lib/jjs/modules/vertxEventBus/demo/VertxBus/VertxBusServer.xml", // Just has links to other demos.
460                "ptolemy/actor/lib/jjs/modules/vertxEventBus/demo/VertxBus/WriteToVertxBus.xml", // Requires that other demos run.
461                "ptolemy/domains/ptides/demo/VertxDemo/VertxDemo.xml", // Just has links to other VertX demos.
462                "ptolemy/domains/ptides/demo/VertxDemo/Publisher.xml", // Requires that other demos run.
463                "ptolemy/domains/ptides/demo/VertxDemo/Subscriber.xml", // Requires that other demos run.
464                "ptolemy/domains/ptides/demo/VertxDemo/Publisher2.xml", // Requires that other demos run.
465                "// ptolemy/actor/lib/jjs/modules/vertxEventBus/demo/VertxBus/VertxBusServer.xml", // Requires that other demos run.
466                "UnitSystemExample.xml", // Has links to other models.
467                "VideoCapture.xml", // Requires a video camera.
468                "WatchEmulator.xml", // Fails periodically.                         
469                "WatchCommandUpdater.xml", // Audio device unavailable.
470                "Weather.xml", // Skip because it requires a key
471                "WebSocketChat.xml", // Has links to other models.
472                "WebSocketClient.xml", // Times out unless the server is running.
473                "MatlabWirelessSoundDetection.xml", // If it takes more than 30 seconds to start up, then killing it causes an infinite loop because killing this is difficult when inside a native call.
474                "demo/XBee", // Needs XBee hardware.
475                "modules/xbee", // Needs XBee hardware.
476        };
477        for (String element : skip) {
478            if (modelPath.indexOf(element) != -1) {
479                return false;
480            }
481        }
482        return true;
483    }
484
485    /** Return the time out in milliseconds.
486     *  The timeout for most demos is 30 seconds.
487     *  Some demos run longer.
488     */
489    private long _timeOut(String modelPath) {
490        // Pathnames for demos that get a longer running time
491        String[] longRunningDemos = { "ExecDemos.xml" };
492        for (String longRunningDemo : longRunningDemos) {
493            if (modelPath.indexOf(longRunningDemo) != -1) {
494                return 30000 * 2;
495            }
496        }
497        // Pathnames for demos that get a shorter running time because
498        // they produce too much output.
499        String[] shortRunningDemos = { "CntToLedsAndRfm.xml",
500                "SendAndReceiveCnt.xml", "RfmToLeds.xml", "Surge.xml" };
501        for (String shortRunningDemo : shortRunningDemos) {
502            if (modelPath.indexOf(shortRunningDemo) != -1) {
503                return 5000;
504            }
505        }
506        return 30000;
507    }
508
509    /** Number of models exported. */
510    private static int _count = 0;
511}