1 /* 2 * Copyright (c) 2003, 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 /* @test 25 * @bug 4287596 26 * @summary Unit test for "Pluggable Connectors and Transports" feature. 27 * 28 * This test checks that VirtualMachineManager creates Connectors that 29 * are "compatible" those created by 1.4 or earilier releases. 30 * @modules jdk.jdi 31 */ 32 33 import com.sun.jdi.*; 34 import com.sun.jdi.connect.*; 35 import java.util.*; 36 37 public class CompatibleConnectors { 38 39 // number of tests that fail 40 static int failures; 41 42 static void fail(String msg) { 43 System.out.println(msg + " - test failed."); 44 failures++; 45 } 46 47 // the AttachingConnectors that we expect 48 static Object[][] attachingConnectors() { 49 return new Object[][] { 50 { "com.sun.jdi.SocketAttach", 51 "dt_socket", 52 new String[] { "hostname", "Connector.StringArgument", "false" }, 53 new String[] { "port", "Connector.IntegerArgument", "true" } 54 }, 55 56 { "com.sun.jdi.SharedMemoryAttach", 57 "dt_shmem", 58 new String[] { "name", "Connector.StringArgument", "true" } 59 } 60 }; 61 } 62 63 // the ListeningConnectors that we expect 64 static Object[][] listeningConnectors() { 65 return new Object[][] { 66 { "com.sun.jdi.SocketListen", 67 "dt_socket", 68 new String[] { "port", "Connector.IntegerArgument", "true" } 69 }, 70 71 { "com.sun.jdi.SharedMemoryListen", 72 "dt_shmem", 73 new String[] { "name", "Connector.StringArgument", "false" } 74 } 75 }; 76 77 } 78 79 // the LaunchingConnectors that we expect 80 // - note that we don't indicate the transport name (as it varies 81 // for these connectors) 82 static Object[][] launchingConnectors() { 83 return new Object[][] { 84 { "com.sun.jdi.CommandLineLaunch", 85 null, 86 new String[] { "home", "Connector.StringArgument", "false" }, 87 new String[] { "options", "Connector.StringArgument", "false" }, 88 new String[] { "main", "Connector.StringArgument", "true" }, 89 new String[] { "suspend", "Connector.BooleanArgument", "false" }, 90 new String[] { "quote", "Connector.StringArgument", "true" }, 91 new String[] { "vmexec", "Connector.StringArgument", "true" } 92 }, 93 94 { "com.sun.jdi.RawCommandLineLaunch", 95 null, 96 new String[] { "command", "Connector.StringArgument", "true" }, 97 new String[] { "address", "Connector.StringArgument", "true" }, 98 new String[] { "quote", "Connector.StringArgument", "true" } 99 } 100 }; 101 102 } 103 104 // find Connector by name, return null if not found 105 static Connector find(String name, List l) { 106 Iterator i = l.iterator(); 107 while (i.hasNext()) { 108 Connector c = (Connector)i.next(); 109 if (c.name().equals(name)) { 110 return c; 111 } 112 } 113 return null; 114 } 115 116 // check that a connector is of the expected type 117 static void type_match(String arg_name, String arg_type, Connector.Argument arg) { 118 boolean fail = false; 119 if (arg_type.equals("Connector.StringArgument")) { 120 if (!(arg instanceof Connector.StringArgument)) { 121 fail = true; 122 } 123 } 124 if (arg_type.equals("Connector.IntegerArgument")) { 125 if (!(arg instanceof Connector.IntegerArgument)) { 126 fail = true; 127 } 128 } 129 if (arg_type.equals("Connector.BooleanArgument")) { 130 if (!(arg instanceof Connector.BooleanArgument)) { 131 fail = true; 132 } 133 } 134 if (arg_type.equals("Connector.SelectedArgument")) { 135 if (!(arg instanceof Connector.IntegerArgument)) { 136 fail = true; 137 } 138 } 139 if (fail) { 140 fail(arg_name + " is of type: " + arg.getClass() + ", expected: " 141 + arg_type); 142 } 143 } 144 145 146 // check that a Connector is compatible 147 static void check(Object[] desc, Connector connector) { 148 String name = (String)desc[0]; 149 String transport_name = (String)desc[1]; 150 151 // if the transport name is "null" it means its transport may 152 // vary (eg: SunCommandLineLauncher will choose shared memory 153 // on Windows and dt_socket on Solaris). In that case we can't 154 // check the transport name. 155 // 156 if (transport_name != null) { 157 System.out.println("Checking transpot name"); 158 if (!(transport_name.equals(connector.transport().name()))) { 159 fail("transport().name() returns: " + 160 connector.transport().name() + ", expected: " + transport_name); 161 } 162 } 163 164 // check that all the old arguments still exist 165 for (int i=2; i<desc.length; i++) { 166 String[] args = (String[])desc[i]; 167 String arg_name = args[0]; 168 String arg_type = args[1]; 169 String arg_mandatory = args[2]; 170 171 System.out.println("Checking argument: " + arg_name); 172 173 // check that the arg still exists 174 Map defaultArgs = connector.defaultArguments(); 175 Object value = defaultArgs.get(arg_name); 176 if (value == null) { 177 fail(name + " is missing Connector.Argument: " + arg_name); 178 continue; 179 } 180 181 // next check that the type matches 182 Connector.Argument connector_arg = (Connector.Argument)value; 183 184 // check that the argument type hasn't changed 185 type_match(arg_name, arg_type, connector_arg); 186 187 // check that an optional argument has been made mandatory 188 if (arg_mandatory.equals("false")) { 189 if (connector_arg.mustSpecify()) { 190 fail(arg_name + " is now mandatory"); 191 } 192 } 193 } 194 195 // next we check for new arguments that are mandatory but 196 // have no default value 197 198 System.out.println("Checking for new arguments"); 199 Map dfltArgs = connector.defaultArguments(); 200 Iterator iter = dfltArgs.keySet().iterator(); 201 while (iter.hasNext()) { 202 String arg_name = (String)iter.next(); 203 204 // see if the argument is new 205 boolean found = false; 206 for (int j=2; j<desc.length; j++) { 207 String[] args = (String[])desc[j]; 208 if (args[0].equals(arg_name)) { 209 found = true; 210 break; 211 } 212 } 213 214 if (!found) { 215 Connector.Argument connector_arg = 216 (Connector.Argument)dfltArgs.get(arg_name); 217 218 if (connector_arg.mustSpecify()) { 219 String value = connector_arg.value(); 220 if (value.equals("")) { 221 value = null; 222 } 223 if (value == null) { 224 fail("New Connector.Argument \"" + connector_arg.name() + 225 "\" added - argument is mandatory"); 226 } 227 } 228 } 229 } 230 } 231 232 233 // compare the actual list of Connectors against the 234 // expected list of Connectors. 235 static void compare(Object[][] prev, List list) { 236 String os = System.getProperty("os.name"); 237 for (int i=0; i<prev.length; i++) { 238 Object[] desc = prev[i]; 239 String name = (String)desc[0]; 240 241 // ignore Windows specific Connectors are non-Windows machines 242 if (!(os.startsWith("Windows"))) { 243 if (name.equals("com.sun.jdi.SharedMemoryAttach") || 244 name.equals("com.sun.jdi.SharedMemoryListen")) { 245 continue; 246 } 247 } 248 249 System.out.println(""); 250 System.out.println("Checking Connector " + name); 251 252 // check that the Connector exists 253 Connector c = find(name, list); 254 if (c == null) { 255 fail("Connector is missing"); 256 continue; 257 } 258 259 check(desc, c); 260 } 261 } 262 263 public static void main(String args[]) throws Exception { 264 VirtualMachineManager vmm = Bootstrap.virtualMachineManager(); 265 266 // in 1.2/1.3/1.4 the defualtConnector was 267 // com.sun.jdi.CommandLineLaunch. Many debuggers probably 268 // depend on this so check that it's always the default. 269 // 270 String expected = "com.sun.jdi.CommandLineLaunch"; 271 System.out.println("Checking that defaultConnector is: " + expected); 272 String dflt = vmm.defaultConnector().name(); 273 if (!(dflt.equals(expected))) { 274 System.err.println("defaultConnector() is: " + dflt + 275 ", expected:" + expected); 276 failures++; 277 } else { 278 System.out.println("Okay"); 279 } 280 281 compare(attachingConnectors(), vmm.attachingConnectors()); 282 compare(listeningConnectors(), vmm.listeningConnectors()); 283 compare(launchingConnectors(), vmm.launchingConnectors()); 284 285 // test results 286 if (failures > 0) { 287 System.out.println(""); 288 throw new RuntimeException(failures + " test(s) failed"); 289 } 290 } 291 }