1 /*
   2  * Copyright (c) 2004, 2013, 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 /* DemoRun:
  26  *
  27  * Support classes for java jvmti demo tests
  28  *
  29  */
  30 
  31 import java.io.InputStream;
  32 import java.io.IOException;
  33 import java.io.File;
  34 import java.io.BufferedInputStream;
  35 import java.io.PrintStream;
  36 
  37 /*
  38  * Helper class to direct process output to a StringBuffer
  39  */
  40 class MyInputStream implements Runnable {
  41     private String              name;
  42     private BufferedInputStream in;
  43     private StringBuffer        buffer;
  44 
  45     /* Create MyInputStream that saves all output to a StringBuffer */
  46     MyInputStream(String name, InputStream in) {
  47         this.name = name;
  48         this.in = new BufferedInputStream(in);
  49         buffer = new StringBuffer(4096);
  50         Thread thr = new Thread(this);
  51         thr.setDaemon(true);
  52         thr.start();
  53     }
  54 
  55     /* Dump the buffer */
  56     void dump(PrintStream x) {
  57         String str = buffer.toString();
  58         x.println("<beginning of " + name + " buffer>");
  59         x.println(str);
  60         x.println("<end of buffer>");
  61     }
  62 
  63     /* Check to see if a pattern is inside the output. */
  64     boolean contains(String pattern) {
  65         String str = buffer.toString();
  66         return str.contains(pattern);
  67     }
  68 
  69     /* Runs as a separate thread capturing all output in a StringBuffer */
  70     public void run() {
  71         try {
  72             byte b[] = new byte[100];
  73             for (;;) {
  74                 int n = in.read(b);
  75                 String str;
  76                 if (n < 0) {
  77                     break;
  78                 }
  79                 str = new String(b, 0, n);
  80                 buffer.append(str);
  81                 System.out.print(str);
  82             }
  83         } catch (IOException ioe) { /* skip */ }
  84     }
  85 }
  86 
  87 /*
  88  * Main JVMTI Demo Run class.
  89  */
  90 public class DemoRun {
  91 
  92     private String        demo_name;
  93     private String        demo_options;
  94     private MyInputStream output;
  95     private MyInputStream error;
  96 
  97     /* Create a Demo run process */
  98     public DemoRun(String name, String options)
  99     {
 100         demo_name    = name;
 101         demo_options = options;
 102     }
 103 
 104     /*
 105      * Execute a process with an -agentpath or -agentlib command option
 106      */
 107     public void runit(String class_name)
 108     {
 109         runit(class_name, null);
 110     }
 111 
 112     /*
 113      * Execute a process with an -agentpath or -agentlib command option
 114      *    plus any set of other java options.
 115      */
 116     public void runit(String class_name, String vm_options[])
 117     {
 118         String jre_home  = System.getProperty("java.home");
 119         String sdk_home  = (jre_home.endsWith("jre") ?
 120                             (jre_home + File.separator + "..") :
 121                             jre_home );
 122         String cdir      = System.getProperty("test.classes", ".");
 123         String os_arch   = System.getProperty("os.arch");
 124         String os_name   = System.getProperty("os.name");
 125         String libprefix = os_name.contains("Windows")?"":"lib";
 126         String libsuffix = os_name.contains("Windows")?".dll":
 127                                 os_name.contains("OS X")?".dylib":".so";
 128         boolean hprof    = demo_name.equals("hprof");
 129         String java      = jre_home
 130                              + File.separator + "bin"
 131                              + File.separator + "java";
 132         /* Array of strings to be passed in for exec:
 133          *   1. java
 134          *   2. -Dtest.classes=.
 135          *   3. -Xcheck:jni          (Just because it finds bugs)
 136          *   4. -Xverify:all         (Make sure verification is on full blast)
 137          *   5. -agent
 138          *       vm_options
 139          *   6+i. classname
 140          */
 141         int nvm_options = 0;
 142         if ( vm_options != null ) nvm_options = vm_options.length;
 143         String cmd[]     = new String[1 + 7 + nvm_options];
 144         String cmdLine;
 145         int exitStatus;
 146         int i,j;
 147 
 148         i = 0;
 149         cmdLine = "";
 150         cmdLine += (cmd[i++] = java);
 151         cmdLine += " ";
 152         cmdLine += (cmd[i++] = "-cp");
 153         cmdLine += " ";
 154         cmdLine += (cmd[i++] = cdir);
 155         cmdLine += " ";
 156         cmdLine += (cmd[i++] = "-Dtest.classes=" + cdir);
 157         cmdLine += " ";
 158         cmdLine += (cmd[i++] = "-Xcheck:jni");
 159         cmdLine += " ";
 160         cmdLine += (cmd[i++] = "-Xverify:all");
 161         if ( hprof ) {
 162             /* Load hprof with -agentlib since it's part of jre */
 163             cmdLine += " ";
 164             cmdLine += (cmd[i++] = "-agentlib:" + demo_name
 165                      + (demo_options.equals("")?"":("="+demo_options)));
 166         } else {
 167             String libname  = sdk_home
 168                          + File.separator + "demo"
 169                          + File.separator + "jvmti"
 170                          + File.separator + demo_name
 171                          + File.separator + "lib"
 172                          + File.separator + libprefix + demo_name + libsuffix;
 173             cmdLine += " ";
 174             cmdLine += (cmd[i++] = "-agentpath:" + libname
 175                      + (demo_options.equals("")?"":("="+demo_options)));
 176         }
 177         /* Add any special VM options */
 178         for ( j = 0; j < nvm_options; j++ ) {
 179             cmdLine += " ";
 180             cmdLine += (cmd[i++] = vm_options[j]);
 181         }
 182         /* Add classname */
 183         cmdLine += " ";
 184         cmdLine += (cmd[i++] = class_name);
 185 
 186         /* Begin process */
 187         Process p;
 188 
 189         System.out.println("Starting: " + cmdLine);
 190         try {
 191             p = Runtime.getRuntime().exec(cmd);
 192         } catch ( IOException e ) {
 193             throw new RuntimeException("Test failed - exec got IO exception");
 194         }
 195 
 196         /* Save process output in StringBuffers */
 197         output = new MyInputStream("Input Stream", p.getInputStream());
 198         error  = new MyInputStream("Error Stream", p.getErrorStream());
 199 
 200         /* Wait for process to complete, and if exit code is non-zero we fail */
 201         try {
 202             exitStatus = p.waitFor();
 203             if ( exitStatus != 0) {
 204                 System.out.println("Exit code is " + exitStatus);
 205                 error.dump(System.out);
 206                 output.dump(System.out);
 207                 throw new RuntimeException("Test failed - " +
 208                                     "exit return code non-zero " +
 209                                     "(exitStatus==" + exitStatus + ")");
 210             }
 211         } catch ( InterruptedException e ) {
 212             throw new RuntimeException("Test failed - process interrupted");
 213         }
 214         System.out.println("Completed: " + cmdLine);
 215     }
 216 
 217     /* Does the pattern appear in the output of this process */
 218     public boolean output_contains(String pattern)
 219     {
 220         return output.contains(pattern) || error.contains(pattern);
 221     }
 222 }