/* * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * @test 8151754 8080883 8160089 8170162 8166581 8172102 8171343 8178023 8186708 8179856 8185840 8190383 8341631 * @summary Testing startExCe-up options. * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main * jdk.jdeps/com.sun.tools.javap * jdk.jshell/jdk.internal.jshell.tool * @library /tools/lib * @build Compiler toolbox.ToolBox * @run testng StartOptionTest */ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.PrintStream; import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.util.HashMap; import java.util.Locale; import java.util.function.Consumer; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import jdk.jshell.tool.JavaShellToolBuilder; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; @Test public class StartOptionTest { protected ByteArrayOutputStream cmdout; protected ByteArrayOutputStream cmderr; protected ByteArrayOutputStream console; protected ByteArrayOutputStream userout; protected ByteArrayOutputStream usererr; protected InputStream cmdInStream; private JavaShellToolBuilder builder() { // turn on logging of launch failures Logger.getLogger("jdk.jshell.execution").setLevel(Level.ALL); return JavaShellToolBuilder .builder() .out(new PrintStream(cmdout), new PrintStream(console), new PrintStream(userout)) .err(new PrintStream(cmderr), new PrintStream(usererr)) .in(cmdInStream, null) .persistence(new HashMap<>()) .env(new HashMap<>()) .locale(Locale.ROOT); } protected int runShell(String... args) { try { return builder() .start(Presets.addExecutionIfMissing(args)); } catch (Exception ex) { fail("Repl tool died with exception", ex); } return -1; // for compiler } protected void check(ByteArrayOutputStream str, Consumer checkOut, String label) { byte[] bytes = str.toByteArray(); str.reset(); String out = new String(bytes, StandardCharsets.UTF_8); out = stripAnsi(out); out = out.replaceAll("[\r\n]+", "\n"); if (checkOut != null) { checkOut.accept(out); } else { assertEquals(out, "", label + ": Expected empty -- "); } } protected void checkExit(int ec, Consumer checkCode) { if (checkCode != null) { checkCode.accept(ec); } else { assertEquals(ec, 0, "Expected standard exit code (0), but found: " + ec); } } // Start and check the resultant: exit code (Ex), command output (Co), // user output (Uo), command error (Ce), and console output (Cn) protected void startExCoUoCeCn(Consumer checkExitCode, Consumer checkCmdOutput, Consumer checkUserOutput, Consumer checkError, Consumer checkConsole, String... args) { int ec = runShell(args); checkExit(ec, checkExitCode); check(cmdout, checkCmdOutput, "cmdout"); check(cmderr, checkError, "cmderr"); check(console, checkConsole, "console"); check(userout, checkUserOutput, "userout"); check(usererr, null, "usererr"); } protected void startCheckUserOutput(Consumer checkUserOutput, String... args) { runShell(args); check(userout, checkUserOutput, "userout"); check(usererr, null, "usererr"); } // Start with an exit code and command error check protected void startExCe(int eec, Consumer checkError, String... args) { StartOptionTest.this.startExCoUoCeCn( (Integer ec) -> assertEquals((int) ec, eec, "Expected error exit code (" + eec + "), but found: " + ec), null, null, checkError, null, args); } // Start with a command output check protected void startCo(Consumer checkCmdOutput, String... args) { StartOptionTest.this.startExCoUoCeCn(null, checkCmdOutput, null, null, null, args); } private Consumer assertOrNull(String expected, String label) { return expected == null ? null : s -> assertEquals(s.replaceAll("\\r\\n?", "\n").trim(), expected.trim(), label); } // Start and check the resultant: exit code (Ex), command output (Co), // user output (Uo), command error (Ce), and console output (Cn) protected void startExCoUoCeCn(int expectedExitCode, String expectedCmdOutput, String expectedUserOutput, String expectedError, String expectedConsole, String... args) { startExCoUoCeCn( expectedExitCode == 0 ? null : (Integer i) -> assertEquals((int) i, expectedExitCode, "Expected exit code (" + expectedExitCode + "), but found: " + i), assertOrNull(expectedCmdOutput, "cmdout: "), assertOrNull(expectedUserOutput, "userout: "), assertOrNull(expectedError, "cmderr: "), assertOrNull(expectedConsole, "console: "), args); } // Start with an expected exit code and command error protected void startExCe(int ec, String expectedError, String... args) { startExCoUoCeCn(ec, null, null, expectedError, null, args); } // Start with an expected command output protected void startCo(String expectedCmdOutput, String... args) { startExCoUoCeCn(0, expectedCmdOutput, null, null, null, args); } // Start with an expected user output protected void startUo(String expectedUserOutput, String... args) { startExCoUoCeCn(0, null, expectedUserOutput, null, null, args); } @BeforeMethod public void setUp() { cmdout = new ByteArrayOutputStream(); cmderr = new ByteArrayOutputStream(); console = new ByteArrayOutputStream(); userout = new ByteArrayOutputStream(); usererr = new ByteArrayOutputStream(); setIn("/exit\n"); } protected String writeToFile(String stuff) { Compiler compiler = new Compiler(); Path p = compiler.getPath("doit.repl"); compiler.writeToFile(p, stuff); return p.toString(); } // Set the input from a String protected void setIn(String s) { cmdInStream = new ByteArrayInputStream(s.getBytes()); } // Test load files public void testCommandFile() { String fn = writeToFile("String str = \"Hello \"\n" + "/list\n" + "System.out.println(str + str)\n" + "/exit\n"); startExCoUoCeCn(0, "1 : String str = \"Hello \";\n", "Hello Hello", null, null, "--no-startup", fn, "-s"); } // Test that the usage message is printed public void testUsage() { for (String opt : new String[]{"-?", "-h", "--help"}) { startCo(s -> { assertTrue(s.split("\n").length >= 7, "Not enough usage lines: " + s); assertTrue(s.startsWith("Usage: jshell