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