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 public static final class TestSample
177 {
178 private final TestStep testStep;
179 private List<TestStepResult> results;
180
181 public TestSample( TestStep testStep )
182 {
183 this.testStep = testStep;
184 }
185
186 public void addTestStepResult( TestStepResult result )
187 {
188 if( result.getTestStep() != testStep )
189 throw new RuntimeException( "Trying to add sample for false testStep [" + result.getTestStep().getName() + "], " +
190 "expecting [" + testStep.getName() + "]" );
191
192 if( results == null )
193 results = new ArrayList<TestStepResult>();
194
195 results.add( result );
196 }
197
198 public List<TestStepResult> getResults()
199 {
200 return results;
201 }
202
203 public int getResultCount()
204 {
205 return results == null ? 0 : results.size();
206 }
207
208 public long getResultAverage()
209 {
210 if( results == null )
211 return 0;
212
213 if( results.size() == 1 )
214 return results.get( 0 ).getTimeTaken();
215
216 long sum = 0;
217 for( TestStepResult result : results )
218 sum += result.getTimeTaken();
219
220 return sum / results.size();
221 }
222 }
223
224 private class InternalTestSuiteListener extends TestSuiteListenerAdapter
225 {
226 public void testStepAdded(TestStep testStep, int index)
227 {
228 if( testStep.getTestCase() == testCase )
229 {
230 testStep.addPropertyChangeListener( TestStep.NAME_PROPERTY, propertyChangeListener );
231
232
233 for( int i = 0; i < samples.size(); i++ )
234 {
235 TestSample [] testSamples = samples.get( i );
236 TestSample[] newSamples = new TestSample[testSamples.length+1];
237 for( int c = 0; c < testSamples.length; c++ )
238 {
239 if( c < index )
240 {
241 newSamples[c] = testSamples[c];
242 }
243 else
244 {
245 newSamples[c+1] = testSamples[c];
246 }
247 }
248
249 samples.set( i, newSamples );
250 }
251
252 fireTableStructureChanged();
253 }
254 }
255
256 public void testStepRemoved(TestStep testStep, int index)
257 {
258 if( testStep.getTestCase() == testCase )
259 {
260 testStep.removePropertyChangeListener( propertyChangeListener );
261
262
263 for( int i = 0; i < samples.size(); i++ )
264 {
265 TestSample [] testSamples = samples.get( i );
266 TestSample[] newSamples = new TestSample[testSamples.length-1];
267 for( int c = 0; c < testSamples.length; c++ )
268 {
269 if( c < index )
270 {
271 newSamples[c] = testSamples[c];
272 }
273 else if( c > index )
274 {
275 newSamples[c-1] = testSamples[c];
276 }
277 }
278
279 samples.set( i, newSamples );
280 }
281
282 fireTableStructureChanged();
283 }
284 }
285 }
286
287 private class InternalPropertyChangeListener implements PropertyChangeListener
288 {
289 public void propertyChange(PropertyChangeEvent evt)
290 {
291 fireTableStructureChanged();
292 }}
293
294 }