1 /*
  2  * Copyright (c) 2019, 2022, 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 /**
 26  * @test
 27  * @comment the test uses -XX:ArchiveRelocationMode=1 to force relocation.
 28  * @requires vm.cds
 29  * @summary Testing relocation of dynamic CDS archive (during both dump time and run time)
 30  * @comment JDK-8231610 Relocate the CDS archive if it cannot be mapped to the requested address
 31  * @bug 8231610
 32  * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds /test/hotspot/jtreg/runtime/cds/appcds/test-classes
 33  * @build Hello
 34  * @build jdk.test.whitebox.WhiteBox
 35  * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar hello.jar Hello
 36  * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
 37  * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. DynamicArchiveRelocationTest
 38  */
 39 
 40 import jdk.test.lib.process.OutputAnalyzer;
 41 import jdk.test.lib.helpers.ClassFileInstaller;
 42 import jtreg.SkippedException;
 43 
 44 public class DynamicArchiveRelocationTest extends DynamicArchiveTestBase {
 45     public static void main(String... args) throws Exception {
 46         try {
 47             testOuter();
 48         } catch (SkippedException s) {
 49             s.printStackTrace();
 50             throw new RuntimeException("Archive mapping should always succeed after JDK-8231610 (did the machine run out of memory?)");
 51         }
 52     }
 53 
 54     static void testOuter() throws Exception {
 55         testInner(true,  false);
 56         testInner(false, true);
 57         testInner(true,  true);
 58     }
 59 
 60     static boolean dump_top_reloc, run_reloc;
 61 
 62     // dump_top_reloc  - force relocation of archive when dumping top  archive
 63     // run_reloc       - force relocation of archive when running
 64     static void testInner(boolean dump_top_reloc, boolean run_reloc) throws Exception {
 65         DynamicArchiveRelocationTest.dump_top_reloc  = dump_top_reloc;
 66         DynamicArchiveRelocationTest.run_reloc       = run_reloc;
 67 
 68         runTest(DynamicArchiveRelocationTest::doTest);
 69     }
 70 
 71     static int caseCount = 0;
 72     static void doTest() throws Exception {
 73         caseCount += 1;
 74         System.out.println("============================================================");
 75         System.out.println("case = " + caseCount
 76                            + ", top_reloc = " + dump_top_reloc
 77                            + ", run = " + run_reloc);
 78         System.out.println("============================================================");
 79 
 80         String appJar = ClassFileInstaller.getJarPath("hello.jar");
 81         String mainClass = "Hello";
 82         String forceRelocation = "-XX:ArchiveRelocationMode=1";
 83         String dumpTopRelocArg  = dump_top_reloc  ? forceRelocation : "-showversion";
 84         String runRelocArg      = run_reloc       ? forceRelocation : "-showversion";
 85         String logArg = "-Xlog:cds=debug,cds+reloc=debug";
 86 
 87         String baseArchiveName = getNewArchiveName("base");
 88         String topArchiveName  = getNewArchiveName("top");
 89 
 90         String runtimeMsg = "Try to map archive(s) at an alternative address";
 91         String unlockArg = "-XX:+UnlockDiagnosticVMOptions";
 92 
 93         // (1) Dump base archive (static)
 94 
 95         TestCommon.dumpBaseArchive(baseArchiveName, unlockArg, logArg)
 96           .shouldContain("Relocating archive from");
 97 
 98         // (2) Dump top archive (dynamic)
 99 
100         dump2(baseArchiveName, topArchiveName,
101               unlockArg,
102               dumpTopRelocArg,
103               logArg,
104               "-cp", appJar, mainClass)
105             .assertNormalExit(output -> {
106                     if (dump_top_reloc) {
107                         output.shouldContain(runtimeMsg);
108                     }
109                 });
110 
111         run2(baseArchiveName, topArchiveName,
112              unlockArg,
113              runRelocArg,
114              logArg,
115             "-cp", appJar, mainClass)
116             .assertNormalExit(output -> {
117                     if (run_reloc) {
118                         output.shouldContain(runtimeMsg);
119                     }
120                 });
121     }
122 }