Main.java revision 0:37a05a11f281
1/* 2 * Copyright 2000-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any questions. 22 */ 23 24/* 25 * 26 */ 27 28package bench.rmi; 29 30import bench.ConfigFormatException; 31import bench.Harness; 32import bench.HtmlReporter; 33import bench.Reporter; 34import bench.TextReporter; 35import bench.XmlReporter; 36import java.io.FileInputStream; 37import java.io.FileOutputStream; 38import java.io.InputStream; 39import java.io.IOException; 40import java.io.OutputStream; 41import java.io.PrintStream; 42import java.rmi.RemoteException; 43import java.rmi.RMISecurityManager; 44import java.rmi.registry.LocateRegistry; 45import java.rmi.registry.Registry; 46import java.rmi.server.RemoteObject; 47import java.util.Timer; 48import java.util.TimerTask; 49 50/* 51 * RMI/Serialization benchmark tests. 52 */ 53public class Main { 54 55 /** 56 * RMI-specific benchmark harness. 57 */ 58 static class RMIHarness extends Harness { 59 /** 60 * Construct new RMI benchmark harness. 61 */ 62 RMIHarness(InputStream in) throws IOException, ConfigFormatException { 63 super(in); 64 } 65 66 /** 67 * Cleanup both client and server side in between each benchmark. 68 */ 69 protected void cleanup() { 70 System.gc(); 71 if (Main.runmode == CLIENT) { 72 try { 73 Main.server.gc(); 74 } catch (Exception e) { 75 System.err.println("Warning: server gc failed: " + e); 76 } 77 } 78 } 79 } 80 81 static final String CONFFILE = "/bench/rmi/config"; 82 static final String VERSION = "1.3"; 83 static final String REGNAME = "server"; 84 85 static final int SAMEVM = 0; 86 static final int CLIENT = 1; 87 static final int SERVER = 2; 88 89 static final int TEXT = 0; 90 static final int HTML = 1; 91 static final int XML = 2; 92 93 static boolean verbose; 94 static boolean list; 95 static boolean exitOnTimer; 96 static int testDurationSeconds; 97 static volatile boolean exitRequested; 98 static Timer timer; 99 static int format = TEXT; 100 static int runmode; 101 static InputStream confstr; 102 static OutputStream repstr; 103 static String host; 104 static int port; 105 static RMIHarness harness; 106 static Reporter reporter; 107 static BenchServer server; 108 static BenchServerImpl serverImpl; 109 110 /** 111 * Returns reference to benchmark server. 112 */ 113 public static BenchServer getBenchServer() { 114 return server; 115 } 116 117 /** 118 * Prints help message. 119 */ 120 static void usage() { 121 PrintStream p = System.err; 122 p.println("\nUsage: java -jar rmibench.jar [-options]"); 123 p.println("\nwhere options are:"); 124 p.println(" -h print this message"); 125 p.println(" -v verbose mode"); 126 p.println(" -l list configuration file"); 127 p.println(" -t <num hours> repeat benchmarks for specified number of hours"); 128 p.println(" -o <file> specify output file"); 129 p.println(" -c <file> specify (non-default) " + 130 "configuration file"); 131 p.println(" -html format output as html " + 132 "(default is text)"); 133 p.println(" -xml format output as xml"); 134 p.println(" -client <host:port> run benchmark client using server " + 135 "on specified host/port"); 136 p.println(" -server <port> run benchmark server on given port"); 137 } 138 139 /** 140 * Print error message and exit. 141 */ 142 static void die(String mesg) { 143 System.err.println(mesg); 144 System.exit(1); 145 } 146 147 /** 148 * Stop server and exit. 149 */ 150 public static void exit() { 151 switch (runmode) { 152 case CLIENT: 153 if (server != null) { 154 try { 155 server.terminate(0); 156 } catch (RemoteException re) { 157 // ignore 158 } 159 } 160 default: 161 System.exit(0); 162 } 163 } 164 165 /** 166 * Benchmark mainline. 167 */ 168 public static void main(String[] args) { 169 setupSecurity(); 170 parseArgs(args); 171 setupStreams(); 172 if (list) { 173 listConfig(); 174 } else { 175 setupServer(); 176 if (runmode != SERVER) { 177 setupHarness(); 178 setupReporter(); 179 if (exitOnTimer) { 180 setupTimer(testDurationSeconds); 181 while (true) { 182 runBenchmarks(); 183 if (exitRequested) { 184 exit(); 185 } 186 } 187 } else { 188 runBenchmarks(); 189 exit(); 190 } 191 } 192 } 193 } 194 195 /** 196 * Parse command-line arguments. 197 */ 198 static void parseArgs(String[] args) { 199 for (int i = 0; i < args.length; i++) { 200 if (args[i].equals("-h")) { 201 usage(); 202 System.exit(0); 203 } else if (args[i].equals("-v")) { 204 verbose = true; 205 } else if (args[i].equals("-l")) { 206 list = true; 207 } else if (args[i].equals("-t")) { 208 if (++i >= args.length) 209 die("Error: no timeout value specified"); 210 try { 211 exitOnTimer = true; 212 testDurationSeconds = Integer.parseInt(args[i]) * 3600; 213 } catch (Exception e) { 214 die("Error: unable to determine timeout value"); 215 } 216 } else if (args[i].equals("-o")) { 217 if (++i >= args.length) 218 die("Error: no output file specified"); 219 try { 220 repstr = new FileOutputStream(args[i]); 221 } catch (IOException e) { 222 die("Error: unable to open \"" + args[i] + "\""); 223 } 224 } else if (args[i].equals("-c")) { 225 if (++i >= args.length) 226 die("Error: no config file specified"); 227 try { 228 confstr = new FileInputStream(args[i]); 229 } catch (IOException e) { 230 die("Error: unable to open \"" + args[i] + "\""); 231 } 232 } else if (args[i].equals("-html")) { 233 if (format != TEXT) 234 die("Error: conflicting formats"); 235 format = HTML; 236 } else if (args[i].equals("-xml")) { 237 if (format != TEXT) 238 die("Error: conflicting formats"); 239 format = XML; 240 } else if (args[i].equals("-client")) { 241 if (runmode == CLIENT) 242 die("Error: multiple -client options"); 243 if (runmode == SERVER) 244 die("Error: -client and -server options conflict"); 245 if (++i >= args.length) 246 die("Error: -client missing host/port"); 247 try { 248 int sepi = args[i].indexOf(':'); 249 host = args[i].substring(0, sepi); 250 port = Integer.parseInt(args[i].substring(sepi + 1)); 251 } catch (Exception e) { 252 die("Error: illegal host/port specified for -client"); 253 } 254 runmode = CLIENT; 255 } else if (args[i].equals("-server")) { 256 if (runmode == CLIENT) 257 die("Error: -client and -server options conflict"); 258 if (runmode == SERVER) 259 die("Error: multiple -server options"); 260 if (++i >= args.length) 261 die("Error: -server missing port"); 262 try { 263 port = Integer.parseInt(args[i]); 264 } catch (Exception e) { 265 die("Error: illegal port specified for -server"); 266 } 267 runmode = SERVER; 268 } else { 269 System.err.println("Illegal option: \"" + args[i] + "\""); 270 usage(); 271 System.exit(1); 272 } 273 } 274 } 275 276 /** 277 * Set up security manager and policy, if not set already. 278 */ 279 static void setupSecurity() { 280 if (System.getSecurityManager() != null) 281 return; 282 283 /* As of 1.4, it is too late to set the security policy 284 * file at this point so these line have been commented out. 285 */ 286 //System.setProperty("java.security.policy", 287 // Main.class.getResource("/bench/rmi/policy.all").toString()); 288 System.setSecurityManager(new RMISecurityManager()); 289 } 290 291 /** 292 * Set up configuration file and report streams, if not set already. 293 */ 294 static void setupStreams() { 295 if (repstr == null) 296 repstr = System.out; 297 if (confstr == null) 298 confstr = (new Main()).getClass().getResourceAsStream(CONFFILE); 299 if (confstr == null) 300 die("Error: unable to find default config file"); 301 } 302 303 /** 304 * Print contents of configuration file to selected output stream. 305 */ 306 static void listConfig() { 307 try { 308 byte[] buf = new byte[256]; 309 int len; 310 while ((len = confstr.read(buf)) != -1) 311 repstr.write(buf, 0, len); 312 } catch (IOException e) { 313 die("Error: failed to list config file"); 314 } 315 } 316 317 /** 318 * Setup benchmark server. 319 */ 320 static void setupServer() { 321 switch (runmode) { 322 case SAMEVM: 323 try { 324 serverImpl = new BenchServerImpl(); 325 server = (BenchServer) RemoteObject.toStub(serverImpl); 326 } catch (Exception e) { 327 die("Error: failed to create local server: " + e); 328 } 329 if (verbose) 330 System.out.println("Benchmark server created locally"); 331 break; 332 333 case CLIENT: 334 try { 335 Registry reg = LocateRegistry.getRegistry(host, port); 336 server = (BenchServer) reg.lookup(REGNAME); 337 } catch (Exception e) { 338 die("Error: failed to connect to server: " + e); 339 } 340 if (server == null) { 341 die("Error: server not found"); 342 } 343 if (verbose) { 344 System.out.println("Connected to benchmark server on " + 345 host + ":" + port); 346 } 347 break; 348 349 case SERVER: 350 try { 351 Registry reg = LocateRegistry.createRegistry(port); 352 serverImpl = new BenchServerImpl(); 353 reg.bind(REGNAME, serverImpl); 354 } catch (Exception e) { 355 die("Error: failed to initialize server: " + e); 356 } 357 if (verbose) { 358 System.out.println("Benchmark server started on port " + 359 port); 360 } 361 break; 362 363 default: 364 throw new InternalError("illegal runmode"); 365 } 366 } 367 368 /** 369 * Set up the timer to end the test. 370 * 371 * @param delay the amount of delay, in seconds, before requesting 372 * the process exit 373 */ 374 static void setupTimer(int delay) { 375 timer = new Timer(true); 376 timer.schedule( 377 new TimerTask() { 378 public void run() { 379 exitRequested = true; 380 } 381 }, 382 delay * 1000); 383 } 384 385 /** 386 * Set up benchmark harness. 387 */ 388 static void setupHarness() { 389 try { 390 harness = new RMIHarness(confstr); 391 } catch (ConfigFormatException e) { 392 String errmsg = e.getMessage(); 393 if (errmsg != null) { 394 die("Error parsing config file: " + errmsg); 395 } else { 396 die("Error: illegal config file syntax"); 397 } 398 } catch (IOException e) { 399 die("Error: failed to read config file"); 400 } 401 } 402 403 /** 404 * Setup benchmark reporter. 405 */ 406 static void setupReporter() { 407 String title = "RMI Benchmark, v" + VERSION; 408 switch (format) { 409 case TEXT: 410 reporter = new TextReporter(repstr, title); 411 break; 412 413 case HTML: 414 reporter = new HtmlReporter(repstr, title); 415 break; 416 417 case XML: 418 reporter = new XmlReporter(repstr, title); 419 break; 420 421 default: 422 die("Error: unrecognized format type"); 423 } 424 } 425 426 /** 427 * Run benchmarks. 428 */ 429 static void runBenchmarks() { 430 harness.runBenchmarks(reporter, verbose); 431 } 432} 433 434