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.loadtest.data;
    14
    15  import java.beans.PropertyChangeEvent;
    16  import java.beans.PropertyChangeListener;
    17  import java.util.ArrayList;
    18  import java.util.HashMap;
    19  import java.util.List;
    20  import java.util.Map;
    21
    22  import javax.swing.table.AbstractTableModel;
    23
    24  import org.apache.log4j.Logger;
    25
    26  import com.eviware.soapui.model.support.LoadTestRunListenerAdapter;
    27  import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
    28  import com.eviware.soapui.model.testsuite.LoadTest;
    29  import com.eviware.soapui.model.testsuite.LoadTestRunContext;
    30  import com.eviware.soapui.model.testsuite.LoadTestRunner;
    31  import com.eviware.soapui.model.testsuite.TestCase;
    32  import com.eviware.soapui.model.testsuite.TestRunContext;
    33  import com.eviware.soapui.model.testsuite.TestRunner;
    34  import com.eviware.soapui.model.testsuite.TestStep;
    35  import com.eviware.soapui.model.testsuite.TestStepResult;
    36
    37  /***
    38   * TableModel holding loadtest samples
    39   */
    40
    41  public class SamplesModel extends AbstractTableModel
    42  {
    43  	private final LoadTest loadTest;
    44  	private List<TestSample[]> samples = new ArrayList<TestSample[]>();
    45  	private InternalTestRunListener testRunListener;
    46  	private InternalTestSuiteListener testSuiteListener;
    47  	private InternalPropertyChangeListener propertyChangeListener;
    48  	private TestCase testCase;
    49  	private final static Logger log = Logger.getLogger(SamplesModel.class);
    50
    51  	public SamplesModel( LoadTest loadTest )
    52  	{
    53  		this.loadTest = loadTest;
    54
    55  		testRunListener = new InternalTestRunListener();
    56  		testSuiteListener = new InternalTestSuiteListener();
    57  		propertyChangeListener = new InternalPropertyChangeListener();
    58
    59  		testCase = loadTest.getTestCase();
    60  		loadTest.addLoadTestRunListener( testRunListener );
    61  		testCase.getTestSuite().addTestSuiteListener( testSuiteListener );
    62
    63  		for( TestStep testStep : testCase.getTestStepList() )
    64  		{
    65  			testStep.addPropertyChangeListener( TestStep.NAME_PROPERTY, propertyChangeListener );
    66  		}
    67  	}
    68
    69  	public int getRowCount()
    70  	{
    71  		return samples.size();
    72  	}
    73
    74  	public int getColumnCount()
    75  	{
    76  		return testCase.getTestStepCount();
    77  	}
    78
    79  	public Object getValueAt(int rowIndex, int columnIndex)
    80  	{
    81  		TestSample[] testSamples = samples.get( rowIndex );
    82  		return testSamples == null ? "discarded" : testSamples[columnIndex];
    83  	}
    84
    85  	public void addSamples( TestSample [] newSamples )
    86  	{
    87  		if( newSamples.length != getColumnCount() )
    88  			throw new RuntimeException( "Invalid number of samples reported: " + newSamples.length +
    89  					", expected " + getColumnCount() );
    90
    91  		samples.add( newSamples );
    92
    93  		fireTableRowsInserted( samples.size()-1, samples.size()-1 );
    94  	}
    95
    96  	public Class<?> getColumnClass(int columnIndex)
    97  	{
    98  		return TestSample.class;
    99  	}
    100
    101 	public String getColumnName(int column)
    102 	{
    103 		return testCase.getTestStepAt( column ).getName();
    104 	}
    105
    106 	public void clear()
    107 	{
    108 		int size = samples.size();
    109 		if( size > 0 )
    110 		{
    111 			samples.clear();
    112 			fireTableRowsDeleted( 0, size );
    113 		}
    114 	}
    115
    116 	/***
    117 	 * Listener for collecting samples
    118 	 *
    119 	 * @author Ole.Matzura
    120 	 */
    121
    122 	private class InternalTestRunListener extends LoadTestRunListenerAdapter
    123 	{
    124 		public void afterTestCase(LoadTestRunner loadTestRunner, LoadTestRunContext context, TestRunner testRunner, TestRunContext runContext)
    125 		{
    126 			Map<TestStep,TestSample> samplesMap = new HashMap<TestStep, TestSample>();
    127 			List<TestStepResult> results = testRunner.getResults();
    128
    129 			for( int c = 0; c < results.size(); c++ )
    130 			{
    131 				TestStepResult result = results.get( c );
    132 				if( result == null )
    133 				{
    134 					log.warn( "Result [" + c + "] is null in TestCase [" + testCase.getName() + "]" );
    135 					continue;
    136 				}
    137
    138 				TestStep testStep = result.getTestStep();
    139
    140 				if( !samplesMap.containsKey( testStep ))
    141 				{
    142 					samplesMap.put( testStep, new TestSample( testStep ) );
    143 				}
    144
    145 				samplesMap.get( testStep ).addTestStepResult( result );
    146 			}
    147
    148 			TestCase testCase = loadTest.getTestCase();
    149
    150 			TestSample [] samples = new TestSample[testCase.getTestStepCount()];
    151 			for( int c = 0; c < samples.length; c++ )
    152 			{
    153 				samples[c] = samplesMap.get( testCase.getTestStepAt( c ));
    154 			}
    155
    156 			addSamples( samples );
    157 		}
    158 	}
    159
    160 	public List<TestSample[]> getSamples()
    161 	{
    162 		return samples;
    163 	}
    164
    165 	public void release()
    166 	{
    167 		loadTest.removeLoadTestRunListener( testRunListener );
    168 		loadTest.getTestCase().getTestSuite().removeTestSuiteListener( testSuiteListener );
    169
    170 		for( TestStep testStep : loadTest.getTestCase().getTestStepList() )
    171 		{
    172 			testStep.removePropertyChangeListener( propertyChangeListener );
    173 		}
    174 	}
    175
    176 	/***
    177 	 * Holder for a TestSample
    178 	 *
    179 	 * @author ole.matzura
    180 	 */
    181
    182 	public static final class TestSample
    183 	{
    184 		private final TestStep testStep;
    185 		private List<TestStepResult> results;
    186
    187 		public TestSample( TestStep testStep )
    188 		{
    189 			this.testStep = testStep;
    190 		}
    191
    192 		public void addTestStepResult( TestStepResult result )
    193 		{
    194 			if( result.getTestStep() != testStep )
    195 				throw new RuntimeException( "Trying to add sample for false testStep [" + result.getTestStep().getName() + "], " +
    196 						"expecting [" + testStep.getName() + "]" );
    197
    198 			if( results == null )
    199 				results = new ArrayList<TestStepResult>();
    200
    201 			results.add( result );
    202 		}
    203
    204 		public List<TestStepResult> getResults()
    205 		{
    206 			return results;
    207 		}
    208
    209 		public int getResultCount()
    210 		{
    211 			return results == null ? 0 : results.size();
    212 		}
    213
    214 		public long getResultAverage()
    215 		{
    216 			if( results == null )
    217 				return 0;
    218
    219 			if( results.size() == 1 )
    220 				return results.get( 0 ).getTimeTaken();
    221
    222 			long sum = 0;
    223 			for( TestStepResult result : results )
    224 				sum += result.getTimeTaken();
    225
    226 			return sum / results.size();
    227 		}
    228 	}
    229
    230 	private class InternalTestSuiteListener extends TestSuiteListenerAdapter
    231 	{
    232 		public void testStepAdded(TestStep testStep, int index)
    233 		{
    234 			if( testStep.getTestCase() == testCase )
    235 			{
    236 				testStep.addPropertyChangeListener( TestStep.NAME_PROPERTY, propertyChangeListener );
    237
    238 				// insert null entry in existing samples
    239 				for( int i = 0; i < samples.size(); i++ )
    240 				{
    241 					TestSample [] testSamples = samples.get( i );
    242 					TestSample[] newSamples = new TestSample[testSamples.length+1];
    243 					for( int c = 0; c < testSamples.length; c++ )
    244 					{
    245 						if( c < index )
    246 						{
    247 							newSamples[c] = testSamples[c];
    248 						}
    249 						else
    250 						{
    251 							newSamples[c+1] = testSamples[c];
    252 						}
    253 					}
    254
    255 					samples.set( i, newSamples );
    256 				}
    257
    258 				fireTableStructureChanged();
    259 			}
    260 		}
    261
    262 		public void testStepRemoved(TestStep testStep, int index)
    263 		{
    264 			if( testStep.getTestCase() == testCase )
    265 			{
    266 				testStep.removePropertyChangeListener( propertyChangeListener );
    267
    268 				// remove from samples
    269 				for( int i = 0; i < samples.size(); i++ )
    270 				{
    271 					TestSample [] testSamples = samples.get( i );
    272 					TestSample[] newSamples = new TestSample[testSamples.length-1];
    273 					for( int c = 0; c < testSamples.length; c++ )
    274 					{
    275 						if( c < index )
    276 						{
    277 							newSamples[c] = testSamples[c];
    278 						}
    279 						else if( c > index )
    280 						{
    281 							newSamples[c-1] = testSamples[c];
    282 						}
    283 					}
    284
    285 					samples.set( i, newSamples );
    286 				}
    287
    288 				fireTableStructureChanged();
    289 			}
    290 		}
    291 	}
    292
    293 	private class InternalPropertyChangeListener implements PropertyChangeListener
    294 	{
    295 		public void propertyChange(PropertyChangeEvent evt)
    296 		{
    297 			fireTableStructureChanged();
    298 		}}
    299
    300 }