1 /*
   2  * Copyright (c) 2012, 2019, 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
  26  * @bug 7124089 7131021 8042469 8066185 8074373
  27  * @summary Checks for Launcher special flags, such as MacOSX specific flags,
  28  *          and JVM NativeMemoryTracking flags.
  29  * @modules jdk.compiler
  30  *          jdk.zipfs
  31  * @compile -XDignore.symbol.file TestSpecialArgs.java EnvironmentVariables.java
  32  * @run main TestSpecialArgs
  33  */
  34 import java.io.File;
  35 import java.io.FileNotFoundException;
  36 import java.util.HashMap;
  37 import java.util.HashSet;
  38 import java.util.Map;
  39 import java.util.Set;
  40 
  41 public class TestSpecialArgs extends TestHelper {
  42 
  43     public static void main(String... args) throws Exception {
  44         new TestSpecialArgs().run(args);
  45     }
  46 
  47     @Test
  48     void testDocking() {
  49         final Map<String, String> envMap = new HashMap<>();
  50         envMap.put("_JAVA_LAUNCHER_DEBUG", "true");
  51         TestResult tr = doExec(envMap, javaCmd, "-XstartOnFirstThread", "-version");
  52         if (isMacOSX) {
  53             if (!tr.contains("In same thread")) {
  54                 System.out.println(tr);
  55                 throw new RuntimeException("Error: not running in the same thread ?");
  56             }
  57             if (!tr.isOK()) {
  58                 System.out.println(tr);
  59                 throw new RuntimeException("Error: arg was rejected ????");
  60             }
  61         } else {
  62             if (tr.isOK()) {
  63                 System.out.println(tr);
  64                 throw new RuntimeException("Error: argument was accepted ????");
  65             }
  66         }
  67 
  68         tr = doExec(javaCmd, "-Xdock:/tmp/not-available", "-version");
  69         if (isMacOSX) {
  70             if (!tr.isOK()) {
  71                 System.out.println(tr);
  72                 throw new RuntimeException("Error: arg was rejected ????");
  73             }
  74         } else {
  75             if (tr.isOK()) {
  76                 System.out.println(tr);
  77                 throw new RuntimeException("Error: argument was accepted ????");
  78             }
  79         }
  80         // MacOSX specific tests ensue......
  81         if (!isMacOSX) {
  82             return;
  83         }
  84         Set<String> envToRemove = new HashSet<>();
  85         Map<String, String> map = System.getenv();
  86         for (String s : map.keySet()) {
  87             if (s.startsWith("JAVA_MAIN_CLASS_")
  88                     || s.startsWith("APP_NAME_")
  89                     || s.startsWith("APP_ICON_")) {
  90                 envToRemove.add(s);
  91             }
  92         }
  93         runTest(envToRemove, javaCmd, "-cp", TEST_CLASSES_DIR.getAbsolutePath(),
  94                 "EnvironmentVariables", "JAVA_MAIN_CLASS_*",
  95                 "EnvironmentVariables");
  96 
  97         runTest(envToRemove, javaCmd, "-cp", TEST_CLASSES_DIR.getAbsolutePath(),
  98                 "-Xdock:name=TestAppName", "EnvironmentVariables",
  99                 "APP_NAME_*", "TestAppName");
 100 
 101         runTest(envToRemove, javaCmd, "-cp", TEST_CLASSES_DIR.getAbsolutePath(),
 102                 "-Xdock:icon=TestAppIcon", "EnvironmentVariables",
 103                 "APP_ICON_*", "TestAppIcon");
 104     }
 105 
 106     void runTest(Set<String> envToRemove, String... args) {
 107         TestResult tr = doExec(null, envToRemove, args);
 108         if (!tr.isOK()) {
 109             System.err.println(tr.toString());
 110             throw new RuntimeException("Test Fails");
 111         }
 112     }
 113 
 114     @Test
 115     void testNativeMemoryTracking() {
 116         final Map<String, String> envMap = new HashMap<>();
 117         envMap.put("_JAVA_LAUNCHER_DEBUG", "true");
 118         TestResult tr;
 119         /*
 120          * test argument : -XX:NativeMemoryTracking=value
 121          * A JVM flag, comsumed by the JVM, but requiring launcher
 122          * to set an environmental variable if and only if value is supplied.
 123          * Test and order:
 124          * 1) execute with valid parameter: -XX:NativeMemoryTracking=MyValue
 125          *    a) check for correct env variable name: "NMT_LEVEL_" + pid
 126          *    b) check that "MyValue" was found in local env.
 127          * 2) execute with invalid parameter: -XX:NativeMemoryTracking=
 128          *    !) Won't find "NativeMemoryTracking:"
 129          *       Code to create env variable not executed.
 130          * 3) execute with invalid parameter: -XX:NativeMemoryTracking
 131          *    !) Won't find "NativeMemoryTracking:"
 132          *       Code to create env variable not executed.
 133          * 4) give and invalid value and check to make sure JVM commented
 134          */
 135         String envVarPidString = "TRACER_MARKER: NativeMemoryTracking: env var is NMT_LEVEL_";
 136         String NMT_Option_Value = "off";
 137         String myClassName = "helloworld";
 138 
 139         // === Run the tests ===
 140         // ---Test 1a
 141         tr = doExec(envMap, javaCmd, "-XX:NativeMemoryTracking=" + NMT_Option_Value,
 142                 "-version");
 143 
 144         // get the PID from the env var we set for the JVM
 145         String envVarPid = null;
 146         for (String line : tr.testOutput) {
 147             if (line.contains(envVarPidString)) {
 148                 int sindex = envVarPidString.length();
 149                 envVarPid = line.substring(sindex);
 150                 break;
 151             }
 152         }
 153         // did we find envVarPid?
 154         if (envVarPid == null) {
 155             System.out.println(tr);
 156             throw new RuntimeException("Error: failed to find env Var Pid in tracking info");
 157         }
 158         // we think we found the pid string.  min test, not "".
 159         if (envVarPid.length() < 1) {
 160             System.out.println(tr);
 161             throw new RuntimeException("Error: env Var Pid in tracking info is empty string");
 162         }
 163 
 164         // --- Test 1b
 165         if (!tr.contains("NativeMemoryTracking: got value " + NMT_Option_Value)) {
 166             System.out.println(tr);
 167             throw new RuntimeException("Error: Valid param failed to set env variable");
 168         }
 169 
 170         // --- Test 2
 171         tr = doExec(envMap, javaCmd, "-XX:NativeMemoryTracking=",
 172                 "-version");
 173         if (tr.contains("NativeMemoryTracking:")) {
 174             System.out.println(tr);
 175             throw new RuntimeException("Error: invalid param caused env variable to be erroneously created");
 176         }
 177         if (!tr.contains("Syntax error, expecting -XX:NativeMemoryTracking=")) {
 178             System.out.println(tr);
 179             throw new RuntimeException("Error: invalid param not checked by JVM");
 180         }
 181 
 182         // --- Test 3
 183         tr = doExec(envMap, javaCmd, "-XX:NativeMemoryTracking",
 184                 "-version");
 185         if (tr.contains("NativeMemoryTracking:")) {
 186             System.out.println(tr);
 187             throw new RuntimeException("Error: invalid param caused env variable to be erroneously created");
 188         }
 189         if (!tr.contains("Syntax error, expecting -XX:NativeMemoryTracking=")) {
 190             System.out.println(tr);
 191             throw new RuntimeException("Error: invalid param not checked by JVM");
 192         }
 193         // --- Test 4
 194         tr = doExec(envMap, javaCmd, "-XX:NativeMemoryTracking=BADVALUE",
 195                 "-version");
 196         if (!tr.contains("expecting -XX:NativeMemoryTracking")) {
 197             System.out.println(tr);
 198             throw new RuntimeException("Error: invalid param did not get JVM Syntax error message");
 199         }
 200     }
 201 
 202     @Test
 203     void testNMArgumentProcessing() throws FileNotFoundException {
 204         TestResult tr;
 205         // the direct invokers of the VM
 206         String options[] = {
 207             "-version", "-fullversion", "-help", "-?", "-X"
 208         };
 209         for (String option : options) {
 210             tr = doExec(javaCmd, option, "-XX:NativeMemoryTracking=summary");
 211             checkTestResult(tr);
 212         }
 213 
 214         // create a test jar
 215         File jarFile = new File("test.jar");
 216         createJar(jarFile, "public static void main(String... args){}");
 217 
 218         // ones that involve main-class of some sort
 219         tr = doExec(javaCmd, "-jar", jarFile.getName(),
 220                 "-XX:NativeMemoryTracking=summary");
 221         checkTestResult(tr);
 222 
 223         tr = doExec(javaCmd, "-cp", jarFile.getName(), "Foo",
 224                 "-XX:NativeMemoryTracking=summary");
 225         checkTestResult(tr);
 226 
 227         final Map<String, String> envMap = new HashMap<>();
 228         // checkwith CLASSPATH set ie. no -cp or -classpath
 229         envMap.put("CLASSPATH", ".");
 230         tr = doExec(envMap, javaCmd, "Foo", "-XX:NativeMemoryTracking=summary");
 231         checkTestResult(tr);
 232 
 233         // should accept with no warnings
 234         tr = doExec(javaCmd, "-cp", jarFile.getName(),
 235                     "-XX:NativeMemoryTracking=summary", "Foo");
 236         ensureNoWarnings(tr);
 237 
 238         // should accept with no warnings
 239         tr = doExec(javaCmd, "-classpath", jarFile.getName(),
 240                     "-XX:NativeMemoryTracking=summary", "Foo");
 241         ensureNoWarnings(tr);
 242 
 243         // make sure a missing class is handled correctly, because the class
 244         // resolution is performed by the JVM.
 245         tr = doExec(javaCmd, "AbsentClass", "-XX:NativeMemoryTracking=summary");
 246         if (!tr.contains("Error: Could not find or load main class AbsentClass")) {
 247             throw new RuntimeException("Test Fails");
 248         }
 249     }
 250 
 251     void ensureNoWarnings(TestResult tr) {
 252         checkTestResult(tr);
 253         if (tr.contains("warning: Native Memory Tracking")) {
 254             System.err.println(tr.toString());
 255             throw new RuntimeException("Test Fails");
 256         }
 257     }
 258 
 259     void checkTestResult(TestResult tr) {
 260         if (!tr.isOK()) {
 261             System.err.println(tr.toString());
 262             throw new RuntimeException("Test Fails");
 263         }
 264     }
 265 }