You are viewing a plain text version of this content. The canonical link for it is here.
Posted to jmeter-dev@jakarta.apache.org by ms...@apache.org on 2002/04/30 04:41:32 UTC

cvs commit: jakarta-jmeter/xdocs/usermanual boss.xml

mstover1    02/04/29 19:41:32

  Modified:    docs     running.html
               docs/usermanual boss.html
               src_1/org/apache/jmeter/engine StandardJMeterEngine.java
               src_1/org/apache/jmeter/gui/util FilePanel.java
               src_1/org/apache/jmeter/reporters ResultCollector.java
               src_1/org/apache/jmeter/threads JMeterThread.java
               src_1/org/apache/jmeter/util SearchByClass.java
               src_1/org/apache/jmeter/visualizers/gui
                        AbstractVisualizer.java
               xdocs/stylesheets site.vsl
               xdocs/usermanual boss.xml
  Log:
  GraphVisualizer saves all results to file
  fixed problems with anakia
  
  Revision  Changes    Path
  1.39      +0 -0      jakarta-jmeter/docs/running.html
  
  Index: running.html
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/docs/running.html,v
  retrieving revision 1.38
  retrieving revision 1.39
  diff -u -r1.38 -r1.39
  --- running.html	14 Mar 2002 00:59:16 -0000	1.38
  +++ running.html	30 Apr 2002 02:41:32 -0000	1.39
  @@ -243,7 +243,7 @@
   												<br	>
   						</br>
   									
  -$Id: running.html,v 1.38 2002/03/14 00:59:16 mstover1 Exp $
  +$Id: running.html,v 1.39 2002/04/30 02:41:32 mstover1 Exp $
   						</font>
   									 
   												<br	>
  
  
  
  1.12      +406 -2    jakarta-jmeter/docs/usermanual/boss.html
  
  Index: boss.html
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/docs/usermanual/boss.html,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- boss.html	7 Mar 2002 23:03:12 -0000	1.11
  +++ boss.html	30 Apr 2002 02:41:32 -0000	1.12
  @@ -11,7 +11,9 @@
   		  <head>
   				<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
   
  -								
  +													 				<meta name="author" value="Martin Ramshaw">
  +				<meta name="email" value="$au.getAttributeValue("email")">
  +				
   				<title>JMeter - User's Manual: My boss wants me to...</title>
   		  </head>
   
  @@ -74,8 +76,410 @@
   		<tr><td>
   		  <blockquote>
   		  									 				<p	>
  -								To be written.
  +								This is a fairly open-ended proposition. There are a number of questions to
  +be asked first, and additionally a number of resources that will be needed. You
  +will need some hardware to run the benchmarks/load-tests from. A number of
  +tools will prove useful. There are a number of products to consider.  And finally,
  +why is Java a good choice to implement a load-testing/Benchmarking product.
  +
  +						</p>
  +							  									 			 	 <table border="0" cellspacing="0" cellpadding="2" width="100%">
  +		<tr><td bgcolor="#828DA6">
  +		  <font color="#ffffff" face="arial,helvetica,sanserif">
  +			 <a name="$subsection.getAttributeValue("anchor")"><strong>12.1 Questions to ask</strong></a>
  +		  </font>
  +		</td></tr>
  +		<tr><td>
  +		  <blockquote>
  +		  									 				<p	>
  +								What is our anticipated average number of users (normal load) ?
  +
  +						</p>
  +							  									 				<p	>
  +								What is our anticipated peak number of users ?
  +
  +						</p>
  +							  									 				<p	>
  +								When is a good time to load-test our application (i.e. off-hours or week-ends),
  +bearing in mind that this may very well crash one or more of our servers ?
  +
  +						</p>
  +							  									 				<p	>
  +								Does our application have state ? If so, how does our application manage it
  +(cookies, session-rewriting, or some other method) ?
  +
  +						</p>
  +							  		  </blockquote>
  +		</td></tr>
  +		<tr><td><br/></td></tr>
  +	 </table>
  +							  									 			 	 <table border="0" cellspacing="0" cellpadding="2" width="100%">
  +		<tr><td bgcolor="#828DA6">
  +		  <font color="#ffffff" face="arial,helvetica,sanserif">
  +			 <a name="$subsection.getAttributeValue("anchor")"><strong>12.2 Resources</strong></a>
  +		  </font>
  +		</td></tr>
  +		<tr><td>
  +		  <blockquote>
  +		  									 				<p	>
  +								The following resources will prove very helpful. Bear in mind that if you
  +cannot locate these resources, 
  +												<b	>
  +								you
  +						</b>
  +									 will become these resources. As you
  +already have your work cut out for you, it is worth knowing who the following
  +people are, so that you can ask them for help if you need it.
  +
  +						</p>
  +							  									 			 	 <table border="0" cellspacing="0" cellpadding="2" width="100%">
  +		<tr><td bgcolor="#828DA6">
  +		  <font color="#ffffff" face="arial,helvetica,sanserif">
  +			 <a name="$subsection.getAttributeValue("anchor")"><strong>12.2.1 Network</strong></a>
  +		  </font>
  +		</td></tr>
  +		<tr><td>
  +		  <blockquote>
  +		  									 				<p	>
  +								Who knows our network topology ? If you run into any firewall or
  +	proxy issues, this will become very important. As well, a private
  +	testing network (which will therefore have very low network latency)
  +	would be a very nice thing. Knowing who can set one up for you
  +	(if you feel that this is necessary) will be very useful. If the
  +	application doesn't scale as expected, who can add additional
  +	hardware ?
  +	
  +						</p>
  +							  		  </blockquote>
  +		</td></tr>
  +		<tr><td><br/></td></tr>
  +	 </table>
  +							  									 			 	 <table border="0" cellspacing="0" cellpadding="2" width="100%">
  +		<tr><td bgcolor="#828DA6">
  +		  <font color="#ffffff" face="arial,helvetica,sanserif">
  +			 <a name="$subsection.getAttributeValue("anchor")"><strong>12.2.2 Application</strong></a>
  +		  </font>
  +		</td></tr>
  +		<tr><td>
  +		  <blockquote>
  +		  									 				<p	>
  +								Who knows how our application functions ? The normal sequence is
  +	
  +												<ul	>
  +								
  +		
  +												<li	>
  +								test (low-volume - can we benchmark our application?)
  +						</li>
  +									
  +		
  +												<li	>
  +								benchmark (the average number of users)
  +						</li>
  +									
  +		
  +												<li	>
  +								load-test (the maximum number of users)
  +						</li>
  +									
  +		
  +												<li	>
  +								test destructively (what is our hard limit?)
  +						</li>
  +									
  +	
  +						</ul>
  +									
  +	The 
  +												<b	>
  +								test
  +						</b>
  +									 process may progress from black-box testing to
  +	white-box testing (the difference is that the first requires
  +	no knowledge of the application [it is treated as a "black box"]
  +	while the second requires some knowledge of the application).
  +	It is not uncommon to discover problems with the application
  +	during this process, so be prepared to defend your work.
  +	
  +						</p>
  +							  		  </blockquote>
  +		</td></tr>
  +		<tr><td><br/></td></tr>
  +	 </table>
  +							  		  </blockquote>
  +		</td></tr>
  +		<tr><td><br/></td></tr>
  +	 </table>
  +							  									 			 	 <table border="0" cellspacing="0" cellpadding="2" width="100%">
  +		<tr><td bgcolor="#828DA6">
  +		  <font color="#ffffff" face="arial,helvetica,sanserif">
  +			 <a name="$subsection.getAttributeValue("anchor")"><strong>12.3 What platform should I use to run the benchmarks/load-tests ?</strong></a>
  +		  </font>
  +		</td></tr>
  +		<tr><td>
  +		  <blockquote>
  +		  									 				<p	>
  +								This should be a widely-used piece of hardware, with a standard
  +(i.e. vanilla) software installation. Remember, if you publish your results,
  +the first thing your clients will do is hire a graduate student to verify them.
  +You might as well make it as easy for this person as you possibly can.
  +
  +						</p>
  +							  									 				<p	>
  +								For Windows, Windows XP Professional should be a minimum (the others
  +do not multi-thread past 50-60 connections, and you probably anticipate
  +more users than that).
  +
  +						</p>
  +							  									 				<p	>
  +								Good free platforms include the linuxes, the BSDs, and Solaris Intel. If
  +you have a little more money, there are commercial linuxes. If you can justify
  +it, a commercial Unix (Solaris, etc) is probably the best choice.
  +
  +						</p>
  +							  									 				<p	>
  +								
  +For non-Windows platforms, investigate "umount -n unlimited" with a view to
  +including it in your user account startup scripts (.bashrc or .cshrc scripts
  +for the testing account).
  +
  +						</p>
  +							  									 				<p	>
  +								As you progress to larger-scale benchmarks/load-tests, this platform
  +will become the limiting factor. So it's worth using the best hardware and
  +software that you have available. Remember to include the hardware/software
  +configuration in your published benchmarks.
  +
  +						</p>
  +							  		  </blockquote>
  +		</td></tr>
  +		<tr><td><br/></td></tr>
  +	 </table>
  +							  									 			 	 <table border="0" cellspacing="0" cellpadding="2" width="100%">
  +		<tr><td bgcolor="#828DA6">
  +		  <font color="#ffffff" face="arial,helvetica,sanserif">
  +			 <a name="$subsection.getAttributeValue("anchor")"><strong>12.4 Tools</strong></a>
  +		  </font>
  +		</td></tr>
  +		<tr><td>
  +		  <blockquote>
  +		  									 				<p	>
  +								The following tools will all prove useful. It is definitely worthwhile to
  +become familiar with them. This should include trying them out, and reading the
  +appropriate documentation (man-pages, info-files, application --help messages,
  +and any supplied documentation).
  +
  +						</p>
  +							  									 			 	 <table border="0" cellspacing="0" cellpadding="2" width="100%">
  +		<tr><td bgcolor="#828DA6">
  +		  <font color="#ffffff" face="arial,helvetica,sanserif">
  +			 <a name="$subsection.getAttributeValue("anchor")"><strong>12.4.1 ping</strong></a>
  +		  </font>
  +		</td></tr>
  +		<tr><td>
  +		  <blockquote>
  +		  									 				<p	>
  +								
  +	This can be used to establish whether or not you can reach your
  +	target site.
  +	
  +						</p>
  +							  		  </blockquote>
  +		</td></tr>
  +		<tr><td><br/></td></tr>
  +	 </table>
  +							  									 			 	 <table border="0" cellspacing="0" cellpadding="2" width="100%">
  +		<tr><td bgcolor="#828DA6">
  +		  <font color="#ffffff" face="arial,helvetica,sanserif">
  +			 <a name="$subsection.getAttributeValue("anchor")"><strong>12.4.2 nslookup</strong></a>
  +		  </font>
  +		</td></tr>
  +		<tr><td>
  +		  <blockquote>
  +		  									 				<p	>
  +								
  +	While the 
  +												<u	>
  +								user
  +						</u>
  +									 will normally use a human-readable internet
  +	address, 
  +												<u	>
  +								you
  +						</u>
  +									 may wish to avoid the overhead of DNS lookups when
  +	performing benchmarking/load-testing. This can be used to determine
  +	the unique address (dotted quad) of your target site.
  +	
  +						</p>
  +							  		  </blockquote>
  +		</td></tr>
  +		<tr><td><br/></td></tr>
  +	 </table>
  +							  									 			 	 <table border="0" cellspacing="0" cellpadding="2" width="100%">
  +		<tr><td bgcolor="#828DA6">
  +		  <font color="#ffffff" face="arial,helvetica,sanserif">
  +			 <a name="$subsection.getAttributeValue("anchor")"><strong>12.4.3 traceroute</strong></a>
  +		  </font>
  +		</td></tr>
  +		<tr><td>
  +		  <blockquote>
  +		  									 				<p	>
  +								
  +	If you cannot "ping" your target site, this may be used to determine 
  +	the problem (possibly a firewall or a proxy). It can also be used
  +	to estimate the overall network latency (running locally should give
  +	the lowest possible network latency - remember that your users will
  +	be running over a possibly busy internet). Generally, the fewer hops
  +	the better.
  +	
  +						</p>
  +							  		  </blockquote>
  +		</td></tr>
  +		<tr><td><br/></td></tr>
  +	 </table>
  +							  		  </blockquote>
  +		</td></tr>
  +		<tr><td><br/></td></tr>
  +	 </table>
  +							  									 			 	 <table border="0" cellspacing="0" cellpadding="2" width="100%">
  +		<tr><td bgcolor="#828DA6">
  +		  <font color="#ffffff" face="arial,helvetica,sanserif">
  +			 <a name="$subsection.getAttributeValue("anchor")"><strong>12.5 What other products are there ?</strong></a>
  +		  </font>
  +		</td></tr>
  +		<tr><td>
  +		  <blockquote>
  +		  									 				<p	>
  +								There are a number of commercial products, which generally have fairly
  +hefty pricetags. If you can justify it, these are probably the way to go.
  +If, however, these products do not do exactly what you want, or you are on a
  +limited budget, the following are worth a look. In fact, you should probably
  +start by trying the Apache 
  +												<b	>
  +								ab
  +						</b>
  +									 tool, as it may very well do the job
  +if your requirements are not particularly complicated.
  +
  +						</p>
  +							  									 			 	 <table border="0" cellspacing="0" cellpadding="2" width="100%">
  +		<tr><td bgcolor="#828DA6">
  +		  <font color="#ffffff" face="arial,helvetica,sanserif">
  +			 <a name="$subsection.getAttributeValue("anchor")"><strong>12.5.1 Apache 'ab' tool</strong></a>
  +		  </font>
  +		</td></tr>
  +		<tr><td>
  +		  <blockquote>
  +		  									 				<p	>
  +								
  +	You should definitely start with this one. It handles HTTP 'get' requests
  +	very well, and can be made to handle HTTP 'post' requests with a little
  +	effort. Written in 'C', it performs very well, and offers good (if basic)
  +	performance reporting.
  +	
   						</p>
  +							  		  </blockquote>
  +		</td></tr>
  +		<tr><td><br/></td></tr>
  +	 </table>
  +							  									 			 	 <table border="0" cellspacing="0" cellpadding="2" width="100%">
  +		<tr><td bgcolor="#828DA6">
  +		  <font color="#ffffff" face="arial,helvetica,sanserif">
  +			 <a name="$subsection.getAttributeValue("anchor")"><strong>12.5.2 Microsoft WAS</strong></a>
  +		  </font>
  +		</td></tr>
  +		<tr><td>
  +		  <blockquote>
  +		  									 				<p	>
  +								
  +	This is definitely worth a look. It has an excellent user interface
  +	but it may not do exactly what you want. If this is the case, be aware
  +	that the functionality of this product is not likely to change.
  +	
  +						</p>
  +							  		  </blockquote>
  +		</td></tr>
  +		<tr><td><br/></td></tr>
  +	 </table>
  +							  									 			 	 <table border="0" cellspacing="0" cellpadding="2" width="100%">
  +		<tr><td bgcolor="#828DA6">
  +		  <font color="#ffffff" face="arial,helvetica,sanserif">
  +			 <a name="$subsection.getAttributeValue("anchor")"><strong>12.5.3 JMeter</strong></a>
  +		  </font>
  +		</td></tr>
  +		<tr><td>
  +		  <blockquote>
  +		  									 				<p	>
  +								
  +	If you have non-standard requirements, then this solution offers an
  +	open-source community to provide them (of course, if you are reading
  +	
  +												<u	>
  +								this
  +						</u>
  +									, you are probably already committed to this one). This
  +	product is free to evolve along with your requirements.
  +	
  +						</p>
  +							  		  </blockquote>
  +		</td></tr>
  +		<tr><td><br/></td></tr>
  +	 </table>
  +							  		  </blockquote>
  +		</td></tr>
  +		<tr><td><br/></td></tr>
  +	 </table>
  +							  									 			 	 <table border="0" cellspacing="0" cellpadding="2" width="100%">
  +		<tr><td bgcolor="#828DA6">
  +		  <font color="#ffffff" face="arial,helvetica,sanserif">
  +			 <a name="$subsection.getAttributeValue("anchor")"><strong>12.6 Why Java ?</strong></a>
  +		  </font>
  +		</td></tr>
  +		<tr><td>
  +		  <blockquote>
  +		  									 				<p	>
  +								Why not Perl or C ?
  +
  +						</p>
  +							  									 				<p	>
  +								Well, Perl might be a very good choice except that the Benchmark package
  +seems to give fairly fuzzy results. Also, simulating multiple users with
  +Perl is a tricky proposition (multiple connections can be simulated by forking
  +many processes from a shell script, but these will not be threads, they will
  +be processes). However, the Perl community is very large. If you find that
  +someone has already written something that seems useful, this could be a very
  +good solution.
  +
  +						</p>
  +							  									 				<p	>
  +								C, of course, is a very good choice (check out the Apache 
  +												<b	>
  +								ab
  +						</b>
  +									 tool).
  +But be prepared to write all of the custom networking, threading, and state
  +management code that you will need to benchmark your application.
  +
  +						</p>
  +							  									 				<p	>
  +								Java gives you (for free) the custom networking, threading, and state
  +management code that you will need to benchmark your application. Java is
  +aware of HTTP, FTP, and HTTPS - as well as RMI, IIOP, and JDBC (not to mention
  +cookies, URL-encoding, and URL-rewriting). In addition Java gives you automatic
  +garbage-collection, and byte-code level security.
  +
  +						</p>
  +							  									 				<p	>
  +								And once Microsoft moves to a CLR (common language run-time) a Windows Java
  +solution will not be any slower than any other type of solution on the Windows
  +platform.
  +
  +						</p>
  +							  		  </blockquote>
  +		</td></tr>
  +		<tr><td><br/></td></tr>
  +	 </table>
   							  		  </blockquote>
   		  </p>
   		</td></tr>
  
  
  
  1.3       +40 -8     jakarta-jmeter/src_1/org/apache/jmeter/engine/StandardJMeterEngine.java
  
  Index: StandardJMeterEngine.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src_1/org/apache/jmeter/engine/StandardJMeterEngine.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- StandardJMeterEngine.java	29 Apr 2002 17:08:07 -0000	1.2
  +++ StandardJMeterEngine.java	30 Apr 2002 02:41:32 -0000	1.3
  @@ -62,26 +62,29 @@
   import org.apache.jmeter.util.ListedHashTree;
   import org.apache.jmeter.util.SearchByClass;
   import org.apache.jmeter.threads.TestCompiler;
  +import org.apache.jmeter.testelement.TestListener;
  +import org.apache.jmeter.threads.JMeterThreadMonitor;
   
   /************************************************************
    *  !ToDo (Class description)
    *
    *@author     $Author: mstover1 $
  - *@created    $Date: 2002/04/29 17:08:07 $
  - *@version    $Revision: 1.2 $
  + *@created    $Date: 2002/04/30 02:41:32 $
  + *@version    $Revision: 1.3 $
    ***********************************************************/
  -public class StandardJMeterEngine implements JMeterEngine
  +public class StandardJMeterEngine implements JMeterEngine,JMeterThreadMonitor
   {
  -	Collection allThreads;
  +	Set allThreads;
   	boolean running = false;
   	ListedHashTree test;
  +	SearchByClass testListeners;
   
   	/************************************************************
   	 *  !ToDo (Constructor description)
   	 ***********************************************************/
   	public StandardJMeterEngine()
   	{
  -		allThreads = new LinkedList();
  +		allThreads = new HashSet();
   	}
   
   	public void configure(ListedHashTree testTree)
  @@ -102,6 +105,8 @@
   		System.out.println("Running the test!");
   		running = true;
   		SearchByClass searcher = new SearchByClass(ThreadGroup.class);
  +		testListeners = new SearchByClass(TestListener.class);
  +		getTestTree().traverse(testListeners);
   		getTestTree().traverse(searcher);
   		TestCompiler.initialize();
   		//for each thread group, generate threads
  @@ -110,13 +115,14 @@
   		JMeterThread[] threads;
   		Iterator iter = searcher.getSearchResults().iterator();
   		System.out.println("found " + searcher.getSearchResults().size() + " threadgroups");
  +		notifyTestListenersOfStart();
   		while(iter.hasNext())
   		{
   			ThreadGroup group = (ThreadGroup)iter.next();
   			threads = new JMeterThread[group.getNumThreads()];
   			for(int i = 0; i < threads.length; i++)
   			{
  -				threads[i] = new JMeterThread(cloneTree(searcher.getSubTree(group)));
  +				threads[i] = new JMeterThread(cloneTree(searcher.getSubTree(group)),this);
   				threads[i].setInitialDelay((int)(((float)(group.getRampUp() * 1000) /
   						(float)group.getNumThreads()) * (float)i));
   				Thread newThread = new Thread(threads[i]);
  @@ -125,6 +131,24 @@
   			}
   		}
   	}
  +	
  +	protected void notifyTestListenersOfStart()
  +	{
  +		Iterator iter = testListeners.getSearchResults().iterator();
  +		while(iter.hasNext())
  +		{
  +			((TestListener)iter.next()).testStarted();
  +		}
  +	}
  +	
  +	protected void notifyTestListenersOfEnd()
  +	{
  +		Iterator iter = testListeners.getSearchResults().iterator();
  +		while(iter.hasNext())
  +		{
  +			((TestListener)iter.next()).testEnded();
  +		}
  +	}
   
   	private ListedHashTree cloneTree(ListedHashTree tree)
   	{
  @@ -143,19 +167,27 @@
   			stopTest();
   		}
   	}
  +	
  +	public void threadFinished(JMeterThread thread)
  +	{
  +		allThreads.remove(thread);
  +		if(allThreads.size() == 0)
  +		{
  +			notifyTestListenersOfEnd();
  +		}
  +	}
   
   	/************************************************************
   	 *  !ToDo (Method description)
   	 ***********************************************************/
   	public void stopTest()
   	{
  -		Iterator iter = allThreads.iterator();
  +		Iterator iter = new HashSet(allThreads).iterator();
   		while(iter.hasNext())
   		{
   			JMeterThread item = (JMeterThread)iter.next();
   			item.stop();
   		}
  -		allThreads.clear();
   	}
   
   }
  
  
  
  1.2       +31 -2     jakarta-jmeter/src_1/org/apache/jmeter/gui/util/FilePanel.java
  
  Index: FilePanel.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src_1/org/apache/jmeter/gui/util/FilePanel.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- FilePanel.java	26 Apr 2002 00:03:55 -0000	1.1
  +++ FilePanel.java	30 Apr 2002 02:41:32 -0000	1.2
  @@ -2,6 +2,8 @@
   import javax.swing.*;
   import java.awt.event.ActionEvent;
   import java.awt.event.ActionListener;
  +import java.util.*;
  +import javax.swing.event.*;
   import org.apache.jmeter.util.JMeterUtils;
   
   /**
  @@ -19,7 +21,8 @@
   	JTextField filename = new JTextField(30);
   	JLabel label = new JLabel(JMeterUtils.getResString("file_visualizer_filename"));
   	JButton browse = new JButton(JMeterUtils.getResString("browse"));
  -
  +	List listeners = new LinkedList();
  +	
   	/**
   	 *  Constructor for the FilePanel object
   	 */
  @@ -29,6 +32,20 @@
   	}
   
   	/**
  +	 *  Constructor for the FilePanel object
  +	 */
  +	public FilePanel(ChangeListener l)
  +	{
  +		init();
  +		listeners.add(l);
  +	}
  +	
  +	public void addChangeListener(ChangeListener l)
  +	{
  +		listeners.add(l);
  +	}
  +
  +	/**
   	 *  Description of the Method
   	 */
   	private void init()
  @@ -58,6 +75,17 @@
   	{
   		filename.setText(f);
   	}
  +	
  +	private void fireFileChanged()
  +	{
  +		System.out.println("Firing state change");
  +		Iterator iter = listeners.iterator();
  +		while(iter.hasNext())
  +		{
  +			((ChangeListener)iter.next()).stateChanged(new ChangeEvent(this));
  +		}
  +	}
  +			
   
   	/**
   	 *  Description of the Method
  @@ -67,9 +95,10 @@
   	public void actionPerformed(ActionEvent e)
   	{
   		JFileChooser chooser = FileDialoger.promptToOpenFile();
  -		if(chooser != null)
  +		if(chooser != null && chooser.getSelectedFile() != null)
   		{
   			filename.setText(chooser.getSelectedFile().getPath());
  +			fireFileChanged();
   		}
   	}
   }
  
  
  
  1.5       +46 -11    jakarta-jmeter/src_1/org/apache/jmeter/reporters/ResultCollector.java
  
  Index: ResultCollector.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src_1/org/apache/jmeter/reporters/ResultCollector.java,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ResultCollector.java	26 Apr 2002 23:26:14 -0000	1.4
  +++ ResultCollector.java	30 Apr 2002 02:41:32 -0000	1.5
  @@ -62,17 +62,18 @@
   import org.apache.jmeter.visualizers.ViewResultsVisualizer;
   import org.apache.avalon.framework.configuration.*;
   import org.xml.sax.SAXException;
  +import org.apache.jmeter.testelement.TestListener;
   
   /**
    *  Title: Description: Copyright: Copyright (c) 2001 Company:
    *
    *@author     Michael Stover
  - *@created    $Date: 2002/04/26 23:26:14 $
  + *@created    $Date: 2002/04/30 02:41:32 $
    *@version    1.0
    */
   
   public class ResultCollector extends AbstractListenerElement implements SampleListener, Clearable,
  -		Serializable
  +		Serializable,TestListener
   {
   
   	/**
  @@ -83,6 +84,7 @@
   	private String filename;
   	private PrintWriter out;
   	private DefaultConfigurationSerializer serializer = new DefaultConfigurationSerializer();
  +	private boolean inLoading = false;
   
   	/**
   	 *  !ToDo (Constructor description)
  @@ -99,15 +101,17 @@
   	 */
   	public void setFilename(String f) throws IOException
   	{
  +		System.out.println("Setting filename");
   		try
   		{
   			filename = f;
   			finalizeFileOutput();
  -			Configuration savedSamples = getConfiguration(filename);
  -			readSamples(savedSamples);
  +			clear();
  +			loadExistingFile();
   		}
   		catch(SAXException e)
   		{
  +			e.printStackTrace();
   			throw new IOException("File "+f+" was improperly formatted");
   		}
   		catch(ConfigurationException e)
  @@ -115,6 +119,26 @@
   			throw new IOException("File "+f+" was improperly formatted");
   		}
   	}
  +	
  +	public void testEnded()
  +	{
  +		finalizeFileOutput();
  +	}
  +	
  +	public void testStarted()
  +	{
  +	}
  +
  +	public void loadExistingFile()
  +		throws SAXException, IOException, ConfigurationException {
  +			inLoading = true;
  +		try {
  +			Configuration savedSamples = getConfiguration(filename);
  +			readSamples(savedSamples);
  +		} catch(Exception e) {
  +		}
  +		inLoading = false;
  +	}
   
   	/**
   	 *  Description of the Method
  @@ -153,14 +177,16 @@
   	 *
   	 *@param  testResults  Description of the Parameter
   	 */
  -	private void readSamples(Configuration testResults)
  +	private void readSamples(Configuration testResults) throws
  +			IOException,SAXException,ConfigurationException
   	{
   		Configuration[] samples = testResults.getChildren();
   		for(int i = 0; i < samples.length; i++)
   		{
   			SampleResult result = new SampleResult();
   			result.configure(samples[i]);
  -			sampleOccurred(new SampleEvent(result, null));
  +			sendToVisualizer(result);
  +			recordResult(result);
   		}
   	}
   
  @@ -302,10 +328,7 @@
   				current--;
   			}
   		}
  -		if(getVisualizer() != null)
  -		{
  -			getVisualizer().add(e.getResult());
  -		}
  +		sendToVisualizer(e.getResult());
   		try
   		{
   			recordResult(e.getResult());
  @@ -316,6 +339,13 @@
   		}
   	}
   
  +	protected void sendToVisualizer(SampleResult r) {
  +		if(getVisualizer() != null)
  +		{
  +			getVisualizer().add(r);
  +		}
  +	}
  +
   	/**
   	 *  Description of the Method
   	 *
  @@ -331,10 +361,15 @@
   		}
   	}
   
  -	private void initializeFileOutput() throws IOException
  +	private void initializeFileOutput() throws IOException,
  +			ConfigurationException,SAXException
   	{
   		if(out == null && filename != null)
   		{
  +			if(!inLoading)
  +			{
  +				loadExistingFile();
  +			}
   			try
   			{
   				out = new PrintWriter(new BufferedOutputStream(new FileOutputStream(filename)));
  
  
  
  1.6       +6 -3      jakarta-jmeter/src_1/org/apache/jmeter/threads/JMeterThread.java
  
  Index: JMeterThread.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src_1/org/apache/jmeter/threads/JMeterThread.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- JMeterThread.java	29 Apr 2002 17:08:14 -0000	1.5
  +++ JMeterThread.java	30 Apr 2002 02:41:32 -0000	1.6
  @@ -71,8 +71,8 @@
    * timing, add listeners for sampling events and to stop the sampling process.
    *
    *@author    $Author: mstover1 $
  - *@created   $Date: 2002/04/29 17:08:14 $
  - *@version   $Revision: 1.5 $
  + *@created   $Date: 2002/04/30 02:41:32 $
  + *@version   $Revision: 1.6 $
    ***************************************/
   public class JMeterThread implements Runnable, java.io.Serializable
   {
  @@ -83,14 +83,16 @@
   	private boolean running;
   	ListedHashTree testTree;
   	TestCompiler compiler;
  +	JMeterThreadMonitor monitor;
   
   	/****************************************
   	 * !ToDo (Constructor description)
   	 ***************************************/
   	public JMeterThread() { }
   
  -	public JMeterThread(ListedHashTree test)
  +	public JMeterThread(ListedHashTree test,JMeterThreadMonitor monitor)
   	{
  +		this.monitor = monitor;
   		testTree = test;
   		compiler = new TestCompiler(testTree);
   		controller = (Controller)testTree.getArray()[0];
  @@ -121,6 +123,7 @@
   				running = false;
   			}
   		}
  +		monitor.threadFinished(this);
   	}
   
   	/****************************************
  
  
  
  1.2       +1 -1      jakarta-jmeter/src_1/org/apache/jmeter/util/SearchByClass.java
  
  Index: SearchByClass.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src_1/org/apache/jmeter/util/SearchByClass.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- SearchByClass.java	19 Apr 2002 02:10:50 -0000	1.1
  +++ SearchByClass.java	30 Apr 2002 02:41:32 -0000	1.2
  @@ -38,7 +38,7 @@
   
   	public void addNode(Object node,ListedHashTree subTree)
   	{
  -		if(node.getClass().equals(searchClass))
  +		if(node.getClass().isAssignableFrom(searchClass))
   		{
   			objectsOfClass.add(node);
   			ListedHashTree tree = new ListedHashTree(node);
  
  
  
  1.6       +7 -4      jakarta-jmeter/src_1/org/apache/jmeter/visualizers/gui/AbstractVisualizer.java
  
  Index: AbstractVisualizer.java
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/src_1/org/apache/jmeter/visualizers/gui/AbstractVisualizer.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- AbstractVisualizer.java	29 Apr 2002 17:08:16 -0000	1.5
  +++ AbstractVisualizer.java	30 Apr 2002 02:41:32 -0000	1.6
  @@ -3,6 +3,7 @@
   import java.io.*;
   import javax.swing.JPanel;
   import javax.swing.JPopupMenu;
  +import javax.swing.event.*;
   import org.apache.jmeter.gui.JMeterGUIComponent;
   import org.apache.jmeter.gui.NamePanel;
   import org.apache.jmeter.gui.util.MenuFactory;
  @@ -17,12 +18,12 @@
    * Title: JMeter Description: Copyright: Copyright (c) 2000 Company: Apache
    *
    *@author    Michael Stover
  - *@created   $Date: 2002/04/29 17:08:16 $
  + *@created   $Date: 2002/04/30 02:41:32 $
    *@version   1.0
    ***************************************/
   
   public abstract class AbstractVisualizer extends JPanel implements JMeterGUIComponent,
  -		Visualizer
  +		Visualizer,ChangeListener
   {
   
   	/****************************************
  @@ -38,7 +39,7 @@
   	public AbstractVisualizer()
   	{
   		namePanel = new NamePanel();
  -		filePanel = new FilePanel();
  +		filePanel = new FilePanel(this);
   		setName(getStaticLabel());
   	}
   
  @@ -93,8 +94,9 @@
   		return MenuFactory.getDefaultVisualizerMenu();
   	}
   
  -	public void loadFile()
  +	public void stateChanged(ChangeEvent e)
   	{
  +		System.out.println("getting new collector");
   		collector = (ResultCollector)createTestElement();
   	}
   
  @@ -134,6 +136,7 @@
   		}
   		catch(IOException e)
   		{
  +			e.printStackTrace();
   		}
   		return collector;
   	}
  
  
  
  1.11      +40 -40    jakarta-jmeter/xdocs/stylesheets/site.vsl
  
  Index: site.vsl
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/xdocs/stylesheets/site.vsl,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- site.vsl	7 Mar 2002 23:03:13 -0000	1.10
  +++ site.vsl	30 Apr 2002 02:41:32 -0000	1.11
  @@ -185,31 +185,31 @@
   	</table></p>
   #end
   
  -#macro (unknown $node)
  -	#if($node.getName() == "note")
  -		#note($node)
  -	#elseif($node.getName() == "complink")
  -		#complink($node)
  -	#elseif($node.getName() == "figure")
  -		#figure($node)
  -	#elseif ($node.getName() == "links")
  -		 #seeAlso ($node)
  -	#elseif ($node.getName() == "properties")
  -		 #properties ($node)
  -	#elseif ($node.getName() == "example")
  -		#example ($node)
  -	#elseif ($node.getName().equals("source"))
  -		 #source ($node)
  -	#elseif ($node.getName().equals("table"))
  -		 #table ($node)
  -	#elseif ($node.getName().equals("component"))
  -		#component($node)
  -	#elseif ($node.getName().equals("subsection"))
  -		 #subsection ($node)
  +#macro (unknown $u_node)
  +	#if($u_node.getName() == "note")
  +		#note($u_node)
  +	#elseif($u_node.getName() == "complink")
  +		#complink($u_node)
  +	#elseif($u_node.getName() == "figure")
  +		#figure($u_node)
  +	#elseif ($u_node.getName() == "links")
  +		 #seeAlso ($u_node)
  +	#elseif ($u_node.getName() == "properties")
  +		 #properties ($u_node)
  +	#elseif ($u_node.getName() == "example")
  +		#example ($u_node)
  +	#elseif ($u_node.getName().equals("source"))
  +		 #source ($u_node)
  +	#elseif ($u_node.getName().equals("table"))
  +		 #table ($u_node)
  +	#elseif ($u_node.getName().equals("component"))
  +		#component($u_node)
  +	#elseif ($u_node.getName().equals("subsection"))
  +		 #subsection ($u_node)
   	#else
  -		#outputTag($node)
  -		#runloop($node)
  -		#outputEndTag($node)
  +		#outputTag($u_node)
  +		#runloop($u_node)
  +		#outputEndTag($u_node)
   	#end
   #end
   
  @@ -230,11 +230,11 @@
   #end
   
   #macro (runloop $itemToLoop)
  -	#foreach ($node in $itemToLoop.getMixedContent())
  -		#if($node.getClass().getName().indexOf("Element") > -1)
  -			#unknown($node)
  +	#foreach ($rl_node in $itemToLoop.getContent())
  +		#if($rl_node.getClass().getName().indexOf("Element") > -1)
  +			#unknown($rl_node)
   		#else
  -			$node
  +			$rl_node.getText()
   		#end
   	#end
   #end
  @@ -249,15 +249,15 @@
   		  </font>
   		</td></tr>
   		<tr><td>
  -		  #foreach ( $items in $component.getChildren() )
  -				#if ($items.getName().equals("description"))
  -					#runloop($items)
  +		  #foreach ( $c_items in $component.getChildren() )
  +				#if ($c_items.getName().equals("description"))
  +					#runloop($c_items)
   					<p><b>Control Panel</b></p>
   					#if ($screenshot != "")
   						<div align="center"><img src="$screenshot"></div>
   					#end
   				#else
  -					 #unknown($items)
  +					 #unknown($c_items)
   				#end
   		  #end
   		</td></tr>
  @@ -275,11 +275,11 @@
   		</td></tr>
   		<tr><td>
   		  <blockquote>
  -		  #foreach ( $items in $subsection.getChildren() )
  -				#if ($items.getName().equals("img"))
  -					 #image ($items)
  +		  #foreach ( $su_items in $subsection.getChildren() )
  +				#if ($su_items.getName().equals("img"))
  +					 #image ($su_items)
   				#else
  -					 #unknown($items)
  +					 #unknown($su_items)
   				#end
   		  #end
   		  </blockquote>
  @@ -297,11 +297,11 @@
   		</td></tr>
   		<tr><td>
   		  <blockquote>
  -		  #foreach ( $items in $section.getChildren() )
  -				#if ($items.getName().equals("img"))
  -					 #image ($items)
  +		  #foreach ( $s_items in $section.getChildren() )
  +				#if ($s_items.getName().equals("img"))
  +					 #image ($s_items)
   				#else
  -					 #unknown($items)
  +					 #unknown($s_items)
   				#end
   		  #end
   		  </blockquote>
  
  
  
  1.4       +166 -1    jakarta-jmeter/xdocs/usermanual/boss.xml
  
  Index: boss.xml
  ===================================================================
  RCS file: /home/cvs/jakarta-jmeter/xdocs/usermanual/boss.xml,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- boss.xml	6 Mar 2002 03:52:03 -0000	1.3
  +++ boss.xml	30 Apr 2002 02:41:32 -0000	1.4
  @@ -2,13 +2,178 @@
   <document>
   
   <properties>
  +  <author>Martin Ramshaw</author>
     <title>User's Manual: My boss wants me to...</title>
   </properties>
   
   <body>
   
   <section name="12. Help! My boss wants me to load test our web app!" anchor="boss">
  -<p>To be written.</p>
  +<p>This is a fairly open-ended proposition. There are a number of questions to
  +be asked first, and additionally a number of resources that will be needed. You
  +will need some hardware to run the benchmarks/load-tests from. A number of
  +tools will prove useful. There are a number of products to consider.  And finally,
  +why is Java a good choice to implement a load-testing/Benchmarking product.
  +</p>
  +<subsection name="12.1 Questions to ask">
  +<p>What is our anticipated average number of users (normal load) ?
  +</p>
  +<p>What is our anticipated peak number of users ?
  +</p>
  +<p>When is a good time to load-test our application (i.e. off-hours or week-ends),
  +bearing in mind that this may very well crash one or more of our servers ?
  +</p>
  +<p>Does our application have state ? If so, how does our application manage it
  +(cookies, session-rewriting, or some other method) ?
  +</p>
  +</subsection>
  +<subsection name="12.2 Resources">
  +<p>The following resources will prove very helpful. Bear in mind that if you
  +cannot locate these resources, <b>you</b> will become these resources. As you
  +already have your work cut out for you, it is worth knowing who the following
  +people are, so that you can ask them for help if you need it.
  +</p>
  +	<subsection name="12.2.1 Network">
  +	<p>Who knows our network topology ? If you run into any firewall or
  +	proxy issues, this will become very important. As well, a private
  +	testing network (which will therefore have very low network latency)
  +	would be a very nice thing. Knowing who can set one up for you
  +	(if you feel that this is necessary) will be very useful. If the
  +	application doesn't scale as expected, who can add additional
  +	hardware ?
  +	</p>
  +	</subsection>
  +	<subsection name="12.2.2 Application">
  +	<p>Who knows how our application functions ? The normal sequence is
  +	<ul>
  +		<li>test (low-volume - can we benchmark our application?)</li>
  +		<li>benchmark (the average number of users)</li>
  +		<li>load-test (the maximum number of users)</li>
  +		<li>test destructively (what is our hard limit?)</li>
  +	</ul>
  +	The <b>test</b> process may progress from black-box testing to
  +	white-box testing (the difference is that the first requires
  +	no knowledge of the application [it is treated as a "black box"]
  +	while the second requires some knowledge of the application).
  +	It is not uncommon to discover problems with the application
  +	during this process, so be prepared to defend your work.
  +	</p>
  +	</subsection>
  +</subsection>
  +<subsection name="12.3 What platform should I use to run the benchmarks/load-tests ?">
  +<p>This should be a widely-used piece of hardware, with a standard
  +(i.e. vanilla) software installation. Remember, if you publish your results,
  +the first thing your clients will do is hire a graduate student to verify them.
  +You might as well make it as easy for this person as you possibly can.
  +</p>
  +<p>For Windows, Windows XP Professional should be a minimum (the others
  +do not multi-thread past 50-60 connections, and you probably anticipate
  +more users than that).
  +</p>
  +<p>Good free platforms include the linuxes, the BSDs, and Solaris Intel. If
  +you have a little more money, there are commercial linuxes. If you can justify
  +it, a commercial Unix (Solaris, etc) is probably the best choice.
  +</p>
  +<p>
  +For non-Windows platforms, investigate "umount -n unlimited" with a view to
  +including it in your user account startup scripts (.bashrc or .cshrc scripts
  +for the testing account).
  +</p>
  +<p>As you progress to larger-scale benchmarks/load-tests, this platform
  +will become the limiting factor. So it's worth using the best hardware and
  +software that you have available. Remember to include the hardware/software
  +configuration in your published benchmarks.
  +</p>
  +</subsection>
  +<subsection name="12.4 Tools">
  +<p>The following tools will all prove useful. It is definitely worthwhile to
  +become familiar with them. This should include trying them out, and reading the
  +appropriate documentation (man-pages, info-files, application --help messages,
  +and any supplied documentation).
  +</p>
  +	<subsection name="12.4.1 ping">
  +	<p>
  +	This can be used to establish whether or not you can reach your
  +	target site.
  +	</p>
  +	</subsection>
  +	<subsection name="12.4.2 nslookup">
  +	<p>
  +	While the <u>user</u> will normally use a human-readable internet
  +	address, <u>you</u> may wish to avoid the overhead of DNS lookups when
  +	performing benchmarking/load-testing. This can be used to determine
  +	the unique address (dotted quad) of your target site.
  +	</p>
  +	</subsection>
  +	<subsection name="12.4.3 traceroute">
  +	<p>
  +	If you cannot "ping" your target site, this may be used to determine 
  +	the problem (possibly a firewall or a proxy). It can also be used
  +	to estimate the overall network latency (running locally should give
  +	the lowest possible network latency - remember that your users will
  +	be running over a possibly busy internet). Generally, the fewer hops
  +	the better.
  +	</p>
  +	</subsection>
  +</subsection>
  +<subsection name="12.5 What other products are there ?">
  +<p>There are a number of commercial products, which generally have fairly
  +hefty pricetags. If you can justify it, these are probably the way to go.
  +If, however, these products do not do exactly what you want, or you are on a
  +limited budget, the following are worth a look. In fact, you should probably
  +start by trying the Apache <b>ab</b> tool, as it may very well do the job
  +if your requirements are not particularly complicated.
  +</p>
  +	<subsection name="12.5.1 Apache 'ab' tool">
  +	<p>
  +	You should definitely start with this one. It handles HTTP 'get' requests
  +	very well, and can be made to handle HTTP 'post' requests with a little
  +	effort. Written in 'C', it performs very well, and offers good (if basic)
  +	performance reporting.
  +	</p>
  +	</subsection>
  +	<subsection name="12.5.2 Microsoft WAS">
  +	<p>
  +	This is definitely worth a look. It has an excellent user interface
  +	but it may not do exactly what you want. If this is the case, be aware
  +	that the functionality of this product is not likely to change.
  +	</p>
  +	</subsection>
  +	<subsection name="12.5.3 JMeter">
  +	<p>
  +	If you have non-standard requirements, then this solution offers an
  +	open-source community to provide them (of course, if you are reading
  +	<u>this</u>, you are probably already committed to this one). This
  +	product is free to evolve along with your requirements.
  +	</p>
  +	</subsection>
  +</subsection>
  +<subsection name="12.6 Why Java ?">
  +<p>Why not Perl or C ?
  +</p>
  +<p>Well, Perl might be a very good choice except that the Benchmark package
  +seems to give fairly fuzzy results. Also, simulating multiple users with
  +Perl is a tricky proposition (multiple connections can be simulated by forking
  +many processes from a shell script, but these will not be threads, they will
  +be processes). However, the Perl community is very large. If you find that
  +someone has already written something that seems useful, this could be a very
  +good solution.
  +</p>
  +<p>C, of course, is a very good choice (check out the Apache <b>ab</b> tool).
  +But be prepared to write all of the custom networking, threading, and state
  +management code that you will need to benchmark your application.
  +</p>
  +<p>Java gives you (for free) the custom networking, threading, and state
  +management code that you will need to benchmark your application. Java is
  +aware of HTTP, FTP, and HTTPS - as well as RMI, IIOP, and JDBC (not to mention
  +cookies, URL-encoding, and URL-rewriting). In addition Java gives you automatic
  +garbage-collection, and byte-code level security.
  +</p>
  +<p>And once Microsoft moves to a CLR (common language run-time) a Windows Java
  +solution will not be any slower than any other type of solution on the Windows
  +platform.
  +</p>
  +</subsection>
   </section>
   
   </body>
  
  
  

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>