ToolBasicTest.java revision 3607:bfc6d670ec1f
1/*
2 * Copyright (c) 2015, 2016, 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.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 8143037 8142447 8144095 8140265 8144906 8146138 8147887 8147886 8148316 8148317 8143955 8157953 8080347
27 * @summary Tests for Basic tests for REPL tool
28 * @modules jdk.compiler/com.sun.tools.javac.api
29 *          jdk.compiler/com.sun.tools.javac.main
30 *          jdk.jdeps/com.sun.tools.javap
31 *          jdk.jshell/jdk.internal.jshell.tool
32 * @library /tools/lib
33 * @build toolbox.ToolBox toolbox.JarTask toolbox.JavacTask
34 * @build KullaTesting TestingInputStream Compiler
35 * @run testng/timeout=600 ToolBasicTest
36 */
37
38import java.io.IOException;
39import java.io.PrintWriter;
40import java.io.StringWriter;
41import java.nio.file.Files;
42import java.nio.file.Path;
43import java.nio.file.Paths;
44import java.util.ArrayList;
45import java.util.Arrays;
46import java.util.List;
47import java.util.Locale;
48import java.util.Scanner;
49import java.util.function.BiFunction;
50import java.util.function.Consumer;
51import java.util.function.Function;
52import java.util.prefs.BackingStoreException;
53import java.util.prefs.Preferences;
54import java.util.stream.Collectors;
55import java.util.stream.Stream;
56
57import org.testng.annotations.Test;
58
59import static org.testng.Assert.assertEquals;
60import static org.testng.Assert.assertTrue;
61import static org.testng.Assert.fail;
62
63@Test
64public class ToolBasicTest extends ReplToolTesting {
65
66    public void elideStartUpFromList() {
67        test(
68                (a) -> assertCommandOutputContains(a, "123", "==> 123"),
69                (a) -> assertCommandCheckOutput(a, "/list", (s) -> {
70                    int cnt;
71                    try (Scanner scanner = new Scanner(s)) {
72                        cnt = 0;
73                        while (scanner.hasNextLine()) {
74                            String line = scanner.nextLine();
75                            if (!line.trim().isEmpty()) {
76                                ++cnt;
77                            }
78                        }
79                    }
80                    assertEquals(cnt, 1, "Expected only one listed line");
81                })
82        );
83    }
84
85    public void elideStartUpFromSave() throws IOException {
86        Compiler compiler = new Compiler();
87        Path path = compiler.getPath("myfile");
88        test(
89                (a) -> assertCommandOutputContains(a, "123", "==> 123"),
90                (a) -> assertCommand(a, "/save " + path.toString(), "")
91        );
92        try (Stream<String> lines = Files.lines(path)) {
93            assertEquals(lines.count(), 1, "Expected only one saved line");
94        }
95    }
96
97    public void testInterrupt() {
98        ReplTest interrupt = (a) -> assertCommand(a, "\u0003", "");
99        for (String s : new String[] { "", "\u0003" }) {
100            test(false, new String[]{"--no-startup"},
101                    (a) -> assertCommand(a, "int a = 2 +" + s, ""),
102                    interrupt,
103                    (a) -> assertCommand(a, "int a\u0003", ""),
104                    (a) -> assertCommand(a, "int a = 2 + 2\u0003", ""),
105                    (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()),
106                    (a) -> evaluateExpression(a, "int", "2", "2"),
107                    (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()),
108                    (a) -> assertCommand(a, "void f() {", ""),
109                    (a) -> assertCommand(a, "int q = 10;" + s, ""),
110                    interrupt,
111                    (a) -> assertCommand(a, "void f() {}\u0003", ""),
112                    (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()),
113                    (a) -> assertMethod(a, "int f() { return 0; }", "()int", "f"),
114                    (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()),
115                    (a) -> assertCommand(a, "class A {" + s, ""),
116                    interrupt,
117                    (a) -> assertCommand(a, "class A {}\u0003", ""),
118                    (a) -> assertCommandCheckOutput(a, "/types", assertClasses()),
119                    (a) -> assertClass(a, "interface A {}", "interface", "A"),
120                    (a) -> assertCommandCheckOutput(a, "/types", assertClasses()),
121                    (a) -> assertCommand(a, "import java.util.stream." + s, ""),
122                    interrupt,
123                    (a) -> assertCommand(a, "import java.util.stream.\u0003", ""),
124                    (a) -> assertCommandCheckOutput(a, "/imports", assertImports()),
125                    (a) -> assertImport(a, "import java.util.stream.Stream", "", "java.util.stream.Stream"),
126                    (a) -> assertCommandCheckOutput(a, "/imports", assertImports())
127            );
128        }
129    }
130
131    private final Object lock = new Object();
132    private PrintWriter out;
133    private boolean isStopped;
134    private Thread t;
135    private void assertStop(boolean after, String cmd, String output) {
136        if (!after) {
137            isStopped = false;
138            StringWriter writer = new StringWriter();
139            out = new PrintWriter(writer);
140            setCommandInput(cmd + "\n");
141            t = new Thread(() -> {
142                try {
143                    // no chance to know whether cmd is being evaluated
144                    Thread.sleep(5000);
145                } catch (InterruptedException ignored) {
146                }
147                int i = 1;
148                int n = 30;
149                synchronized (lock) {
150                    do {
151                        setCommandInput("\u0003");
152                        if (!isStopped) {
153                            out.println("Not stopped. Try again: " + i);
154                            try {
155                                lock.wait(1000);
156                            } catch (InterruptedException ignored) {
157                            }
158                        }
159                    } while (i++ < n && !isStopped);
160                    if (!isStopped) {
161                        System.err.println(writer.toString());
162                        fail("Evaluation was not stopped: '" + cmd + "'");
163                    }
164                }
165            });
166            t.start();
167        } else {
168            synchronized (lock)  {
169                out.println("Evaluation was stopped successfully: '" + cmd + "'");
170                isStopped = true;
171                lock.notify();
172            }
173            try {
174                t.join();
175                t = null;
176            } catch (InterruptedException ignored) {
177            }
178            assertOutput(getCommandOutput(), "", "command");
179            assertOutput(getCommandErrorOutput(), "", "command error");
180            assertOutput(getUserOutput().trim(), output, "user");
181            assertOutput(getUserErrorOutput(), "", "user error");
182        }
183    }
184
185    public void testStop() {
186        test(
187                (a) -> assertStop(a, "while (true) {}", ""),
188                (a) -> assertStop(a, "while (true) { try { Thread.sleep(100); } catch (InterruptedException ex) { } }", "")
189        );
190    }
191
192    public void testRerun() {
193        test(false, new String[] {"--no-startup"},
194                (a) -> assertCommand(a, "/0", "|  No such command or snippet id: /0\n|  Type /help for help."),
195                (a) -> assertCommand(a, "/5", "|  No such command or snippet id: /5\n|  Type /help for help.")
196        );
197        String[] codes = new String[] {
198                "int a = 0;", // var
199                "class A {}", // class
200                "void f() {}", // method
201                "bool b;", // active failed
202                "void g() { h(); }", // active corralled
203        };
204        List<ReplTest> tests = new ArrayList<>();
205        for (String s : codes) {
206            tests.add((a) -> assertCommand(a, s, null));
207        }
208        // Test /1 through /5 -- assure references are correct
209        for (int i = 0; i < codes.length; ++i) {
210            final int finalI = i;
211            Consumer<String> check = (s) -> {
212                String[] ss = s.split("\n");
213                assertEquals(ss[0], codes[finalI]);
214                assertTrue(ss.length > 1, s);
215            };
216            tests.add((a) -> assertCommandCheckOutput(a, "/" + (finalI + 1), check));
217        }
218        // Test /-1 ... note that the snippets added by history must be stepped over
219        for (int i = 0; i < codes.length; ++i) {
220            final int finalI = i;
221            Consumer<String> check = (s) -> {
222                String[] ss = s.split("\n");
223                assertEquals(ss[0], codes[codes.length - finalI - 1]);
224                assertTrue(ss.length > 1, s);
225            };
226            tests.add((a) -> assertCommandCheckOutput(a, "/-" + (2 * finalI + 1), check));
227        }
228        tests.add((a) -> assertCommandCheckOutput(a, "/!", assertStartsWith("int a = 0;")));
229        test(false, new String[]{"--no-startup"},
230                tests.toArray(new ReplTest[tests.size()]));
231    }
232
233    public void test8142447() {
234        Function<String, BiFunction<String, Integer, ReplTest>> assertRerun = cmd -> (code, assertionCount) ->
235                (a) -> assertCommandCheckOutput(a, cmd, s -> {
236                            String[] ss = s.split("\n");
237                            assertEquals(ss[0], code);
238                            loadVariable(a, "int", "assertionCount", Integer.toString(assertionCount), Integer.toString(assertionCount));
239                        });
240        ReplTest assertVariables = (a) -> assertCommandCheckOutput(a, "/v", assertVariables());
241
242        Compiler compiler = new Compiler();
243        Path startup = compiler.getPath("StartupFileOption/startup.txt");
244        compiler.writeToFile(startup, "int assertionCount = 0;\n" + // id: s1
245                "void add(int n) { assertionCount += n; }");
246        test(new String[]{"--startup", startup.toString()},
247                (a) -> assertCommand(a, "add(1)", ""), // id: 1
248                (a) -> assertCommandCheckOutput(a, "add(ONE)", s -> assertEquals(s.split("\n")[0], "|  Error:")), // id: e1
249                (a) -> assertVariable(a, "int", "ONE", "1", "1"),
250                assertRerun.apply("/1").apply("add(1)", 2), assertVariables,
251                assertRerun.apply("/e1").apply("add(ONE)", 3), assertVariables,
252                assertRerun.apply("/s1").apply("int assertionCount = 0;", 0), assertVariables
253        );
254
255        test(false, new String[] {"--no-startup"},
256                (a) -> assertCommand(a, "/s1", "|  No such command or snippet id: /s1\n|  Type /help for help."),
257                (a) -> assertCommand(a, "/1", "|  No such command or snippet id: /1\n|  Type /help for help."),
258                (a) -> assertCommand(a, "/e1", "|  No such command or snippet id: /e1\n|  Type /help for help.")
259        );
260    }
261
262    public void testClasspathDirectory() {
263        Compiler compiler = new Compiler();
264        Path outDir = Paths.get("testClasspathDirectory");
265        compiler.compile(outDir, "package pkg; public class A { public String toString() { return \"A\"; } }");
266        Path classpath = compiler.getPath(outDir);
267        test(
268                (a) -> assertCommand(a, "/classpath " + classpath, String.format("|  Path '%s' added to classpath", classpath)),
269                (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A")
270        );
271        test(new String[] { "--class-path", classpath.toString() },
272                (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A")
273        );
274    }
275
276    public void testClasspathJar() {
277        Compiler compiler = new Compiler();
278        Path outDir = Paths.get("testClasspathJar");
279        compiler.compile(outDir, "package pkg; public class A { public String toString() { return \"A\"; } }");
280        String jarName = "test.jar";
281        compiler.jar(outDir, jarName, "pkg/A.class");
282        Path jarPath = compiler.getPath(outDir).resolve(jarName);
283        test(
284                (a) -> assertCommand(a, "/classpath " + jarPath, String.format("|  Path '%s' added to classpath", jarPath)),
285                (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A")
286        );
287        test(new String[] { "--class-path", jarPath.toString() },
288                (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "A")
289        );
290    }
291
292    public void testStartupFileOption() {
293        try {
294            Compiler compiler = new Compiler();
295            Path startup = compiler.getPath("StartupFileOption/startup.txt");
296            compiler.writeToFile(startup, "class A { public String toString() { return \"A\"; } }");
297            test(new String[]{"--startup", startup.toString()},
298                    (a) -> evaluateExpression(a, "A", "new A()", "A")
299            );
300            test(new String[]{"--no-startup"},
301                    (a) -> assertCommandCheckOutput(a, "printf(\"\")", assertStartsWith("|  Error:\n|  cannot find symbol"))
302            );
303            test(
304                    (a) -> assertCommand(a, "printf(\"A\")", "", "", null, "A", "")
305            );
306        } finally {
307            removeStartup();
308        }
309    }
310
311    public void testLoadingFromArgs() {
312        Compiler compiler = new Compiler();
313        Path path = compiler.getPath("loading.repl");
314        compiler.writeToFile(path, "int a = 10; double x = 20; double a = 10;");
315        test(new String[] { path.toString() },
316                (a) -> assertCommand(a, "x", "x ==> 20.0"),
317                (a) -> assertCommand(a, "a", "a ==> 10.0")
318        );
319        Path unknown = compiler.getPath("UNKNOWN.jar");
320        test(Locale.ROOT, true, new String[]{unknown.toString()},
321                "|  File '" + unknown
322                + "' for 'jshell' is not found.");
323    }
324
325    public void testReset() {
326        test(
327                (a) -> assertReset(a, "/res"),
328                (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()),
329                (a) -> assertVariable(a, "int", "x"),
330                (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()),
331                (a) -> assertMethod(a, "void f() { }", "()void", "f"),
332                (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()),
333                (a) -> assertClass(a, "class A { }", "class", "A"),
334                (a) -> assertCommandCheckOutput(a, "/types", assertClasses()),
335                (a) -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"),
336                (a) -> assertCommandCheckOutput(a, "/imports", assertImports()),
337                (a) -> assertReset(a, "/reset"),
338                (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()),
339                (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()),
340                (a) -> assertCommandCheckOutput(a, "/types", assertClasses()),
341                (a) -> assertCommandCheckOutput(a, "/imports", assertImports())
342        );
343    }
344
345    public void testOpen() {
346        Compiler compiler = new Compiler();
347        Path path = compiler.getPath("testOpen.repl");
348        compiler.writeToFile(path,
349                "int a = 10;\ndouble x = 20;\ndouble a = 10;\n" +
350                        "class A { public String toString() { return \"A\"; } }\nimport java.util.stream.*;");
351        for (String s : new String[]{"/o", "/open"}) {
352            test(
353                    (a) -> assertCommand(a, s + " " + path.toString(), ""),
354                    (a) -> assertCommand(a, "a", "a ==> 10.0"),
355                    (a) -> evaluateExpression(a, "A", "new A();", "A"),
356                    (a) -> evaluateExpression(a, "long", "Stream.of(\"A\").count();", "1"),
357                    (a) -> {
358                        loadVariable(a, "double", "x", "20.0", "20.0");
359                        loadVariable(a, "double", "a", "10.0", "10.0");
360                        loadVariable(a, "A", "$7", "new A();", "A");
361                        loadVariable(a, "long", "$8", "Stream.of(\"A\").count();", "1");
362                        loadClass(a, "class A { public String toString() { return \"A\"; } }",
363                                "class", "A");
364                        loadImport(a, "import java.util.stream.*;", "", "java.util.stream.*");
365                        assertCommandCheckOutput(a, "/types", assertClasses());
366                    },
367                    (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()),
368                    (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()),
369                    (a) -> assertCommandCheckOutput(a, "/imports", assertImports())
370            );
371            Path unknown = compiler.getPath("UNKNOWN.repl");
372            test(
373                    (a) -> assertCommand(a, s + " " + unknown,
374                            "|  File '" + unknown + "' for '/open' is not found.")
375            );
376        }
377    }
378
379    public void testSave() throws IOException {
380        Compiler compiler = new Compiler();
381        Path path = compiler.getPath("testSave.repl");
382        List<String> list = Arrays.asList(
383                "int a;",
384                "class A { public String toString() { return \"A\"; } }"
385        );
386        test(
387                (a) -> assertVariable(a, "int", "a"),
388                (a) -> assertCommand(a, "()", null, null, null, "", ""),
389                (a) -> assertClass(a, "class A { public String toString() { return \"A\"; } }", "class", "A"),
390                (a) -> assertCommand(a, "/save " + path.toString(), "")
391        );
392        assertEquals(Files.readAllLines(path), list);
393        {
394            List<String> output = new ArrayList<>();
395            test(
396                    (a) -> assertCommand(a, "int a;", null),
397                    (a) -> assertCommand(a, "()", null, null, null, "", ""),
398                    (a) -> assertClass(a, "class A { public String toString() { return \"A\"; } }", "class", "A"),
399                    (a) -> assertCommandCheckOutput(a, "/list -all", (out) ->
400                            output.addAll(Stream.of(out.split("\n"))
401                                    .filter(str -> !str.isEmpty())
402                                    .map(str -> str.substring(str.indexOf(':') + 2))
403                                    .filter(str -> !str.startsWith("/"))
404                                    .collect(Collectors.toList()))),
405                    (a) -> assertCommand(a, "/save -all " + path.toString(), "")
406            );
407            assertEquals(Files.readAllLines(path), output);
408        }
409        List<String> output = new ArrayList<>();
410        test(
411                (a) -> assertVariable(a, "int", "a"),
412                (a) -> assertCommand(a, "()", null, null, null, "", ""),
413                (a) -> assertClass(a, "class A { public String toString() { return \"A\"; } }", "class", "A"),
414                (a) -> assertCommandCheckOutput(a, "/history", (out) ->
415                        output.addAll(Stream.of(out.split("\n"))
416                                .filter(str -> !str.isEmpty())
417                                .collect(Collectors.toList()))),
418                (a) -> assertCommand(a, "/save -history " + path.toString(), "")
419        );
420        output.add("/save -history " + path.toString());
421        assertEquals(Files.readAllLines(path), output);
422    }
423
424    public void testStartRetain() throws BackingStoreException {
425        try {
426            Compiler compiler = new Compiler();
427            Path startUpFile = compiler.getPath("startUp.txt");
428            test(
429                    (a) -> assertVariable(a, "int", "a"),
430                    (a) -> assertVariable(a, "double", "b", "10", "10.0"),
431                    (a) -> assertMethod(a, "void f() {}", "()V", "f"),
432                    (a) -> assertImport(a, "import java.util.stream.*;", "", "java.util.stream.*"),
433                    (a) -> assertCommand(a, "/save " + startUpFile.toString(), null),
434                    (a) -> assertCommand(a, "/retain start " + startUpFile.toString(), null)
435            );
436            Path unknown = compiler.getPath("UNKNOWN");
437            test(
438                    (a) -> assertCommandOutputStartsWith(a, "/retain start " + unknown.toString(),
439                            "|  File '" + unknown + "' for '/retain start' is not found.")
440            );
441            test(false, new String[0],
442                    (a) -> {
443                        loadVariable(a, "int", "a");
444                        loadVariable(a, "double", "b", "10.0", "10.0");
445                        loadMethod(a, "void f() {}", "()void", "f");
446                        loadImport(a, "import java.util.stream.*;", "", "java.util.stream.*");
447                        assertCommandCheckOutput(a, "/types", assertClasses());
448                    },
449                    (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()),
450                    (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()),
451                    (a) -> assertCommandCheckOutput(a, "/imports", assertImports())
452            );
453        } finally {
454            removeStartup();
455        }
456    }
457
458    private void removeStartup() {
459        Preferences preferences = Preferences.userRoot().node("tool/JShell");
460        if (preferences != null) {
461            preferences.remove("STARTUP");
462        }
463    }
464
465    public void testStartSave() throws IOException {
466        Compiler compiler = new Compiler();
467        Path startSave = compiler.getPath("startSave.txt");
468        test(a -> assertCommand(a, "/save -start " + startSave.toString(), null));
469        List<String> lines = Files.lines(startSave)
470                .filter(s -> !s.isEmpty())
471                .collect(Collectors.toList());
472        assertEquals(lines, START_UP);
473    }
474
475    public void testConstrainedUpdates() {
476        test(
477                a -> assertClass(a, "class XYZZY { }", "class", "XYZZY"),
478                a -> assertVariable(a, "XYZZY", "xyzzy"),
479                a -> assertCommandCheckOutput(a, "import java.util.stream.*",
480                        (out) -> assertTrue(out.trim().isEmpty(), "Expected no output, got: " + out))
481        );
482    }
483
484    public void testRemoteExit() {
485        test(
486                a -> assertVariable(a, "int", "x"),
487                a -> assertCommandCheckOutput(a, "/vars", assertVariables()),
488                a -> assertCommandOutputContains(a, "System.exit(5);", "terminated"),
489                a -> assertCommandCheckOutput(a, "/vars", s ->
490                        assertTrue(s.trim().isEmpty(), s)),
491                a -> assertMethod(a, "void f() { }", "()void", "f"),
492                a -> assertCommandCheckOutput(a, "/methods", assertMethods())
493        );
494    }
495
496    public void testFeedbackNegative() {
497        test(a -> assertCommandCheckOutput(a, "/set feedback aaaa",
498                assertStartsWith("|  Does not match any current feedback mode")));
499    }
500
501    public void testFeedbackSilent() {
502        for (String off : new String[]{"s", "silent"}) {
503            test(
504                    a -> assertCommand(a, "/set feedback " + off, ""),
505                    a -> assertCommand(a, "int a", ""),
506                    a -> assertCommand(a, "void f() {}", ""),
507                    a -> assertCommandCheckOutput(a, "aaaa", assertStartsWith("|  Error:")),
508                    a -> assertCommandCheckOutput(a, "public void f() {}", assertStartsWith("|  Warning:"))
509            );
510        }
511    }
512
513    public void testFeedbackNormal() {
514        Compiler compiler = new Compiler();
515        Path testNormalFile = compiler.getPath("testConciseNormal");
516        String[] sources = new String[] {"int a", "void f() {}", "class A {}", "a = 10"};
517        String[] sources2 = new String[] {"int a //again", "void f() {int y = 4;}", "class A {} //again", "a = 10"};
518        String[] output = new String[] {
519                "a ==> 0",
520                "|  created method f()",
521                "|  created class A",
522                "a ==> 10"
523        };
524        compiler.writeToFile(testNormalFile, sources2);
525        for (String feedback : new String[]{"/set fe", "/set feedback"}) {
526            for (String feedbackState : new String[]{"n", "normal"}) {
527                test(
528                        a -> assertCommand(a, feedback + " " + feedbackState, "|  Feedback mode: normal"),
529                        a -> assertCommand(a, sources[0], output[0]),
530                        a -> assertCommand(a, sources[1], output[1]),
531                        a -> assertCommand(a, sources[2], output[2]),
532                        a -> assertCommand(a, sources[3], output[3]),
533                        a -> assertCommand(a, "/o " + testNormalFile.toString(), "")
534                );
535            }
536        }
537    }
538
539    public void testVarsWithNotActive() {
540        test(
541                a -> assertVariable(a, "Blath", "x"),
542                a -> assertCommandOutputContains(a, "/var -all", "(not-active)")
543        );
544    }
545
546    public void testHistoryReference() {
547        test(false, new String[]{"--no-startup"},
548                a -> assertCommand(a, "System.err.println(1)", "", "", null, "", "1\n"),
549                a -> assertCommand(a, "System.err.println(2)", "", "", null, "", "2\n"),
550                a -> assertCommand(a, "/-2", "System.err.println(1)", "", null, "", "1\n"),
551                a -> assertCommand(a, "/history",
552                                                    "/debug 0\n" +
553                                                    "System.err.println(1)\n" +
554                                                    "System.err.println(2)\n" +
555                                                    "System.err.println(1)\n" +
556                                                    "/history\n"),
557                a -> assertCommand(a, "/-2", "System.err.println(2)", "", null, "", "2\n"),
558                a -> assertCommand(a, "/!", "System.err.println(2)", "", null, "", "2\n"),
559                a -> assertCommand(a, "/2", "System.err.println(2)", "", null, "", "2\n"),
560                a -> assertCommand(a, "/1", "System.err.println(1)", "", null, "", "1\n")
561        );
562    }
563
564    @Test(enabled = false) // TODO 8158197
565    public void testHeadlessEditPad() {
566        String prevHeadless = System.getProperty("java.awt.headless");
567        try {
568            System.setProperty("java.awt.headless", "true");
569            test(
570                (a) -> assertCommandOutputStartsWith(a, "/edit printf", "|  Cannot launch editor -- unexpected exception:")
571            );
572        } finally {
573            System.setProperty("java.awt.headless", prevHeadless==null? "false" : prevHeadless);
574        }
575    }
576
577}
578