test/langtools/jdk/jshell/StartOptionTest.java

Print this page

        

@@ -19,22 +19,21 @@
  * 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
- * @summary Testing start-up options.
+ /*
+ * @test 8151754 8080883 8160089 8170162 8166581 8172102 8171343 8178023 8186708 8179856 8185840 8190383
+ * @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;

@@ -55,16 +54,16 @@
 import static org.testng.Assert.fail;
 
 @Test
 public class StartOptionTest {
 
-    private ByteArrayOutputStream cmdout;
-    private ByteArrayOutputStream cmderr;
-    private ByteArrayOutputStream console;
-    private ByteArrayOutputStream userout;
-    private ByteArrayOutputStream usererr;
-    private InputStream cmdInStream;
+    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

@@ -75,217 +74,286 @@
                     .persistence(new HashMap<>())
                     .env(new HashMap<>())
                     .locale(Locale.ROOT);
     }
 
-    private void runShell(String... args) {
+    protected int runShell(String... args) {
         try {
-            builder()
-                    .run(args);
+            return builder()
+                    .start(args);
         } catch (Exception ex) {
             fail("Repl tool died with exception", ex);
         }
+        return -1; // for compiler
     }
 
     protected void check(ByteArrayOutputStream str, Consumer<String> checkOut, String label) {
         byte[] bytes = str.toByteArray();
         str.reset();
         String out =  new String(bytes, StandardCharsets.UTF_8);
         if (checkOut != null) {
             checkOut.accept(out);
         } else {
-            assertEquals("", out, label + ": Expected empty -- ");
+            assertEquals(out, "", label + ": Expected empty -- ");
+        }
+    }
+
+    protected void checkExit(int ec, Consumer<Integer> checkCode) {
+        if (checkCode != null) {
+            checkCode.accept(ec);
+        } else {
+            assertEquals(ec, 0, "Expected standard exit code (0), but found: " + ec);
         }
     }
 
-    protected void start(Consumer<String> checkCmdOutput,
-            Consumer<String> checkUserOutput, Consumer<String> checkError,
-            String... args) throws Exception {
-        runShell(args);
+    // 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<Integer> checkExitCode,
+            Consumer<String> checkCmdOutput,
+            Consumer<String> checkUserOutput,
+            Consumer<String> checkError,
+            Consumer<String> checkConsole,
+            String... args) {
+        int ec = runShell(args);
+        checkExit(ec, checkExitCode);
         check(cmdout, checkCmdOutput, "cmdout");
         check(cmderr, checkError, "cmderr");
-        check(console, null, "console");
+        check(console, checkConsole, "console");
         check(userout, checkUserOutput, "userout");
         check(usererr, null, "usererr");
     }
 
-    protected void start(String expectedCmdOutput, String expectedError, String... args) throws Exception {
-        startWithUserOutput(expectedCmdOutput, "",  expectedError, args);
+    // Start with an exit code and command error check
+    protected void startExCe(int eec, Consumer<String> 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<String> checkCmdOutput, String... args) {
+        StartOptionTest.this.startExCoUoCeCn(null, checkCmdOutput, null, null, null, args);
+    }
+
+    private Consumer<String> assertOrNull(String expected, String label) {
+        return expected == null
+                ? null
+                : s -> assertEquals(s.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);
     }
 
-    private void startWithUserOutput(String expectedCmdOutput, String expectedUserOutput,
-            String expectedError, String... args) throws Exception {
-        start(
-                s -> assertEquals(s.trim(), expectedCmdOutput, "cmdout: "),
-                s -> assertEquals(s.trim(), expectedUserOutput, "userout: "),
-                s -> assertEquals(s.trim(), expectedError, "cmderr: "),
-                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();
-        cmdInStream = new ByteArrayInputStream("/exit\n".getBytes());
+        setIn("/exit\n");
     }
 
-    protected String writeToFile(String stuff) throws Exception {
+    protected String writeToFile(String stuff) {
         Compiler compiler = new Compiler();
         Path p = compiler.getPath("doit.repl");
         compiler.writeToFile(p, stuff);
         return p.toString();
     }
 
-    public void testCommandFile() throws Exception {
-        String fn = writeToFile("String str = \"Hello \"\n/list\nSystem.out.println(str + str)\n/exit\n");
-        startWithUserOutput("1 : String str = \"Hello \";", "Hello Hello", "", "--no-startup", fn, "-s");
+    // 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");
     }
 
-    public void testUsage() throws Exception {
+    // Test that the usage message is printed
+    public void testUsage() {
         for (String opt : new String[]{"-h", "--help"}) {
-            start(s -> {
+            startCo(s -> {
                 assertTrue(s.split("\n").length >= 7, "Not enough usage lines: " + s);
                 assertTrue(s.startsWith("Usage:   jshell <option>..."), "Unexpect usage start: " + s);
                 assertTrue(s.contains("--show-version"), "Expected help: " + s);
                 assertFalse(s.contains("Welcome"), "Unexpected start: " + s);
-            }, null, null, opt);
+            }, opt);
         }
     }
 
-    public void testHelpExtra() throws Exception {
+    // Test the --help-extra message
+    public void testHelpExtra() {
         for (String opt : new String[]{"-X", "--help-extra"}) {
-            start(s -> {
+            startCo(s -> {
                 assertTrue(s.split("\n").length >= 5, "Not enough help-extra lines: " + s);
                 assertTrue(s.contains("--add-exports"), "Expected --add-exports: " + s);
                 assertTrue(s.contains("--execution"), "Expected --add-exports: " + s);
                 assertFalse(s.contains("Welcome"), "Unexpected start: " + s);
-            }, null, null, opt);
+            }, opt);
         }
     }
 
-    public void testUnknown() throws Exception {
-        start(null, null,
-              s -> assertEquals(s.trim(), "Unknown option: u"), "-unknown");
-        start(null, null,
-              s -> assertEquals(s.trim(), "Unknown option: unknown"), "--unknown");
+    // Test handling of bogus options
+    public void testUnknown() {
+        startExCe(1, "Unknown option: u", "-unknown");
+        startExCe(1, "Unknown option: unknown", "--unknown");
     }
 
-    /**
-     * Test that input is read with "-" and there is no extra output.
-     * @throws Exception
-     */
-    public void testHypenFile() throws Exception {
-        cmdInStream = new ByteArrayInputStream("System.out.print(\"Hello\");\n".getBytes());
-        startWithUserOutput("", "Hello", "", "-");
-        cmdInStream = new ByteArrayInputStream("System.out.print(\"Hello\");\n".getBytes());
-        startWithUserOutput("", "Hello", "", "-", "-");
-        Compiler compiler = new Compiler();
-        Path path = compiler.getPath("markload.jsh");
-        compiler.writeToFile(path, "System.out.print(\"===\");");
-        cmdInStream = new ByteArrayInputStream("System.out.print(\"Hello\");\n".getBytes());
-        startWithUserOutput("", "===Hello===", "", path.toString(), "-", path.toString());
+    // Test that input is read with "-" and there is no extra output.
+    public void testHypenFile() {
+        setIn("System.out.print(\"Hello\");\n");
+        startUo("Hello", "-");
+        setIn("System.out.print(\"Hello\");\n");
+        startUo("Hello", "-", "-");
+        String fn = writeToFile("System.out.print(\"===\");");
+        setIn("System.out.print(\"Hello\");\n");
+        startUo("===Hello===", fn, "-", fn);
         // check that errors go to standard error
-        cmdInStream = new ByteArrayInputStream(") Foobar".getBytes());
-        start(
-                s -> assertEquals(s.trim(), "", "cmdout: empty"),
-                s -> assertEquals(s.trim(), "", "userout: empty"),
-                s -> assertTrue(s.contains("illegal start of expression"),
+        setIn(") Foobar");
+        startExCe(0, s -> assertTrue(s.contains("illegal start of expression"),
                             "cmderr: illegal start of expression"),
                 "-");
     }
 
-    /**
-     * Test that non-existent load file sends output to stderr and does not start (no welcome).
-     * @throws Exception
-     */
-    public void testUnknownLoadFile() throws Exception {
-        start("", "File 'UNKNOWN' for 'jshell' is not found.", "UNKNOWN");
-    }
-
-    public void testStartup() throws Exception {
-        Compiler compiler = new Compiler();
-        Path p = compiler.getPath("file.txt");
-        compiler.writeToFile(p);
-        start("", "Argument to startup missing.", "--startup");
-        start("", "Conflicting options: both --startup and --no-startup were used.", "--no-startup", "--startup", p.toString());
-        start("", "Conflicting options: both --startup and --no-startup were used.", "--startup", p.toString(), "--no-startup");
-        start("", "Argument to startup missing.", "--no-startup", "--startup");
-    }
-
-    public void testStartupFailedOption() throws Exception {
-        start(
-                s -> assertEquals(s.trim(), "", "cmdout: "),
-                s -> assertEquals(s.trim(), "", "userout: "),
-                s -> assertTrue(s.contains("Unrecognized option: -hoge-foo-bar"), "cmderr: " + s),
+    // Test that user specified exit codes are propagated
+    public void testExitCode() {
+        setIn("/exit 57\n");
+        startExCoUoCeCn(57, null, null, null, "-> /exit 57", "-s");
+        setIn("int eight = 8\n" +
+                "/exit eight + \n" +
+                " eight\n");
+        startExCoUoCeCn(16, null, null, null,
+                "-> int eight = 8\n" +
+                "-> /exit eight + \n" +
+                ">>  eight",
+                "-s");
+    }
+
+    // Test that non-existent load file sends output to stderr and does not startExCe (no welcome).
+    public void testUnknownLoadFile() {
+        startExCe(1, "File 'UNKNOWN' for 'jshell' is not found.", "UNKNOWN");
+    }
+
+    // Test bad usage of the --startup option
+    public void testStartup() {
+        String fn = writeToFile("");
+        startExCe(1, "Argument to startup missing.", "--startup");
+        startExCe(1, "Conflicting options: both --startup and --no-startup were used.", "--no-startup", "--startup", fn);
+        startExCe(1, "Conflicting options: both --startup and --no-startup were used.", "--startup", fn, "--no-startup");
+        startExCe(1, "Argument to startup missing.", "--no-startup", "--startup");
+    }
+
+    // Test an option that causes the back-end to fail is propagated
+    public void testStartupFailedOption() {
+        startExCe(1, s -> assertTrue(s.contains("Unrecognized option: -hoge-foo-bar"), "cmderr: " + s),
                 "-R-hoge-foo-bar");
     }
 
-    public void testStartupUnknown() throws Exception {
-        start("", "File 'UNKNOWN' for '--startup' is not found.", "--startup", "UNKNOWN");
-        start("", "File 'UNKNOWN' for '--startup' is not found.", "--startup", "DEFAULT", "--startup", "UNKNOWN");
+    // Test the use of non-existant files with the --startup option
+    public void testStartupUnknown() {
+        startExCe(1, "File 'UNKNOWN' for '--startup' is not found.", "--startup", "UNKNOWN");
+        startExCe(1, "File 'UNKNOWN' for '--startup' is not found.", "--startup", "DEFAULT", "--startup", "UNKNOWN");
     }
 
-    public void testClasspath() throws Exception {
-        for (String cp : new String[] {"--class-path"}) {
-            start("", "Only one --class-path option may be used.", cp, ".", "--class-path", ".");
-            start("", "Argument to class-path missing.", cp);
+    // Test bad usage of --class-path option
+    public void testClasspath() {
+        for (String cp : new String[]{"--class-path"}) {
+            startExCe(1, "Only one --class-path option may be used.", cp, ".", "--class-path", ".");
+            startExCe(1, "Argument to class-path missing.", cp);
         }
     }
 
-    public void testUnknownModule() throws Exception {
-        start(
-                s -> assertEquals(s.trim(), "", "cmdout: "),
-                s -> assertEquals(s.trim(), "", "userout: "),
-                s -> assertTrue(s.contains("rror") && s.contains("unKnown"), "cmderr: " + s),
+    // Test bogus module on --add-modules option
+    public void testUnknownModule() {
+        startExCe(1, s -> assertTrue(s.contains("rror") && s.contains("unKnown"), "cmderr: " + s),
                 "--add-modules", "unKnown");
     }
 
-    public void testFeedbackOptionConflict() throws Exception {
-        start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.",
+    // Test that muliple feedback options fail
+    public void testFeedbackOptionConflict() {
+        startExCe(1, "Only one feedback option (--feedback, -q, -s, or -v) may be used.",
                 "--feedback", "concise", "--feedback", "verbose");
-        start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "--feedback", "concise", "-s");
-        start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "--feedback", "verbose", "-q");
-        start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "--feedback", "concise", "-v");
-        start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "-v", "--feedback", "concise");
-        start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "-q", "-v");
-        start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "-s", "-v");
-        start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "-v", "-q");
-        start("", "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "-q", "-s");
-    }
-
-    public void testNegFeedbackOption() throws Exception {
-        start("", "Argument to feedback missing.", "--feedback");
-        start("", "Does not match any current feedback mode: blorp -- --feedback blorp", "--feedback", "blorp");
-    }
-
-    public void testVersion() throws Exception {
-        start(
-                s -> {
+        startExCe(1, "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "--feedback", "concise", "-s");
+        startExCe(1, "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "--feedback", "verbose", "-q");
+        startExCe(1, "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "--feedback", "concise", "-v");
+        startExCe(1, "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "-v", "--feedback", "concise");
+        startExCe(1, "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "-q", "-v");
+        startExCe(1, "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "-s", "-v");
+        startExCe(1, "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "-v", "-q");
+        startExCe(1, "Only one feedback option (--feedback, -q, -s, or -v) may be used.", "-q", "-s");
+    }
+
+    // Test bogus arguments to the --feedback option
+    public void testNegFeedbackOption() {
+        startExCe(1, "Argument to feedback missing.", "--feedback");
+        startExCe(1, "Does not match any current feedback mode: blorp -- --feedback blorp", "--feedback", "blorp");
+    }
+
+    // Test --version
+    public void testVersion() {
+        startCo(s -> {
                     assertTrue(s.startsWith("jshell"), "unexpected version: " + s);
                     assertFalse(s.contains("Welcome"), "Unexpected start: " + s);
                 },
-                null, null,
                 "--version");
     }
 
-    public void testShowVersion() throws Exception {
-        runShell("--show-version");
-        check(cmdout,
+    // Test --show-version
+    public void testShowVersion() {
+        startExCoUoCeCn(null,
                 s -> {
                     assertTrue(s.startsWith("jshell"), "unexpected version: " + s);
                     assertTrue(s.contains("Welcome"), "Expected start (but got no welcome): " + s);
                 },
-                "cmdout");
-        check(cmderr, null, "cmderr");
-        check(console,
+                null,
+                null,
                 s -> assertTrue(s.trim().startsWith("jshell>"), "Expected prompt, got: " + s),
-                "console");
-        check(userout, null, "userout");
-        check(usererr, null, "usererr");
+                "--show-version");
     }
 
     @AfterMethod
     public void tearDown() {
         cmdout  = null;