1
2
3
4
5
6
7
8
9
10
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.TestCaseRunContext;
33 import com.eviware.soapui.model.testsuite.TestCaseRunner;
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 + ", expected "
89 + 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, TestCaseRunner testRunner,
125 TestCaseRunContext runContext )
126 {
127 Map<TestStep, TestSample> samplesMap = new HashMap<TestStep, TestSample>();
128 List<TestStepResult> results = testRunner.getResults();
129
130 for( int c = 0; c < results.size(); c++ )
131 {
132 TestStepResult result = results.get( c );
133 if( result == null )
134 {
135 log.warn( "Result [" + c + "] is null in TestCase [" + testCase.getName() + "]" );
136 continue;
137 }
138
139 TestStep testStep = result.getTestStep();
140
141 if( !samplesMap.containsKey( testStep ) )
142 {
143 samplesMap.put( testStep, new TestSample( testStep ) );
144 }
145
146 samplesMap.get( testStep ).addTestStepResult( result );
147 }
148
149 TestCase testCase = loadTest.getTestCase();
150
151 TestSample[] samples = new TestSample[testCase.getTestStepCount()];
152 for( int c = 0; c < samples.length; c++ )
153 {
154 samples[c] = samplesMap.get( testCase.getTestStepAt( c ) );
155 }
156
157 addSamples( samples );
158 }
159 }
160
161 public List<TestSample[]> getSamples()
162 {
163 return samples;
164 }
165
166 public void release()
167 {
168 loadTest.removeLoadTestRunListener( testRunListener );
169 loadTest.getTestCase().getTestSuite().removeTestSuiteListener( testSuiteListener );
170
171 for( TestStep testStep : loadTest.getTestCase().getTestStepList() )
172 {
173 testStep.removePropertyChangeListener( propertyChangeListener );
174 }
175 }
176
177 /***
178 * Holder for a TestSample
179 *
180 * @author ole.matzura
181 */
182
183 public static final class TestSample
184 {
185 private final TestStep testStep;
186 private List<TestStepResult> results;
187
188 public TestSample( TestStep testStep )
189 {
190 this.testStep = testStep;
191 }
192
193 public void addTestStepResult( TestStepResult result )
194 {
195 if( result.getTestStep() != testStep )
196 throw new RuntimeException( "Trying to add sample for false testStep [" + result.getTestStep().getName()
197 + "], " + "expecting [" + testStep.getName() + "]" );
198
199 if( results == null )
200 results = new ArrayList<TestStepResult>();
201
202 results.add( result );
203 }
204
205 public List<TestStepResult> getResults()
206 {
207 return results;
208 }
209
210 public int getResultCount()
211 {
212 return results == null ? 0 : results.size();
213 }
214
215 public long getResultAverage()
216 {
217 if( results == null )
218 return 0;
219
220 if( results.size() == 1 )
221 return results.get( 0 ).getTimeTaken();
222
223 long sum = 0;
224 for( TestStepResult result : results )
225 sum += result.getTimeTaken();
226
227 return sum / results.size();
228 }
229 }
230
231 private class InternalTestSuiteListener extends TestSuiteListenerAdapter
232 {
233 public void testStepAdded( TestStep testStep, int index )
234 {
235 if( testStep.getTestCase() == testCase )
236 {
237 testStep.addPropertyChangeListener( TestStep.NAME_PROPERTY, propertyChangeListener );
238
239
240 for( int i = 0; i < samples.size(); i++ )
241 {
242 TestSample[] testSamples = samples.get( i );
243 TestSample[] newSamples = new TestSample[testSamples.length + 1];
244 for( int c = 0; c < testSamples.length; c++ )
245 {
246 if( c < index )
247 {
248 newSamples[c] = testSamples[c];
249 }
250 else
251 {
252 newSamples[c + 1] = testSamples[c];
253 }
254 }
255
256 samples.set( i, newSamples );
257 }
258
259 fireTableStructureChanged();
260 }
261 }
262
263 public void testStepRemoved( TestStep testStep, int index )
264 {
265 if( testStep.getTestCase() == testCase )
266 {
267 testStep.removePropertyChangeListener( propertyChangeListener );
268
269
270 for( int i = 0; i < samples.size(); i++ )
271 {
272 TestSample[] testSamples = samples.get( i );
273 TestSample[] newSamples = new TestSample[testSamples.length - 1];
274 for( int c = 0; c < testSamples.length; c++ )
275 {
276 if( c < index )
277 {
278 newSamples[c] = testSamples[c];
279 }
280 else if( c > index )
281 {
282 newSamples[c - 1] = testSamples[c];
283 }
284 }
285
286 samples.set( i, newSamples );
287 }
288
289 fireTableStructureChanged();
290 }
291 }
292 }
293
294 private class InternalPropertyChangeListener implements PropertyChangeListener
295 {
296 public void propertyChange( PropertyChangeEvent evt )
297 {
298 fireTableStructureChanged();
299 }
300 }
301
302 }