ScriptRunnable.java revision 877:cf4d2252d444
11590Srgrimes/*
21590Srgrimes * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
31590Srgrimes * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
41590Srgrimes *
51590Srgrimes * This code is free software; you can redistribute it and/or modify it
61590Srgrimes * under the terms of the GNU General Public License version 2 only, as
71590Srgrimes * published by the Free Software Foundation.  Oracle designates this
81590Srgrimes * particular file as subject to the "Classpath" exception as provided
91590Srgrimes * by Oracle in the LICENSE file that accompanied this code.
101590Srgrimes *
111590Srgrimes * This code is distributed in the hope that it will be useful, but WITHOUT
121590Srgrimes * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
131590Srgrimes * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
141590Srgrimes * version 2 for more details (a copy is included in the LICENSE file that
151590Srgrimes * accompanied this code).
161590Srgrimes *
171590Srgrimes * You should have received a copy of the GNU General Public License version
181590Srgrimes * 2 along with this work; if not, write to the Free Software Foundation,
191590Srgrimes * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
201590Srgrimes *
211590Srgrimes * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
221590Srgrimes * or visit www.oracle.com if you need additional information or have any
231590Srgrimes * questions.
241590Srgrimes */
251590Srgrimes
261590Srgrimespackage jdk.nashorn.internal.test.framework;
271590Srgrimes
281590Srgrimesimport java.io.BufferedReader;
291590Srgrimesimport java.io.ByteArrayOutputStream;
301590Srgrimesimport java.io.File;
311590Srgrimesimport java.io.FileInputStream;
321590Srgrimesimport java.io.FileOutputStream;
331590Srgrimesimport java.io.IOException;
3487690Smarkmimport java.io.InputStreamReader;
3587690Smarkmimport java.io.OutputStream;
3687690Smarkmimport java.io.PrintStream;
3787690Smarkmimport java.io.PrintWriter;
381590Srgrimesimport java.io.StringReader;
3928693Scharnierimport java.nio.file.FileSystems;
401590Srgrimesimport java.nio.file.Files;
411590Srgrimesimport java.nio.file.StandardCopyOption;
4287690Smarkmimport java.util.ArrayList;
431590Srgrimesimport java.util.List;
441590Srgrimesimport java.util.Map;
4587690Smarkmimport jdk.nashorn.tools.Shell;
4628693Scharnierimport org.testng.Assert;
471590Srgrimesimport org.testng.ITest;
481590Srgrimesimport org.testng.annotations.Test;
491590Srgrimes
501590Srgrimes/**
5112811Sbde * Compiles a single JavaScript script source file and executes the resulting
521590Srgrimes * class. Optionally, output from running the script is compared against the
531590Srgrimes * corresponding .EXPECTED file.
541590Srgrimes */
551590Srgrimespublic final class ScriptRunnable extends AbstractScriptRunnable implements ITest {
561590Srgrimes    public ScriptRunnable(final String framework, final File testFile, final List<String> engineOptions, final Map<String, String> testOptions,  final List<String> scriptArguments) {
57111008Sphk        super(framework, testFile, engineOptions, testOptions, scriptArguments);
581590Srgrimes
5912804Speter        if (this.shouldRun) {
6012811Sbde          // add --dump-on-error option always so that we can get detailed error msg.
6112811Sbde          engineOptions.add("-doe");
6212811Sbde        }
6328693Scharnier    }
6487690Smarkm
6528693Scharnier    @Override
6628693Scharnier    public String getTestName() {
6728693Scharnier        return testFile.getAbsolutePath();
6828693Scharnier    }
691590Srgrimes
7028693Scharnier    @Test
711590Srgrimes    @Override
721590Srgrimes    public void runTest() throws IOException {
731590Srgrimes        try {
7430180Sdima            super.runTest();
7528693Scharnier        } catch(final AssertionError e) {
7628693Scharnier            throw new AssertionError("Failed executing test " + testFile, e);
771590Srgrimes        }
7887690Smarkm    }
7987690Smarkm
8087690Smarkm    @Override
811590Srgrimes    protected void execute() {
821590Srgrimes        if (fork) {
8339230Sgibbs            executeInNewProcess();
841590Srgrimes        } else {
8539230Sgibbs            executeInThisProcess();
861590Srgrimes        }
8739230Sgibbs    }
881590Srgrimes
8939230Sgibbs    // avoid direct System.out.println - use reporter to capture
901590Srgrimes    @Override
9139230Sgibbs    protected void log(final String msg) {
921590Srgrimes        org.testng.Reporter.log(msg, true);
9339230Sgibbs    }
941590Srgrimes
9539230Sgibbs    // throw Assert fail - but log as well so that user can see this at console
961590Srgrimes    @Override
9739230Sgibbs    protected void fail(final String msg) {
981590Srgrimes        log(msg);
9939230Sgibbs        Assert.fail(msg);
1001590Srgrimes    }
10130180Sdima
10294729Sjeff    @Override
1031590Srgrimes    protected void compile() throws IOException {
104113460Stjr        final ByteArrayOutputStream out = new ByteArrayOutputStream();
1051590Srgrimes        final ByteArrayOutputStream err = new ByteArrayOutputStream();
106113460Stjr        final List<String> args = getCompilerArgs();
1071590Srgrimes        int errors;
108113460Stjr
1091590Srgrimes        try {
110113460Stjr            errors = evaluateScript(out, err, args.toArray(new String[args.size()]));
11192653Sjeff        } catch (final AssertionError e) {
11294729Sjeff            final PrintWriter writer = new PrintWriter(err);
1131590Srgrimes            e.printStackTrace(writer);
1141590Srgrimes            writer.flush();
1151590Srgrimes            errors = 1;
1161590Srgrimes        }
11739230Sgibbs
11839498Sken        if (errors != 0 || checkCompilerMsg) {
11939498Sken            if (expectCompileFailure || checkCompilerMsg) {
12039230Sgibbs                final PrintStream outputDest = new PrintStream(new FileOutputStream(errorFileName));
12139230Sgibbs                TestHelper.dumpFile(outputDest, new StringReader(new String(err.toByteArray())));
12239230Sgibbs                outputDest.println("--");
12339230Sgibbs            } else {
12439498Sken                log(new String(err.toByteArray()));
12539498Sken            }
12639230Sgibbs
12739230Sgibbs            if (errors != 0 && !expectCompileFailure) {
1281590Srgrimes                fail(String.format("%d errors compiling %s", errors, testFile));
1291590Srgrimes            }
1301590Srgrimes            if (checkCompilerMsg) {
1311590Srgrimes                compare(errorFileName, expectedFileName, true);
13239372Sdillon            }
1331590Srgrimes        }
1341590Srgrimes
1351590Srgrimes        if (expectCompileFailure && errors == 0) {
1361590Srgrimes            fail(String.format("No errors encountered compiling negative test %s", testFile));
1371590Srgrimes        }
1381590Srgrimes    }
1391590Srgrimes
1401590Srgrimes    private void executeInThisProcess() {
1411590Srgrimes        final List<String> args = getRuntimeArgs();
14243962Sdillon        final File outputFileHandle = new File(outputFileName);
1431590Srgrimes        final File errorFileHandle  = new File(errorFileName);
14492922Simp
14592922Simp        try (OutputStream outputFile = new FileOutputStream(outputFileName); OutputStream errorFile = new FileOutputStream(errorFileName)) {
146122300Sjmg            final int errors = evaluateScript(outputFile, errorFile, args.toArray(new String[args.size()]));
14792922Simp
14892922Simp            if (errors != 0 || errorFileHandle.length() > 0) {
14992922Simp                if (expectRunFailure) {
150122300Sjmg                    return;
15192922Simp                }
15292922Simp
15392922Simp                if (!ignoreStdError) {
15492922Simp                    if (outputFileHandle.length() > 0) {
15592922Simp                        TestHelper.dumpFile(outputFileHandle);
15692922Simp                    }
1571590Srgrimes                    fail(TestHelper.fullContent(errorFileHandle));
15892922Simp                }
15992922Simp            }
16087690Smarkm
16192922Simp            if (compare) {
16287690Smarkm                compare(outputFileName, expectedFileName, false);
16328693Scharnier            }
1641590Srgrimes        } catch (final IOException e) {
16587690Smarkm            if (!expectRunFailure) {
16687690Smarkm                fail("Failure running test " + testFile + ": " + e.getMessage());
1671590Srgrimes                // else success
16887690Smarkm            }
1691590Srgrimes        }
1701590Srgrimes    }
1711590Srgrimes
17278474Sschweikh    private void executeInNewProcess() {
1731590Srgrimes
1741590Srgrimes        final String separator = System.getProperty("file.separator");
1751590Srgrimes        final List<String> cmd = new ArrayList<>();
17643822Sken
17744067Sbde        cmd.add(System.getProperty("java.home") + separator + "bin" + separator + "java");
1781590Srgrimes        cmd.add("-Djava.ext.dirs=dist");
1791590Srgrimes        for (final String str : forkJVMOptions) {
1801590Srgrimes            if(!str.isEmpty()) {
1811590Srgrimes                cmd.add(str);
1821590Srgrimes            }
183113460Stjr        }
1841590Srgrimes        cmd.add(Shell.class.getName());
1851590Srgrimes        // now add the rest of the "in process" runtime arguments
1861590Srgrimes        cmd.addAll(getRuntimeArgs());
1871590Srgrimes
1881590Srgrimes        final File outputFileHandle = new File(outputFileName);
1891590Srgrimes        final File errorFileHandle = new File(errorFileName);
1901590Srgrimes
1911590Srgrimes        try {
1921590Srgrimes            final ProcessBuilder pb = new ProcessBuilder(cmd);
1931590Srgrimes            pb.redirectOutput(outputFileHandle);
1941590Srgrimes            pb.redirectError(errorFileHandle);
1951590Srgrimes            final Process process = pb.start();
1961590Srgrimes
19739230Sgibbs            process.waitFor();
19839372Sdillon
19939230Sgibbs            if (errorFileHandle.length() > 0) {
20039230Sgibbs                if (expectRunFailure) {
20139230Sgibbs                    return;
20239230Sgibbs                }
20339230Sgibbs                if (!ignoreStdError) {
20439230Sgibbs                    if (outputFileHandle.length() > 0) {
205112284Sphk                        TestHelper.dumpFile(outputFileHandle);
20639230Sgibbs                    }
20739230Sgibbs                    fail(TestHelper.fullContent(errorFileHandle));
2081590Srgrimes                }
2091590Srgrimes            }
2101590Srgrimes
2111590Srgrimes            if (compare) {
21230180Sdima                compare(outputFileName, expectedFileName, false);
2131590Srgrimes            }
21430180Sdima        } catch (final IOException | InterruptedException e) {
21530180Sdima            if (!expectRunFailure) {
21630180Sdima                fail("Failure running test " + testFile + ": " + e.getMessage());
2171590Srgrimes                // else success
2181590Srgrimes            }
2191590Srgrimes        }
2201590Srgrimes    }
22144067Sbde
22244067Sbde    private void compare(final String outputFileName0, final String expectedFileName0, final boolean compareCompilerMsg) throws IOException {
22344067Sbde        final File expectedFile = new File(expectedFileName0);
2241590Srgrimes
2251590Srgrimes        BufferedReader expected;
2261590Srgrimes        if (expectedFile.exists()) {
2271590Srgrimes            expected = new BufferedReader(new InputStreamReader(new FileInputStream(expectedFileName0)));
2281590Srgrimes            // copy expected file overwriting existing file and preserving last
2291590Srgrimes            // modified time of source
2301590Srgrimes            try {
2311590Srgrimes                Files.copy(FileSystems.getDefault().getPath(expectedFileName0),
2321590Srgrimes                        FileSystems.getDefault().getPath(copyExpectedFileName),
2331590Srgrimes                        StandardCopyOption.REPLACE_EXISTING,
2341590Srgrimes                        StandardCopyOption.COPY_ATTRIBUTES);
2351590Srgrimes            } catch (final IOException ex) {
2361590Srgrimes                fail("failed to copy expected " + expectedFileName + " to " + copyExpectedFileName + ": " + ex.getMessage());
2371590Srgrimes            }
2381590Srgrimes        } else {
2391590Srgrimes            expected = new BufferedReader(new StringReader(""));
2401590Srgrimes        }
2411590Srgrimes
24228693Scharnier        final BufferedReader actual = new BufferedReader(new InputStreamReader(new FileInputStream(outputFileName0)));
24328693Scharnier        compare(actual, expected, compareCompilerMsg);
24428693Scharnier    }
24582664Sru}
2461590Srgrimes