1 18 19 package org.apache.jmeter; 20 21 import java.awt.event.ActionEvent ; 22 import java.io.File ; 23 import java.io.FileInputStream ; 24 import java.io.FileNotFoundException ; 25 import java.io.IOException ; 26 import java.net.Authenticator ; 27 import java.util.Iterator ; 28 import java.util.LinkedList ; 29 import java.util.List ; 30 import java.util.Properties ; 31 32 import org.apache.commons.cli.avalon.CLArgsParser; 33 import org.apache.commons.cli.avalon.CLOption; 34 import org.apache.commons.cli.avalon.CLOptionDescriptor; 35 import org.apache.commons.cli.avalon.CLUtil; 36 import org.apache.jmeter.config.gui.AbstractConfigGui; 37 import org.apache.jmeter.control.gui.AbstractControllerGui; 38 import org.apache.jmeter.control.gui.TestPlanGui; 39 import org.apache.jmeter.control.gui.WorkBenchGui; 40 import org.apache.jmeter.engine.ClientJMeterEngine; 41 import org.apache.jmeter.engine.JMeterEngine; 42 import org.apache.jmeter.engine.RemoteJMeterEngineImpl; 43 import org.apache.jmeter.engine.StandardJMeterEngine; 44 import org.apache.jmeter.engine.event.LoopIterationEvent; 45 import org.apache.jmeter.exceptions.IllegalUserActionException; 46 import org.apache.jmeter.gui.GuiPackage; 47 import org.apache.jmeter.gui.action.ActionRouter; 48 import org.apache.jmeter.gui.action.CheckDirty; 49 import org.apache.jmeter.gui.action.Load; 50 import org.apache.jmeter.gui.tree.JMeterTreeListener; 51 import org.apache.jmeter.gui.tree.JMeterTreeModel; 52 import org.apache.jmeter.plugin.JMeterPlugin; 53 import org.apache.jmeter.plugin.PluginManager; 54 import org.apache.jmeter.processor.gui.AbstractPostProcessorGui; 55 import org.apache.jmeter.processor.gui.AbstractPreProcessorGui; 56 import org.apache.jmeter.reporters.ResultCollector; 57 import org.apache.jmeter.reporters.Summariser; 58 import org.apache.jmeter.samplers.Remoteable; 59 import org.apache.jmeter.samplers.gui.AbstractSamplerGui; 60 import org.apache.jmeter.save.SaveService; 61 import org.apache.jmeter.testelement.TestElement; 62 import org.apache.jmeter.testelement.TestListener; 63 import org.apache.jmeter.testelement.property.NullProperty; 64 import org.apache.jmeter.threads.gui.ThreadGroupGui; 65 import org.apache.jmeter.timers.gui.AbstractTimerGui; 66 import org.apache.jmeter.util.BeanShellServer; 67 import org.apache.jmeter.util.JMeterUtils; 68 import org.apache.jmeter.visualizers.gui.AbstractVisualizer; 69 import org.apache.jorphan.collections.HashTree; 70 import org.apache.jorphan.gui.ComponentUtil; 71 import org.apache.jorphan.logging.LoggingManager; 72 import org.apache.log.Logger; 73 74 78 public class JMeter implements JMeterPlugin 79 { 80 transient private static Logger log = LoggingManager.getLoggerForClass(); 81 82 private static final int PROPFILE_OPT = 'p'; 83 private static final int PROPFILE2_OPT = 'q'; private static final int TESTFILE_OPT = 't'; 85 private static final int LOGFILE_OPT = 'l'; 86 private static final int NONGUI_OPT = 'n'; 87 private static final int HELP_OPT = 'h'; 88 private static final int VERSION_OPT = 'v'; 89 private static final int SERVER_OPT = 's'; 90 private static final int PROXY_HOST = 'H'; 91 private static final int PROXY_PORT = 'P'; 92 private static final int PROXY_USERNAME = 'u'; 93 private static final int PROXY_PASSWORD = 'a'; 94 private static final int JMETER_PROPERTY = 'J'; 95 private static final int SYSTEM_PROPERTY = 'D'; 96 private static final int LOGLEVEL = 'L'; 97 private static final int REMOTE_OPT = 'r'; 98 private static final int JMETER_HOME_OPT = 'd'; 99 100 111 protected static final CLOptionDescriptor[] options = 112 new CLOptionDescriptor[] { 113 new CLOptionDescriptor( 114 "help", 115 CLOptionDescriptor.ARGUMENT_DISALLOWED, 116 HELP_OPT, 117 "print usage information and exit"), 118 new CLOptionDescriptor( 119 "version", 120 CLOptionDescriptor.ARGUMENT_DISALLOWED, 121 VERSION_OPT, 122 "print the version information and exit"), 123 new CLOptionDescriptor( 124 "propfile", 125 CLOptionDescriptor.ARGUMENT_REQUIRED, 126 PROPFILE_OPT, 127 "the jmeter property file to use"), 128 new CLOptionDescriptor( 129 "addprop", 130 CLOptionDescriptor.ARGUMENT_REQUIRED 131 | CLOptionDescriptor.DUPLICATES_ALLOWED, PROPFILE2_OPT, 133 "additional property file(s)"), 134 new CLOptionDescriptor( 135 "testfile", 136 CLOptionDescriptor.ARGUMENT_REQUIRED, 137 TESTFILE_OPT, 138 "the jmeter test(.jmx) file to run"), 139 new CLOptionDescriptor( 140 "logfile", 141 CLOptionDescriptor.ARGUMENT_REQUIRED, 142 LOGFILE_OPT, 143 "the file to log samples to"), 144 new CLOptionDescriptor( 145 "nongui", 146 CLOptionDescriptor.ARGUMENT_DISALLOWED, 147 NONGUI_OPT, 148 "run JMeter in nongui mode"), 149 new CLOptionDescriptor( 150 "server", 151 CLOptionDescriptor.ARGUMENT_DISALLOWED, 152 SERVER_OPT, 153 "run the JMeter server"), 154 new CLOptionDescriptor( 155 "proxyHost", 156 CLOptionDescriptor.ARGUMENT_REQUIRED, 157 PROXY_HOST, 158 "Set a proxy server for JMeter to use"), 159 new CLOptionDescriptor( 160 "proxyPort", 161 CLOptionDescriptor.ARGUMENT_REQUIRED, 162 PROXY_PORT, 163 "Set proxy server port for JMeter to use"), 164 new CLOptionDescriptor( 165 "username", 166 CLOptionDescriptor.ARGUMENT_REQUIRED, 167 PROXY_USERNAME, 168 "Set username for proxy server that JMeter is to use"), 169 new CLOptionDescriptor( 170 "password", 171 CLOptionDescriptor.ARGUMENT_REQUIRED, 172 PROXY_PASSWORD, 173 "Set password for proxy server that JMeter is to use"), 174 new CLOptionDescriptor( 175 "jmeterproperty", 176 CLOptionDescriptor.DUPLICATES_ALLOWED 177 | CLOptionDescriptor.ARGUMENTS_REQUIRED_2, 178 JMETER_PROPERTY, 179 "Define additional JMeter properties"), 180 new CLOptionDescriptor( 181 "systemproperty", 182 CLOptionDescriptor.DUPLICATES_ALLOWED 183 | CLOptionDescriptor.ARGUMENTS_REQUIRED_2, 184 SYSTEM_PROPERTY, 185 "Define additional JMeter properties"), 186 new CLOptionDescriptor( 187 "loglevel", 188 CLOptionDescriptor.DUPLICATES_ALLOWED 189 | CLOptionDescriptor.ARGUMENTS_REQUIRED_2, 190 LOGLEVEL, 191 "Define loglevel: [category=]level e.g. jorphan=INFO or " + 192 "jmeter.util=DEBUG"), 193 new CLOptionDescriptor( 194 "runremote", 195 CLOptionDescriptor.ARGUMENT_DISALLOWED, 196 REMOTE_OPT, 197 "Start remote servers from non-gui mode"), 198 new CLOptionDescriptor( 199 "homedir", 200 CLOptionDescriptor.ARGUMENT_REQUIRED, 201 JMETER_HOME_OPT, 202 "the jmeter home directory to use"), 203 }; 204 205 public JMeter() 206 { 207 } 208 209 212 public void startGui(CLOption testFile) 213 throws 214 IllegalUserActionException, 215 IllegalAccessException , 216 ClassNotFoundException , 217 InstantiationException 218 { 219 220 PluginManager.install(this, true); 221 JMeterTreeModel treeModel = new JMeterTreeModel(); 222 JMeterTreeListener treeLis = new JMeterTreeListener(treeModel); 223 treeLis.setActionHandler(ActionRouter.getInstance()); 224 GuiPackage.getInstance(treeLis, treeModel); 226 org.apache.jmeter.gui.MainFrame main = 227 new org.apache.jmeter.gui.MainFrame( 228 ActionRouter.getInstance(), 229 treeModel, 230 treeLis); 231 main.setTitle("Apache JMeter"); 232 main.setIconImage(JMeterUtils.getImage("jmeter.jpg").getImage()); 233 ComponentUtil.centerComponentInWindow(main, 80); 234 main.show(); 235 ActionRouter.getInstance().actionPerformed( 236 new ActionEvent (main, 1, CheckDirty.ADD_ALL)); 237 if (testFile != null) 238 { 239 try 240 { 241 File f = new File (testFile.getArgument()); 242 log.info("Loading file: " + f); 243 FileInputStream reader = new FileInputStream (f); 244 HashTree tree = SaveService.loadSubTree(reader); 245 new Load().insertLoadedTree(1, tree); 246 } 247 catch (Exception e) 248 { 249 log.error("Failure loading test file", e); 250 } 251 } 252 } 253 254 258 public void start(String [] args) 259 { 260 261 CLArgsParser parser = new CLArgsParser(args, options); 262 if (null != parser.getErrorString()) 263 { 264 System.err.println("Error: " + parser.getErrorString()); 265 System.out.println("Usage"); 266 System.out.println(CLUtil.describeOptions(options).toString()); 267 return; 268 } 269 try 270 { 271 initializeProperties(parser); 272 setProxy(parser); 273 log.info("Version " + JMeterUtils.getJMeterVersion()); 274 log.info("java.version="+System.getProperty("java.version")); 275 log.info(JMeterUtils.getJMeterCopyright()); 276 if (parser.getArgumentById(VERSION_OPT) != null) 277 { 278 System.out.println(JMeterUtils.getJMeterCopyright()); 279 System.out.println("Version " + JMeterUtils.getJMeterVersion()); 280 } 281 else if (parser.getArgumentById(HELP_OPT) != null) 282 { 283 System.out.println( 284 JMeterUtils.getResourceFileAsText( 285 "org/apache/jmeter/help.txt")); 286 } 287 else if (parser.getArgumentById(SERVER_OPT) != null) 288 { 289 startServer(); 290 startBSH(); 291 } 292 else if (parser.getArgumentById(NONGUI_OPT) == null) 293 { 294 startGui(parser.getArgumentById(TESTFILE_OPT)); 295 startBSH(); 296 } 297 else 298 { 299 startNonGui( 300 parser.getArgumentById(TESTFILE_OPT), 301 parser.getArgumentById(LOGFILE_OPT), 302 parser.getArgumentById(REMOTE_OPT)); 303 startBSH(); 304 } 305 } 306 catch (IllegalUserActionException e) 307 { 308 System.out.println(e.getMessage()); 309 System.out.println("Incorrect Usage"); 310 System.out.println(CLUtil.describeOptions(options).toString()); 311 } 312 catch (Exception e) 313 { 314 e.printStackTrace(); 315 System.out.println("An error occurred: " + e.getMessage()); 316 System.exit(-1); 317 } 318 } 319 320 323 private void startBSH() { 324 int bshport = JMeterUtils.getPropDefault("beanshell.server.port",0); 325 String bshfile = JMeterUtils.getPropDefault("beanshell.server.file",""); 326 if (bshport > 0 ){ 327 log.info("Starting Beanshell server ("+bshport+","+bshfile+")"); 328 Runnable t = new BeanShellServer(bshport,bshfile); 329 t.run(); 330 } 331 } 332 333 337 private void setProxy(CLArgsParser parser) 338 throws IllegalUserActionException 339 { 340 if (parser.getArgumentById(PROXY_USERNAME) != null) 341 { 342 if (parser.getArgumentById(PROXY_PASSWORD) != null) 343 { 344 String u,p; 345 Authenticator.setDefault( 346 new ProxyAuthenticator( 347 u=parser.getArgumentById(PROXY_USERNAME).getArgument(), 348 p=parser.getArgumentById(PROXY_PASSWORD).getArgument())); 349 log.info("Set Proxy login: "+u+"/"+p); 350 } 351 else 352 { 353 String u; 354 Authenticator.setDefault( 355 new ProxyAuthenticator( 356 u=parser.getArgumentById(PROXY_USERNAME).getArgument(), 357 "")); 358 log.info("Set Proxy login: "+u); 359 } 360 } 361 if (parser.getArgumentById(PROXY_HOST) != null 362 && parser.getArgumentById(PROXY_PORT) != null) 363 { 364 String h,p; 365 System.setProperty( 366 "http.proxyHost", 367 h=parser.getArgumentById(PROXY_HOST).getArgument()); 368 System.setProperty( 369 "https.proxyHost", 370 parser.getArgumentById(PROXY_HOST).getArgument()); 371 System.setProperty( 372 "http.proxyPort", 373 p=parser.getArgumentById(PROXY_PORT).getArgument()); 374 System.setProperty( 375 "https.proxyPort", 376 parser.getArgumentById(PROXY_PORT).getArgument()); 377 log.info("Set http[s].proxyHost: "+h+" Port: "+p); 378 } 379 else if ( 380 parser.getArgumentById(PROXY_HOST) != null 381 || parser.getArgumentById(PROXY_PORT) != null) 382 { 383 throw new IllegalUserActionException( 384 JMeterUtils.getResString("proxy_cl_error")); 385 } 386 } 387 388 private void initializeProperties(CLArgsParser parser) 389 { 390 if (parser.getArgumentById(PROPFILE_OPT) != null) 391 { 392 JMeterUtils.getProperties( 393 parser.getArgumentById(PROPFILE_OPT).getArgument()); 394 } 395 else 396 { 397 JMeterUtils.getProperties( 398 NewDriver.getJMeterDir() 399 + File.separator 400 + "bin" 401 + File.separator 402 + "jmeter.properties"); 403 } 404 405 if (parser.getArgumentById(JMETER_HOME_OPT) == null) { 407 JMeterUtils.setJMeterHome(NewDriver.getJMeterDir()); 408 } else { 409 JMeterUtils.setJMeterHome(parser.getArgumentById(JMETER_HOME_OPT).getArgument()); 410 } 411 412 414 Properties jmeterProps = JMeterUtils.getJMeterProperties(); 415 List clOptions = parser.getArguments(); 416 int size = clOptions.size(); 417 418 for (int i = 0; i < size; i++) 419 { 420 CLOption option = (CLOption) clOptions.get(i); 421 String name = option.getArgument(0); 422 String value = option.getArgument(1); 423 424 switch (option.getDescriptor().getId()) 425 { 426 case PROPFILE2_OPT : File f = new File (name); 428 try { 429 jmeterProps.load(new FileInputStream (f)); 430 } catch (FileNotFoundException e) { 431 log.warn("Can't find additional property file: "+name,e); 432 } catch (IOException e) { 433 log.warn("Error loading additional property file: "+name,e); 434 } 435 break; 436 case SYSTEM_PROPERTY : 437 if (value.length() > 0) 438 { log.info( 440 "Setting System property: " + name + "=" + value); 441 System.getProperties().setProperty(name, value); 442 } 443 else 444 { log.warn("Removing System property: " + name); 446 System.getProperties().remove(name); 447 } 448 break; 449 case JMETER_PROPERTY : 450 if (value.length() > 0) 451 { log.info( 453 "Setting JMeter property: " + name + "=" + value); 454 jmeterProps.setProperty(name, value); 455 } 456 else 457 { log.warn("Removing JMeter property: " + name); 459 jmeterProps.remove(name); 460 } 461 break; 462 case LOGLEVEL : 463 if (value.length() > 0) 464 { log.info("LogLevel: " + name + "=" + value); 466 LoggingManager.setPriority(value, name); 467 } 468 else 469 { log.warn("LogLevel: " + name); 471 LoggingManager.setPriority(name); 472 } 473 break; 474 } 475 } 476 477 } 478 479 public void startServer() 480 { 481 try 482 { 483 new RemoteJMeterEngineImpl(); 484 while (true) 485 { 486 Thread.sleep(Long.MAX_VALUE); 487 } 488 } 489 catch (Exception ex) 490 { 491 log.error("Giving up, as server failed with:", ex); 492 System.exit(0); } 494 } 495 496 public void startNonGui( 497 CLOption testFile, 498 CLOption logFile, 499 CLOption remoteStart) 500 throws 501 IllegalUserActionException, 502 IllegalAccessException , 503 ClassNotFoundException , 504 InstantiationException 505 { 506 System.setProperty("JMeter.NonGui","true"); 509 JMeter driver = new JMeter(); 510 PluginManager.install(this, false); 511 512 if (testFile == null) 513 { 514 throw new IllegalUserActionException(); 515 } 516 if (logFile == null) 517 { 518 driver.run(testFile.getArgument(), null, remoteStart != null); 519 } 520 else 521 { 522 driver.run( 523 testFile.getArgument(), 524 logFile.getArgument(), 525 remoteStart != null); 526 } 527 } 528 529 private void run(String testFile, String logFile, boolean remoteStart) 530 { FileInputStream reader = null; 532 try 533 { 534 File f = new File (testFile); 535 if (!f.exists() || !f.isFile()) 536 { 537 println("Could not open " + testFile); 538 return; 539 } 540 541 reader = new FileInputStream (f); 542 log.info("Loading file: " + f); 543 544 HashTree tree = SaveService.loadSubTree(reader); 545 546 convertSubTree(tree); 549 550 if (logFile != null) 551 { 552 ResultCollector logger = new ResultCollector(); 553 logger.setFilename(logFile); 554 tree.add(tree.getArray()[0], logger); 555 } 556 String summariserName= 557 JMeterUtils.getPropDefault("summariser.name",""); if (summariserName.length() > 0){ 559 log.info("Creating summariser <"+summariserName+">"); 560 println( "Creating summariser <"+summariserName+">"); 561 Summariser summer=new Summariser(summariserName); 562 tree.add(tree.getArray()[0], summer); 563 } 564 tree.add(tree.getArray()[0], new ListenToTest()); 565 println("Created the tree successfully"); 566 JMeterEngine engine = null; 567 if (!remoteStart) 568 { 569 engine = new StandardJMeterEngine(); 570 engine.configure(tree); 571 println("Starting the test"); 572 engine.runTest(); 573 } 574 else 575 { 576 String remote_hosts_string = 577 JMeterUtils.getPropDefault("remote_hosts", "127.0.0.1"); 578 java.util.StringTokenizer st = 579 new java.util.StringTokenizer (remote_hosts_string, ","); 580 List engines = new LinkedList (); 581 while (st.hasMoreElements()) 582 { 583 String el = (String ) st.nextElement(); 584 println("Configuring remote engine for "+el); 585 engines.add(doRemoteInit(el.trim(), tree)); 586 } 587 println("Starting remote engines"); 588 Iterator iter = engines.iterator(); 589 while (iter.hasNext()) 590 { 591 engine = (JMeterEngine) iter.next(); 592 engine.runTest(); 593 } 594 println("Remote engines have been started"); 595 } 596 } 597 catch (Exception e) 598 { 599 System.out.println("Error in NonGUIDriver " + e.toString()); 600 log.error("", e); 601 } 602 } 603 604 private boolean isEnabled(TestElement te){ return 606 te.getProperty(TestElement.ENABLED) instanceof NullProperty 607 || 608 te.getPropertyAsBoolean(TestElement.ENABLED); 609 } 610 611 615 private void convertSubTree(HashTree tree) { Iterator iter = new LinkedList (tree.list()).iterator(); 617 while (iter.hasNext()) 618 { 619 TestElement item = (TestElement) iter.next(); 620 if (isEnabled(item)) 621 { { 638 convertSubTree(tree.getTree(item)); 640 } 643 } 644 else 645 { 646 tree.remove(item); 648 } 649 } 650 } 651 652 private JMeterEngine doRemoteInit(String hostName, HashTree testTree) 653 { 654 JMeterEngine engine = null; 655 try 656 { 657 engine = new ClientJMeterEngine(hostName); 658 } 659 catch (Exception e) 660 { 661 log.fatalError("Failure connecting to remote host", e); 662 System.exit(0); 663 } 664 engine.configure(testTree); 665 return engine; 666 } 667 668 672 private class ListenToTest implements TestListener, Runnable , Remoteable 673 { 674 int started = 0; 675 public synchronized void testEnded(String host) 676 { 677 started--; 678 log.info("Remote host " + host + " finished"); 679 if (started == 0) 680 { 681 testEnded(); 682 } 683 } 684 685 public void testEnded() 686 { 687 Thread stopSoon = new Thread (this); 688 stopSoon.start(); 689 } 690 691 public synchronized void testStarted(String host) 692 { 693 started++; 694 log.info("Started remote host: " + host); 695 } 696 697 public void testStarted() 698 { 699 log.info(JMeterUtils.getResString("running_test")); 700 } 701 702 709 public void run() 710 { 711 println("Tidying up ..."); 712 try 713 { 714 Thread.sleep(5000); 715 } 716 catch (InterruptedException e) 717 { 718 } 719 println("... end of run"); 720 System.exit(0); 721 } 722 725 public void testIterationStart(LoopIterationEvent event) 726 { 727 } 728 } 729 730 private static void println(String str) 731 { 732 System.out.println(str); 733 } 734 735 public String [][] getIconMappings() 736 { 737 return new String [][] { 738 { 739 TestPlanGui.class.getName(), 740 "org/apache/jmeter/images/beaker.gif" }, 741 { 742 AbstractTimerGui.class.getName(), 743 "org/apache/jmeter/images/timer.gif" }, 744 { 745 ThreadGroupGui.class.getName(), 746 "org/apache/jmeter/images/thread.gif" }, 747 { 748 AbstractVisualizer.class.getName(), 749 "org/apache/jmeter/images/meter.png" }, 750 { 751 AbstractConfigGui.class.getName(), 752 "org/apache/jmeter/images/testtubes.png" }, 753 { 754 AbstractPreProcessorGui.class.getName(), 755 "org/apache/jmeter/images/testtubes.gif" }, 756 { 757 AbstractPostProcessorGui.class.getName(), 758 "org/apache/jmeter/images/testtubes.gif" }, 759 { 760 AbstractControllerGui.class.getName(), 761 "org/apache/jmeter/images/knob.gif" }, 762 { 763 WorkBenchGui.class.getName(), 764 "org/apache/jmeter/images/clipboard.gif" }, 765 { 766 AbstractSamplerGui.class.getName(), 767 "org/apache/jmeter/images/pipet.png" } 768 }; 769 } 770 771 public String [][] getResourceBundles() 772 { 773 return new String [0][]; 774 } 775 } | Popular Tags |