View Javadoc

    1   /*
    2    *  soapUI, copyright (C) 2004-2007 eviware.com
    3    *
    4    *  soapUI is free software; you can redistribute it and/or modify it under the
    5    *  terms of version 2.1 of the GNU Lesser General Public License as published by
    6    *  the Free Software Foundation.
    7    *
    8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
    9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
    10   *  See the GNU Lesser General Public License for more details at gnu.org.
    11   */
    12
    13  package com.eviware.soapui.impl.wsdl.panels.loadtest;
    14
    15  import java.awt.BorderLayout;
    16  import java.awt.Dimension;
    17  import java.awt.event.ActionEvent;
    18  import java.awt.event.ItemEvent;
    19  import java.awt.event.ItemListener;
    20  import java.beans.PropertyChangeEvent;
    21  import java.beans.PropertyChangeListener;
    22
    23  import javax.swing.AbstractAction;
    24  import javax.swing.Action;
    25  import javax.swing.BorderFactory;
    26  import javax.swing.Box;
    27  import javax.swing.JButton;
    28  import javax.swing.JComboBox;
    29  import javax.swing.JComponent;
    30  import javax.swing.JLabel;
    31  import javax.swing.JPanel;
    32  import javax.swing.JProgressBar;
    33  import javax.swing.JSpinner;
    34  import javax.swing.JSplitPane;
    35  import javax.swing.JTabbedPane;
    36  import javax.swing.SpinnerNumberModel;
    37  import javax.swing.event.ChangeEvent;
    38  import javax.swing.event.ChangeListener;
    39
    40  import com.eviware.soapui.SoapUI;
    41  import com.eviware.soapui.config.LoadTestLimitTypesConfig;
    42  import com.eviware.soapui.impl.wsdl.actions.loadtest.LoadTestOptionsAction;
    43  import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
    44  import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTest;
    45  import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTestRunner;
    46  import com.eviware.soapui.impl.wsdl.loadtest.data.LoadTestStatistics;
    47  import com.eviware.soapui.impl.wsdl.loadtest.data.LoadTestStatistics.Statistic;
    48  import com.eviware.soapui.impl.wsdl.loadtest.data.actions.ExportStatisticsAction;
    49  import com.eviware.soapui.impl.wsdl.loadtest.log.LoadTestLog;
    50  import com.eviware.soapui.impl.wsdl.loadtest.strategy.LoadStrategy;
    51  import com.eviware.soapui.impl.wsdl.loadtest.strategy.LoadStrategyFactory;
    52  import com.eviware.soapui.impl.wsdl.loadtest.strategy.LoadStrategyRegistry;
    53  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
    54  import com.eviware.soapui.model.ModelItem;
    55  import com.eviware.soapui.model.support.LoadTestRunListenerAdapter;
    56  import com.eviware.soapui.model.testsuite.LoadTestRunContext;
    57  import com.eviware.soapui.model.testsuite.LoadTestRunListener;
    58  import com.eviware.soapui.model.testsuite.LoadTestRunner;
    59  import com.eviware.soapui.model.testsuite.LoadTestRunner.Status;
    60  import com.eviware.soapui.support.UISupport;
    61  import com.eviware.soapui.support.action.swing.SwingActionDelegate;
    62  import com.eviware.soapui.support.components.JComponentInspector;
    63  import com.eviware.soapui.support.components.JInspectorPanel;
    64  import com.eviware.soapui.support.components.JXToolBar;
    65  import com.eviware.soapui.ui.desktop.DesktopPanel;
    66  import com.eviware.soapui.ui.support.DesktopListenerAdapter;
    67  import com.eviware.soapui.ui.support.ModelItemDesktopPanel;
    68  import com.jgoodies.forms.builder.ButtonBarBuilder;
    69
    70  /***
    71   * Desktop panel for LoadTests
    72   *
    73   * @author Ole.Matzura
    74   */
    75
    76  public class WsdlLoadTestDesktopPanel extends ModelItemDesktopPanel<WsdlLoadTest> implements PropertyChangeListener
    77  {
    78  	private static final String SECONDS_LIMIT = "Seconds";
    79  	private static final String RUNS_LIMIT = "Total Runs";
    80  	private JPanel contentPanel;
    81  	@SuppressWarnings("unused")
    82  	private JSplitPane mainSplit;
    83  	@SuppressWarnings("unused")
    84  	private JTabbedPane mainTabs;
    85  	@SuppressWarnings("unused")
    86  	private JPanel graphPanel;
    87  	private JButton runButton;
    88  	private JButton cancelButton;
    89  	private JButton statisticsGraphButton;
    90  	private WsdlLoadTestRunner runner;
    91  	private JSpinner threadsSpinner;
    92  	private LoadTestRunListener internalLoadTestListener = new InternalLoadTestListener();
    93  	private JComboBox strategyCombo;
    94  	private JPanel loadStrategyConfigurationPanel;
    95  	private JButton resetButton;
    96  	private LoadTestLog loadTestLog;
    97  	private JButton optionsButton;
    98  	private JButton testTimesGraphButton;
    99  	@SuppressWarnings("unused")
    100 	private Object limit;
    101 	private JSpinner limitSpinner;
    102 	private JComboBox limitTypeCombo;
    103 	private SpinnerNumberModel limitSpinnerModel;
    104 	private JProgressBar progressBar;
    105 	private long loadTestStartTime;
    106 	private StatisticsDesktopPanel statisticsDesktopPanel;
    107 	private StatisticsHistoryDesktopPanel statisticsHistoryDesktopPanel;
    108
    109 	public boolean loadTestIsRunning;
    110 	private InternalDesktopListener desktopListener;
    111 	private JButton exportButton;
    112 	private JLoadTestAssertionsTable assertionsTable;
    113 	private JStatisticsTable statisticsTable;
    114
    115 	public WsdlLoadTestDesktopPanel(WsdlLoadTest loadTest)
    116 	{
    117 		super( loadTest );
    118
    119 		loadTestLog = loadTest.getLoadTestLog();
    120 		loadTest.addPropertyChangeListener( this );
    121 		loadTest.addLoadTestRunListener( internalLoadTestListener );
    122
    123 		desktopListener = new InternalDesktopListener();
    124 	   SoapUI.getDesktop().addDesktopListener( desktopListener );
    125
    126 		buildUI();
    127 	}
    128
    129 	private void buildUI()
    130 	{
    131 		contentPanel = new JPanel( new BorderLayout());
    132
    133 		contentPanel.add( buildToolbar(), BorderLayout.NORTH );
    134 		contentPanel.add( buildContent(), BorderLayout.CENTER );
    135
    136 		contentPanel.setPreferredSize( new Dimension( 600, 500 ));
    137 	}
    138
    139 	private JComponent buildContent()
    140 	{
    141 		JInspectorPanel inspectorPanel = new JInspectorPanel( buildStatistics() );
    142 		inspectorPanel.addInspector( new JComponentInspector( buildLog(), "LoadTest Log", "The current LoadTest execution log", true ) );
    143 		inspectorPanel.addInspector( new JComponentInspector( buildAssertions(), "LoadTest Assertions", "The assertions for this LoadTest", true ) );
    144 		inspectorPanel.setDefaultDividerLocation( 0.6F );
    145 		inspectorPanel.setCurrentInspector( "LoadTest Log" );
    146
    147 //
    148 //		JTabbedPane tabbedPane = new JTabbedPane( JTabbedPane.BOTTOM );
    149 //		tabbedPane.addTab( "LoadTest Log", buildLog() );
    150 //		tabbedPane.addTab( "LoadTest Assertions", buildAssertions() );
    151 //		JPanel p = new JPanel( new BorderLayout() );
    152 //		p.add( tabbedPane, BorderLayout.CENTER );
    153 //		p.setBackground( Color.LIGHT_GRAY );
    154 //
    155 //		JSplitPane mainSplit = UISupport.createVerticalSplit( buildStatistics(), p );
    156 //		mainSplit.setDividerLocation( 150 );
    157 //		return mainSplit;
    158
    159 		return inspectorPanel;
    160 	}
    161
    162 	private JComponent buildStatistics(	)
    163 	{
    164 		statisticsTable = new JStatisticsTable( getModelItem() );
    165 		return statisticsTable;
    166 	}
    167
    168 	private JComponent buildLog()
    169 	{
    170 		JLoadTestLogTable loadTestLogTable = new JLoadTestLogTable( loadTestLog );
    171 		return loadTestLogTable;
    172 	}
    173
    174 	private JComponent buildAssertions()
    175 	{
    176 		assertionsTable = new JLoadTestAssertionsTable( getModelItem() );
    177 		return assertionsTable;
    178 	}
    179
    180 	private JComponent buildToolbar()
    181 	{
    182 		WsdlLoadTest loadTest = getModelItem();
    183
    184 		JXToolBar toolbar = UISupport.createToolbar();
    185
    186 		//ButtonBarBuilder builder = new ButtonBarBuilder();
    187       runButton = UISupport.createToolbarButton( new RunLoadTestAction());
    188       cancelButton = UISupport.createToolbarButton( new CancelRunTestCaseAction(), false );
    189       resetButton = UISupport.createToolbarButton( new ResetAction() );
    190       exportButton = UISupport.createToolbarButton( new ExportStatisticsAction( loadTest.getStatisticsModel() ) );
    191
    192       statisticsGraphButton = UISupport.createToolbarButton( new ShowStatisticsGraphAction() );
    193       testTimesGraphButton = UISupport.createToolbarButton( new ShowTestTimesGraphAction() );
    194
    195       statisticsGraphButton.setEnabled( getModelItem().getHistoryLimit() != 0 );
    196 		testTimesGraphButton.setEnabled( getModelItem().getHistoryLimit() != 0  );
    197
    198       AbstractAction optionsDelegate = SwingActionDelegate.createDelegate( LoadTestOptionsAction.SOAPUI_ACTION_ID, loadTest );
    199       optionsDelegate.putValue( Action.SMALL_ICON,	UISupport.createImageIcon( "/options.gif" ));
    200 		optionsButton = UISupport.createToolbarButton( optionsDelegate );
    201
    202       strategyCombo = new JComboBox( LoadStrategyRegistry.getInstance().getStrategies() );
    203       strategyCombo.setToolTipText( "Selects which LoadTest Strategy to use" );
    204       UISupport.setPreferredHeight( strategyCombo, 18 );
    205 		strategyCombo.setSelectedItem( loadTest.getLoadStrategy().getType());
    206 		strategyCombo.addItemListener( new ItemListener()
    207 				{
    208 					public void itemStateChanged(ItemEvent e)
    209 					{
    210 						Object item = e.getItem();
    211 						if( item == null )
    212 							return;
    213
    214 						setLoadStrategy(item.toString());
    215 					}} );
    216
    217 		toolbar.add( runButton );
    218 		toolbar.add( cancelButton );
    219 		toolbar.add( statisticsGraphButton );
    220 		toolbar.add( testTimesGraphButton );
    221 		toolbar.add( resetButton );
    222 		toolbar.add( exportButton );
    223
    224 		toolbar.add( optionsButton );
    225 		toolbar.add( UISupport.createToolbarButton( new ShowOnlineHelpAction( HelpUrls.LOADTESTEDITOR_HELP_URL )));
    226 		toolbar.add( Box.createHorizontalGlue() );
    227 		buildLimitBar( toolbar );
    228       toolbar.addSeparator();
    229
    230 		progressBar = new JProgressBar( 0, 100 );
    231 		progressBar.setPreferredSize( new Dimension( 70, 20 ));
    232
    233 		toolbar.addFixed( progressBar );
    234
    235 		ButtonBarBuilder builder = new ButtonBarBuilder();
    236
    237 		builder.addFixed( new JLabel( "Threads:" ));
    238       builder.addRelatedGap();
    239
    240 		threadsSpinner = new JSpinner( new SpinnerNumberModel(getModelItem().getThreadCount(), 1, 9999, 1) );
    241 		threadsSpinner.setToolTipText( "Sets the number of threads (\"Virtual Users\") to run this TestCase" );
    242 		UISupport.setPreferredHeight( threadsSpinner, 18 );
    243       threadsSpinner.getModel().addChangeListener( new ChangeListener() {
    244
    245 			public void stateChanged(ChangeEvent e)
    246 			{
    247 				getModelItem().setThreadCount( ((SpinnerNumberModel) threadsSpinner.getModel()).getNumber().intValue() );
    248 			}} );
    249
    250 		builder.addFixed( threadsSpinner);
    251 		builder.addUnrelatedGap();
    252
    253 		LoadStrategy loadStrategy = loadTest.getLoadStrategy();
    254
    255 		builder.addFixed( new JLabel( "Strategy" ));
    256       builder.addRelatedGap();
    257       builder.addFixed( strategyCombo );
    258       builder.addUnrelatedGap();
    259
    260       loadStrategyConfigurationPanel = new JPanel( new BorderLayout() );
    261 		loadStrategyConfigurationPanel.add( loadStrategy.getConfigurationPanel(), BorderLayout.CENTER );
    262
    263       builder.addFixed( loadStrategyConfigurationPanel );
    264       builder.setBorder( BorderFactory.createEmptyBorder( 2, 3, 3, 3 ) );
    265
    266 		return UISupport.buildPanelWithToolbar( toolbar, builder.getPanel() );
    267 	}
    268
    269 	public void buildLimitBar( JXToolBar toolbar )
    270 	{
    271 		limitSpinnerModel = new SpinnerNumberModel(getModelItem().getTestLimit(), 0, Long.MAX_VALUE, 100 );
    272
    273 		limitSpinner = new JSpinner( limitSpinnerModel );
    274 		limitSpinner.setPreferredSize( new Dimension( 70, 20 ));
    275 		limitSpinner.setToolTipText( "Sets the limit for this test; total number of requests or seconds to run" );
    276 		limitSpinner.getModel().addChangeListener( new ChangeListener() {
    277
    278 			public void stateChanged(ChangeEvent e)
    279 			{
    280 				int intValue = ((SpinnerNumberModel) limitSpinner.getModel()).getNumber().intValue();
    281 				getModelItem().setTestLimit( intValue );
    282 			}} );
    283
    284 		toolbar.addSeparator();
    285 		toolbar.addFixed( new JLabel( "Limit:" ));
    286 		toolbar.addSeparator();
    287 		toolbar.addFixed(limitSpinner );
    288 		toolbar.addSeparator();
    289
    290 		limitTypeCombo = new JComboBox( new String[] { WsdlLoadTestDesktopPanel.RUNS_LIMIT, WsdlLoadTestDesktopPanel.SECONDS_LIMIT});
    291
    292 		if( getModelItem().getLimitType() == LoadTestLimitTypesConfig.TIME )
    293 			limitTypeCombo.setSelectedIndex( 1 );
    294
    295 		toolbar.addFixed( limitTypeCombo);
    296 		toolbar.addSeparator();
    297
    298 		limitTypeCombo.addItemListener( new ItemListener()
    299 		{
    300 			public void itemStateChanged(ItemEvent e)
    301 			{
    302 				Object item = e.getItem();
    303 				if( WsdlLoadTestDesktopPanel.RUNS_LIMIT.equals( item ))
    304 				{
    305 					getModelItem().setLimitType( LoadTestLimitTypesConfig.COUNT );
    306 				}
    307 				else if( WsdlLoadTestDesktopPanel.SECONDS_LIMIT.equals( item ))
    308 				{
    309 					getModelItem().setLimitType( LoadTestLimitTypesConfig.TIME );
    310 				}
    311 			}} );
    312 	}
    313
    314 	public boolean onClose( boolean canCancel )
    315 	{
    316 		if( runner != null && runner.getStatus() == Status.RUNNING )
    317 		{
    318 			if( !UISupport.confirm( "Running test will be canceled when closing window. Close anyway?", "Close LoadTest" ))
    319 				return false;
    320 		}
    321
    322 		getModelItem().removeLoadTestRunListener( internalLoadTestListener );
    323 		getModelItem().removePropertyChangeListener( this );
    324 		getModelItem().getStatisticsModel().reset();
    325
    326 		if( runner != null && runner.getStatus() == Status.RUNNING )
    327 			runner.cancel( "closing window" );
    328
    329 		if( statisticsDesktopPanel != null )
    330 			SoapUI.getDesktop().closeDesktopPanel( statisticsDesktopPanel );
    331
    332 		if( statisticsHistoryDesktopPanel != null )
    333 			SoapUI.getDesktop().closeDesktopPanel( statisticsHistoryDesktopPanel );
    334
    335 		assertionsTable.release();
    336 		loadStrategyConfigurationPanel.removeAll();
    337 		SoapUI.getDesktop().removeDesktopListener( desktopListener );
    338
    339 		statisticsTable.release();
    340
    341 		return release();
    342 	}
    343
    344 	public JComponent getComponent()
    345 	{
    346 		return contentPanel;
    347 	}
    348
    349    private final class InternalDesktopListener extends DesktopListenerAdapter
    350 	{
    351 		public void desktopPanelClosed(DesktopPanel desktopPanel)
    352 		{
    353 			if( desktopPanel == statisticsDesktopPanel )
    354 				statisticsDesktopPanel = null;
    355 			else if( desktopPanel == statisticsHistoryDesktopPanel )
    356 				statisticsHistoryDesktopPanel = null;
    357 		}
    358 	}
    359
    360 	public class RunLoadTestAction extends AbstractAction
    361    {
    362 		public RunLoadTestAction()
    363       {
    364          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/run_testcase.gif"));
    365          putValue( Action.SHORT_DESCRIPTION, "Runs this LoadTest" );
    366       }
    367
    368 		public void actionPerformed(ActionEvent e)
    369 		{
    370 			WsdlLoadTest loadtest = getModelItem();
    371 			if( loadtest.getTestCase().getTestStepCount() == 0 )
    372 			{
    373 				UISupport.showErrorMessage( "Missing TestSteps for testing!");
    374 				return;
    375 			}
    376
    377 			if( loadtest.getLimitType() == LoadTestLimitTypesConfig.COUNT &&
    378 				 loadtest.getTestLimit() < loadtest.getThreadCount() )
    379 			{
    380 				if( !UISupport.confirm( "The run limit is set to a lower count than number of threads\nRun Anyway?",
    381 							"Run LoadTest" ))
    382 				{
    383 					return;
    384 				}
    385 			}
    386
    387 			runButton.setEnabled( false );
    388          runner = loadtest.run();
    389 		}
    390    }
    391
    392    public class ResetAction extends AbstractAction
    393    {
    394 		public ResetAction()
    395       {
    396          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/reset_loadtest_statistics.gif"));
    397          putValue( Action.SHORT_DESCRIPTION, "Resets statistics for this LoadTest" );
    398       }
    399
    400 		public void actionPerformed(ActionEvent e)
    401 		{
    402 			getModelItem().getStatisticsModel().reset();
    403 		}
    404    }
    405
    406    public class ShowStatisticsGraphAction extends AbstractAction
    407    {
    408 		public ShowStatisticsGraphAction()
    409       {
    410          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/stats_graph.gif"));
    411          putValue( Action.SHORT_DESCRIPTION, "Shows the statistics graph" );
    412       }
    413
    414 		public void actionPerformed(ActionEvent e)
    415 		{
    416 			if( statisticsDesktopPanel == null )
    417 				statisticsDesktopPanel = new StatisticsDesktopPanel( getModelItem() );
    418
    419          UISupport.showDesktopPanel( statisticsDesktopPanel );
    420 		}
    421    }
    422
    423    public class ShowTestTimesGraphAction extends AbstractAction
    424    {
    425 		public ShowTestTimesGraphAction()
    426       {
    427          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/samples_graph.gif"));
    428          putValue( Action.SHORT_DESCRIPTION, "Shows the Statistics History graph" );
    429       }
    430
    431 		public void actionPerformed(ActionEvent e)
    432 		{
    433 			if( statisticsHistoryDesktopPanel == null )
    434 				statisticsHistoryDesktopPanel = new StatisticsHistoryDesktopPanel( getModelItem() );
    435
    436          UISupport.showDesktopPanel( statisticsHistoryDesktopPanel );
    437 		}
    438    }
    439
    440    public class CancelRunTestCaseAction extends AbstractAction
    441    {
    442
    443 		public CancelRunTestCaseAction()
    444       {
    445          putValue( Action.SMALL_ICON, UISupport.createImageIcon( "/stop_testcase.gif"));
    446          putValue( Action.SHORT_DESCRIPTION, "Stops running this LoadTest" );
    447       }
    448
    449 		public void actionPerformed(ActionEvent e)
    450 		{
    451       	if( runner != null )
    452       	{
    453       		runner.cancel( "Canceled" );
    454       		cancelButton.setEnabled( false );
    455       	}
    456       }
    457    }
    458
    459    public boolean dependsOn(ModelItem modelItem)
    460 	{
    461    	WsdlLoadTest loadTest = getModelItem();
    462
    463 		return modelItem == loadTest || modelItem == loadTest.getTestCase() ||
    464 			modelItem == loadTest.getTestCase().getTestSuite() ||
    465 			modelItem == loadTest.getTestCase().getTestSuite().getProject();
    466 	}
    467
    468 	public void setLoadStrategy(String type)
    469 	{
    470 		LoadStrategyFactory factory = LoadStrategyRegistry.getInstance().getFactory( type );
    471 		LoadStrategy loadStrategy = factory.create();
    472 		getModelItem().setLoadStrategy( loadStrategy );
    473 		loadStrategyConfigurationPanel.removeAll();
    474 		loadStrategyConfigurationPanel.add( loadStrategy.getConfigurationPanel(), BorderLayout.CENTER );
    475 		loadStrategyConfigurationPanel.revalidate();
    476 	}
    477
    478 	private class InternalLoadTestListener extends LoadTestRunListenerAdapter
    479 	{
    480 		public void beforeLoadTest( LoadTestRunner testRunner, LoadTestRunContext context )
    481 		{
    482          loadTestLog.clear();
    483
    484 			loadTestStartTime = System.currentTimeMillis();
    485 			loadTestIsRunning = true;
    486 			if( getModelItem().getTestLimit() > 0 )
    487 			{
    488 				progressBar.setValue(0);
    489 				progressBar.setString( null );
    490 			}
    491 			else
    492 			{
    493 				progressBar.setString("...");
    494 			}
    495
    496 			progressBar.setStringPainted(true);
    497
    498 			runButton.setEnabled( false );
    499 			cancelButton.setEnabled( true );
    500 			strategyCombo.setEnabled( false );
    501 			limitTypeCombo.setEnabled( false );
    502 			threadsSpinner.setEnabled( getModelItem().getLoadStrategy().allowThreadCountChangeDuringRun() );
    503
    504 			new Thread( new ProgressBarUpdater(), getModelItem().getName() + " ProgressBarUpdater" ).start();
    505 		}
    506
    507 		public void afterLoadTest( LoadTestRunner testRunner, LoadTestRunContext context )
    508 		{
    509 			runButton.setEnabled( true );
    510
    511 			cancelButton.setEnabled( false );
    512 			strategyCombo.setEnabled( true );
    513 			limitTypeCombo.setEnabled( true );
    514 			threadsSpinner.setEnabled( true );
    515
    516 			runner = null;
    517 			loadTestIsRunning = false;
    518
    519 			if( progressBar.isIndeterminate() )
    520 			{
    521 				progressBar.setIndeterminate( false );
    522 				progressBar.setValue(0);
    523 			}
    524 			else if( testRunner.getStatus() == Status.FINISHED )
    525 			{
    526 				progressBar.setValue( 100 );
    527 			}
    528
    529 			if( testRunner.getStatus() == Status.FAILED )
    530 			{
    531 				UISupport.showErrorMessage( "LoadTest failed; " + testRunner.getReason() );
    532 			}
    533 		}
    534
    535
    536 	}
    537
    538 	private class ProgressBarUpdater implements Runnable
    539 	{
    540 		public void run()
    541 		{
    542 			while( true )
    543 			{
    544 				if( !loadTestIsRunning )
    545 					break;
    546
    547 				if( getModelItem().getTestLimit() == 0 )
    548 				{
    549 					if( loadTestIsRunning && !progressBar.isIndeterminate())
    550 					{
    551 						progressBar.setIndeterminate( true );
    552 						progressBar.setString("...");
    553 					}
    554 				}
    555 				else if( getModelItem().getLimitType() == LoadTestLimitTypesConfig.TIME )
    556 				{
    557 					if( loadTestIsRunning && progressBar.isIndeterminate())
    558 					{
    559 						progressBar.setIndeterminate( false );
    560 						progressBar.setString(null);
    561 					}
    562
    563 					long timePassed = System.currentTimeMillis()-loadTestStartTime;
    564 					int value = (int) ((timePassed*100)/(getModelItem().getTestLimit()*1000));
    565 					progressBar.setValue( value );
    566 				}
    567 				else if( getModelItem().getLimitType() == LoadTestLimitTypesConfig.COUNT )
    568 				{
    569 					if( loadTestIsRunning && progressBar.isIndeterminate())
    570 					{
    571 						progressBar.setIndeterminate( false );
    572 						progressBar.setString(null);
    573 					}
    574
    575 					long counts = getModelItem().getStatisticsModel().getStatistic( LoadTestStatistics.TOTAL, Statistic.COUNT );
    576 					if( counts > 0 )
    577 						progressBar.setValue(  (int) ((counts*100)/getModelItem().getTestLimit()) );
    578 				}
    579
    580 				try
    581 				{
    582 					Thread.sleep( 500 );
    583 				}
    584 				catch (InterruptedException e)
    585 				{
    586 					SoapUI.logError( e );
    587 				}
    588 			}
    589 		}
    590 	}
    591
    592 	public void propertyChange(PropertyChangeEvent evt)
    593 	{
    594 		if( evt.getPropertyName().equals( WsdlLoadTest.THREADCOUNT_PROPERTY ))
    595 		{
    596 			threadsSpinner.setValue( evt.getNewValue() );
    597 		}
    598 		else if( evt.getPropertyName().equals( WsdlLoadTest.HISTORYLIMIT_PROPERTY ))
    599 		{
    600 			long lng = (Long)evt.getNewValue();
    601
    602 			statisticsGraphButton.setEnabled( lng != 0 );
    603 			testTimesGraphButton.setEnabled( lng != 0 );
    604 		}
    605 	}
    606
    607 }