test/hotspot/jtreg/vmTestbase/ExecDriver.java
changeset 49934 44839fbb20db
child 50618 2aa21bb12059
equal deleted inserted replaced
49933:c63bdf53a1a7 49934:44839fbb20db
       
     1 /*
       
     2  * Copyright (c) 2017, 2018, 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 jdk.test.lib.Platform;
       
    25 import jdk.test.lib.Utils;
       
    26 
       
    27 import java.io.File;
       
    28 import java.io.IOException;
       
    29 import java.io.InputStream;
       
    30 import java.io.OutputStream;
       
    31 import java.nio.file.Path;
       
    32 import java.nio.file.Paths;
       
    33 import java.util.Arrays;
       
    34 
       
    35 /**
       
    36  * Starts a new process to execute a command.
       
    37  * <p>Usage: --java|--cmd|--launcher <arg>+
       
    38  * <p>If {@code --cmd} flag is specified, the arguments are treated as
       
    39  * a program to run and its arguments. Non-zero exit code of the created process
       
    40  * will be reported as an {@link AssertionError}.
       
    41  * <p>If {@code --java} flag is specified, the arguments are passed to {@code java}
       
    42  * from JDK under test. If exit code doesn't equal to 0 or 95, {@link AssertionError}
       
    43  * will be thrown.
       
    44  * <p>If {@code --launcher} flag is specified, the arguments treated similar as
       
    45  * for {@code --cmd}, but the started process will have the directory which
       
    46  * contains {@code jvm.so} in dynamic library path, and {@code test.class.path}
       
    47  * as CLASSPATH environment variable. Exit codes are checked as in
       
    48  * {@code --java}, i.e. 0 or 95 means pass.
       
    49  */
       
    50 public class ExecDriver {
       
    51     public static void main(String[] args) throws IOException, InterruptedException {
       
    52         boolean java = false;
       
    53         boolean launcher = false;
       
    54 
       
    55         String type = args[0];
       
    56         switch (type) {
       
    57             case "--java":
       
    58                 String[] oldArgs = args;
       
    59                 int count;
       
    60                 String libraryPath = System.getProperty("test.nativepath");
       
    61                 if (libraryPath != null && !libraryPath.isEmpty()) {
       
    62                     count = 4;
       
    63                     args = new String[args.length + 3];
       
    64                     args[3] = "-Djava.library.path=" + libraryPath;
       
    65                 } else {
       
    66                     count = 3;
       
    67                     args = new String[args.length + 2];
       
    68                 }
       
    69                 args[0] = javaBin();
       
    70                 args[1] = "-cp";
       
    71                 args[2] = Utils.TEST_CLASS_PATH;
       
    72                 System.arraycopy(oldArgs, 1, args, count, oldArgs.length - 1);
       
    73                 java = true;
       
    74                 break;
       
    75             case "--launcher":
       
    76                 java = true;
       
    77                 launcher = true;
       
    78             case "--cmd":
       
    79                 args = Arrays.copyOfRange(args, 1, args.length);
       
    80                 break;
       
    81             default:
       
    82                 throw new Error("unknown type: " + type);
       
    83         }
       
    84         // adding 'test.vm.opts' and 'test.java.opts'
       
    85         if (java) {
       
    86             String[] oldArgs = args;
       
    87             String[] testJavaOpts = Utils.getTestJavaOpts();
       
    88             if (testJavaOpts.length > 0) {
       
    89                 args = new String[args.length + testJavaOpts.length];
       
    90                 // bin/java goes before options
       
    91                 args[0] = oldArgs[0];
       
    92                 // then external java options
       
    93                 System.arraycopy(testJavaOpts, 0, args, 1, testJavaOpts.length);
       
    94                 // and then options and args from a test
       
    95                 System.arraycopy(oldArgs, 1, args, 1 + testJavaOpts.length, oldArgs.length - 1);
       
    96             }
       
    97         }
       
    98         String command = Arrays.toString(args);
       
    99         System.out.println("exec " + command);
       
   100 
       
   101         ProcessBuilder pb = new ProcessBuilder(args);
       
   102         // adding jvm.so to library path
       
   103         if (launcher) {
       
   104             Path dir = Paths.get(Utils.TEST_JDK);
       
   105             String name;
       
   106             if (Platform.isWindows()) {
       
   107                 dir = dir.resolve("bin")
       
   108                          .resolve(variant())
       
   109                          .toAbsolutePath();
       
   110                 name = "PATH";
       
   111             } else {
       
   112                 dir = dir.resolve("lib")
       
   113                          .resolve(variant())
       
   114                          .toAbsolutePath();
       
   115                 name = Platform.isOSX() ? "DYLD_LIBRARY_PATH" : "LD_LIBRARY_PATH";
       
   116             }
       
   117 
       
   118             System.out.println("  with " + name + " = " +
       
   119                     pb.environment()
       
   120                       .merge(name, dir.toString(), (x, y) -> y + File.pathSeparator + x));
       
   121             System.out.println("  with CLASSPATH = " +
       
   122                     pb.environment()
       
   123                       .put("CLASSPATH", Utils.TEST_CLASS_PATH));
       
   124         }
       
   125         Process p = pb.start();
       
   126         // inheritIO does not work as expected for @run driver
       
   127         new Thread(() -> copy(p.getInputStream(), System.out)).start();
       
   128         new Thread(() -> copy(p.getErrorStream(), System.out)).start();
       
   129         int exitCode = p.waitFor();
       
   130 
       
   131         if (exitCode != 0 && (!java || exitCode != 95)) {
       
   132             throw new AssertionError(command + " exit code is " + exitCode);
       
   133         }
       
   134     }
       
   135 
       
   136     private static String variant() {
       
   137         if (Platform.isServer()) {
       
   138             return "server";
       
   139         } else if (Platform.isClient()) {
       
   140             return "client";
       
   141         } else if (Platform.isMinimal()) {
       
   142             return "minimal";
       
   143         } else {
       
   144             throw new Error("TESTBUG: unsuppported vm variant");
       
   145         }
       
   146     }
       
   147 
       
   148 
       
   149     private static void copy(InputStream is, OutputStream os) {
       
   150         byte[] buffer = new byte[1024];
       
   151         int n;
       
   152         try (InputStream close = is) {
       
   153             while ((n = is.read(buffer)) != -1) {
       
   154                 os.write(buffer, 0, n);
       
   155             }
       
   156             os.flush();
       
   157         } catch (IOException e) {
       
   158             e.printStackTrace();
       
   159         }
       
   160     }
       
   161 
       
   162     private static String javaBin() {
       
   163         return Paths.get(Utils.TEST_JDK)
       
   164                     .resolve("bin")
       
   165                     .resolve("java")
       
   166                     .toAbsolutePath()
       
   167                     .toString();
       
   168     }
       
   169 }
       
   170