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.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
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
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 }