1 /*
   2  * Copyright (c) 2005, 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 import static jdk.test.lib.Asserts.assertTrue;
  25 import static jdk.test.lib.Asserts.fail;
  26 
  27 import java.io.File;
  28 import java.util.Arrays;
  29 
  30 import jdk.test.lib.JDKToolLauncher;
  31 import jdk.test.lib.hprof.HprofParser;
  32 import jdk.test.lib.process.OutputAnalyzer;
  33 import jdk.test.lib.process.ProcessTools;
  34 
  35 /*
  36  * @test
  37  * @summary Unit test for jmap utility
  38  * @key intermittent
  39  * @library /test/lib
  40  * @build jdk.test.lib.hprof.*
  41  * @build jdk.test.lib.hprof.model.*
  42  * @build jdk.test.lib.hprof.parser.*
  43  * @build jdk.test.lib.hprof.util.*
  44  * @run main/timeout=240 BasicJMapTest
  45  */
  46 public class BasicJMapTest {
  47 
  48     private static ProcessBuilder processBuilder = new ProcessBuilder();
  49 
  50     public static void main(String[] args) throws Exception {
  51         testHisto();
  52         testHistoLive();
  53         testHistoAll();
  54         testHistoToFile();
  55         testHistoLiveToFile();
  56         testHistoAllToFile();
  57         testFinalizerInfo();
  58         testClstats();
  59         testDump();
  60         testDumpLive();
  61         testDumpAll();
  62     }
  63 
  64     private static void testHisto() throws Exception {
  65         OutputAnalyzer output = jmap("-histo:");
  66         output.shouldHaveExitValue(0);
  67         OutputAnalyzer output1 = jmap("-histo");
  68         output1.shouldHaveExitValue(0);
  69     }
  70 
  71     private static void testHistoLive() throws Exception {
  72         OutputAnalyzer output = jmap("-histo:live");
  73         output.shouldHaveExitValue(0);
  74     }
  75 
  76     private static void testHistoAll() throws Exception {
  77         OutputAnalyzer output = jmap("-histo:all");
  78         output.shouldHaveExitValue(0);
  79     }
  80 
  81     private static void testHistoToFile() throws Exception {
  82         histoToFile(false);
  83     }
  84 
  85     private static void testHistoLiveToFile() throws Exception {
  86         histoToFile(true);
  87     }
  88 
  89     private static void testHistoAllToFile() throws Exception {
  90         boolean explicitAll = true;
  91         histoToFile(false, explicitAll);
  92     }
  93 
  94     private static void histoToFile(boolean live) throws Exception {
  95         boolean explicitAll = false;
  96         histoToFile(live, explicitAll);
  97     }
  98 
  99     private static void histoToFile(boolean live, boolean explicitAll) throws Exception {
 100         if (live == true && explicitAll == true) {
 101             fail("Illegal argument setting for jmap -histo");
 102         }
 103         File file = new File("jmap.histo.file" + System.currentTimeMillis() + ".histo");
 104         if (file.exists()) {
 105             file.delete();
 106         }
 107         OutputAnalyzer output;
 108         if (live) {
 109             output = jmap("-histo:live,file=" + file.getName());
 110         } else if (explicitAll == true) {
 111             output = jmap("-histo:all,file=" + file.getName());
 112         } else {
 113             output = jmap("-histo:file=" + file.getName());
 114         }
 115         output.shouldHaveExitValue(0);
 116         output.shouldContain("Heap inspection file created");
 117         file.delete();
 118     }
 119 
 120     private static void testFinalizerInfo() throws Exception {
 121         OutputAnalyzer output = jmap("-finalizerinfo");
 122         output.shouldHaveExitValue(0);
 123     }
 124 
 125     private static void testClstats() throws Exception {
 126         OutputAnalyzer output = jmap("-clstats");
 127         output.shouldHaveExitValue(0);
 128     }
 129 
 130     private static void testDump() throws Exception {
 131         dump(false);
 132     }
 133 
 134     private static void testDumpLive() throws Exception {
 135         dump(true);
 136     }
 137 
 138     private static void testDumpAll() throws Exception {
 139         boolean explicitAll = true;
 140         dump(false, explicitAll);
 141     }
 142 
 143     private static void dump(boolean live) throws Exception {
 144         boolean explicitAll = false;
 145         dump(live, explicitAll);
 146     }
 147 
 148     private static void dump(boolean live, boolean explicitAll) throws Exception {
 149         if (live == true && explicitAll == true) {
 150           fail("Illegal argument setting for jmap -dump");
 151         }
 152         File dump = new File("jmap.dump." + System.currentTimeMillis() + ".hprof");
 153         if (dump.exists()) {
 154             dump.delete();
 155         }
 156         OutputAnalyzer output;
 157         if (live) {
 158             output = jmap("-dump:live,format=b,file=" + dump.getName());
 159         } else if (explicitAll == true) {
 160             output = jmap("-dump:all,format=b,file=" + dump.getName());
 161         } else {
 162             output = jmap("-dump:format=b,file=" + dump.getName());
 163         }
 164         output.shouldHaveExitValue(0);
 165         output.shouldContain("Heap dump file created");
 166         verifyDumpFile(dump);
 167         dump.delete();
 168     }
 169 
 170     private static void verifyDumpFile(File dump) {
 171         assertTrue(dump.exists() && dump.isFile(), "Could not create dump file " + dump.getAbsolutePath());
 172         try {
 173             HprofParser.parse(dump);
 174         } catch (Exception e) {
 175             e.printStackTrace();
 176             fail("Could not parse dump file " + dump.getAbsolutePath());
 177         }
 178     }
 179 
 180     private static OutputAnalyzer jmap(String... toolArgs) throws Exception {
 181         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jmap");
 182         if (toolArgs != null) {
 183             for (String toolArg : toolArgs) {
 184                 launcher.addToolArg(toolArg);
 185             }
 186         }
 187         launcher.addToolArg(Long.toString(ProcessTools.getProcessId()));
 188 
 189         processBuilder.command(launcher.getCommand());
 190         System.out.println(Arrays.toString(processBuilder.command().toArray()));
 191         OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
 192         System.out.println(output.getOutput());
 193 
 194         return output;
 195     }
 196 
 197 }