001/* Run the Ptolemy model tests in the auto/ directory using cg code generation under JUnit.
002
003   Copyright (c) 2011-2014 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.util.test.junit;
030
031import java.io.File;
032import java.lang.reflect.Method;
033import java.util.Arrays;
034import java.util.LinkedList;
035
036import org.junit.Assert;
037
038import ptolemy.util.FileUtilities;
039import ptolemy.util.StringUtilities;
040
041///////////////////////////////////////////////////////////////////
042//// AutoCGTests
043
044/**
045 * Run the Ptolemy model tests in the auto/ directory using cg code generation
046 * under JUnit.
047 *
048 * <p>
049 * This class provides common facilities used by classes that generate
050 * C and Java code.
051 *
052 * @author Christopher Brooks
053 * @version $Id$
054 * @since Ptolemy II 10.0
055 * @Pt.ProposedRating Red (cxh)
056 * @Pt.AcceptedRating Red (cxh)
057 */
058public class AutoCGTests extends ModelTests {
059
060    /**
061     * Find the ptolemy.cg.kernel.generic.GenericCodeGenerator class
062     * and its generateCode static method that takes an array of
063     * strings.
064     *
065     * @exception Throwable If the class or constructor cannot be found.
066     */
067    public void setUp() throws Throwable {
068        _applicationClass = Class
069                .forName("ptolemy.cg.kernel.generic.GenericCodeGenerator");
070
071        _cgDirectory = new File(
072                StringUtilities.getProperty("user.home") + "/cg");
073
074        Class[] argTypes = new Class[] { String[].class };
075        _generateCodeMethod = _applicationClass.getMethod("generateCode",
076                argTypes);
077    }
078
079    /**
080     *  Generate, compile and run code for a model.
081     *  The
082     *  @param fullPath
083     *            The full path to the model file to be executed. If the
084     *            fullPath ends with the value of the
085     *            {@link #THERE_ARE_NO_AUTO_TESTS}, then the method returns
086     *            immediately.
087     * @param language Either "c" or "java".
088     * @param generateInSubdirectory If true, then generate the code in
089     * in a subdirectory of ~/cg/.
090     * @param inline If true, then generate inline code.
091     * @param maximumLinesPerBlock The maximum number of line of code
092     * generated per block
093     * @param variablesAsArrays If true, then try to save space by
094     * putting variables into arrays.
095     * @param generatorPackageList A semicolon or * separated list of
096     * Java packages to be searched for adapters.  For example,
097     * generic.program.procedural.c.arduino means use the arduino
098     * target.
099     * @exception Throwable If thrown while generating, compiling or
100     * executing the compiled code.
101     */
102    public void runModel(String fullPath, String language,
103            boolean generateInSubdirectory, boolean inline,
104            int maximumLinesPerBlock, boolean variablesAsArrays,
105            String generatorPackageList) throws Throwable {
106        if (fullPath.endsWith(THERE_ARE_NO_AUTO_TESTS)) {
107            System.out.println("No auto/*.xml tests in "
108                    + StringUtilities.getProperty("user.dir"));
109            return;
110        }
111
112        // Delete the ~/cg directory each time so that if the user generates code for
113        // a model using -generateInSubdirectory, we can still have gcc generate an
114        // executable with that name.
115        if (!FileUtilities.deleteDirectory(_cgDirectory)) {
116            System.out.println("Warning, failed to delete " + _cgDirectory);
117        }
118
119        LinkedList<String> argumentsList = new LinkedList<String>(Arrays.asList(
120                "-language", language, "-generateInSubdirectory",
121                Boolean.toString(generateInSubdirectory), "-inline",
122                Boolean.toString(inline), "-maximumLinesPerBlock",
123                Integer.toString(maximumLinesPerBlock), "-variablesAsArrays",
124                Boolean.toString(variablesAsArrays)));
125        if (generatorPackageList != null && generatorPackageList.length() > 0) {
126            argumentsList.add("-generatorPackageList");
127            argumentsList.add(generatorPackageList);
128        }
129        argumentsList.add(fullPath);
130
131        String[] args = argumentsList.toArray(new String[argumentsList.size()]);
132
133        System.out.print("----------------- AutoCG $PTII/bin/ptcg");
134        for (int i = 0; i < args.length; i++) {
135            System.out.print(" " + args[i]);
136        }
137
138        int returnValue = ((Integer) _generateCodeMethod.invoke(null,
139                (Object) args)).intValue();
140        if (returnValue != 0) {
141            System.out.println("AutoCGTests: " + fullPath
142                    + ": Return value of the last command executed was not zero, it was: "
143                    + returnValue + ", marking this as a test failure.");
144            Assert.fail(
145                    "Return value of the last command executed was not zero, it was: "
146                            + returnValue);
147        }
148    }
149
150    ///////////////////////////////////////////////////////////////////
151    ////                         protected variables               ////
152
153    /** The directory where the code is generated, usually $HOME/cg. */
154    protected static File _cgDirectory;
155
156    /** The GenericCodeGenerator.generateCode(String[]) method. */
157    protected static Method _generateCodeMethod;
158
159}