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