1 /*
2  * Copyright (c) 2005, 2020, 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 import static jdk.test.lib.Asserts.assertTrue;
25 import static jdk.test.lib.Asserts.assertFalse;
26 import static jdk.test.lib.Asserts.fail;
27 
28 import java.io.File;
29 import java.nio.file.Files;
30 import java.util.Arrays;
31 import java.util.List;
32 
33 import jdk.test.lib.JDKToolLauncher;
34 import jdk.test.lib.Utils;
35 import jdk.test.lib.hprof.HprofParser;
36 import jdk.test.lib.process.OutputAnalyzer;
37 import jdk.test.lib.process.ProcessTools;
38 
39 /*
40  * @test id=Serial
41  * @requires vm.gc.Serial
42  * @summary Unit test for jmap utility (Serial GC)
43  * @key intermittent
44  * @library /test/lib
45  * @build jdk.test.lib.hprof.*
46  * @build jdk.test.lib.hprof.model.*
47  * @build jdk.test.lib.hprof.parser.*
48  * @build jdk.test.lib.hprof.util.*
49  * @run main/othervm/timeout=240 -XX:+UseSerialGC BasicJMapTest
50  */
51 
52 /*
53  * @test id=Parallel
54  * @requires vm.gc.Parallel
55  * @summary Unit test for jmap utility (Parallel GC)
56  * @key intermittent
57  * @library /test/lib
58  * @build jdk.test.lib.hprof.*
59  * @build jdk.test.lib.hprof.model.*
60  * @build jdk.test.lib.hprof.parser.*
61  * @build jdk.test.lib.hprof.util.*
62  * @run main/othervm/timeout=240 -XX:+UseParallelGC BasicJMapTest
63  */
64 
65 /*
66  * @test id=G1
67  * @requires vm.gc.G1
68  * @summary Unit test for jmap utility (G1 GC)
69  * @key intermittent
70  * @library /test/lib
71  * @build jdk.test.lib.hprof.*
72  * @build jdk.test.lib.hprof.model.*
73  * @build jdk.test.lib.hprof.parser.*
74  * @build jdk.test.lib.hprof.util.*
75  * @run main/othervm/timeout=240 -XX:+UseG1GC BasicJMapTest
76  */
77 
78 /*
79  * @test id=Shenandoah
80  * @requires vm.gc.Shenandoah
81  * @summary Unit test for jmap utility (Shenandoah GC)
82  * @key intermittent
83  * @library /test/lib
84  * @build jdk.test.lib.hprof.*
85  * @build jdk.test.lib.hprof.model.*
86  * @build jdk.test.lib.hprof.parser.*
87  * @build jdk.test.lib.hprof.util.*
88  * @run main/othervm/timeout=240 -XX:+UseShenandoahGC BasicJMapTest
89  */
90 
91 /*
92  * @test id=Z
93  * @requires vm.gc.Z
94  * @summary Unit test for jmap utility (Z GC)
95  * @key intermittent
96  * @library /test/lib
97  * @build jdk.test.lib.hprof.*
98  * @build jdk.test.lib.hprof.model.*
99  * @build jdk.test.lib.hprof.parser.*
100  * @build jdk.test.lib.hprof.util.*
101  * @run main/othervm/timeout=240 -XX:+UseZGC BasicJMapTest
102  */
103 
104 public class BasicJMapTest {
105 
106     private static ProcessBuilder processBuilder = new ProcessBuilder();
107 
main(String[] args)108     public static void main(String[] args) throws Exception {
109         testHisto();
110         testHistoLive();
111         testHistoAll();
112         testHistoToFile();
113         testHistoLiveToFile();
114         testHistoAllToFile();
115         testFinalizerInfo();
116         testClstats();
117         testDump();
118         testDumpLive();
119         testDumpAll();
120         testDumpCompressed();
121     }
122 
testHisto()123     private static void testHisto() throws Exception {
124         OutputAnalyzer output = jmap("-histo:");
125         output.shouldHaveExitValue(0);
126         OutputAnalyzer output1 = jmap("-histo");
127         output1.shouldHaveExitValue(0);
128     }
129 
testHistoLive()130     private static void testHistoLive() throws Exception {
131         OutputAnalyzer output = jmap("-histo:live");
132         output.shouldHaveExitValue(0);
133     }
134 
testHistoAll()135     private static void testHistoAll() throws Exception {
136         OutputAnalyzer output = jmap("-histo:all");
137         output.shouldHaveExitValue(0);
138     }
139 
testHistoParallelZero()140     private static void testHistoParallelZero() throws Exception {
141         OutputAnalyzer output = jmap("-histo:parallel=0");
142         output.shouldHaveExitValue(0);
143     }
144 
testHistoParallel()145     private static void testHistoParallel() throws Exception {
146         OutputAnalyzer output = jmap("-histo:parallel=2");
147         output.shouldHaveExitValue(0);
148     }
149 
testHistoNonParallel()150     private static void testHistoNonParallel() throws Exception {
151         OutputAnalyzer output = jmap("-histo:parallel=1");
152         output.shouldHaveExitValue(0);
153     }
154 
testHistoToFile()155     private static void testHistoToFile() throws Exception {
156         histoToFile(false, false, 1);
157     }
158 
testHistoLiveToFile()159     private static void testHistoLiveToFile() throws Exception {
160         histoToFile(true, false, 1);
161     }
162 
testHistoAllToFile()163     private static void testHistoAllToFile() throws Exception {
164         histoToFile(false, true, 1);
165     }
166 
testHistoFileParallelZero()167     private static void testHistoFileParallelZero() throws Exception {
168         histoToFile(false, false, 0);
169     }
170 
testHistoFileParallel()171     private static void testHistoFileParallel() throws Exception {
172         histoToFile(false, false, 2);
173     }
174 
histoToFile(boolean live, boolean explicitAll, int parallelThreadNum)175     private static void histoToFile(boolean live,
176                                     boolean explicitAll,
177                                     int parallelThreadNum) throws Exception {
178         String liveArg = "";
179         String fileArg = "";
180         String parArg = "parallel=" + parallelThreadNum;
181         String allArgs = "-histo:";
182 
183         if (live && explicitAll) {
184             fail("Illegal argument setting for jmap -histo");
185         }
186         if (live) {
187             liveArg = "live,";
188         }
189         if (explicitAll) {
190             liveArg = "all,";
191         }
192 
193         File file = new File("jmap.histo.file" + System.currentTimeMillis() + ".histo");
194         if (file.exists()) {
195             file.delete();
196         }
197         fileArg = "file=" + file.getName();
198 
199         OutputAnalyzer output;
200         allArgs = allArgs + liveArg + fileArg + ',' + parArg;
201         output = jmap(allArgs);
202         output.shouldHaveExitValue(0);
203         output.shouldContain("Heap inspection file created");
204         file.delete();
205     }
206 
testFinalizerInfo()207     private static void testFinalizerInfo() throws Exception {
208         OutputAnalyzer output = jmap("-finalizerinfo");
209         output.shouldHaveExitValue(0);
210     }
211 
testClstats()212     private static void testClstats() throws Exception {
213         OutputAnalyzer output = jmap("-clstats");
214         output.shouldHaveExitValue(0);
215     }
216 
testDump()217     private static void testDump() throws Exception {
218         dump(false, false, false);
219     }
220 
testDumpLive()221     private static void testDumpLive() throws Exception {
222         dump(true, false, false);
223     }
224 
testDumpAll()225     private static void testDumpAll() throws Exception {
226         dump(false, true, false);
227     }
228 
testDumpCompressed()229     private static void testDumpCompressed() throws Exception {
230         dump(true, false, true);
231     }
232 
dump(boolean live, boolean explicitAll, boolean compressed)233     private static void dump(boolean live, boolean explicitAll, boolean compressed) throws Exception {
234         String liveArg = "";
235         String fileArg = "";
236         String compressArg = "";
237         String allArgs = "-dump:";
238 
239         if (live && explicitAll) {
240             fail("Illegal argument setting for jmap -dump");
241         }
242         if (live) {
243             liveArg = "live,";
244         }
245         if (explicitAll) {
246             liveArg = "all,";
247         }
248 
249         String filePath = "jmap.dump" + System.currentTimeMillis() + ".hprof";
250         if (compressed) {
251             compressArg = "gz=1,";
252             filePath = filePath + ".gz";
253         }
254 
255         File file = new File(filePath);
256         if (file.exists()) {
257             file.delete();
258         }
259         fileArg = "file=" + file.getName();
260 
261         OutputAnalyzer output;
262         allArgs = allArgs + liveArg + compressArg + "format=b," + fileArg;
263         output = jmap(allArgs);
264         output.shouldHaveExitValue(0);
265         output.shouldContain("Heap dump file created");
266         verifyDumpFile(file);
267         file.delete();
268     }
269 
verifyDumpFile(File dump)270     private static void verifyDumpFile(File dump) {
271         assertTrue(dump.exists() && dump.isFile(), "Could not create dump file " + dump.getAbsolutePath());
272         try {
273             File out = HprofParser.parse(dump);
274 
275             assertTrue(out != null && out.exists() && out.isFile(),
276                        "Could not find hprof parser output file");
277             List<String> lines = Files.readAllLines(out.toPath());
278             assertTrue(lines.size() > 0, "hprof parser output file is empty");
279             for (String line : lines) {
280                 assertFalse(line.matches(".*WARNING(?!.*Failed to resolve " +
281                                          "object.*constantPoolOop.*).*"));
282             }
283 
284             out.delete();
285         } catch (Exception e) {
286             e.printStackTrace();
287             fail("Could not parse dump file " + dump.getAbsolutePath());
288         }
289     }
290 
jmap(String... toolArgs)291     private static OutputAnalyzer jmap(String... toolArgs) throws Exception {
292         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jmap");
293         launcher.addVMArgs(Utils.getTestJavaOpts());
294         if (toolArgs != null) {
295             for (String toolArg : toolArgs) {
296                 launcher.addToolArg(toolArg);
297             }
298         }
299         launcher.addToolArg(Long.toString(ProcessTools.getProcessId()));
300 
301         processBuilder.command(launcher.getCommand());
302         System.out.println(Arrays.toString(processBuilder.command().toArray()));
303         OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
304         System.out.println(output.getOutput());
305 
306         return output;
307     }
308 }
309