1 /*
   2  * Copyright (c) 2007, 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 import jdk.test.lib.process.OutputAnalyzer;
  27 import jdk.test.lib.process.ProcessTools;
  28 
  29 import java.io.File;
  30 import java.nio.file.Path;
  31 import java.nio.file.Paths;
  32 import java.util.ArrayList;
  33 import java.util.Arrays;
  34 import java.util.Collections;
  35 import java.util.List;
  36 import java.util.stream.Collectors;
  37 import java.util.stream.Stream;
  38 
  39 public class SigTestDriver {
  40     public static void main(String[] args) {
  41         // No signal tests on Windows yet; so setting to no-op
  42         if (Platform.isWindows()) {
  43             System.out.println("SKIPPED: no signal tests on Windows, ignore.");
  44             return;
  45         }
  46 
  47         // At least one argument should be specified
  48         if ( (args == null) || (args.length < 1) ) {
  49             throw new IllegalArgumentException("At lease one argument should be specified, the signal name");
  50         }
  51 
  52         String signame = args[0];
  53         switch (signame) {
  54             case "SIGWAITING":
  55             case "SIGKILL":
  56             case "SIGSTOP": {
  57                 System.out.println("SKIPPED: signals SIGWAITING, SIGKILL and SIGSTOP can't be tested, ignore.");
  58                 return;
  59             }
  60             case "SIGUSR2": {
  61                 if (Platform.isLinux()) {
  62                     System.out.println("SKIPPED: SIGUSR2 can't be tested on Linux, ignore.");
  63                     return;
  64                 } else if (Platform.isOSX()) {
  65                     System.out.println("SKIPPED: SIGUSR2 can't be tested on OS X, ignore.");
  66                     return;
  67                 }
  68             }
  69         }
  70 
  71         Path test = Paths.get(System.getProperty("test.nativepath"))
  72                          .resolve("sigtest")
  73                          .toAbsolutePath();
  74         String envVar = Platform.isWindows() ? "PATH" :
  75                 (Platform.isOSX() ? "DYLD_LIBRARY_PATH" : "LD_LIBRARY_PATH");
  76 
  77         List<String> cmd = new ArrayList<>();
  78         Collections.addAll(cmd,
  79                 test.toString(),
  80                 "-sig",
  81                 signame,
  82                 "-mode",
  83                 null, // modeIdx
  84                 "-scenario",
  85                 null // scenarioIdx
  86         );
  87         int modeIdx = 4;
  88         int scenarioIdx = 6;
  89 
  90         // add external flags
  91         cmd.addAll(vmargs());
  92 
  93         // add test specific arguments w/o signame
  94         cmd.addAll(Arrays.asList(args)
  95                          .subList(1, args.length));
  96 
  97         boolean passed = true;
  98 
  99         for (String mode : new String[]{"sigset", "sigaction"}) {
 100             for (String scenario : new String[] {"nojvm", "prepre", "prepost", "postpre", "postpost"}) {
 101                 cmd.set(modeIdx, mode);
 102                 cmd.set(scenarioIdx, scenario);
 103                 System.out.printf("START TESTING: SIGNAL = %s, MODE = %s, SCENARIO=%s%n",signame, mode, scenario);
 104                 System.out.printf("Do execute: %s%n", cmd.toString());
 105 
 106                 ProcessBuilder pb = new ProcessBuilder(cmd);
 107                 pb.environment().merge(envVar, jvmLibDir().toString(),
 108                         (x, y) -> y + File.pathSeparator + x);
 109                 pb.environment().put("CLASSPATH", Utils.TEST_CLASS_PATH);
 110 
 111                 switch (scenario) {
 112                     case "postpre":
 113                     case "postpost": {
 114                         pb.environment().merge("LD_PRELOAD", libjsig().toString(),
 115                                 (x, y) -> y + File.pathSeparator + x);
 116                     }
 117                 }
 118 
 119                 try {
 120                     OutputAnalyzer oa = ProcessTools.executeProcess(pb);
 121                     oa.reportDiagnosticSummary();
 122                     int exitCode = oa.getExitValue();
 123                     if (exitCode == 0) {
 124                        System.out.println("PASSED with exit code 0");
 125                     } else {
 126                         System.out.println("FAILED with exit code " + exitCode);
 127                         passed = false;
 128                     }
 129                 } catch (Exception e) {
 130                     throw new Error("execution failed", e);
 131                 }
 132             }
 133         }
 134 
 135         if (!passed) {
 136             throw new Error("test failed");
 137         }
 138     }
 139 
 140     private static List<String> vmargs() {
 141         return Stream.concat(Arrays.stream(Utils.VM_OPTIONS.split(" ")),
 142                              Arrays.stream(Utils.JAVA_OPTIONS.split(" ")))
 143                      .filter(s -> !s.isEmpty())
 144                      .filter(s -> s.startsWith("-X"))
 145                      .flatMap(arg -> Stream.of("-vmopt", arg))
 146                      .collect(Collectors.toList());
 147     }
 148 
 149     private static Path libjsig() {
 150         return jvmLibDir().resolve((Platform.isWindows() ? "" : "lib")
 151                 + "jsig." + Platform.sharedLibraryExt());
 152     }
 153 
 154     private static Path jvmLibDir() {
 155         Path dir = Paths.get(Utils.TEST_JDK);
 156         if (Platform.isWindows()) {
 157             return dir.resolve("bin")
 158                       .resolve(variant())
 159                       .toAbsolutePath();
 160         } else {
 161             return dir.resolve("lib")
 162                       .resolve(variant())
 163                       .toAbsolutePath();
 164         }
 165     }
 166 
 167     private static String variant() {
 168         if (Platform.isServer()) {
 169             return "server";
 170         } else if (Platform.isClient()) {
 171             return "client";
 172         } else if (Platform.isMinimal()) {
 173             return "minimal";
 174         } else {
 175             throw new Error("TESTBUG: unsupported vm variant");
 176         }
 177     }
 178 }