1 /* 2 * Copyright (c) 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 // This is the main test class for testing transformation of related classes 26 // in combination with CDS, to ensure these features work well together. 27 // The relationships that can be tested using this test class are: 28 // superclass/subclass, and interface/implementor relationships. 29 // 30 // The test uses combinatorial approach. 31 // For details on test table and test cases see main() method in this class. 32 // 33 // This test consists of multiple classes for better flexibility and reuse, 34 // and also relies on certain common utility code. 35 // Here are the details on the structure of the test 36 // 37 // Structure of the test: 38 // TransformRelatedClasses -- common main test driver 39 // The TransformRelatedClasses is invoked from test driver classes: 40 // TransformInterfaceAndImplementor, TransformSuperAndSubClasses 41 // It is responsible for preparing test artifacts (test jar, agent jar 42 // and the shared archive), running test cases and checking the results. 43 // The following test classes below are launched in a sub-process with use 44 // of shared archive: 45 // SuperClazz, SubClass -- super/sub class pair under test 46 // Interface, Implementor -- classes under test 47 // This test will transform these classes, based on the test case data, 48 // by changing a predefined unique string in each class. 49 // For more details, see the test classes' code and comments. 50 // 51 // Other related classes: 52 // TestEntry - a class representing a single test case, as test entry in the table 53 // TransformTestCommon - common methods for transformation test cases 54 // 55 // Other utility/helper classes and files used in this test: 56 // TransformerAgent - an agent that is used when JVM-under-test is executed 57 // to transform specific strings inside specified classes 58 // TransformerAgent.mf - accompanies transformer agent 59 // CDSTestUtils - Test Utilities common to all CDS tests 60 61 import java.io.File; 62 import java.util.ArrayList; 63 import jdk.test.lib.process.OutputAnalyzer; 64 import jdk.test.lib.process.ProcessTools; 65 66 67 public class TransformRelatedClasses { 68 static final String archiveName = "./TransformRelatedClasses.jsa"; 69 static String agentClasses[] = { 70 "TransformerAgent", 71 "TransformerAgent$SimpleTransformer", 72 "TransformUtil" 73 }; 74 75 String parent; 76 String child; 77 String[] testClasses = new String[2]; 78 String[] testNames = new String[2]; 79 String testJar; 80 String agentJar; 81 82 83 private static void log(String msg) { 84 System.out.println("TransformRelatedClasses: " + msg); 85 } 86 87 88 // This class is intended to test 2 parent-child relationships: 89 // 1. Base Class (parent) and Derived Class (child) 90 // 2. Interface (parent) and Implementor (child) 91 // Parameters to main(): parent, child 92 public static void main(String args[]) throws Exception { 93 TransformRelatedClasses test = new TransformRelatedClasses(args[0], args[1]); 94 test.prepare(); 95 96 // Test Table 97 // TestEntry: (testCaseId, transformParent, tranformChild, 98 // isParentExpectedShared, isChildExpectedShared) 99 ArrayList<TestEntry> testTable = new ArrayList<>(); 100 101 // base case - no tranformation - all expected to be shared 102 testTable.add(new TestEntry(0, false, false, true, true)); 103 104 // transform parent only - both parent and child should not be shared 105 testTable.add(new TestEntry(1, true, false, false, false)); 106 107 // transform parent and child - both parent and child should not be shared 108 testTable.add(new TestEntry(2, true, true, false, false)); 109 110 // transform child only - parent should still be shared, but not child 111 testTable.add(new TestEntry(3, false, true, true, false)); 112 113 // run the tests 114 for (TestEntry entry : testTable) { 115 test.runTest(entry); 116 } 117 } 118 119 120 public TransformRelatedClasses(String parent, String child) { 121 log("Constructor: parent = " + parent + ", child = " + child); 122 this.parent = parent; 123 this.child = child; 124 testClasses[0] = parent; 125 testClasses[1] = child; 126 testNames[0] = parent.replace('.', '/'); 127 testNames[1] = child.replace('.', '/'); 128 } 129 130 131 // same test jar and archive can be used for all test cases 132 private void prepare() throws Exception { 133 // create agent jar 134 // Agent is the same for all test cases 135 String pathToManifest = "../../../../testlibrary/jvmti/TransformerAgent.mf"; 136 agentJar = ClassFileInstaller.writeJar("TransformerAgent.jar", 137 ClassFileInstaller.Manifest.fromSourceFile(pathToManifest), 138 agentClasses); 139 140 // create a test jar 141 testJar = 142 ClassFileInstaller.writeJar(parent + "-" + child + ".jar", 143 testClasses); 144 145 // create an archive 146 File classList = CDSTestUtils.makeClassList("transform-" + parent, 147 testNames); 148 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, 149 "-Xbootclasspath/a:" + testJar, 150 "-XX:+UnlockDiagnosticVMOptions", 151 "-XX:ExtraSharedClassListFile=" + 152 classList.getPath(), 153 "-XX:SharedArchiveFile=" + archiveName, 154 "-XX:+PrintSharedSpaces", 155 "-Xshare:dump"); 156 OutputAnalyzer out = new OutputAnalyzer(pb.start()); 157 CDSTestUtils.checkDump(out); 158 } 159 160 161 private void runTest(TestEntry entry) throws Exception { 162 log("runTest(): testCaseId = " + entry.testCaseId); 163 164 // execute with archive 165 String agentParam = "-javaagent:" + agentJar + "=" + 166 TransformTestCommon.getAgentParams(entry, parent, child); 167 168 ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(true, 169 "-Xbootclasspath/a:" + testJar, 170 "-XX:+UnlockDiagnosticVMOptions", 171 "-XX:SharedArchiveFile=" + archiveName, 172 "-Xlog:class+load=info", 173 "-Xshare:on", "-showversion", 174 agentParam, child); 175 OutputAnalyzer out = new OutputAnalyzer(pb.start()); 176 177 TransformTestCommon.checkResults(entry, out, parent, child); 178 } 179 }