1 /*
   2  * Copyright (c) 2014, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 import org.testng.annotations.Test;
  27 import org.testng.annotations.BeforeClass;
  28 import sun.tools.jinfo.JInfo;
  29 
  30 import java.lang.reflect.Constructor;
  31 import java.lang.reflect.Field;
  32 import java.util.Arrays;
  33 
  34 import static org.testng.Assert.*;
  35 
  36 /**
  37  * @test
  38  * @bug 8039080
  39  * @run testng JInfoLauncherTest
  40  * @summary Test JInfo launcher argument parsing
  41  */
  42 @Test
  43 public class JInfoLauncherTest {
  44     public static final String VALIDATION_EXCEPTION_CLSNAME =
  45                                 IllegalArgumentException.class.getName();
  46 
  47     private Constructor<JInfo> jInfoConstructor;
  48     private Field fldUseSA;
  49 
  50     @BeforeClass
  51     public void setup() throws Exception {
  52         jInfoConstructor = JInfo.class.getDeclaredConstructor(String[].class);
  53         jInfoConstructor.setAccessible(true);
  54         fldUseSA = JInfo.class.getDeclaredField("useSA");
  55         fldUseSA.setAccessible(true);
  56     }
  57 
  58     private JInfo newJInfo(String[] args) throws Exception {
  59         try {
  60             return jInfoConstructor.newInstance((Object) args);
  61         } catch (Exception e) {
  62             if (isValidationException(e.getCause())) {
  63                 throw (Exception)e.getCause();
  64             }
  65             throw e;
  66         }
  67     }
  68 
  69     private boolean getUseSA(JInfo jinfo) throws Exception {
  70         return fldUseSA.getBoolean(jinfo);
  71     }
  72 
  73     private void cmdPID(String cmd, String ... params) throws Exception {
  74         int offset = (cmd != null ? 1 : 0);
  75         String[] args = new String[offset + params.length];
  76         args[0] = cmd;
  77         System.arraycopy(params, 0, args, offset, params.length);
  78         JInfo j = newJInfo(args);
  79         assertFalse(getUseSA(j), "Local jinfo must not forward to SA");
  80     }
  81 
  82     private void cmdCore(String cmd, String ... params) throws Exception {
  83         int offset = (cmd != null ? 1 : 0);
  84         String[] args = new String[offset + params.length];
  85         args[0] = cmd;
  86         System.arraycopy(params, 0, args, offset, params.length);
  87         JInfo j = newJInfo(args);
  88         assertTrue(getUseSA(j), "Core jinfo must forward to SA");
  89     }
  90 
  91     private void cmdRemote(String cmd, String ... params) throws Exception {
  92         int offset = (cmd != null ? 1 : 0);
  93         String[] args = new String[offset + params.length];
  94         args[0] = cmd;
  95         System.arraycopy(params, 0, args, offset, params.length);
  96         JInfo j = newJInfo(args);
  97         assertTrue(getUseSA(j), "Remote jinfo must forward to SA");
  98     }
  99 
 100     private void cmdExtraArgs(String cmd, int argsLen) throws Exception {
 101         String[] args = new String[argsLen + 1 + (cmd != null ? 1 : 0)];
 102         Arrays.fill(args, "a");
 103         if (cmd != null) {
 104             args[0] = cmd;
 105         } else {
 106             cmd = "default";
 107         }
 108         try {
 109             JInfo j = newJInfo(args);
 110             fail("\"" + cmd + "\" does not support more than " + argsLen +
 111                  " arguments");
 112         } catch (Exception e) {
 113             if (!isValidationException(e)) {
 114                 throw e;
 115             }
 116             // ignore
 117         }
 118     }
 119 
 120     private void cmdMissingArgs(String cmd, int reqArgs) throws Exception {
 121         String[] args = new String[reqArgs - 1 + (cmd != null ? 1 : 0)];
 122         Arrays.fill(args, "a");
 123         if (cmd != null) {
 124             args[0] = cmd;
 125         } else {
 126             cmd = "default";
 127         }
 128         try {
 129             JInfo j = newJInfo(args);
 130             fail("\"" + cmd + "\" requires at least " + reqArgs + " argument");
 131         } catch (Exception e) {
 132             if (!isValidationException(e)) {
 133                 throw e;
 134             }
 135             // ignore
 136         }
 137     }
 138 
 139     public void testDefaultPID() throws Exception {
 140         cmdPID(null, "1234");
 141     }
 142 
 143     public void testFlagsPID() throws Exception {
 144         cmdPID("-flags", "1234");
 145     }
 146 
 147     public void testSyspropsPID() throws Exception {
 148         cmdPID("-sysprops", "1234");
 149     }
 150 
 151     public void testReadFlagPID() throws Exception {
 152         cmdPID("-flag", "SomeManagementFlag", "1234");
 153     }
 154 
 155     public void testSetFlag1PID() throws Exception {
 156         cmdPID("-flag", "+SomeManagementFlag", "1234");
 157     }
 158 
 159     public void testSetFlag2PID() throws Exception {
 160         cmdPID("-flag", "-SomeManagementFlag", "1234");
 161     }
 162 
 163     public void testSetFlag3PID() throws Exception {
 164         cmdPID("-flag", "SomeManagementFlag=314", "1234");
 165     }
 166 
 167     public void testDefaultCore() throws Exception {
 168         cmdCore(null, "myapp.exe", "my.core");
 169     }
 170 
 171     public void testFlagsCore() throws Exception {
 172         cmdCore("-flags", "myapp.exe", "my.core");
 173     }
 174 
 175     public void testSyspropsCore() throws Exception {
 176         cmdCore("-sysprops", "myapp.exe", "my.core");
 177     }
 178 
 179     public void testReadFlagCore() throws Exception {
 180         try {
 181             cmdCore("-flag", "SomeManagementFlag", "myapp.exe", "my.core");
 182             fail("Flags can not be read from core files");
 183         } catch (Exception e) {
 184             if (!isValidationException(e)) {
 185                 throw e;
 186             }
 187             // ignore
 188         }
 189     }
 190 
 191     public void testSetFlag1Core() throws Exception {
 192         try {
 193             cmdCore("-flag", "+SomeManagementFlag", "myapp.exe", "my.core");
 194             fail("Flags can not be set in core files");
 195         } catch (Exception e) {
 196             if (!isValidationException(e)) {
 197                 throw e;
 198             }
 199             // ignore
 200         }
 201     }
 202 
 203     public void testSetFlag2Core() throws Exception {
 204         try {
 205             cmdCore("-flag", "-SomeManagementFlag", "myapp.exe", "my.core");
 206             fail("Flags can not be set in core files");
 207         } catch (Exception e) {
 208             if (!isValidationException(e)) {
 209                 throw e;
 210             }
 211             // ignore
 212         }
 213     }
 214 
 215     public void testSetFlag3Core() throws Exception {
 216         try {
 217             cmdCore("-flag", "SomeManagementFlag=314", "myapp.exe", "my.core");
 218             fail("Flags can not be set in core files");
 219         } catch (Exception e) {
 220             if (!isValidationException(e)) {
 221                 throw e;
 222             }
 223             // ignore
 224         }
 225     }
 226 
 227     public void testDefaultRemote() throws Exception {
 228         cmdRemote(null, "serverid@host");
 229     }
 230 
 231     public void testFlagsRemote() throws Exception {
 232         cmdRemote("-flags", "serverid@host");
 233     }
 234 
 235     public void testSyspropsRemote() throws Exception {
 236         cmdRemote("-sysprops", "serverid@host");
 237     }
 238 
 239     public void testReadFlagRemote() throws Exception {
 240         try {
 241             cmdCore("-flag", "SomeManagementFlag", "serverid@host");
 242             fail("Flags can not be read from SA server");
 243         } catch (Exception e) {
 244             if (!isValidationException(e)) {
 245                 throw e;
 246             }
 247             // ignore
 248         }
 249     }
 250 
 251     public void testSetFlag1Remote() throws Exception {
 252         try {
 253             cmdCore("-flag", "+SomeManagementFlag","serverid@host");
 254             fail("Flags can not be set on SA server");
 255         } catch (Exception e) {
 256             if (!isValidationException(e)) {
 257                 throw e;
 258             }
 259             // ignore
 260         }
 261     }
 262 
 263     public void testSetFlag2Remote() throws Exception {
 264         try {
 265             cmdCore("-flag", "-SomeManagementFlag", "serverid@host");
 266             fail("Flags can not be read set on SA server");
 267         } catch (Exception e) {
 268             if (!isValidationException(e)) {
 269                 throw e;
 270             }
 271             // ignore
 272         }
 273     }
 274 
 275     public void testSetFlag3Remote() throws Exception {
 276         try {
 277             cmdCore("-flag", "SomeManagementFlag=314", "serverid@host");
 278             fail("Flags can not be read set on SA server");
 279         } catch (Exception e) {
 280             if (!isValidationException(e)) {
 281                 throw e;
 282             }
 283             // ignore
 284         }
 285     }
 286 
 287     public void testDefaultExtraArgs() throws Exception {
 288         cmdExtraArgs(null, 2);
 289     }
 290 
 291     public void testFlagsExtraArgs() throws Exception {
 292         cmdExtraArgs("-flags", 2);
 293     }
 294 
 295     public void testSyspropsExtraArgs() throws Exception {
 296         cmdExtraArgs("-sysprops", 2);
 297     }
 298 
 299     public void testFlagExtraArgs() throws Exception {
 300         cmdExtraArgs("-flag", 2);
 301     }
 302 
 303     public void testHelp1ExtraArgs() throws Exception {
 304         cmdExtraArgs("-h", 0);
 305     }
 306 
 307     public void testHelp2ExtraArgs() throws Exception {
 308         cmdExtraArgs("-help", 0);
 309     }
 310 
 311     public void testDefaultMissingArgs() throws Exception {
 312         cmdMissingArgs(null, 1);
 313     }
 314 
 315     public void testFlagsMissingArgs() throws Exception {
 316         cmdMissingArgs("-flags", 1);
 317     }
 318 
 319     public void testSyspropsMissingArgs() throws Exception {
 320         cmdMissingArgs("-sysprops", 1);
 321     }
 322 
 323     public void testFlagMissingArgs() throws Exception {
 324         cmdMissingArgs("-flag", 2);
 325     }
 326 
 327     public void testUnknownCommand() throws Exception {
 328         try {
 329             JInfo j = newJInfo(new String[]{"-unknown_command"});
 330             fail("JInfo accepts unknown commands");
 331         } catch (Exception e) {
 332             if (!isValidationException(e)) {
 333                 throw e;
 334             }
 335             // ignore
 336         }
 337     }
 338 
 339     private static boolean isValidationException(Throwable e) {
 340         return e.getClass().getName().equals(VALIDATION_EXCEPTION_CLSNAME);
 341     }
 342 }