1 /* 2 * Copyright (c) 2015, 2017, 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 * @key intermittent 27 * @bug 8081845 8147898 8143955 8165405 8178023 28 * @summary Tests for /reload in JShell tool 29 * @modules jdk.compiler/com.sun.tools.javac.api 30 * jdk.compiler/com.sun.tools.javac.main 31 * jdk.jdeps/com.sun.tools.javap 32 * jdk.jshell/jdk.internal.jshell.tool 33 * @library /tools/lib 34 * @build KullaTesting TestingInputStream toolbox.ToolBox Compiler 35 * @run testng ToolReloadTest 36 */ 37 38 import java.nio.file.Path; 39 import java.nio.file.Paths; 40 import java.util.function.Function; 41 42 import org.testng.annotations.Test; 43 import static org.testng.Assert.assertTrue; 44 45 46 @Test 47 public class ToolReloadTest extends ReplToolTesting { 48 testReloadSnippets()49 public void testReloadSnippets() { 50 test( 51 (a) -> assertVariable(a, "int", "x", "5", "5"), 52 (a) -> assertMethod(a, "int m(int z) { return z * z; }", 53 "(int)int", "m"), 54 (a) -> evaluateExpression(a, "int", "m(x)", "25"), 55 (a) -> assertCommand(a, "/reload", 56 "| Restarting and restoring state.\n" + 57 "-: int x = 5;\n" + 58 "-: int m(int z) { return z * z; }\n" + 59 "-: m(x)\n"), 60 (a) -> evaluateExpression(a, "int", "m(x)", "25"), 61 (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()), 62 (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()) 63 ); 64 } 65 testReloadClasspath()66 public void testReloadClasspath() { 67 Function<String,String> prog = (s) -> String.format( 68 "package pkg; public class A { public String toString() { return \"%s\"; } }\n", s); 69 Compiler compiler = new Compiler(); 70 Path outDir = Paths.get("testClasspathDirectory"); 71 compiler.compile(outDir, prog.apply("A")); 72 Path classpath = compiler.getPath(outDir); 73 test( 74 (a) -> assertCommand(a, "/env --class-path " + classpath, 75 "| Setting new options and restoring state."), 76 (a) -> assertMethod(a, "String foo() { return (new pkg.A()).toString(); }", 77 "()String", "foo"), 78 (a) -> assertVariable(a, "String", "v", "foo()", "\"A\""), 79 (a) -> { 80 if (!a) compiler.compile(outDir, prog.apply("Aprime")); 81 assertCommand(a, "/reload", 82 "| Restarting and restoring state.\n" + 83 "-: String foo() { return (new pkg.A()).toString(); }\n" + 84 "-: String v = foo();\n"); 85 }, 86 (a) -> assertCommand(a, "v", "v ==> \"Aprime\""), 87 (a) -> evaluateExpression(a, "String", "foo()", "\"Aprime\""), 88 (a) -> evaluateExpression(a, "pkg.A", "new pkg.A();", "Aprime") 89 ); 90 } 91 testReloadDrop()92 public void testReloadDrop() { 93 test(false, new String[]{"--no-startup"}, 94 a -> assertVariable(a, "int", "a"), 95 a -> dropVariable(a, "/dr 1", "int a = 0", "| dropped variable a"), 96 a -> assertMethod(a, "int b() { return 0; }", "()int", "b"), 97 a -> dropMethod(a, "/drop b", "int b()", "| dropped method b()"), 98 a -> assertClass(a, "class A {}", "class", "A"), 99 a -> dropClass(a, "/dr A", "class A", "| dropped class A"), 100 a -> assertCommand(a, "/reload", 101 "| Restarting and restoring state.\n" + 102 "-: int a;\n" + 103 "-: /drop 1\n" + 104 "-: int b() { return 0; }\n" + 105 "-: /drop b\n" + 106 "-: class A {}\n" + 107 "-: /drop A\n"), 108 a -> assertCommandCheckOutput(a, "/vars", assertVariables()), 109 a -> assertCommandCheckOutput(a, "/methods", assertMethods()), 110 a -> assertCommandCheckOutput(a, "/types", assertClasses()), 111 a -> assertCommandCheckOutput(a, "/imports", assertImports()) 112 ); 113 } 114 testReloadQuiet()115 public void testReloadQuiet() { 116 test(false, new String[]{"--no-startup"}, 117 a -> assertVariable(a, "int", "a"), 118 a -> dropVariable(a, "/dr 1", "int a = 0", "| dropped variable a"), 119 a -> assertMethod(a, "int b() { return 0; }", "()int", "b"), 120 a -> dropMethod(a, "/drop b", "int b()", "| dropped method b()"), 121 a -> assertClass(a, "class A {}", "class", "A"), 122 a -> dropClass(a, "/dr A", "class A", "| dropped class A"), 123 a -> assertCommand(a, "/reload -quiet", 124 "| Restarting and restoring state."), 125 a -> assertCommandCheckOutput(a, "/vars", assertVariables()), 126 a -> assertCommandCheckOutput(a, "/methods", assertMethods()), 127 a -> assertCommandCheckOutput(a, "/types", assertClasses()), 128 a -> assertCommandCheckOutput(a, "/imports", assertImports()) 129 ); 130 } 131 testReloadRepeat()132 public void testReloadRepeat() { 133 test(false, new String[]{"--no-startup"}, 134 (a) -> assertVariable(a, "int", "c", "7", "7"), 135 (a) -> assertCommand(a, "++c", null), 136 (a) -> assertCommand(a, "/!", null), 137 (a) -> assertCommand(a, "/2", null), 138 (a) -> assertCommand(a, "/-1", null), 139 (a) -> assertCommand(a, "/reload", 140 "| Restarting and restoring state.\n" + 141 "-: int c = 7;\n" + 142 "-: ++c\n" + 143 "-: ++c\n" + 144 "-: ++c\n" + 145 "-: ++c\n" 146 ), 147 (a) -> assertCommand(a, "c", "c ==> 11"), 148 (a) -> assertCommand(a, "$4", "$4 ==> 10") 149 ); 150 } 151 testReloadIgnore()152 public void testReloadIgnore() { 153 test(false, new String[]{"--no-startup"}, 154 (a) -> assertCommand(a, "(-)", null), 155 (a) -> assertCommand(a, "/list", null), 156 (a) -> assertCommand(a, "/history", null), 157 (a) -> assertCommand(a, "/help", null), 158 (a) -> assertCommand(a, "/vars", null), 159 (a) -> assertCommand(a, "/save abcd", null), 160 (a) -> assertCommand(a, "/reload", 161 "| Restarting and restoring state.") 162 ); 163 } 164 testReloadResetRestore()165 public void testReloadResetRestore() { 166 test( 167 (a) -> assertVariable(a, "int", "x", "5", "5"), 168 (a) -> assertMethod(a, "int m(int z) { return z * z; }", 169 "(int)int", "m"), 170 (a) -> evaluateExpression(a, "int", "m(x)", "25"), 171 (a) -> assertCommand(a, "/reset", "| Resetting state."), 172 (a) -> assertCommand(a, "/reload -restore", 173 "| Restarting and restoring from previous state.\n" + 174 "-: int x = 5;\n" + 175 "-: int m(int z) { return z * z; }\n" + 176 "-: m(x)\n"), 177 (a) -> evaluateExpression(a, "int", "m(x)", "25"), 178 (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()), 179 (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()) 180 ); 181 } 182 testReloadCrashRestore()183 public void testReloadCrashRestore() { 184 test( 185 (a) -> assertVariable(a, "int", "x", "5", "5"), 186 (a) -> assertMethod(a, "int m(int z) { return z * z; }", 187 "(int)int", "m"), 188 (a) -> evaluateExpression(a, "int", "m(x)", "25"), 189 (a) -> assertCommand(a, "System.exit(1);", 190 "| State engine terminated.\n" + 191 "| Restore definitions with: /reload -restore"), 192 (a) -> assertCommand(a, "/reload -restore", 193 "| Restarting and restoring from previous state.\n" + 194 "-: int x = 5;\n" + 195 "-: int m(int z) { return z * z; }\n" + 196 "-: m(x)\n"), 197 (a) -> evaluateExpression(a, "int", "m(x)", "25"), 198 (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()), 199 (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()) 200 ); 201 } 202 testEnvBadModule()203 public void testEnvBadModule() { 204 test( 205 (a) -> assertVariable(a, "int", "x", "5", "5"), 206 (a) -> assertMethod(a, "int m(int z) { return z * z; }", 207 "(int)int", "m"), 208 (a) -> assertCommandCheckOutput(a, "/env --add-module unKnown", 209 s -> { 210 assertTrue(s.startsWith( 211 "| Setting new options and restoring state.\n" + 212 "| Restart failed:")); 213 assertTrue(s.contains("unKnown"), 214 "\"unKnown\" missing from: " + s); 215 assertTrue(s.contains("previous settings"), 216 "\"previous settings\" missing from: " + s); 217 }), 218 (a) -> evaluateExpression(a, "int", "m(x)", "25"), 219 (a) -> assertCommandCheckOutput(a, "/vars", assertVariables()), 220 (a) -> assertCommandCheckOutput(a, "/methods", assertMethods()) 221 ); 222 } 223 testReloadExitRestore()224 public void testReloadExitRestore() { 225 test(false, new String[]{"--no-startup"}, 226 (a) -> assertVariable(a, "int", "x", "5", "5"), 227 (a) -> assertMethod(a, "int m(int z) { return z * z; }", 228 "(int)int", "m"), 229 (a) -> evaluateExpression(a, "int", "m(x)", "25") 230 ); 231 test(false, new String[]{"--no-startup"}, 232 (a) -> assertCommand(a, "/reload -restore", 233 "| Restarting and restoring from previous state.\n" + 234 "-: int x = 5;\n" + 235 "-: int m(int z) { return z * z; }\n" + 236 "-: m(x)\n"), 237 (a) -> evaluateExpression(a, "int", "m(x)", "25") 238 ); 239 } 240 } 241