# HG changeset patch # User jlahoda # Date 1458736842 -3600 # Node ID ae6fa9280e0bfa5dd51b8ad1851cbc1c2702e7ee # Parent 329f0f6baff5dd859ca8dcc3220a2afa4685eb4c 8152296: langtools/test/jdk/jshell/ToolReloadTest.java failing if there is not persisted history Summary: Create a custom Terminal for use in tests; avoid use of global Preferences in tests. Reviewed-by: rfield diff -r 329f0f6baff5 -r ae6fa9280e0b langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Wed Mar 23 13:44:53 2016 +0100 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java Wed Mar 23 13:40:42 2016 +0100 @@ -48,7 +48,7 @@ import jdk.internal.jline.NoInterruptUnixTerminal; import jdk.internal.jline.Terminal; import jdk.internal.jline.TerminalFactory; -import jdk.internal.jline.UnsupportedTerminal; +import jdk.internal.jline.TerminalSupport; import jdk.internal.jline.WindowsTerminal; import jdk.internal.jline.console.ConsoleReader; import jdk.internal.jline.console.KeyMap; @@ -70,7 +70,7 @@ this.input = new StopDetectingInputStream(() -> repl.state.stop(), ex -> repl.hard("Error on input: %s", ex)); Terminal term; if (System.getProperty("test.jdk") != null) { - term = new UnsupportedTerminal(); + term = new TestTerminal(input); } else if (System.getProperty("os.name").toLowerCase(Locale.US).contains(TerminalFactory.WINDOWS)) { term = new JShellWindowsTerminal(input); } else { @@ -80,7 +80,7 @@ in = new ConsoleReader(cmdin, cmdout, term); in.setExpandEvents(false); in.setHandleUserInterrupt(true); - in.setHistory(history = new EditingHistory(JShellTool.PREFS) { + in.setHistory(history = new EditingHistory(repl.prefs) { @Override protected CompletionInfo analyzeCompletion(String input) { return repl.analysis.analyzeCompletion(input); } @@ -538,4 +538,22 @@ } } + + private static final class TestTerminal extends TerminalSupport { + + private final StopDetectingInputStream input; + + public TestTerminal(StopDetectingInputStream input) throws Exception { + super(true); + setAnsiSupported(false); + setEchoEnabled(true); + this.input = input; + } + + @Override + public InputStream wrapInIfNeeded(InputStream in) throws IOException { + return input.setInputStream(super.wrapInIfNeeded(in)); + } + + } } diff -r 329f0f6baff5 -r ae6fa9280e0b langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java --- a/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Wed Mar 23 13:44:53 2016 +0100 +++ b/langtools/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java Wed Mar 23 13:40:42 2016 +0100 @@ -121,6 +121,7 @@ final InputStream userin; final PrintStream userout; final PrintStream usererr; + final Preferences prefs; final Feedback feedback = new Feedback(); @@ -137,7 +138,8 @@ */ public JShellTool(InputStream cmdin, PrintStream cmdout, PrintStream cmderr, PrintStream console, - InputStream userin, PrintStream userout, PrintStream usererr) { + InputStream userin, PrintStream userout, PrintStream usererr, + Preferences prefs) { this.cmdin = cmdin; this.cmdout = cmdout; this.cmderr = cmderr; @@ -145,6 +147,7 @@ this.userin = userin; this.userout = userout; this.usererr = usererr; + this.prefs = prefs; initializeFeedbackModes(); } @@ -230,8 +233,6 @@ private List replayableHistory; private List replayableHistoryPrevious; - static final Preferences PREFS = Preferences.userRoot().node("tool/JShell"); - static final String STARTUP_KEY = "STARTUP"; static final String REPLAY_RESTORE_KEY = "REPLAY_RESTORE"; @@ -387,7 +388,8 @@ */ public static void main(String[] args) throws Exception { new JShellTool(System.in, System.out, System.err, System.out, - new ByteArrayInputStream(new byte[0]), System.out, System.err) + new ByteArrayInputStream(new byte[0]), System.out, System.err, + Preferences.userRoot().node("tool/JShell")) .start(args); } @@ -406,7 +408,7 @@ resetState(); // Initialize // Read replay history from last jshell session into previous history - String prevReplay = PREFS.get(REPLAY_RESTORE_KEY, null); + String prevReplay = prefs.get(REPLAY_RESTORE_KEY, null); if (prevReplay != null) { replayableHistoryPrevious = Arrays.asList(prevReplay.split(RECORD_SEPARATOR)); } @@ -558,10 +560,10 @@ String start; if (cmdlineStartup == null) { - start = PREFS.get(STARTUP_KEY, ""); + start = prefs.get(STARTUP_KEY, ""); if (start.equals("")) { start = DEFAULT_STARTUP; - PREFS.put(STARTUP_KEY, DEFAULT_STARTUP); + prefs.put(STARTUP_KEY, DEFAULT_STARTUP); } } else { start = cmdlineStartup; @@ -1198,7 +1200,7 @@ try { byte[] encoded = Files.readAllBytes(toPathResolvingUserHome(filename)); String init = new String(encoded); - PREFS.put(STARTUP_KEY, init); + prefs.put(STARTUP_KEY, init); } catch (AccessDeniedException e) { hard("File '%s' for /set start is not accessible.", filename); return false; @@ -1347,7 +1349,7 @@ regenerateOnDeath = false; live = false; if (!replayableHistory.isEmpty()) { - PREFS.put(REPLAY_RESTORE_KEY, replayableHistory.stream().reduce( + prefs.put(REPLAY_RESTORE_KEY, replayableHistory.stream().reduce( (a, b) -> a + RECORD_SEPARATOR + b).get()); } fluff("Goodbye\n"); diff -r 329f0f6baff5 -r ae6fa9280e0b langtools/test/jdk/jshell/ReplToolTesting.java --- a/langtools/test/jdk/jshell/ReplToolTesting.java Wed Mar 23 13:44:53 2016 +0100 +++ b/langtools/test/jdk/jshell/ReplToolTesting.java Wed Mar 23 13:40:42 2016 +0100 @@ -33,6 +33,9 @@ import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Predicate; +import java.util.prefs.AbstractPreferences; +import java.util.prefs.BackingStoreException; +import java.util.prefs.Preferences; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; @@ -41,6 +44,8 @@ import jdk.internal.jshell.tool.JShellTool; import jdk.jshell.SourceCodeAnalysis.Suggestion; +import org.testng.annotations.BeforeMethod; + import static java.util.stream.Collectors.toList; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNotNull; @@ -83,6 +88,7 @@ private Map classes; private Map imports; private boolean isDefaultStartUp = true; + private Preferences prefs; public JShellTool repl = null; @@ -219,6 +225,11 @@ } } + @BeforeMethod + public void setUp() { + prefs = new MemoryPreferences(); + } + public void testRaw(String[] args, ReplTest... tests) { cmdin = new WaitingTestingInputStream(); cmdout = new ByteArrayOutputStream(); @@ -234,7 +245,8 @@ new PrintStream(console), userin, new PrintStream(userout), - new PrintStream(usererr)); + new PrintStream(usererr), + prefs); repl.testPrompt = true; try { repl.start(args); @@ -447,7 +459,7 @@ private List computeCompletions(String code, boolean isSmart) { JShellTool js = this.repl != null ? this.repl - : new JShellTool(null, null, null, null, null, null, null); + : new JShellTool(null, null, null, null, null, null, null, prefs); int cursor = code.indexOf('|'); code = code.replace("|", ""); assertTrue(cursor > -1, "'|' not found: " + code); @@ -762,4 +774,62 @@ } } } + + public static final class MemoryPreferences extends AbstractPreferences { + + private final Map values = new HashMap<>(); + private final Map nodes = new HashMap<>(); + + public MemoryPreferences() { + this(null, ""); + } + + public MemoryPreferences(MemoryPreferences parent, String name) { + super(parent, name); + } + + @Override + protected void putSpi(String key, String value) { + values.put(key, value); + } + + @Override + protected String getSpi(String key) { + return values.get(key); + } + + @Override + protected void removeSpi(String key) { + values.remove(key); + } + + @Override + protected void removeNodeSpi() throws BackingStoreException { + ((MemoryPreferences) parent()).nodes.remove(name()); + } + + @Override + protected String[] keysSpi() throws BackingStoreException { + return values.keySet().toArray(new String[0]); + } + + @Override + protected String[] childrenNamesSpi() throws BackingStoreException { + return nodes.keySet().toArray(new String[0]); + } + + @Override + protected AbstractPreferences childSpi(String name) { + return nodes.computeIfAbsent(name, n -> new MemoryPreferences(this, name)); + } + + @Override + protected void syncSpi() throws BackingStoreException { + } + + @Override + protected void flushSpi() throws BackingStoreException { + } + + } } diff -r 329f0f6baff5 -r ae6fa9280e0b langtools/test/jdk/jshell/StartOptionTest.java --- a/langtools/test/jdk/jshell/StartOptionTest.java Wed Mar 23 13:44:53 2016 +0100 +++ b/langtools/test/jdk/jshell/StartOptionTest.java Wed Mar 23 13:40:42 2016 +0100 @@ -54,7 +54,8 @@ private ByteArrayOutputStream err; private JShellTool getShellTool() { - return new JShellTool(null, new PrintStream(out), new PrintStream(err), null, null, null, null); + return new JShellTool(null, new PrintStream(out), new PrintStream(err), null, null, null, + null, new ReplToolTesting.MemoryPreferences()); } private String getOutput() {