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 testHistoParallelZero() throws Exception {
  82         OutputAnalyzer output = jmap("-histo:parallel=0");
  83         output.shouldHaveExitValue(0);
  84     }
  85 
  86     private static void testHistoParallel() throws Exception {
  87         OutputAnalyzer output = jmap("-histo:parallel=2");
  88         output.shouldHaveExitValue(0);
  89     }
  90 
  91     private static void testHistoNonParallel() throws Exception {
  92         OutputAnalyzer output = jmap("-histo:parallel=1");
  93         output.shouldHaveExitValue(0);
  94     }
  95 
  96     private static void testHistoToFile() throws Exception {
  97         histoToFile(false);
  98     }
  99 
 100     private static void testHistoLiveToFile() throws Exception {
 101         histoToFile(true);
 102     }
 103 
 104     private static void testHistoAllToFile() throws Exception {
 105         boolean explicitAll = true;
 106         histoToFile(false, explicitAll);
 107     }
 108 
 109     private static void testHistoFileParallelZero() throws Exception {
 110         histoToFile(false, false, 0);
 111     }
 112 
 113     private static void testHistoFileParallel() throws Exception {
 114         histoToFile(false, false, 2);
 115     }
 116 
 117     private static void testHistoFileNonParallel() throws Exception {
 118         histoToFile(false, false, 1);
 119     }
 120 
 121     private static void histoToFile(boolean live) throws Exception {
 122         boolean explicitAll = false;
 123         histoToFile(live, explicitAll);
 124     }
 125 
 126     private static void histoToFile(boolean live, boolean explicitAll) throws Exception {
 127         if (live == true && explicitAll == true) {
 128             fail("Illegal argument setting for jmap -histo");
 129         }
 130         File file = new File("jmap.histo.file" + System.currentTimeMillis() + ".histo");
 131         if (file.exists()) {
 132             file.delete();
 133         }
 134         OutputAnalyzer output;
 135         if (live) {
 136             output = jmap("-histo:live,file=" + file.getName());
 137         } else if (explicitAll == true) {
 138             output = jmap("-histo:all,file=" + file.getName());
 139         } else {
 140             output = jmap("-histo:file=" + file.getName());
 141         }
 142         output.shouldHaveExitValue(0);
 143         output.shouldContain("Heap inspection file created");
 144         file.delete();
 145     }
 146 
 147     private static void histoToFile(boolean live,
 148                                     boolean explicitAll,
 149                                     int parallelThreadNum) throws Exception {
 150         String liveArg = "";
 151         String fileArg = "";
 152         String parArg = "parallel=" + parallelThreadNum;
 153         String allArgs = "-histo:";
 154 
 155         if (live == true && explicitAll == true) {
 156             fail("Illegal argument setting for jmap -histo");
 157         }
 158         if (live == true ) {
 159             liveArg = "live,";
 160         } else if(explicitAll) {
 161             liveArg = "all,";
 162         }
 163 
 164         File file = new File("jmap.histo.file" + System.currentTimeMillis() + ".histo");
 165         if (file.exists()) {
 166             file.delete();
 167         }
 168         fileArg = "file=" + file.getName();
 169 
 170         OutputAnalyzer output;
 171         allArgs = allArgs + liveArg + fileArg + "," + parArg + "";
 172         if (live) {
 173             output = jmap(allArgs);
 174         } else if (explicitAll == true) {
 175             output = jmap(allArgs);
 176         } else {
 177             output = jmap(allArgs);
 178         }
 179         output.shouldHaveExitValue(0);
 180         output.shouldContain("Heap inspection file created");
 181         file.delete();
 182     }
 183 
 184     private static void testFinalizerInfo() throws Exception {
 185         OutputAnalyzer output = jmap("-finalizerinfo");
 186         output.shouldHaveExitValue(0);
 187     }
 188 
 189     private static void testClstats() throws Exception {
 190         OutputAnalyzer output = jmap("-clstats");
 191         output.shouldHaveExitValue(0);
 192     }
 193 
 194     private static void testDump() throws Exception {
 195         dump(false);
 196     }
 197 
 198     private static void testDumpLive() throws Exception {
 199         dump(true);
 200     }
 201 
 202     private static void testDumpAll() throws Exception {
 203         boolean explicitAll = true;
 204         dump(false, explicitAll);
 205     }
 206 
 207     private static void dump(boolean live) throws Exception {
 208         boolean explicitAll = false;
 209         dump(live, explicitAll);
 210     }
 211 
 212     private static void dump(boolean live, boolean explicitAll) throws Exception {
 213         if (live == true && explicitAll == true) {
 214           fail("Illegal argument setting for jmap -dump");
 215         }
 216         File dump = new File("jmap.dump." + System.currentTimeMillis() + ".hprof");
 217         if (dump.exists()) {
 218             dump.delete();
 219         }
 220         OutputAnalyzer output;
 221         if (live) {
 222             output = jmap("-dump:live,format=b,file=" + dump.getName());
 223         } else if (explicitAll == true) {
 224             output = jmap("-dump:all,format=b,file=" + dump.getName());
 225         } else {
 226             output = jmap("-dump:format=b,file=" + dump.getName());
 227         }
 228         output.shouldHaveExitValue(0);
 229         output.shouldContain("Heap dump file created");
 230         verifyDumpFile(dump);
 231         dump.delete();
 232     }
 233 
 234     private static void verifyDumpFile(File dump) {
 235         assertTrue(dump.exists() && dump.isFile(), "Could not create dump file " + dump.getAbsolutePath());
 236         try {
 237             HprofParser.parse(dump);
 238         } catch (Exception e) {
 239             e.printStackTrace();
 240             fail("Could not parse dump file " + dump.getAbsolutePath());
 241         }
 242     }
 243 
 244     private static OutputAnalyzer jmap(String... toolArgs) throws Exception {
 245         JDKToolLauncher launcher = JDKToolLauncher.createUsingTestJDK("jmap");
 246         if (toolArgs != null) {
 247             for (String toolArg : toolArgs) {
 248                 launcher.addToolArg(toolArg);
 249             }
 250         }
 251         launcher.addToolArg(Long.toString(ProcessTools.getProcessId()));
 252 
 253         processBuilder.command(launcher.getCommand());
 254         System.out.println(Arrays.toString(processBuilder.command().toArray()));
 255         OutputAnalyzer output = ProcessTools.executeProcess(processBuilder);
 256         System.out.println(output.getOutput());
 257 
 258         return output;
 259     }
 260 
 261 }