1 /*
   2  * Copyright (c) 2005, 2015, 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  * @test       OnThrowTest.java
  26  * @bug        6263814
  27  * @summary    Test for -agentlib::[onthrow,launch]
  28  * @author     Kelly O'Hair
  29  *
  30  * @run compile -g OnThrowTest.java
  31  * @run compile -g OnThrowTarget.java
  32  * @run compile -g VMConnection.java
  33  * @run driver OnThrowTest
  34  */
  35 
  36 import java.io.File;
  37 import java.io.FileWriter;
  38 import java.io.BufferedInputStream;
  39 import java.io.IOException;
  40 
  41 public class OnThrowTest extends Object {
  42 
  43     /* Full pathname for file to be touched or created by the launch */
  44     private String touchFile;
  45 
  46     OnThrowTest() throws Exception {
  47         /* Name of touch file */
  48         touchFile = System.getProperty("test.classes") +
  49                     File.separator + "OnThrowLaunchTouchFile";
  50         /* Make sure it's gone when we start */
  51         File f = new File(touchFile);
  52         f.delete();
  53         if ( f.exists() ) {
  54             throw new Exception("Test failed: Cannot remove old touch file: " +
  55                   touchFile);
  56         }
  57     }
  58 
  59     /* Used to see if touch file exists */
  60     private boolean touchFileExists() {
  61         File f = new File(touchFile);
  62         return f.exists();
  63     }
  64 
  65     /**
  66      * Run an arbitrary command
  67      *
  68      */
  69     public void run(String[] cmdStrings) throws Exception {
  70         StringBuffer stdoutBuffer = new StringBuffer();
  71         StringBuffer stderrBuffer = new StringBuffer();
  72         String CR = System.getProperty("line.separator");
  73         int subprocessStatus = 1;
  74 
  75         System.out.print(CR + "runCommand method about to execute: ");
  76         for (int iNdx = 0; iNdx < cmdStrings.length; iNdx++) {
  77             System.out.print(" ");
  78             System.out.print(cmdStrings[iNdx]);
  79         }
  80         System.out.println(CR);
  81 
  82         try {
  83             Process process = Runtime.getRuntime().
  84                 exec(VMConnection.insertDebuggeeVMOptions(cmdStrings));
  85             int BUFFERSIZE = 4096;
  86             /*
  87              * Gather up the output of the subprocess using non-blocking
  88              * reads so we can get both the subprocess stdout and the
  89              * subprocess stderr without overfilling any buffers.
  90              */
  91             BufferedInputStream is =
  92                 new BufferedInputStream(process.getInputStream());
  93             int isLen = 0;
  94             byte[] isBuf = new byte[BUFFERSIZE];
  95 
  96             BufferedInputStream es =
  97                 new BufferedInputStream(process.getErrorStream());
  98             int esLen = 0;
  99             byte[] esBuf = new byte[BUFFERSIZE];
 100 
 101             do {
 102                 isLen = is.read(isBuf);
 103                 if (isLen > 0) {
 104                     stdoutBuffer.append(new String(isBuf, 0, isLen));
 105                 }
 106                 esLen = es.read(esBuf);
 107                 if (esLen > 0) {
 108                     stderrBuffer.append(new String(esBuf, 0, esLen));
 109                 }
 110             } while ((isLen > -1) || (esLen > -1));
 111 
 112             try {
 113                 process.waitFor();
 114                 subprocessStatus = process.exitValue();
 115                 process = null;
 116             } catch(java.lang.InterruptedException e) {
 117                 System.err.println("InterruptedException: " + e);
 118                 throw new Exception("Test failed: process interrupted");
 119             }
 120 
 121         } catch(IOException ex) {
 122             System.err.println("IO error: " + ex);
 123             throw new Exception("Test failed: IO error running process");
 124         }
 125 
 126         System.out.println(CR + "--- Return code was: " +
 127                            CR + Integer.toString(subprocessStatus));
 128         System.out.println(CR + "--- Return stdout was: " +
 129                            CR + stdoutBuffer.toString());
 130         System.out.println(CR + "--- Return stderr was: " +
 131                            CR + stderrBuffer.toString());
 132 
 133     }
 134 
 135     public static void main(String[] args) throws Exception {
 136 
 137         OnThrowTest myTest = new OnThrowTest();
 138 
 139         String launch = System.getProperty("test.classes") +
 140                         File.separator + "OnThrowLaunch.sh";
 141         File f = new File(launch);
 142         f.delete();
 143         FileWriter fw = new FileWriter(f);
 144         fw.write("#!/bin/sh\n echo OK $* > " +
 145                  myTest.touchFile.replace('\\','/') + "\n exit 0\n");
 146         fw.flush();
 147         fw.close();
 148         if ( ! f.exists() ) {
 149             throw new Exception("Test failed: sh file not created: " + launch);
 150         }
 151 
 152         String javaExe = System.getProperty("java.home") +
 153                          File.separator + "bin" + File.separator + "java";
 154         String targetClass = "OnThrowTarget";
 155         String cmds [] = {javaExe,
 156                           "-agentlib:jdwp=transport=dt_socket," +
 157                           "onthrow=OnThrowException,server=y,suspend=n," +
 158                           "launch=" + "sh " + launch.replace('\\','/'),
 159                           targetClass};
 160 
 161         /* Run the target app, which will launch the launch script */
 162         myTest.run(cmds);
 163         if ( !myTest.touchFileExists() ) {
 164             throw new Exception("Test failed: touch file not found: " +
 165                   myTest.touchFile);
 166         }
 167 
 168         System.out.println("Test passed: launch create file");
 169     }
 170 
 171 }