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 }