test/hotspot/jtreg/runtime/appcds/jvmti/transformRelatedClasses/TransformRelatedClassesAppCDS.java
changeset 57567 b000362a89a0
parent 57566 ad84ae073248
child 57568 460ac76019f4
equal deleted inserted replaced
57566:ad84ae073248 57567:b000362a89a0
     1 /*
       
     2  * Copyright (c) 2016, 2019, 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 // Structure of the test:
       
    26 // TransformRelatedClassesAppCDS -- common main test driver
       
    27 // Invoked from test driver classes:
       
    28 //     TransformInterfaceAndImplementor, TransformSuperAndSubClasses.java
       
    29 //     prepares test artifacts, launches tests, checks results
       
    30 // SuperClazz, SubClass -- classes under test
       
    31 // Interface, Implementor -- classes under test
       
    32 // TransformerAgent -- an agent that is used when JVM-under-test is executed
       
    33 //     to transform specific strings inside specified classes
       
    34 // TransformerAgent.mf - accompanies transformer agent
       
    35 // CustomLoaderApp -- a test "application" that is used to load
       
    36 //     classes-under-test (Parent, Child) via custom class loader, using
       
    37 //     AppCDS-v2 mechanism (unregistered custom loaders, aka FP)
       
    38 //     This "app" is launched in a child process by this driver with sharing on.
       
    39 
       
    40 import java.io.File;
       
    41 import java.util.ArrayList;
       
    42 import jdk.test.lib.Platform;
       
    43 import jdk.test.lib.process.OutputAnalyzer;
       
    44 
       
    45 // This class is intended to test 2 parent-child relationships:
       
    46 // 1. Base Class (parent) and Derived Class (child)
       
    47 // 2. Interface (parent) and Implementor (child)
       
    48 //    Parameters to main(): parent, child
       
    49 
       
    50 public class TransformRelatedClassesAppCDS extends TransformRelatedClasses {
       
    51     private static void log(String msg, Object... args) {
       
    52         String msg0 = String.format(msg, args);
       
    53         System.out.println("TransformRelatedClassesAppCDS: " + msg0);
       
    54     }
       
    55 
       
    56     // Initial Test Matrix:
       
    57     // (ParentTransformed = true/false, ChildTransformed = true/false) x
       
    58     // (BootCDS - see open tests, AppCDS-v1, AppCDS-v2-unregistered)
       
    59     // Total cases: 2 x 4 = 8
       
    60     public static void main(String args[]) throws Exception {
       
    61         TransformRelatedClassesAppCDS test =
       
    62             new TransformRelatedClassesAppCDS(args[0], args[1]);
       
    63 
       
    64         test.prepareAgent(agentClasses);
       
    65 
       
    66         // Test Table
       
    67         // testCaseId |  transformParent | tranformChild | isParentExpectedShared | isChildExpectedShared
       
    68         ArrayList<TestEntry> testTable = new ArrayList<>();
       
    69 
       
    70         // base case - no tranformation - all expected to be shared
       
    71         testTable.add(new TestEntry(0, false, false, true, true));
       
    72 
       
    73         // transform parent only - both parent and child should not be shared
       
    74         testTable.add(new TestEntry(1, true, false, false, false));
       
    75 
       
    76         // transform parent and child - both parent and child should not be shared
       
    77         testTable.add(new TestEntry(2, true, true, false, false));
       
    78 
       
    79         // transform child only - parent should still be shared, but not child
       
    80         testTable.add(new TestEntry(3, false, true, true, false));
       
    81 
       
    82         // run the tests
       
    83         test.runWithAppLoader(testTable);
       
    84         test.runWithCustomLoader(testTable);
       
    85     }
       
    86 
       
    87 
       
    88     public TransformRelatedClassesAppCDS(String parent, String child) {
       
    89         super(parent, child);
       
    90 
       
    91         // a trick to get it compiled by jtreg
       
    92         CustomLoaderApp.ping();
       
    93     }
       
    94 
       
    95 
       
    96     private void prepareAgent(String[] agentClasses) throws Exception {
       
    97         String manifest = "../../../../testlibrary/jvmti/TransformerAgent.mf";
       
    98         agentJar = ClassFileInstaller.writeJar("TransformerAgent.jar",
       
    99                    ClassFileInstaller.Manifest.fromSourceFile(manifest),
       
   100                                            agentClasses);
       
   101     }
       
   102 
       
   103 
       
   104     private void runWithAppLoader(ArrayList<TestEntry> testTable) throws Exception {
       
   105         String appJar = writeJar("app", testClasses);
       
   106 
       
   107         // create an archive
       
   108         OutputAnalyzer out = TestCommon.dump(appJar, testClasses);
       
   109         TestCommon.checkDump(out);
       
   110 
       
   111         // execute with archive
       
   112         for (TestEntry entry : testTable) {
       
   113             log("runTestWithAppLoader(): testCaseId = %d", entry.testCaseId);
       
   114             String params = TransformTestCommon.getAgentParams(entry, parent, child);
       
   115             String agentParam = String.format("-javaagent:%s=%s", agentJar, params);
       
   116             TestCommon.run("-Xlog:class+load=info", "-cp", appJar,
       
   117                            agentParam, child)
       
   118               .assertNormalExit(output -> TransformTestCommon.checkResults(entry, output, parent, child));
       
   119         }
       
   120     }
       
   121 
       
   122 
       
   123     private String[] getCustomClassList(String loaderType, String customJar) {
       
   124         String type = child + "-" + loaderType;
       
   125 
       
   126         switch (type) {
       
   127 
       
   128         case "SubClass-unregistered":
       
   129             return new String[] {
       
   130                 "CustomLoaderApp",
       
   131                 "java/lang/Object id: 0",
       
   132                 parent + " id: 1 super: 0 source: " + customJar,
       
   133                 child +  " id: 2 super: 1 source: " + customJar,
       
   134             };
       
   135 
       
   136         case "Implementor-unregistered":
       
   137             return new String[] {
       
   138                 "CustomLoaderApp",
       
   139                 "java/lang/Object id: 0",
       
   140                 parent + " id: 1 super: 0 source: " + customJar,
       
   141                 child +  " id: 2 super: 0 interfaces: 1 source: " + customJar,
       
   142             };
       
   143 
       
   144         default:
       
   145             throw new IllegalArgumentException("getCustomClassList - wrong type: " + type);
       
   146         }
       
   147     }
       
   148 
       
   149 
       
   150     private void runWithCustomLoader(ArrayList<TestEntry> testTable) throws Exception {
       
   151         if (!Platform.areCustomLoadersSupportedForCDS()) {
       
   152             log("custom loader not supported for this platform" +
       
   153                 " - skipping test case for custom loader");
       
   154             return;
       
   155         }
       
   156 
       
   157         if (TestCommon.isDynamicArchive()) {
       
   158             log("custom loader class list not applicable to dynamic archive" +
       
   159                 " - skipping test case for custom loader");
       
   160             return;
       
   161         }
       
   162 
       
   163         String appClasses[] = {
       
   164             "CustomLoaderApp",
       
   165         };
       
   166 
       
   167         String customClasses[] = { parent, child };
       
   168 
       
   169         // create jar files: appJar, customJar (for custom loaders to load classes from)
       
   170         String appJar = writeJar("custldr-app", appClasses);
       
   171         String customJar = writeJar("custldr-custom", customClasses);
       
   172 
       
   173         for (TestEntry entry : testTable) {
       
   174             log("runTestWithCustomLoader(): testCaseId = %d", entry.testCaseId);
       
   175             // unregistered (aka FP) case
       
   176             String[] classList = getCustomClassList("unregistered",customJar);
       
   177             execAndCheckWithCustomLoader(entry, "unregistered", classList,
       
   178                                          appJar, agentJar, customJar);
       
   179         }
       
   180     }
       
   181 
       
   182 
       
   183     private void
       
   184         execAndCheckWithCustomLoader(TestEntry entry, String loaderType,
       
   185                                      String[] classList, String appJar,
       
   186                                      String agentJar, String customJar)
       
   187         throws Exception {
       
   188 
       
   189         OutputAnalyzer out = TestCommon.dump(appJar, classList);
       
   190         TestCommon.checkDump(out);
       
   191 
       
   192         String agentParam = "-javaagent:" + agentJar + "=" +
       
   193             TransformTestCommon.getAgentParams(entry, parent, child);
       
   194 
       
   195         TestCommon.run("-Xlog:class+load=info",
       
   196                        "-cp", appJar,
       
   197                        agentParam,
       
   198                        "CustomLoaderApp",
       
   199                        customJar, loaderType, child)
       
   200           .assertNormalExit(output -> TransformTestCommon.checkResults(entry, output, parent, child));
       
   201     }
       
   202 
       
   203 
       
   204     private String writeJar(String type, String[] classes)
       
   205         throws Exception {
       
   206         String jarName = String.format("%s-%s.jar", child, type);
       
   207         return ClassFileInstaller.writeJar(jarName, classes);
       
   208     }
       
   209 }