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>