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 */
MyInputStream(String name, InputStream in)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 */
dump(PrintStream x)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. */
contains(String pattern)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 */
run()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 */
DemoRun(String name, String options)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      */
runit(String class_name)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      */
runit(String class_name, String vm_options[])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 */
output_contains(String pattern)218     public boolean output_contains(String pattern)
219     {
220         return output.contains(pattern) || error.contains(pattern);
221     }
222 }
223