1 /* 2 * Copyright (c) 2016, 2018, 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 8168836 27 * @summary Basic argument validation for --patch-module 28 * @library /test/lib 29 * @modules jdk.compiler 30 * @build PatchTestWarningError JarUtils 31 * jdk.test.lib.compiler.CompilerUtils 32 * @run testng PatchTestWarningError 33 */ 34 35 import java.io.File; 36 import java.nio.file.Files; 37 import java.nio.file.Path; 38 import java.nio.file.Paths; 39 import java.util.stream.Collectors; 40 import java.util.stream.Stream; 41 42 import jdk.test.lib.compiler.CompilerUtils; 43 import static jdk.test.lib.process.ProcessTools.*; 44 45 import org.testng.annotations.BeforeTest; 46 import org.testng.annotations.DataProvider; 47 import org.testng.annotations.Test; 48 import static org.testng.Assert.*; 49 50 51 /** 52 * This test 53 * See PatchTestWarningError for test description. 54 */ 55 56 @Test 57 public class PatchTestWarningError { 58 59 // top-level source directory 60 private static final String TEST_SRC = System.getProperty("test.src"); 61 62 // source/destination tree for the test module 63 private static final Path SRC_DIR = Paths.get(TEST_SRC, "src"); 64 private static final Path MODS_DIR = Paths.get("mods"); 65 66 // source/destination tree for patch tree 1 67 private static final Path SRC1_DIR = Paths.get(TEST_SRC, "src1"); 68 private static final Path PATCHES1_DIR = Paths.get("patches1"); 69 70 // source/destination tree for patch tree 2 71 private static final Path SRC2_DIR = Paths.get(TEST_SRC, "src2"); 72 private static final Path PATCHES2_DIR = Paths.get("patches2"); 73 74 // patch path for java.base 75 private static final String PATCHES_PATH = 76 PATCHES1_DIR.resolve("java.base") + File.pathSeparator + 77 PATCHES2_DIR.resolve("java.base"); 78 79 // the classes overridden or added with --patch-module 80 private static final String[] CLASSES = { 81 82 // java.base = boot loader 83 "java.base/java.text.Annotation", // override class 84 "java.base/java.text.AnnotationBuddy", // add class to package 85 "java.base/java.lang2.Object", // new package 86 87 }; 88 89 90 @BeforeTest 91 public void setup() throws Exception { 92 93 // javac -d mods/test src/test/** 94 boolean compiled= CompilerUtils.compile(SRC_DIR.resolve("test"), 95 MODS_DIR.resolve("test")); 96 assertTrue(compiled, "classes did not compile"); 97 98 // javac --patch-module $MODULE=patches1/$MODULE -d patches1/$MODULE patches1/$MODULE/** 99 Path src = SRC1_DIR.resolve("java.base"); 100 Path output = PATCHES1_DIR.resolve(src.getFileName()); 101 Files.createDirectories(output); 102 String mn = src.getFileName().toString(); 103 compiled = CompilerUtils.compile(src, output, 104 "--patch-module", mn + "=" + src.toString()); 105 assertTrue(compiled, "classes did not compile"); 106 107 // javac --patch-module $MODULE=patches2/$MODULE -d patches2/$MODULE patches2/$MODULE/** 108 src = SRC2_DIR.resolve("java.base"); 109 output = PATCHES2_DIR.resolve(src.getFileName()); 110 Files.createDirectories(output); 111 mn = src.getFileName().toString(); 112 compiled = CompilerUtils.compile(src, output, 113 "--patch-module", mn + "=" + src.toString()); 114 assertTrue(compiled, "classes did not compile"); 115 116 } 117 118 /** 119 * Test with --patch-module options patching the same module 120 */ 121 public void testDuplicateModule() throws Exception { 122 int exitValue = 123 executeTestJava("--patch-module", "java.base=" + PATCHES1_DIR.resolve("java.base"), 124 "--patch-module", "java.base=" + PATCHES2_DIR.resolve("java.base"), 125 "--module-path", MODS_DIR.toString(), 126 "-m", "test/jdk.test.Main") 127 .outputTo(System.out) 128 .errorTo(System.out) 129 // error output by VM 130 .shouldContain("Cannot specify java.base more than once to --patch-module") 131 .getExitValue(); 132 133 assertTrue(exitValue != 0); 134 } 135 136 @DataProvider(name = "emptyItem") 137 public Object[][] emptyItems() { 138 String patch1 = PATCHES1_DIR.resolve("java.base").toString(); 139 String patch2 = PATCHES2_DIR.resolve("java.base").toString(); 140 String pathSep = File.pathSeparator; 141 return new Object[][]{ 142 143 { "java.base="+ pathSep + patch1 + pathSep + patch2, null }, 144 { "java.base="+ patch1 + pathSep + pathSep + patch2, null }, 145 { "java.base="+ patch1 + pathSep + patch2 + pathSep + pathSep, null }, 146 }; 147 } 148 149 /** 150 * Empty item in a non-empty path list 151 */ 152 @Test(dataProvider = "emptyItem") 153 public void testEmptyItem(String value, String msg) throws Exception { 154 // the argument to the test is the list of classes overridden or added 155 String arg = Stream.of(CLASSES).collect(Collectors.joining(",")); 156 157 int exitValue = 158 executeTestJava("--patch-module", value, 159 "--add-exports", "java.base/java.lang2=test", 160 "--module-path", MODS_DIR.toString(), 161 "-m", "test/jdk.test.Main", arg) 162 .outputTo(System.out) 163 .errorTo(System.out) 164 .getExitValue(); 165 166 assertTrue(exitValue == 0); 167 } 168 169 /** 170 * Test bad module name that should emit a warning 171 */ 172 public void testBadName() throws Exception { 173 // the argument to the test is the list of classes overridden or added 174 String arg = Stream.of(CLASSES).collect(Collectors.joining(",")); 175 176 int exitValue = 177 executeTestJava("--patch-module", "DoesNotExist=tmp", 178 "--patch-module", "java.base=" + PATCHES_PATH, 179 "--add-exports", "java.base/java.lang2=test", 180 "--module-path", MODS_DIR.toString(), 181 "-m", "test/jdk.test.Main", arg) 182 .outputTo(System.out) 183 .errorTo(System.out) 184 .shouldContain("WARNING: Unknown module: DoesNotExist specified to --patch-module") 185 .getExitValue(); 186 187 assertTrue(exitValue == 0); 188 } 189 190 @DataProvider(name = "badArguments") 191 public Object[][] badArguments() { 192 return new Object[][]{ 193 194 // source not found 195 { "=tmp", "Unable to parse --patch-module <module>=<value>: =tmp" }, 196 197 // target not found: check by VM 198 { "java.base", "Missing '=' in --patch-module specification" }, 199 { "foo", "Missing '=' in --patch-module specification" }, 200 201 // target not found 202 { "java.base=", "Unable to parse --patch-module <module>=<value>: java.base=" }, 203 { "java.base=" + File.pathSeparator, 204 "Target must be specified: --patch-module java.base=" + File.pathSeparator } 205 }; 206 } 207 208 /** 209 * Test ill-formed argument to --patch-module 210 */ 211 @Test(dataProvider = "badArguments") 212 public void testBadArgument(String value, String msg) throws Exception { 213 int exitValue = 214 executeTestJava("--patch-module", value, 215 "--module-path", MODS_DIR.toString(), 216 "-m", "test/jdk.test.Main") 217 .outputTo(System.out) 218 .errorTo(System.out) 219 .shouldContain(msg) 220 .getExitValue(); 221 222 assertTrue(exitValue != 0); 223 } 224 }