test/hotspot/jtreg/runtime/SharedArchiveFile/serviceability/transformRelatedClasses/TransformRelatedClasses.java
changeset 57567 b000362a89a0
parent 57566 ad84ae073248
child 57568 460ac76019f4
equal deleted inserted replaced
57566:ad84ae073248 57567:b000362a89a0
     1 /*
       
     2  * Copyright (c) 2016, 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 // 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 
       
    60 import java.io.File;
       
    61 import java.util.ArrayList;
       
    62 import jdk.test.lib.cds.CDSOptions;
       
    63 import jdk.test.lib.cds.CDSTestUtils;
       
    64 import jdk.test.lib.process.OutputAnalyzer;
       
    65 import jdk.test.lib.process.ProcessTools;
       
    66 
       
    67 
       
    68 public class TransformRelatedClasses {
       
    69     static final String archiveName = "./TransformRelatedClasses.jsa";
       
    70     static String agentClasses[] = {
       
    71         "TransformerAgent",
       
    72         "TransformerAgent$SimpleTransformer",
       
    73         "TransformUtil"
       
    74     };
       
    75 
       
    76     String parent;
       
    77     String child;
       
    78     String[] testClasses = new String[2];
       
    79     String[] testNames = new String[2];
       
    80     String testJar;
       
    81     String agentJar;
       
    82 
       
    83 
       
    84     private static void log(String msg) {
       
    85         System.out.println("TransformRelatedClasses: " + msg);
       
    86     }
       
    87 
       
    88 
       
    89     // This class is intended to test 2 parent-child relationships:
       
    90     // 1. Base Class (parent) and Derived Class (child)
       
    91     // 2. Interface (parent) and Implementor (child)
       
    92     //    Parameters to main(): parent, child
       
    93     public static void main(String args[]) throws Exception {
       
    94         TransformRelatedClasses test = new TransformRelatedClasses(args[0], args[1]);
       
    95         test.prepare();
       
    96 
       
    97         // Test Table
       
    98         // TestEntry:  (testCaseId, transformParent, tranformChild,
       
    99         //             isParentExpectedShared, isChildExpectedShared)
       
   100         ArrayList<TestEntry> testTable = new ArrayList<>();
       
   101 
       
   102         // base case - no tranformation - all expected to be shared
       
   103         testTable.add(new TestEntry(0, false, false, true, true));
       
   104 
       
   105         // transform parent only - both parent and child should not be shared
       
   106         testTable.add(new TestEntry(1, true, false, false, false));
       
   107 
       
   108         // transform parent and child - both parent and child should not be shared
       
   109         testTable.add(new TestEntry(2, true, true, false, false));
       
   110 
       
   111         // transform child only - parent should still be shared, but not child
       
   112         testTable.add(new TestEntry(3, false, true, true, false));
       
   113 
       
   114         // run the tests
       
   115         for (TestEntry entry : testTable) {
       
   116             test.runTest(entry);
       
   117         }
       
   118     }
       
   119 
       
   120 
       
   121     public TransformRelatedClasses(String parent, String child) {
       
   122         log("Constructor: parent = " + parent + ", child = " + child);
       
   123         this.parent = parent;
       
   124         this.child = child;
       
   125         testClasses[0] = parent;
       
   126         testClasses[1] = child;
       
   127         testNames[0] = parent.replace('.', '/');
       
   128         testNames[1] = child.replace('.', '/');
       
   129     }
       
   130 
       
   131 
       
   132     // same test jar and archive can be used for all test cases
       
   133     private void prepare() throws Exception {
       
   134         // create agent jar
       
   135         // Agent is the same for all test cases
       
   136         String pathToManifest = "../../../../testlibrary/jvmti/TransformerAgent.mf";
       
   137         agentJar = ClassFileInstaller.writeJar("TransformerAgent.jar",
       
   138                        ClassFileInstaller.Manifest.fromSourceFile(pathToManifest),
       
   139                                            agentClasses);
       
   140 
       
   141         // create a test jar
       
   142         testJar =
       
   143             ClassFileInstaller.writeJar(parent + "-" + child + ".jar",
       
   144                                            testClasses);
       
   145 
       
   146         // create an archive
       
   147         String classList =
       
   148             CDSTestUtils.makeClassList("transform-" + parent, testNames).getPath();
       
   149 
       
   150         CDSTestUtils.createArchiveAndCheck("-Xbootclasspath/a:" + testJar,
       
   151             "-XX:ExtraSharedClassListFile=" + classList);
       
   152     }
       
   153 
       
   154 
       
   155     private void runTest(TestEntry entry) throws Exception {
       
   156         log("runTest(): testCaseId = " + entry.testCaseId);
       
   157 
       
   158         // execute with archive
       
   159         String agentParam = "-javaagent:" + agentJar + "=" +
       
   160             TransformTestCommon.getAgentParams(entry, parent, child);
       
   161 
       
   162         CDSOptions opts = new CDSOptions()
       
   163             .addPrefix("-Xbootclasspath/a:" + testJar, "-Xlog:class+load=info")
       
   164             .setUseVersion(false)
       
   165             .addSuffix( "-showversion",agentParam, child);
       
   166 
       
   167         OutputAnalyzer out = CDSTestUtils.runWithArchive(opts);
       
   168         TransformTestCommon.checkResults(entry, out, parent, child);
       
   169     }
       
   170 }