Thu, 26 Jul 2018 06:16:09 -0400
8189762: [TESTBUG] Create tests for JDK-8146115 container awareness and resource configuration
Summary: Created tests for the feature
Reviewed-by: mseledtsov
mgerdin@4637 | 1 | /* |
vaibhav@9421 | 2 | * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. |
mgerdin@4637 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
mgerdin@4637 | 4 | * |
mgerdin@4637 | 5 | * This code is free software; you can redistribute it and/or modify it |
mgerdin@4637 | 6 | * under the terms of the GNU General Public License version 2 only, as |
mgerdin@4637 | 7 | * published by the Free Software Foundation. |
mgerdin@4637 | 8 | * |
mgerdin@4637 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
mgerdin@4637 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
mgerdin@4637 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
mgerdin@4637 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
mgerdin@4637 | 13 | * accompanied this code). |
mgerdin@4637 | 14 | * |
mgerdin@4637 | 15 | * You should have received a copy of the GNU General Public License version |
mgerdin@4637 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
mgerdin@4637 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
mgerdin@4637 | 18 | * |
mgerdin@4637 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
mgerdin@4637 | 20 | * or visit www.oracle.com if you need additional information or have any |
mgerdin@4637 | 21 | * questions. |
mgerdin@4637 | 22 | */ |
mgerdin@4637 | 23 | |
vaibhav@9421 | 24 | import java.io.ByteArrayInputStream; |
vaibhav@9421 | 25 | import java.io.File; |
vaibhav@9421 | 26 | import java.io.FileInputStream; |
vaibhav@9421 | 27 | import java.io.FileOutputStream; |
vaibhav@9421 | 28 | import java.io.FileNotFoundException; |
mgerdin@4637 | 29 | import java.io.InputStream; |
vaibhav@9421 | 30 | import java.io.ByteArrayInputStream; |
mgerdin@4637 | 31 | import java.nio.file.Files; |
mgerdin@4637 | 32 | import java.nio.file.Path; |
mgerdin@4637 | 33 | import java.nio.file.Paths; |
mgerdin@4637 | 34 | import java.nio.file.StandardCopyOption; |
vaibhav@9421 | 35 | import java.util.zip.ZipEntry; |
vaibhav@9421 | 36 | import java.util.zip.ZipOutputStream; |
mgerdin@4637 | 37 | |
mgerdin@4637 | 38 | /** |
vaibhav@9421 | 39 | * Dump a class file for a class on the class path in the current directory, or |
vaibhav@9421 | 40 | * in the specified JAR file. This class is usually used when you build a class |
vaibhav@9421 | 41 | * from a test library, but want to use this class in a sub-process. |
vaibhav@9421 | 42 | * |
vaibhav@9421 | 43 | * For example, to build the following library class: |
vaibhav@9421 | 44 | * test/lib/sun/hotspot/WhiteBox.java |
vaibhav@9421 | 45 | * |
vaibhav@9421 | 46 | * You would use the following tags: |
vaibhav@9421 | 47 | * |
vaibhav@9421 | 48 | * @library /test/lib |
vaibhav@9421 | 49 | * @build sun.hotspot.WhiteBox |
vaibhav@9421 | 50 | * |
vaibhav@9421 | 51 | * JTREG would build the class file under |
vaibhav@9421 | 52 | * ${JTWork}/classes/test/lib/sun/hotspot/WhiteBox.class |
vaibhav@9421 | 53 | * |
vaibhav@9421 | 54 | * With you run your main test class using "@run main MyMainClass", JTREG would setup the |
vaibhav@9421 | 55 | * -classpath to include "${JTWork}/classes/test/lib/", so MyMainClass would be able to |
vaibhav@9421 | 56 | * load the WhiteBox class. |
vaibhav@9421 | 57 | * |
vaibhav@9421 | 58 | * However, if you run a sub process, and do not wish to use the exact same -classpath, |
vaibhav@9421 | 59 | * You can use ClassFileInstaller to ensure that WhiteBox is available in the current |
vaibhav@9421 | 60 | * directory of your test: |
vaibhav@9421 | 61 | * |
vaibhav@9421 | 62 | * @run main ClassFileInstaller sun.hotspot.WhiteBox |
vaibhav@9421 | 63 | * |
vaibhav@9421 | 64 | * Or, you can use the -jar option to store the class in the specified JAR file. If a relative |
vaibhav@9421 | 65 | * path name is given, the JAR file would be relative to the current directory of |
vaibhav@9421 | 66 | * |
vaibhav@9421 | 67 | * @run main ClassFileInstaller -jar myjar.jar sun.hotspot.WhiteBox |
mgerdin@4637 | 68 | */ |
mgerdin@4637 | 69 | public class ClassFileInstaller { |
mgerdin@4637 | 70 | /** |
vaibhav@9421 | 71 | * You can enable debug tracing of ClassFileInstaller by running JTREG with |
vaibhav@9421 | 72 | * jtreg -DClassFileInstaller.debug=true ... <names of tests> |
vaibhav@9421 | 73 | */ |
vaibhav@9421 | 74 | public static boolean DEBUG = Boolean.getBoolean("ClassFileInstaller.debug"); |
vaibhav@9421 | 75 | |
vaibhav@9421 | 76 | /** |
mgerdin@4637 | 77 | * @param args The names of the classes to dump |
mgerdin@4637 | 78 | * @throws Exception |
mgerdin@4637 | 79 | */ |
mgerdin@4637 | 80 | public static void main(String... args) throws Exception { |
vaibhav@9421 | 81 | if (args.length > 1 && args[0].equals("-jar")) { |
vaibhav@9421 | 82 | if (args.length < 2) { |
vaibhav@9421 | 83 | throw new RuntimeException("Usage: ClassFileInstaller <options> <classes>\n" + |
vaibhav@9421 | 84 | "where possible options include:\n" + |
vaibhav@9421 | 85 | " -jar <path> Write to the JAR file <path>"); |
vaibhav@9421 | 86 | } |
vaibhav@9421 | 87 | writeJar(args[1], null, args, 2, args.length); |
vaibhav@9421 | 88 | } else { |
vaibhav@9421 | 89 | if (DEBUG) { |
vaibhav@9421 | 90 | System.out.println("ClassFileInstaller: Writing to " + System.getProperty("user.dir")); |
vaibhav@9421 | 91 | } |
vaibhav@9421 | 92 | for (String arg : args) { |
vaibhav@9421 | 93 | writeClassToDisk(arg); |
vaibhav@9421 | 94 | } |
vaibhav@9421 | 95 | } |
vaibhav@9421 | 96 | } |
mgerdin@4637 | 97 | |
vaibhav@9421 | 98 | public static class Manifest { |
vaibhav@9421 | 99 | private InputStream in; |
mgerdin@4637 | 100 | |
vaibhav@9421 | 101 | private Manifest(InputStream in) { |
vaibhav@9421 | 102 | this.in = in; |
vaibhav@9421 | 103 | } |
vaibhav@9421 | 104 | |
vaibhav@9421 | 105 | static Manifest fromSourceFile(String fileName) throws Exception { |
vaibhav@9421 | 106 | String pathName = System.getProperty("test.src") + File.separator + fileName; |
vaibhav@9421 | 107 | return new Manifest(new FileInputStream(pathName)); |
vaibhav@9421 | 108 | } |
vaibhav@9421 | 109 | |
vaibhav@9421 | 110 | // Example: |
vaibhav@9421 | 111 | // String manifest = "Premain-Class: RedefineClassHelper\n" + |
vaibhav@9421 | 112 | // "Can-Redefine-Classes: true\n"; |
vaibhav@9421 | 113 | // ClassFileInstaller.writeJar("redefineagent.jar", |
vaibhav@9421 | 114 | // ClassFileInstaller.Manifest.fromString(manifest), |
vaibhav@9421 | 115 | // "RedefineClassHelper"); |
vaibhav@9421 | 116 | static Manifest fromString(String manifest) throws Exception { |
vaibhav@9421 | 117 | return new Manifest(new ByteArrayInputStream(manifest.getBytes())); |
vaibhav@9421 | 118 | } |
vaibhav@9421 | 119 | |
vaibhav@9421 | 120 | public InputStream getInputStream() { |
vaibhav@9421 | 121 | return in; |
vaibhav@9421 | 122 | } |
vaibhav@9421 | 123 | } |
vaibhav@9421 | 124 | |
vaibhav@9421 | 125 | private static void writeJar(String jarFile, Manifest manifest, String classes[], int from, int to) throws Exception { |
vaibhav@9421 | 126 | if (DEBUG) { |
vaibhav@9421 | 127 | System.out.println("ClassFileInstaller: Writing to " + getJarPath(jarFile)); |
vaibhav@9421 | 128 | } |
vaibhav@9421 | 129 | |
vaibhav@9421 | 130 | (new File(jarFile)).delete(); |
vaibhav@9421 | 131 | FileOutputStream fos = new FileOutputStream(jarFile); |
vaibhav@9421 | 132 | ZipOutputStream zos = new ZipOutputStream(fos); |
vaibhav@9421 | 133 | |
vaibhav@9421 | 134 | // The manifest must be the first or second entry. See comments in JarInputStream |
vaibhav@9421 | 135 | // constructor and JDK-5046178. |
vaibhav@9421 | 136 | if (manifest != null) { |
vaibhav@9421 | 137 | writeToDisk(zos, "META-INF/MANIFEST.MF", manifest.getInputStream()); |
vaibhav@9421 | 138 | } |
vaibhav@9421 | 139 | |
vaibhav@9421 | 140 | for (int i=from; i<to; i++) { |
vaibhav@9421 | 141 | writeClassToDisk(zos, classes[i]); |
vaibhav@9421 | 142 | } |
vaibhav@9421 | 143 | |
vaibhav@9421 | 144 | zos.close(); |
vaibhav@9421 | 145 | fos.close(); |
vaibhav@9421 | 146 | } |
vaibhav@9421 | 147 | |
vaibhav@9421 | 148 | /* |
vaibhav@9421 | 149 | * You can call ClassFileInstaller.writeJar() from your main test class instead of |
vaibhav@9421 | 150 | * using "@run ClassFileInstaller -jar ...". E.g., |
vaibhav@9421 | 151 | * |
vaibhav@9421 | 152 | * String jarPath = ClassFileInstaller.getJarPath("myjar.jar", "sun.hotspot.WhiteBox") |
vaibhav@9421 | 153 | * |
vaibhav@9421 | 154 | * If you call this API, make sure you build ClassFileInstaller with the following tags: |
vaibhav@9421 | 155 | * |
vaibhav@9421 | 156 | * @library testlibrary |
vaibhav@9421 | 157 | * @build ClassFileInstaller |
vaibhav@9421 | 158 | */ |
vaibhav@9421 | 159 | public static String writeJar(String jarFile, String... classes) throws Exception { |
vaibhav@9421 | 160 | writeJar(jarFile, null, classes, 0, classes.length); |
vaibhav@9421 | 161 | return getJarPath(jarFile); |
vaibhav@9421 | 162 | } |
vaibhav@9421 | 163 | |
vaibhav@9421 | 164 | public static String writeJar(String jarFile, Manifest manifest, String... classes) throws Exception { |
vaibhav@9421 | 165 | writeJar(jarFile, manifest, classes, 0, classes.length); |
vaibhav@9421 | 166 | return getJarPath(jarFile); |
vaibhav@9421 | 167 | } |
vaibhav@9421 | 168 | |
vaibhav@9421 | 169 | /** |
vaibhav@9421 | 170 | * This returns the absolute path to the file specified in "@ClassFileInstaller -jar myjar.jar", |
vaibhav@9421 | 171 | * In your test program, instead of using the JAR file name directly: |
vaibhav@9421 | 172 | * |
vaibhav@9421 | 173 | * String jarPath = "myjar.jar"; |
vaibhav@9421 | 174 | * |
vaibhav@9421 | 175 | * you should call this function, like: |
vaibhav@9421 | 176 | * |
vaibhav@9421 | 177 | * String jarPath = ClassFileInstaller.getJarPath("myjar.jar") |
vaibhav@9421 | 178 | * |
vaibhav@9421 | 179 | * The reasons are: |
vaibhav@9421 | 180 | * (1) Using absolute path makes it easy to cut-and-paste from the JTR file and rerun your |
vaibhav@9421 | 181 | * test in any directory. |
vaibhav@9421 | 182 | * (2) In the future, we may make the JAR file name unique to avoid clobbering |
vaibhav@9421 | 183 | * during parallel JTREG execution. |
vaibhav@9421 | 184 | * |
vaibhav@9421 | 185 | */ |
vaibhav@9421 | 186 | public static String getJarPath(String jarFileName) { |
vaibhav@9421 | 187 | return new File(jarFileName).getAbsolutePath(); |
vaibhav@9421 | 188 | } |
vaibhav@9421 | 189 | |
vaibhav@9421 | 190 | public static void writeClassToDisk(String className) throws Exception { |
vaibhav@9421 | 191 | writeClassToDisk((ZipOutputStream)null, className); |
vaibhav@9421 | 192 | } |
vaibhav@9421 | 193 | private static void writeClassToDisk(ZipOutputStream zos, String className) throws Exception { |
vaibhav@9421 | 194 | writeClassToDisk(zos, className, ""); |
vaibhav@9421 | 195 | } |
vaibhav@9421 | 196 | |
vaibhav@9421 | 197 | public static void writeClassToDisk(String className, String prependPath) throws Exception { |
vaibhav@9421 | 198 | writeClassToDisk(null, className, prependPath); |
vaibhav@9421 | 199 | } |
vaibhav@9421 | 200 | private static void writeClassToDisk(ZipOutputStream zos, String className, String prependPath) throws Exception { |
vaibhav@9421 | 201 | ClassLoader cl = ClassFileInstaller.class.getClassLoader(); |
vaibhav@9421 | 202 | |
vaibhav@9421 | 203 | // Convert dotted class name to a path to a class file |
vaibhav@9421 | 204 | String pathName = className.replace('.', '/').concat(".class"); |
vaibhav@9421 | 205 | InputStream is = cl.getResourceAsStream(pathName); |
vaibhav@9421 | 206 | if (is == null) { |
vaibhav@9421 | 207 | throw new RuntimeException("Failed to find " + pathName); |
vaibhav@9421 | 208 | } |
vaibhav@9421 | 209 | if (prependPath.length() > 0) { |
vaibhav@9421 | 210 | pathName = prependPath + "/" + pathName; |
vaibhav@9421 | 211 | } |
vaibhav@9421 | 212 | writeToDisk(zos, pathName, is); |
vaibhav@9421 | 213 | } |
vaibhav@9421 | 214 | |
vaibhav@9421 | 215 | public static void writeClassToDisk(String className, byte[] bytecode) throws Exception { |
vaibhav@9421 | 216 | writeClassToDisk(null, className, bytecode); |
vaibhav@9421 | 217 | } |
vaibhav@9421 | 218 | private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode) throws Exception { |
vaibhav@9421 | 219 | writeClassToDisk(zos, className, bytecode, ""); |
vaibhav@9421 | 220 | } |
vaibhav@9421 | 221 | |
vaibhav@9421 | 222 | public static void writeClassToDisk(String className, byte[] bytecode, String prependPath) throws Exception { |
vaibhav@9421 | 223 | writeClassToDisk(null, className, bytecode, prependPath); |
vaibhav@9421 | 224 | } |
vaibhav@9421 | 225 | private static void writeClassToDisk(ZipOutputStream zos, String className, byte[] bytecode, String prependPath) throws Exception { |
vaibhav@9421 | 226 | // Convert dotted class name to a path to a class file |
vaibhav@9421 | 227 | String pathName = className.replace('.', '/').concat(".class"); |
vaibhav@9421 | 228 | if (prependPath.length() > 0) { |
vaibhav@9421 | 229 | pathName = prependPath + "/" + pathName; |
vaibhav@9421 | 230 | } |
vaibhav@9421 | 231 | writeToDisk(zos, pathName, new ByteArrayInputStream(bytecode)); |
vaibhav@9421 | 232 | } |
vaibhav@9421 | 233 | |
vaibhav@9421 | 234 | private static void writeToDisk(ZipOutputStream zos, String pathName, InputStream is) throws Exception { |
vaibhav@9421 | 235 | if (DEBUG) { |
vaibhav@9421 | 236 | System.out.println("ClassFileInstaller: Writing " + pathName); |
vaibhav@9421 | 237 | } |
vaibhav@9421 | 238 | if (zos != null) { |
vaibhav@9421 | 239 | ZipEntry ze = new ZipEntry(pathName); |
vaibhav@9421 | 240 | zos.putNextEntry(ze); |
vaibhav@9421 | 241 | byte[] buf = new byte[1024]; |
vaibhav@9421 | 242 | int len; |
vaibhav@9421 | 243 | while ((len = is.read(buf))>0){ |
vaibhav@9421 | 244 | zos.write(buf, 0, len); |
vaibhav@9421 | 245 | } |
vaibhav@9421 | 246 | } else { |
mgerdin@4637 | 247 | // Create the class file's package directory |
mgerdin@4637 | 248 | Path p = Paths.get(pathName); |
coleenp@5100 | 249 | if (pathName.contains("/")) { |
coleenp@5100 | 250 | Files.createDirectories(p.getParent()); |
coleenp@5100 | 251 | } |
mgerdin@4637 | 252 | // Create the class file |
mgerdin@4637 | 253 | Files.copy(is, p, StandardCopyOption.REPLACE_EXISTING); |
mgerdin@4637 | 254 | } |
vaibhav@9421 | 255 | is.close(); |
mgerdin@4637 | 256 | } |
mgerdin@4637 | 257 | } |