1 /*
  2  * Copyright (c) 2024, 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  * @summary "AOT" aliases for traditional CDS command-line options
 28  * @requires vm.cds
 29  * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes
 30  * @build Hello
 31  * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar hello.jar Hello
 32  * @run driver AOTFlags
 33  */
 34 
 35 import jdk.test.lib.cds.CDSTestUtils;
 36 import jdk.test.lib.helpers.ClassFileInstaller;
 37 import jdk.test.lib.process.OutputAnalyzer;
 38 import jdk.test.lib.process.ProcessTools;
 39 
 40 public class AOTFlags {
 41     static String appJar = ClassFileInstaller.getJarPath("hello.jar");
 42     static String aotConfigFile = "hello.aotconfig";
 43     static String aotCacheFile = "hello.aot";
 44     static String helloClass = "Hello";
 45 
 46     public static void main(String[] args) throws Exception {
 47         positiveTests();
 48         negativeTests();
 49     }
 50 
 51     static void positiveTests() throws Exception {
 52         // (1) Training Run
 53         ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(
 54             "-XX:AOTMode=record",
 55             "-XX:AOTConfiguration=" + aotConfigFile,
 56             "-cp", appJar, helloClass);
 57 
 58         OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, "train");
 59         out.shouldContain("Hello World");
 60         out.shouldHaveExitValue(0);
 61 
 62         // (2) Assembly Phase
 63         pb = ProcessTools.createLimitedTestJavaProcessBuilder(
 64             "-XX:AOTMode=create",
 65             "-XX:AOTConfiguration=" + aotConfigFile,
 66             "-XX:AOTCache=" + aotCacheFile,
 67             "-Xlog:cds",
 68             "-cp", appJar);
 69         out = CDSTestUtils.executeAndLog(pb, "asm");
 70         out.shouldContain("Dumping shared data to file:");
 71         out.shouldMatch("cds.*hello[.]aot");
 72         out.shouldHaveExitValue(0);
 73 
 74         // (3) Production Run with AOTCache
 75         pb = ProcessTools.createLimitedTestJavaProcessBuilder(
 76             "-XX:AOTCache=" + aotCacheFile,
 77             "-Xlog:cds",
 78             "-cp", appJar, helloClass);
 79         out = CDSTestUtils.executeAndLog(pb, "prod");
 80         out.shouldContain("Opened archive hello.aot.");
 81         out.shouldContain("Hello World");
 82         out.shouldHaveExitValue(0);
 83 
 84         // (4) AOTMode=off
 85         pb = ProcessTools.createLimitedTestJavaProcessBuilder(
 86             "-XX:AOTCache=" + aotCacheFile,
 87             "--show-version",
 88             "-Xlog:cds",
 89             "-XX:AOTMode=off",
 90             "-cp", appJar, helloClass);
 91         out = CDSTestUtils.executeAndLog(pb, "prod");
 92         out.shouldNotContain(", sharing");
 93         out.shouldNotContain("Opened archive hello.aot.");
 94         out.shouldContain("Hello World");
 95         out.shouldHaveExitValue(0);
 96 
 97         // (5) AOTMode=auto
 98         pb = ProcessTools.createLimitedTestJavaProcessBuilder(
 99             "-XX:AOTCache=" + aotCacheFile,
100             "--show-version",
101             "-Xlog:cds",
102             "-XX:AOTMode=auto",
103             "-cp", appJar, helloClass);
104         out = CDSTestUtils.executeAndLog(pb, "prod");
105         out.shouldContain(", sharing");
106         out.shouldContain("Opened archive hello.aot.");
107         out.shouldContain("Hello World");
108         out.shouldHaveExitValue(0);
109     }
110 
111     static void negativeTests() throws Exception {
112         // (1) Mixing old and new options
113         String mixOldNewErrSuffix = " cannot be used at the same time with -Xshare:on, -Xshare:auto, "
114             + "-Xshare:off, -Xshare:dump, DumpLoadedClassList, SharedClassListFile, "
115             + "or SharedArchiveFile";
116 
117         ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(
118             "-Xshare:off",
119             "-XX:AOTConfiguration=" + aotConfigFile,
120             "-cp", appJar, helloClass);
121 
122         OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, "neg");
123         out.shouldContain("Option AOTConfiguration" + mixOldNewErrSuffix);
124         out.shouldNotHaveExitValue(0);
125 
126         pb = ProcessTools.createLimitedTestJavaProcessBuilder(
127             "-XX:SharedArchiveFile=" + aotCacheFile,
128             "-XX:AOTCache=" + aotCacheFile,
129             "-cp", appJar, helloClass);
130         out = CDSTestUtils.executeAndLog(pb, "neg");
131         out.shouldContain("Option AOTCache" + mixOldNewErrSuffix);
132         out.shouldNotHaveExitValue(0);
133 
134         // (2) Use AOTConfiguration without AOTMode
135         pb = ProcessTools.createLimitedTestJavaProcessBuilder(
136             "-XX:AOTConfiguration=" + aotConfigFile,
137             "-cp", appJar, helloClass);
138 
139         out = CDSTestUtils.executeAndLog(pb, "neg");
140         out.shouldContain("AOTConfiguration can only be used with -XX:AOTMode=record or -XX:AOTMode=create");
141         out.shouldNotHaveExitValue(0);
142 
143         // (3) Use AOTMode without AOTConfiguration
144         pb = ProcessTools.createLimitedTestJavaProcessBuilder(
145             "-XX:AOTMode=record",
146             "-cp", appJar, helloClass);
147 
148         out = CDSTestUtils.executeAndLog(pb, "neg");
149         out.shouldContain("-XX:AOTMode=record cannot be used without setting AOTConfiguration");
150 
151         pb = ProcessTools.createLimitedTestJavaProcessBuilder(
152             "-XX:AOTMode=create",
153             "-cp", appJar, helloClass);
154 
155         out = CDSTestUtils.executeAndLog(pb, "neg");
156         out.shouldContain("-XX:AOTMode=create cannot be used without setting AOTConfiguration");
157         out.shouldNotHaveExitValue(0);
158 
159         // (4) Bad AOTMode
160         pb = ProcessTools.createLimitedTestJavaProcessBuilder(
161             "-XX:AOTMode=foo",
162             "-cp", appJar, helloClass);
163 
164         out = CDSTestUtils.executeAndLog(pb, "neg");
165         out.shouldContain("Unrecognized value foo for AOTMode. Must be one of the following: off, record, create, auto, on");
166         out.shouldNotHaveExitValue(0);
167 
168         // (5) AOTCache specified with -XX:AOTMode=record
169         pb = ProcessTools.createLimitedTestJavaProcessBuilder(
170             "-XX:AOTMode=record",
171             "-XX:AOTConfiguration=" + aotConfigFile,
172             "-XX:AOTCache=" + aotCacheFile,
173             "-cp", appJar, helloClass);
174 
175         out = CDSTestUtils.executeAndLog(pb, "neg");
176         out.shouldContain("AOTCache must not be specified when using -XX:AOTMode=record");
177         out.shouldNotHaveExitValue(0);
178 
179         // (5) AOTCache not specified with -XX:AOTMode=create
180         pb = ProcessTools.createLimitedTestJavaProcessBuilder(
181             "-XX:AOTMode=create",
182             "-XX:AOTConfiguration=" + aotConfigFile,
183             "-cp", appJar, helloClass);
184 
185         out = CDSTestUtils.executeAndLog(pb, "neg");
186         out.shouldContain("AOTCache must be specified when using -XX:AOTMode=create");
187         out.shouldNotHaveExitValue(0);
188 
189     }
190 }