1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 /** 20 * @author Vitaly A. Provodin 21 */ 22 23 /** 24 * Created on 26.01.2005 25 */ 26 package org.apache.harmony.jpda.tests.framework; 27 28 import java.util.HashMap; 29 30 /** 31 * This class provides access to options for running JPDA tests. 32 * <p> 33 * The settings are presented as a set of getters and setters for test options, 34 * which can be implemented in different ways. In this implementation test 35 * options are implemented via VM system properties, which can be specified 36 * using option '-D' in VM command line. 37 * <p> 38 * The following options are currently recognized: 39 * <ul> 40 * <li><code>jpda.settings.debuggeeJavaHome</code> 41 * - path to Java bundle to run debuggee on 42 * <li><code>jpda.settings.debuggeeJavaExec</code> 43 * - name of Java executable to run debuggee on 44 * <li><code>jpda.settings.debuggeeJavaPath</code> 45 * - full path to Java executable to run debuggee on 46 * <li><code>jdpa.settings.debuggeeAgentArgument</code> 47 * - Command-line argument for agent native library. Defaults to "-agentlib:" 48 * <li><code>jpda.settings.debuggeeAgentName</code> 49 * - name of agent native library 50 * <li><code>jpda.settings.debuggeeAgentExtraOptions</code> 51 * - extra options for agent 52 * <li><code>jpda.settings.debuggeeClasspath</code> 53 * - classpath to run debuggee with 54 * <li><code>jpda.settings.debuggeeClassName</code> 55 * - full name of class to run debuggee with 56 * <li><code>jpda.settings.debuggeeVMExtraOptions</code> 57 * - extra options to run debuggee with 58 * <li><code>jpda.settings.debuggeeSuspend</code> 59 * - debuggee suspend mode ("y"|"n") 60 * <li><code>jpda.settings.transportWrapperClass</code> 61 * - class name of TransportWrapper implementation 62 * <li><code>jpda.settings.transportAddress</code> 63 * - address for JDWP connection 64 * <li><code>jpda.settings.connectorKind</code> 65 * - type of JDWP connection (attach or listen) 66 * <li><code>jpda.settings.syncPort</code> 67 * - port number for sync connection (chosen by the OS if not set or set to 0) 68 * <li><code>jpda.settings.timeout</code> 69 * - timeout used in JPDA tests 70 * <li><code>jpda.settings.waitingTime</code> 71 * - timeout for waiting events 72 * </ul> 73 * <li><code>jpda.settings.dumpProcess</code> 74 * - Command to dump a process' data 75 * </ul> 76 * <li><code>jpda.settings.verbose</code> 77 * - flag that disables (default) or enables writing messages to the log 78 * </ul> 79 * All options have default values, if they are not specified. 80 * 81 */ 82 public class TestOptions { 83 84 /** Default timeout value for various operations. */ 85 public static final int DEFAULT_TIMEOUT = 1 * 60 * 1000; // 1 minute 86 87 /** Default time interval for waiting for various events. */ 88 public static final int DEFAULT_WAITING_TIME = DEFAULT_TIMEOUT; 89 90 /** Default static address for transport connection. */ 91 public static final String DEFAULT_ATTACHING_ADDRESS = "127.0.0.1:9898"; 92 93 /** Default port number for sync connection. */ 94 public static final String DEFAULT_STATIC_SYNC_PORT = "9797"; 95 96 /** Default port number for sync connection. */ 97 public static final int DEFAULT_SYNC_PORT = 0; 98 99 /** Default class name for transport wrapper. */ 100 public static final String DEFAULT_TRANSPORT_WRAPPER 101 = "org.apache.harmony.jpda.tests.framework.jdwp.SocketTransportWrapper"; 102 103 /** Default aclass name for debuggee application. */ 104 public static final String DEFAULT_DEBUGGEE_CLASS_NAME 105 = "org.apache.harmony.jpda.tests.jdwp.share.debuggee.HelloWorld"; 106 107 // current waiting time value (negative means using default value) 108 private long waitingTime = -1; 109 110 // current timeout value (negative means using default value) 111 private long timeout = -1; 112 113 // internally set property values 114 private HashMap<String, String> internalProperties = new HashMap<>(); 115 116 /** 117 * Constructs an instance of this class. 118 */ TestOptions()119 public TestOptions() { 120 super(); 121 } 122 123 /** 124 * Gets the command line needed to get backtraces/status of a given pid 125 */ getDumpProcessCommand()126 public String getDumpProcessCommand() { 127 return getProperty("jpda.settings.dumpProcess", "true"); 128 } 129 130 /** 131 * Returns path to Java bundle to run debuggee on. 132 * 133 * @return option "jpda.settings.debuggeeJavaHome" or system property 134 * "java.home" by default. 135 */ getDebuggeeJavaHome()136 public String getDebuggeeJavaHome() { 137 return getProperty("jpda.settings.debuggeeJavaHome", getProperty("java.home", null)); 138 } 139 140 /** 141 * Returns name of Java executable to run debuggee on. 142 * 143 * @return option "jpda.settings.debuggeeJavaExec" or "java" by default. 144 */ getDebuggeeJavaExec()145 public String getDebuggeeJavaExec() { 146 return getProperty("jpda.settings.debuggeeJavaExec", "java"); 147 } 148 149 /** 150 * Returns full path to Java executable to run debuggee on. 151 * 152 * @return option "jpda.settings.debuggeeJavaPath" or construct path from 153 * getDebuggeeJavaHome() and getDebuggeeJavaExec() by default. 154 */ getDebuggeeJavaPath()155 public String getDebuggeeJavaPath() { 156 return getProperty("jpda.settings.debuggeeJavaPath", 157 getDebuggeeJavaHome() + "/bin/" + getDebuggeeJavaExec()); 158 } 159 160 /** 161 * Returns class name of TransportWrapper implementation. 162 * 163 * @return option "jpda.settings.transportWrapperClass" or 164 * DEFAULT_TRANSPORT_WRAPPER by default. 165 */ getTransportWrapperClassName()166 public String getTransportWrapperClassName() { 167 return getProperty("jpda.settings.transportWrapperClass", 168 DEFAULT_TRANSPORT_WRAPPER); 169 } 170 171 /** 172 * Returns address for JDWP connection or null for dynamic address. 173 * 174 * @return option "jpda.settings.transportAddress" or null by default. 175 */ getTransportAddress()176 public String getTransportAddress() { 177 return getProperty("jpda.settings.transportAddress", null); 178 } 179 180 /** 181 * Sets address to attach to debuggee. 182 * 183 * @param address to attach 184 */ setTransportAddress(String address)185 public void setTransportAddress(String address) { 186 setProperty("jpda.settings.transportAddress", address); 187 } 188 189 /** 190 * Returns command line argument to use with name of JDWP agent library. 191 * 192 * @return option "jpda.settings.debuggeeAgentArgument" or "-agentlib:" by default 193 */ getDebuggeeAgentArgument()194 public String getDebuggeeAgentArgument() { 195 return getProperty("jpda.settings.debuggeeAgentArgument", "-agentlib:"); 196 } 197 198 /** 199 * Returns name of JDWP agent library. 200 * 201 * @return option "jpda.settings.debuggeeAgentName" or "jdwp" by default 202 */ getDebuggeeAgentName()203 public String getDebuggeeAgentName() { 204 return getProperty("jpda.settings.debuggeeAgentName", "jdwp"); 205 } 206 207 /** 208 * Returns string with extra options for agent. 209 * 210 * @return option "jpda.settings.debuggeeAgentExtraOptions" or "" by default 211 */ getDebuggeeAgentExtraOptions()212 public String getDebuggeeAgentExtraOptions() { 213 return getProperty("jpda.settings.debuggeeAgentExtraOptions", ""); 214 } 215 216 /** 217 * Returns string with all options for agent including specified connection 218 * address. 219 * 220 * @param address - address to attach 221 * @param isDebuggerListen - true if debugger is listening for connection 222 * 223 * @return string with all agent options 224 */ getDebuggeeAgentOptions(String address, boolean isDebuggerListen)225 public String getDebuggeeAgentOptions(String address, boolean isDebuggerListen) { 226 String serv; 227 if (isDebuggerListen) { 228 serv = "n"; 229 } else { 230 serv = "y"; 231 } 232 233 // add ',' to agent extra options if required 234 String agentExtraOptions = getDebuggeeAgentExtraOptions(); 235 if (agentExtraOptions.length() > 0 && agentExtraOptions.charAt(0) != ',') { 236 agentExtraOptions = "," + agentExtraOptions; 237 } 238 239 return getProperty("jpda.settings.debuggeeAgentOptions", 240 "transport=dt_socket,address=" + address + ",server=" + serv 241 + ",suspend=" + getDebuggeeSuspend() + agentExtraOptions); 242 } 243 244 /** 245 * Returns VM classpath value to run debuggee with. 246 * 247 * @return option "jpda.settings.debuggeeClasspath" or system property "java.class.path" by 248 * default. 249 */ getDebuggeeClassPath()250 public String getDebuggeeClassPath() { 251 return getProperty("jpda.settings.debuggeeClasspath", getProperty("java.class.path", null)); 252 } 253 254 /** 255 * Returns full name of the class to start debuggee with. 256 * 257 * @return option "jpda.settings.debuggeeClassName" or 258 * "org.apache.harmony.jpda.tests.jdwp.share.debuggee.HelloWorld" by default 259 */ getDebuggeeClassName()260 public String getDebuggeeClassName() { 261 return getProperty("jpda.settings.debuggeeClassName", DEFAULT_DEBUGGEE_CLASS_NAME); 262 } 263 264 /** 265 * Sets full name of the class to start debuggee with. 266 * 267 * @param className 268 * full class name 269 */ setDebuggeeClassName(String className)270 public void setDebuggeeClassName(String className) { 271 setProperty("jpda.settings.debuggeeClassName", className); 272 } 273 274 /** 275 * Returns string with extra options to start debuggee with. 276 * 277 * @return option "jpda.settings.debuggeeVMExtraOptions" or "" by default 278 */ getDebuggeeVMExtraOptions()279 public String getDebuggeeVMExtraOptions() { 280 String extOpts = getProperty("jpda.settings.debuggeeVMExtraOptions", ""); 281 extOpts = extOpts + " -Djpda.settings.verbose=" + isVerbose(); 282 return extOpts; 283 } 284 285 /** 286 * Returns debuggee suspend mode ("y"|"n"). 287 * 288 * @return option "jpda.settings.debuggeeSuspend" or "y" by default 289 */ getDebuggeeSuspend()290 public String getDebuggeeSuspend() { 291 return getProperty("jpda.settings.debuggeeSuspend", "y"); 292 } 293 294 /** 295 * Returns debuggee suspend mode ("y"|"n"). 296 * 297 * @param mode 298 * suspend mode 299 */ setDebuggeeSuspend(String mode)300 public void setDebuggeeSuspend(String mode) { 301 setProperty("jpda.settings.debuggeeSuspend", mode); 302 } 303 304 /** 305 * Checks if debuggee is launched in suspend mode. 306 * 307 * @return true if debuggee is launched in suspend mode 308 */ isDebuggeeSuspend()309 public boolean isDebuggeeSuspend() { 310 return getDebuggeeSuspend().equals("y"); 311 } 312 313 /** 314 * Returns string representation of TCP/IP port for synchronization channel. 315 * 316 * @return string with port number or null 317 */ getSyncPortString()318 public String getSyncPortString() { 319 return getProperty("jpda.settings.syncPort", null); 320 } 321 322 /** 323 * Returns type of connection with debuggee. 324 * 325 * @return system property "jpda.settings.connectorKind" or "listen" by default. 326 */ getConnectorKind()327 public String getConnectorKind() { 328 return getProperty("jpda.settings.connectorKind", "listen"); 329 } 330 331 /** 332 * Checks if attach connection with debuggee. 333 * 334 * @return true, if attach connection, false otherwise. 335 */ isAttachConnectorKind()336 public boolean isAttachConnectorKind() { 337 return ((getConnectorKind()).equals("attach")); 338 339 } 340 341 /** 342 * Checks if listen connection with debuggee. 343 * 344 * @return true, if listen connection, false otherwise. 345 */ isListenConnectorKind()346 public boolean isListenConnectorKind() { 347 return (getConnectorKind().equals("listen")); 348 } 349 350 /** 351 * Sets connectorKind to attach to debuggee. 352 */ setAttachConnectorKind()353 public void setAttachConnectorKind() { 354 setConnectorKind("attach"); 355 } 356 357 /** 358 * Sets connectorKind to listen connection from debuggee. 359 */ setListenConnectorKind()360 public void setListenConnectorKind() { 361 setConnectorKind("listen"); 362 } 363 364 /** 365 * Sets kind of connector (attach or listen). 366 */ setConnectorKind(String kind)367 public void setConnectorKind(String kind) { 368 setProperty("jpda.settings.connectorKind", kind); 369 } 370 371 /** 372 * Returns kind of launching debuggee VM, which can be "auto" or "manual". 373 * 374 * @return option "jpda.settings.debuggeeLaunchKind" or "auto" by default. 375 */ getDebuggeeLaunchKind()376 public String getDebuggeeLaunchKind() { 377 return getProperty("jpda.settings.debuggeeLaunchKind", "auto"); 378 } 379 380 /** 381 * Returns TCP/IP port for synchronization channel. 382 * 383 * @return port number if it is set, or DEFAULT_SYNC_PORT otherwise. 384 */ getSyncPortNumber()385 public int getSyncPortNumber() { 386 String buf = getSyncPortString(); 387 if (buf == null) { 388 return DEFAULT_SYNC_PORT; 389 } 390 391 try { 392 return Integer.parseInt(buf); 393 } catch (NumberFormatException e) { 394 throw new TestErrorException(e); 395 } 396 } 397 398 /** 399 * Returns timeout for JPDA tests in milliseconds. 400 * 401 * @return option "jpda.settings.timeout" or DEFAULT_TIMEOUT by default. 402 */ getTimeout()403 public long getTimeout() { 404 if (timeout < 0) { 405 timeout = DEFAULT_TIMEOUT; 406 String buf = getProperty("jpda.settings.timeout", null); 407 if (buf != null) { 408 try { 409 timeout = Long.parseLong(buf); 410 } catch (NumberFormatException e) { 411 throw new TestErrorException(e); 412 } 413 } 414 } 415 return timeout; 416 } 417 418 /** 419 * Sets timeout for JPDA tests in milliseconds. 420 * 421 * @param timeout 422 * timeout to be set 423 */ setTimeout(long timeout)424 public void setTimeout(long timeout) { 425 if (timeout < 0) { 426 throw new TestErrorException("Cannot set negative timeout value: " 427 + timeout); 428 } 429 this.timeout = timeout; 430 } 431 432 /** 433 * Returns waiting time for events in milliseconds. 434 * 435 * @return waiting time 436 */ getWaitingTime()437 public long getWaitingTime() { 438 if (waitingTime < 0) { 439 waitingTime = DEFAULT_WAITING_TIME; 440 String buf = getProperty("jpda.settings.waitingTime", null); 441 if (buf != null) { 442 try { 443 waitingTime = Long.parseLong(buf); 444 } catch (NumberFormatException e) { 445 throw new TestErrorException(e); 446 } 447 } 448 } 449 return waitingTime; 450 } 451 452 /** 453 * Sets waiting time for events in milliseconds. 454 * 455 * @param waitingTime 456 * waiting time to be set 457 */ setWaitingTime(long waitingTime)458 public void setWaitingTime(long waitingTime) { 459 this.waitingTime = waitingTime; 460 } 461 462 /** 463 * Returns whether print to log is enabled. 464 * 465 * @return false (default) if log is disabled or true otherwise. 466 */ isVerbose()467 public boolean isVerbose() { 468 return isTrue(getProperty("jpda.settings.verbose", "true")); 469 } 470 471 /** 472 * Converts text to boolean. 473 * 474 * @param str string representing boolean value 475 * @return boolean 476 */ isTrue(String str)477 static public boolean isTrue(String str) { 478 return str != null && ( 479 str.equalsIgnoreCase("true") || 480 str.equalsIgnoreCase("yes") || 481 str.equalsIgnoreCase("on") || 482 str.equals("1")); 483 } 484 485 /** 486 * Returns value of given property if it was set internally or specified in system properties. 487 * 488 * @param name 489 * property name 490 * @param defaultValue 491 * default value for given property 492 * @return string value of given property or default value if no such property found 493 */ getProperty(String name, String defaultValue)494 protected String getProperty(String name, String defaultValue) { 495 String value = internalProperties.get(name); 496 if (value != null) { 497 return value; 498 } 499 return System.getProperty(name, defaultValue); 500 } 501 502 /** 503 * Sets internal value of given property to override corresponding system property. 504 * 505 * @param name 506 * proparty name 507 * @param value 508 * value for given property 509 */ setProperty(String name, String value)510 protected void setProperty(String name, String value) { 511 internalProperties.put(name, value); 512 } 513 514 } 515