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.util.ArrayList;
16 import java.util.EnumMap;
17 import java.util.HashMap;
18 import java.util.List;
19 import java.util.Map;
20
21 import javax.swing.event.TableModelEvent;
22 import javax.swing.event.TableModelListener;
23 import javax.swing.table.AbstractTableModel;
24
25 import org.apache.log4j.Logger;
26
27 import com.eviware.soapui.SoapUI;
28 import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTest;
29 import com.eviware.soapui.impl.wsdl.loadtest.data.LoadTestStatistics.Statistic;
30 import com.eviware.soapui.model.support.LoadTestRunListenerAdapter;
31 import com.eviware.soapui.model.testsuite.LoadTestRunContext;
32 import com.eviware.soapui.model.testsuite.LoadTestRunner;
33
34 /***
35 * Collector of statistics to be exposed as TableModels
36 *
37 * @author Ole.Matzura
38 */
39
40 public class StatisticsHistory
41 {
42 private final LoadTestStatistics statistics;
43 private List<long[][]> data = new ArrayList<long[][]>();
44 private List<Long> threadCounts = new ArrayList<Long>();
45 private Map<Integer,TestStepStatisticsHistory> testStepStatisticHistories =
46 new HashMap<Integer,TestStepStatisticsHistory>();
47 private EnumMap<Statistic,StatisticsValueHistory> statisticsValueHistories =
48 new EnumMap<Statistic,StatisticsValueHistory>( Statistic.class );
49
50 @SuppressWarnings("unused")
51 private final static Logger logger = Logger.getLogger( StatisticsHistory.class );
52 private long resolution = 0;
53 private InternalTableModelListener internalTableModelListener = new InternalTableModelListener();
54 private Updater updater = new Updater();
55
56 public StatisticsHistory( LoadTestStatistics statistics )
57 {
58 this.statistics = statistics;
59
60 statistics.addTableModelListener( internalTableModelListener );
61 statistics.getLoadTest().addLoadTestRunListener( new LoadTestRunListenerAdapter() {
62
63 public void beforeLoadTest( LoadTestRunner loadTestRunner, LoadTestRunContext context )
64 {
65 if( resolution > 0 )
66 new Thread( updater, StatisticsHistory.this.statistics.getLoadTest().getName() + " StatisticsHistory Updater" ).start();
67 }
68 } );
69 }
70
71 public long getResolution()
72 {
73 return resolution;
74 }
75
76 public void setResolution( long resolution )
77 {
78 long old = this.resolution;
79 this.resolution = resolution;
80
81 if( resolution > 0 && old == 0 && statistics.getLoadTest().getHistoryLimit() != 0 )
82 {
83 new Thread( updater, statistics.getLoadTest().getName() + " StatisticsHistory Updater" ).start();
84 }
85 }
86
87 public int getRowCount()
88 {
89 return data.size();
90 }
91
92 public long[][] getHistoryAt( int index )
93 {
94 return data.get( index );
95 }
96
97 public long getThreadCountAt( int index )
98 {
99 return threadCounts.get( index );
100 }
101
102 public StatisticsHistoryModel getTestStepHistory( int testStepIndex )
103 {
104 if( !testStepStatisticHistories.containsKey( testStepIndex ))
105 {
106 testStepStatisticHistories.put( testStepIndex, new TestStepStatisticsHistory( testStepIndex ));
107 }
108
109 return testStepStatisticHistories.get( testStepIndex );
110 }
111
112 public StatisticsHistoryModel getStatisticsValueHistory( Statistic statistic )
113 {
114 if( !statisticsValueHistories.containsKey( statistic ))
115 {
116 statisticsValueHistories.put( statistic, new StatisticsValueHistory( statistic ) );
117 }
118
119 return statisticsValueHistories.get( statistic );
120 }
121
122 public void reset()
123 {
124 data.clear();
125 threadCounts.clear();
126
127 for( StatisticsValueHistory history : statisticsValueHistories.values() )
128 {
129 history.fireTableDataChanged();
130 history.fireTableStructureChanged();
131 }
132
133 for( TestStepStatisticsHistory history : testStepStatisticHistories.values() )
134 {
135 history.fireTableDataChanged();
136 history.fireTableStructureChanged();
137 }
138 }
139
140 private synchronized void updateHistory()
141 {
142 if( statistics.getStatistic( LoadTestStatistics.TOTAL, Statistic.COUNT ) == 0 )
143 {
144 reset();
145 }
146 else
147 {
148 int columnCount = statistics.getColumnCount();
149 int rowCount = statistics.getRowCount();
150
151 long[][] values = new long[rowCount][columnCount-2];
152
153 for( int c = 0; c < rowCount; c++ )
154 {
155 for( int i = 2; i< columnCount; i++ )
156 {
157 try
158 {
159 values[c][i - 2] = Long.parseLong(statistics.getValueAt(c, i).toString());
160 }
161 catch (NumberFormatException ex)
162 {
163 values[c][i - 2] = (long) Float.parseFloat(statistics.getValueAt(c, i).toString());
164 }
165 }
166 }
167
168 data.add( values );
169 threadCounts.add( statistics.getLoadTest().getThreadCount() );
170
171
172 int sz = data.size()-1;
173 for( StatisticsValueHistory history : statisticsValueHistories.values() )
174 {
175 history.fireTableRowsInserted( sz, sz );
176 }
177
178 for( TestStepStatisticsHistory history : testStepStatisticHistories.values() )
179 {
180 history.fireTableRowsInserted( sz, sz );
181 }
182 }
183 }
184
185 public abstract class StatisticsHistoryModel extends AbstractTableModel
186 {
187 public abstract void release();
188 }
189
190 private class TestStepStatisticsHistory extends StatisticsHistoryModel
191 {
192 private final int testStepIndex;
193
194 public TestStepStatisticsHistory(int testStepIndex)
195 {
196 this.testStepIndex = testStepIndex == -1 ? statistics.getRowCount()-1 : testStepIndex;
197 }
198
199 public int getTestStepIndex()
200 {
201 return testStepIndex;
202 }
203
204 public int getRowCount()
205 {
206 return data.size();
207 }
208
209 public int getColumnCount()
210 {
211 return statistics.getColumnCount()-1;
212 }
213
214 public Object getValueAt(int rowIndex, int columnIndex)
215 {
216 if( columnIndex == 0 ) return threadCounts.get( rowIndex );
217
218
219 if( rowIndex < data.size() )
220 return data.get( rowIndex )[testStepIndex][columnIndex-1];
221 else return
222 new Long( 0 );
223 }
224
225 public Class<?> getColumnClass(int columnIndex)
226 {
227 return Long.class;
228 }
229
230 public String getColumnName(int column)
231 {
232 return column == 0 ? "ThreadCount" :
233 Statistic.forIndex( column-1 ).getName();
234 }
235
236 public void release()
237 {
238 testStepStatisticHistories.remove( testStepIndex );
239 }
240 }
241
242 private class StatisticsValueHistory extends StatisticsHistoryModel
243 {
244 private final Statistic statistic;
245
246 public StatisticsValueHistory(Statistic statistic)
247 {
248 this.statistic = statistic;
249 }
250
251 public Statistic getStatistic()
252 {
253 return statistic;
254 }
255
256 public int getRowCount()
257 {
258 return data.size();
259 }
260
261 public int getColumnCount()
262 {
263 return statistics.getRowCount()+1;
264 }
265
266 public Object getValueAt(int rowIndex, int columnIndex)
267 {
268 if( columnIndex == 0 )
269 return threadCounts.get( rowIndex );
270
271 return data.get( rowIndex )[columnIndex-1][statistic.getIndex()];
272 }
273
274 public Class<?> getColumnClass(int columnIndex)
275 {
276 return Long.class;
277 }
278
279 public String getColumnName(int column)
280 {
281 if( column == 0 )
282 return "ThreadCount";
283
284 if( column == statistics.getRowCount() )
285 return "Total";
286
287 return statistics.getLoadTest().getTestCase().getTestStepAt( column-1 ).getName();
288 }
289
290 public void release()
291 {
292 statisticsValueHistories.remove( statistic );
293 }
294 }
295
296 private class InternalTableModelListener implements TableModelListener
297 {
298 public synchronized void tableChanged(TableModelEvent e)
299 {
300 if( (resolution > 0 && statistics.getLoadTest().isRunning()) ||
301 e.getType() != TableModelEvent.UPDATE ||
302 statistics.getLoadTest().getHistoryLimit() == 0 ) return;
303
304 updateHistory();
305 }
306 }
307
308 private final class Updater implements Runnable
309 {
310 public void run()
311 {
312 WsdlLoadTest loadTest = statistics.getLoadTest();
313
314 while( resolution > 0 && loadTest.isRunning() )
315 {
316 try
317 {
318 if( loadTest.getHistoryLimit() != 0 )
319 updateHistory();
320
321
322 long res = resolution;
323 while( res > 100 && resolution > 0 && loadTest.isRunning() )
324 {
325 Thread.sleep( res );
326 res -= 100;
327 }
328
329 if( resolution > 0 && loadTest.isRunning() )
330 Thread.sleep( res );
331 }
332 catch( InterruptedException e )
333 {
334 SoapUI.logError( e );
335 break;
336 }
337 }
338 }
339 }
340 }