ScriptRunnable.java revision 475:fbd21b00197b
1/* 2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package jdk.nashorn.internal.test.framework; 27 28import java.io.BufferedReader; 29import java.io.ByteArrayOutputStream; 30import java.io.File; 31import java.io.FileInputStream; 32import java.io.FileOutputStream; 33import java.io.IOException; 34import java.io.InputStreamReader; 35import java.io.OutputStream; 36import java.io.PrintStream; 37import java.io.PrintWriter; 38import java.io.StringReader; 39import java.nio.file.FileSystems; 40import java.nio.file.Files; 41import java.nio.file.StandardCopyOption; 42import java.util.ArrayList; 43import java.util.Arrays; 44import java.util.List; 45import java.util.Map; 46 47import jdk.nashorn.tools.Shell; 48import org.testng.Assert; 49import org.testng.ITest; 50import org.testng.annotations.Test; 51 52/** 53 * Compiles a single JavaScript script source file and executes the resulting 54 * class. Optionally, output from running the script is compared against the 55 * corresponding .EXPECTED file. 56 */ 57public final class ScriptRunnable extends AbstractScriptRunnable implements ITest { 58 public ScriptRunnable(final String framework, final File testFile, final List<String> engineOptions, final Map<String, String> testOptions, final List<String> scriptArguments) { 59 super(framework, testFile, engineOptions, testOptions, scriptArguments); 60 61 if (this.shouldRun) { 62 // add --dump-on-error option always so that we can get detailed error msg. 63 engineOptions.add("-doe"); 64 } 65 } 66 67 @Override 68 public String getTestName() { 69 return testFile.getAbsolutePath(); 70 } 71 72 @Test 73 @Override 74 public void runTest() throws IOException { 75 super.runTest(); 76 } 77 78 @Override 79 protected void execute() { 80 if (fork) { 81 executeInNewProcess(); 82 } else { 83 executeInThisProcess(); 84 } 85 } 86 87 // avoid direct System.out.println - use reporter to capture 88 @Override 89 protected void log(String msg) { 90 org.testng.Reporter.log(msg, true); 91 } 92 93 // throw Assert fail - but log as well so that user can see this at console 94 @Override 95 protected void fail(final String msg) { 96 log(msg); 97 Assert.fail(msg); 98 } 99 100 @Override 101 protected void compile() throws IOException { 102 final ByteArrayOutputStream out = new ByteArrayOutputStream(); 103 final ByteArrayOutputStream err = new ByteArrayOutputStream(); 104 final List<String> args = getCompilerArgs(); 105 int errors; 106 107 try { 108 errors = evaluateScript(out, err, args.toArray(new String[args.size()])); 109 } catch (final AssertionError e) { 110 final PrintWriter writer = new PrintWriter(err); 111 e.printStackTrace(writer); 112 writer.flush(); 113 errors = 1; 114 } 115 116 if (errors != 0 || checkCompilerMsg) { 117 if (expectCompileFailure || checkCompilerMsg) { 118 final PrintStream outputDest = new PrintStream(new FileOutputStream(errorFileName)); 119 TestHelper.dumpFile(outputDest, new StringReader(new String(err.toByteArray()))); 120 outputDest.println("--"); 121 } else { 122 log(new String(err.toByteArray())); 123 } 124 125 if (errors != 0 && !expectCompileFailure) { 126 fail(String.format("%d errors compiling %s", errors, testFile)); 127 } 128 if (checkCompilerMsg) { 129 compare(errorFileName, expectedFileName, true); 130 } 131 } 132 133 if (expectCompileFailure && errors == 0) { 134 fail(String.format("No errors encountered compiling negative test %s", testFile)); 135 } 136 } 137 138 private void executeInThisProcess() { 139 final List<String> args = getRuntimeArgs(); 140 final File outputFileHandle = new File(outputFileName); 141 final File errorFileHandle = new File(errorFileName); 142 143 try (OutputStream outputFile = new FileOutputStream(outputFileName); OutputStream errorFile = new FileOutputStream(errorFileName)) { 144 final int errors = evaluateScript(outputFile, errorFile, args.toArray(new String[args.size()])); 145 146 if (errors != 0 || errorFileHandle.length() > 0) { 147 if (expectRunFailure) { 148 return; 149 } 150 151 if (!ignoreStdError) { 152 if (outputFileHandle.length() > 0) { 153 TestHelper.dumpFile(outputFileHandle); 154 } 155 fail(TestHelper.fullContent(errorFileHandle)); 156 } 157 } 158 159 if (compare) { 160 compare(outputFileName, expectedFileName, false); 161 } 162 } catch (final IOException e) { 163 if (!expectRunFailure) { 164 fail("Failure running test " + testFile + ": " + e.getMessage()); 165 // else success 166 } 167 } 168 } 169 170 private void executeInNewProcess() { 171 172 final String separator = System.getProperty("file.separator"); 173 final List<String> cmd = new ArrayList<>(); 174 175 cmd.add(System.getProperty("java.home") + separator + "bin" + separator + "java"); 176 cmd.add("-Djava.ext.dirs=dist"); 177 for (String str : forkJVMOptions) { 178 cmd.add(str); 179 } 180 cmd.add(Shell.class.getName()); 181 // now add the rest of the "in process" runtime arguments 182 cmd.addAll(getRuntimeArgs()); 183 184 final File outputFileHandle = new File(outputFileName); 185 final File errorFileHandle = new File(errorFileName); 186 187 try { 188 final ProcessBuilder pb = new ProcessBuilder(cmd); 189 pb.redirectOutput(outputFileHandle); 190 pb.redirectError(errorFileHandle); 191 final Process process = pb.start(); 192 193 process.waitFor(); 194 195 if (errorFileHandle.length() > 0) { 196 if (expectRunFailure) { 197 return; 198 } 199 if (!ignoreStdError) { 200 if (outputFileHandle.length() > 0) { 201 TestHelper.dumpFile(outputFileHandle); 202 } 203 fail(TestHelper.fullContent(errorFileHandle)); 204 } 205 } 206 207 if (compare) { 208 compare(outputFileName, expectedFileName, false); 209 } 210 } catch (final IOException | InterruptedException e) { 211 if (!expectRunFailure) { 212 fail("Failure running test " + testFile + ": " + e.getMessage()); 213 // else success 214 } 215 } 216 } 217 218 private void compare(final String outputFileName0, final String expectedFileName0, final boolean compareCompilerMsg) throws IOException { 219 final File expectedFile = new File(expectedFileName0); 220 221 BufferedReader expected; 222 if (expectedFile.exists()) { 223 expected = new BufferedReader(new InputStreamReader(new FileInputStream(expectedFileName0))); 224 // copy expected file overwriting existing file and preserving last 225 // modified time of source 226 try { 227 Files.copy(FileSystems.getDefault().getPath(expectedFileName0), 228 FileSystems.getDefault().getPath(copyExpectedFileName), 229 StandardCopyOption.REPLACE_EXISTING, 230 StandardCopyOption.COPY_ATTRIBUTES); 231 } catch (final IOException ex) { 232 fail("failed to copy expected " + expectedFileName + " to " + copyExpectedFileName + ": " + ex.getMessage()); 233 } 234 } else { 235 expected = new BufferedReader(new StringReader("")); 236 } 237 238 final BufferedReader actual = new BufferedReader(new InputStreamReader(new FileInputStream(outputFileName0))); 239 compare(actual, expected, compareCompilerMsg); 240 } 241} 242