1 4 package com.tc.simulator.distrunner; 5 6 import com.tcsimulator.ClientSpec; 7 import com.tcsimulator.distrunner.NullServerSpec; 8 import com.tcsimulator.distrunner.ServerSpec; 9 10 import java.net.URI ; 11 import java.net.URISyntaxException ; 12 import java.util.ArrayList ; 13 import java.util.Collection ; 14 import java.util.Iterator ; 15 import java.util.LinkedList ; 16 import java.util.List ; 17 18 public class ArgParser { 19 20 private final Collection clientSpecs = new LinkedList (); 21 private final SpecFactory specFactory; 22 private final Collection testServerSpecs = new LinkedList (); 23 private final ServerSpec controlServerSpec; 24 private final String testClassname; 25 private final int intensity; 26 private final int testServerStartMode; 27 private final String javaHome; 28 private static final String CLASS_NAME_ARG = "classname"; 29 private static final String INTENSITY_ARG = "intensity"; 30 private static final String CLIENT_ARG = "client"; 31 private static final String TEST_SERVER_ARG = "server"; 32 private static final String CONTROL_SERVER_ARG = "control"; 33 private static final String BACKUP_SERVER_ARG = "backup"; 34 private static final String VM_COUNT_ARG = "vm.count"; 35 private static final String EXECUTION_COUNT_ARG = "execution.count"; 36 private static final String JVM_OPTS_ARG = "jvm.args"; 37 private static final String CACHE_COUNT_ARG = "config.dso.server.cache"; 38 private static final String HTTP_PORT_ARG = "config.dso.http.port"; 39 private static final String JMX_PORT_ARG = "config.dso.jmx.port"; 40 private static final String DSO_PORT_ARG = "config.dso.dso.port"; 41 42 private static final String DSO_START_ARG = "dsostart"; 43 private static final String DSO_START_TRUE_ARG = "true"; 44 private static final String JAVA_HOME_ARG = "javahome"; 45 private static final String UNDEFINED = "undefined"; 46 private static final String UNDEFINED_NUMBER = "-1"; 47 48 public static final int DSO_START = 0; 49 public static final int NON_DSO_START = 1; 50 public static final int DEFAULT_HTTP_PORT = 9515; 52 public static final int DEFAULT_JMX_PORT = 9520; 53 public static final int DEFAULT_DSO_PORT = 9510; 54 public static final int DEFAULT_SERVER_CACHE = 200000; 56 57 public ArgParser(String [] args, SpecFactory specFactory, boolean serverSpecRequired, boolean controlServerSpecRequired) 58 throws ArgException { 59 this.specFactory = specFactory; 60 if (args == null || args.length == 0) { throw new ArgException("No arguments specified"); } 61 ServerSpec theControlServerSpec = new NullServerSpec(); 62 String theTestClassname = ""; 63 int theIntensity = -1; 64 int theTestServerStartMode = -1; 65 String theJavaHome = ""; 66 try { 67 for (int i = 0; i < args.length; i++) { 68 if (args[i].startsWith(CLIENT_ARG)) { 69 parseClientSpecs(args[i]); 70 } else if (args[i].startsWith(TEST_SERVER_ARG) || args[i].startsWith(CONTROL_SERVER_ARG) 71 || args[i].startsWith(BACKUP_SERVER_ARG)) { 72 theControlServerSpec = parseServerSpecs(args[i]); 73 } else if (args[i].startsWith(CLASS_NAME_ARG)) { 74 if (!theTestClassname.equals("")) { throw new ArgException("More than one test classname specified."); } 75 String [] nvPair = args[i].split("="); 76 if (nvPair.length != 2) { throw new ArgException("Malformed test classname argument."); } 77 theTestClassname = nvPair[1]; 78 } else if (args[i].startsWith(INTENSITY_ARG)) { 79 if (theIntensity >= 0) { throw new ArgException("More than one intensity specified."); } 80 String [] nvPair = args[i].split("="); 81 if (nvPair.length != 2) { throw new ArgException("Malformed intensity argument."); } 82 if (!nvPair[1].equals(UNDEFINED)) { 83 theIntensity = Integer.parseInt(nvPair[1]); 84 } 85 } else if (args[i].startsWith(DSO_START_ARG)) { 86 String [] nvPair = args[i].split("="); 87 if (nvPair.length != 2) { throw new ArgException("Malformed dso start argument."); } 88 if (nvPair[1].equalsIgnoreCase(DSO_START_TRUE_ARG)) { 89 theTestServerStartMode = DSO_START; 90 } else { 91 theTestServerStartMode = NON_DSO_START; 92 } 93 } else if (args[i].startsWith(JAVA_HOME_ARG)) { 94 String [] nvPair = args[i].split("="); 95 if (nvPair.length != 2) { throw new ArgException("Malformed java home argument."); } 96 theJavaHome = nvPair[1]; 97 } 98 } 99 } catch (URISyntaxException e) { 100 throw new ArgException(e); 101 } 102 this.testClassname = theTestClassname; this.intensity = theIntensity; this.testServerStartMode = theTestServerStartMode; 105 if (theControlServerSpec.isNull() && controlServerSpecRequired) { throw new ArgException( 106 "No control server spec specified."); } 107 this.controlServerSpec = theControlServerSpec; 108 if (testServerSpecs.isEmpty() && serverSpecRequired) { throw new ArgException("No server spec specified."); } 109 this.javaHome = theJavaHome; 110 } 111 112 private ServerSpec parseServerSpecs(String arg) throws ArgException, URISyntaxException { 113 ServerSpec theControlServerSpec = new NullServerSpec(); 114 String [] specDescriptions = arg.split(";"); 115 for (int i = 0; i < specDescriptions.length; i++) { 116 ServerSpec csSpec = parseServerSpec(new URI (specDescriptions[i])); 117 if (!csSpec.isNull() && theControlServerSpec.isNull()) { 118 theControlServerSpec = csSpec; 119 } else if (!csSpec.isNull()) { throw new ArgException("More than one control server spec specified."); } 120 } 121 return theControlServerSpec; 122 } 123 124 private ServerSpec parseServerSpec(URI uri) throws ArgException { 125 String hostname = uri.getHost(); 126 String testHome = uri.getPath(); 127 int cache = 0; 128 int jmxPort = 0; 129 int dsoPort = 0; 130 List parsedJvmOpts = new ArrayList (); 131 int undefNumber = ArgParser.getUndefinedNumber(); 132 String typeName = uri.getScheme(); 133 int type = -1; 134 135 if (typeName.startsWith(CONTROL_SERVER_ARG)) { 136 type = 0; 137 } else if (typeName.startsWith(TEST_SERVER_ARG)) { 138 type = 1; 139 } else if (typeName.startsWith(BACKUP_SERVER_ARG)) { 140 type = 2; 141 } 142 143 try { 144 cache = Integer.parseInt(getValueFromQuery(CACHE_COUNT_ARG, UNDEFINED_NUMBER, uri.getQuery())); 145 if (cache == undefNumber) { 146 cache = ArgParser.DEFAULT_SERVER_CACHE; 147 } 148 } catch (NumberFormatException e) { 149 throw new ArgException("Unable to parse " + CACHE_COUNT_ARG + ": " + uri); 150 } 151 try { 152 jmxPort = Integer.parseInt(getValueFromQuery(JMX_PORT_ARG, UNDEFINED_NUMBER, uri.getQuery())); 153 if (jmxPort == undefNumber) { 154 jmxPort = ArgParser.DEFAULT_JMX_PORT + type; 155 } 156 } catch (NumberFormatException e) { 157 throw new ArgException("Unable to parse " + JMX_PORT_ARG + ": " + uri); 158 } 159 try { 160 dsoPort = Integer.parseInt(getValueFromQuery(DSO_PORT_ARG, UNDEFINED_NUMBER, uri.getQuery())); 161 if (dsoPort == undefNumber) { 162 dsoPort = ArgParser.DEFAULT_DSO_PORT + type; 163 } 164 } catch (NumberFormatException e) { 165 throw new ArgException("Unable to parse " + DSO_PORT_ARG + ": " + uri); 166 } 167 String [] jvmOpts = getValueFromQuery(JVM_OPTS_ARG, UNDEFINED, uri.getQuery()).split(","); 168 for (int i = 0; i < jvmOpts.length; i++) { 169 parsedJvmOpts.add(jvmOpts[i]); 170 } 171 172 switch (type) { 173 case 0: 174 return specFactory.newServerSpec(hostname, testHome, cache, jmxPort, dsoPort, parsedJvmOpts, 175 ServerSpec.CONTROL_SERVER); 176 case 1: 177 testServerSpecs.add(specFactory.newServerSpec(hostname, testHome, cache, jmxPort, dsoPort, parsedJvmOpts, 178 ServerSpec.TEST_SERVER)); 179 return new NullServerSpec(); 180 case 2: 181 testServerSpecs.add(specFactory.newServerSpec(hostname, testHome, cache, jmxPort, dsoPort, parsedJvmOpts, 182 ServerSpec.BACKUP_SERVER)); 183 return new NullServerSpec(); 184 default: 185 throw new AssertionError ("Attempting to parse unrecognizable server type!"); 186 } 187 } 188 189 private void parseClientSpecs(String arg) throws URISyntaxException , NumberFormatException , ArgException { 190 String [] specDescriptions = arg.split(";"); 191 for (int i = 0; i < specDescriptions.length; i++) { 192 parseClientSpec(new URI (specDescriptions[i])); 193 } 194 } 195 196 private void parseClientSpec(URI uri) throws ArgException { 197 String hostname = uri.getHost(); 198 String testHome = uri.getPath(); 199 int vmCount = 0; 200 int executionCount = 0; 201 List parsedJvmOpts = new ArrayList (); 202 203 try { 204 vmCount = Integer.parseInt(getValueFromQuery(VM_COUNT_ARG, "1", uri.getQuery())); 205 } catch (NumberFormatException e) { 206 throw new ArgException("Unable to parse " + VM_COUNT_ARG + ": " + uri); 207 } 208 try { 209 executionCount = Integer.parseInt(getValueFromQuery(EXECUTION_COUNT_ARG, "1", uri.getQuery())); 210 } catch (NumberFormatException e) { 211 throw new ArgException("Unable to parse " + EXECUTION_COUNT_ARG + ": " + uri); 212 } 213 String [] jvmOpts = getValueFromQuery(JVM_OPTS_ARG, UNDEFINED, uri.getQuery()).split(","); 214 for (int i = 0; i < jvmOpts.length; i++) { 215 parsedJvmOpts.add(jvmOpts[i]); 216 } 217 clientSpecs.add(specFactory.newClientSpec(hostname, testHome, vmCount, executionCount, parsedJvmOpts)); 218 } 219 220 public int getIntensity() { 221 return intensity; 222 } 223 224 public Collection getClientSpecs() { 225 return clientSpecs; 226 } 227 228 public Collection getServerSpecs() { 229 return this.testServerSpecs; 230 } 231 232 public ServerSpec getServerSpec() { 234 return (ServerSpec) this.testServerSpecs.iterator().next(); 235 } 236 237 public ServerSpec getControlServerSpec() { 238 return this.controlServerSpec; 239 } 240 241 public String getTestClassname() { 242 return this.testClassname; 243 } 244 245 public boolean getTestServerStartMode() { 246 if (this.testServerStartMode == DSO_START) { return true; } 247 return false; 248 } 249 250 public String getJavaHome() { 251 String fileSeparator = System.getProperty("file.separator"); 252 253 return this.javaHome + fileSeparator + "bin" + fileSeparator + "java"; 254 } 255 256 private static String getValueFromQuery(String name, String defaultValue, String query) throws ArgException { 257 List results = getValuesFromQuery(name, query); 258 if (results.isEmpty()) { return defaultValue; } 259 if (results.size() > 1) { 260 throw new ArgException("More than one value for name (" + name + "): " + query); 261 } else { 262 return (String ) results.get(0); 263 } 264 } 265 266 private static List getValuesFromQuery(String name, String query) { 267 List rv = new LinkedList (); 268 if (query != null) { 269 String [] pairs = query.split("&"); 270 for (int i = 0; i < pairs.length; i++) { 271 String pair = pairs[i]; 272 int split = pair.indexOf("="); 273 String [] nv = new String [] { pair.substring(0, split), pair.substring(split + 1, pair.length()) }; 274 if (name.equals(nv[0])) { 275 rv.add(nv[1]); 276 } 277 } 278 } 279 return rv; 280 } 281 282 public static String getArgumentForTestClassName(String testClassName) { 283 return CLASS_NAME_ARG + "=" + testClassName; 284 } 285 286 public static String getArgumentForClientSpec(ClientSpec cSpec) { 287 StringBuffer jopts = new StringBuffer (); 288 for (Iterator i = cSpec.getJvmOpts().iterator(); i.hasNext();) { 289 jopts.append(i.next()); 290 if (i.hasNext()) { 291 jopts.append(","); 292 } 293 } 294 StringBuffer result = new StringBuffer (); 295 result.append(CLIENT_ARG + "://" + cSpec.getHostName() + cSpec.getTestHome() + "?" + VM_COUNT_ARG + "=" 296 + cSpec.getVMCount() + "&" + EXECUTION_COUNT_ARG + "=" + cSpec.getExecutionCount()); 297 if (!jopts.toString().equals(UNDEFINED)) { 298 result.append("&" + JVM_OPTS_ARG + "=" + jopts.toString()); 299 } 300 return result.toString(); 301 } 302 303 public static Collection getArgumentsForClientSpecs(Collection clientSpecs) { 304 List result = new ArrayList (); 305 for (Iterator i = clientSpecs.iterator(); i.hasNext();) { 306 result.add(ArgParser.getArgumentForClientSpec((ClientSpec) i.next())); 307 } 308 return result; 309 } 310 311 public static String getArgumentForIntensity(int intensity) { 312 return INTENSITY_ARG + "=" + intensity; 313 } 314 315 public static String getArgumentForServerSpec(ServerSpec sSpec) { 316 int type = sSpec.getType(); 317 String token = null; 318 switch (type) { 319 case ServerSpec.CONTROL_SERVER: 320 token = CONTROL_SERVER_ARG; 321 break; 322 case ServerSpec.TEST_SERVER: 323 token = TEST_SERVER_ARG; 324 break; 325 case ServerSpec.BACKUP_SERVER: 326 token = BACKUP_SERVER_ARG; 327 } 328 329 StringBuffer jopts = new StringBuffer (); 330 for (Iterator i = sSpec.getJvmOpts().iterator(); i.hasNext();) { 331 jopts.append(i.next()); 332 if (i.hasNext()) { 333 jopts.append(","); 334 } 335 } 336 StringBuffer result = new StringBuffer (); 337 result.append(token + "://" + sSpec.getHostName() + sSpec.getTestHome() + "?config.dso.server.cache=" 338 + sSpec.getCache() + "&config.dso.jmx.port=" + sSpec.getJmxPort() + "&config.dso.dso.port=" 339 + sSpec.getDsoPort()); 340 if (!jopts.toString().equals(UNDEFINED)) { 341 result.append("&" + JVM_OPTS_ARG + "=" + jopts.toString()); 342 } 343 return result.toString(); 344 } 345 346 public static Collection getArgumentsForServerSpecs(Collection serverSpecs) { 347 List result = new ArrayList (); 348 for (Iterator i = serverSpecs.iterator(); i.hasNext();) { 349 result.add(ArgParser.getArgumentForServerSpec((ServerSpec) i.next())); 350 } 351 return result; 352 } 353 354 public static String getUndefinedString() { 355 return UNDEFINED; 356 } 357 358 public static int getUndefinedNumber() { 359 return Integer.parseInt(UNDEFINED_NUMBER); 360 } 361 362 public static final String usage() { 363 StringBuffer buf = new StringBuffer ("Setup for distributed test runner.\nUsage:"); 364 365 buf.append("\n\njava "); 366 buf.append("<client spec>[;<client spec>;<client spec>...]"); 367 buf.append(" <server spec>[;<server spec>...]"); 368 buf.append(" " + CLASS_NAME_ARG + "=<test application classname>"); 369 buf.append(" " + INTENSITY_ARG + "=<integer describing intensity>"); 370 buf.append("\n\nclient spec: " + CLIENT_ARG + "://<hostname>/path/to/test/home[?[" + VM_COUNT_ARG + "=<vm count>]"); 371 buf.append("[&" + EXECUTION_COUNT_ARG + "=<execution count>][&" + JVM_OPTS_ARG + "=<jvm args>]]\n"); 372 buf.append("server spec: {" + TEST_SERVER_ARG + " " + CONTROL_SERVER_ARG + "}://<hostname>/path/to/test/home"); 373 buf.append("[?[" + JVM_OPTS_ARG + "=<jvm args>][&" + CACHE_COUNT_ARG + "=<cache count>]"); 374 buf.append("[&" + HTTP_PORT_ARG + "=<http port>][&" + JMX_PORT_ARG + "=<jmx port>]"); 375 buf.append("[&" + DSO_PORT_ARG + "=<dso port>]]\n"); 376 buf.append("\t" + VM_COUNT_ARG + ": how many JVMs to start on this client\n"); 377 buf.append("\t" + EXECUTION_COUNT_ARG + ": the number of application instances to start per vm\n"); 378 buf.append("\t" + JVM_OPTS_ARG + ": jvm options to be used when running this process\n"); 379 buf.append("\t" + TEST_SERVER_ARG + ": DSO server used to run the test apps\n"); 380 buf.append("\t" + CONTROL_SERVER_ARG + ": DSO server used to manage the distribute test framework\n"); 381 return buf.toString(); 382 } 383 } 384 | Popular Tags |