View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 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.monitor;
14  
15  import java.util.HashMap;
16  import java.util.HashSet;
17  import java.util.Iterator;
18  import java.util.Map;
19  import java.util.Set;
20  
21  import com.eviware.soapui.impl.wsdl.WsdlProject;
22  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
23  import com.eviware.soapui.model.mock.MockRunner;
24  import com.eviware.soapui.model.mock.MockService;
25  import com.eviware.soapui.model.project.Project;
26  import com.eviware.soapui.model.support.LoadTestRunListenerAdapter;
27  import com.eviware.soapui.model.support.MockRunListenerAdapter;
28  import com.eviware.soapui.model.support.ProjectListenerAdapter;
29  import com.eviware.soapui.model.support.TestRunListenerAdapter;
30  import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
31  import com.eviware.soapui.model.support.WorkspaceListenerAdapter;
32  import com.eviware.soapui.model.testsuite.LoadTest;
33  import com.eviware.soapui.model.testsuite.LoadTestRunContext;
34  import com.eviware.soapui.model.testsuite.LoadTestRunner;
35  import com.eviware.soapui.model.testsuite.TestCase;
36  import com.eviware.soapui.model.testsuite.TestRunContext;
37  import com.eviware.soapui.model.testsuite.TestRunner;
38  import com.eviware.soapui.model.testsuite.TestSuite;
39  import com.eviware.soapui.model.workspace.Workspace;
40  
41  /***
42   * Global class for monitoring ongoing test runs (both functional and loadtests)
43   * 
44   * @author Ole.Matzura
45   */
46  
47  public class TestMonitor
48  {
49  	private Set<TestMonitorListener> listeners = new HashSet<TestMonitorListener>();
50  	private InternalWorkspaceListener workspaceListener = new InternalWorkspaceListener();
51  	private InternalProjectListener projectListener = new InternalProjectListener();
52  	private InternalTestSuiteListener testSuiteListener = new InternalTestSuiteListener();
53  	private InternalTestRunListener testRunListener = new InternalTestRunListener();
54  	private InternalMockRunListener mockRunListener = new InternalMockRunListener();
55  	private InternalLoadTestRunListener loadTestRunListener = new InternalLoadTestRunListener();
56  	private Set<TestRunner> runningTestCases = new HashSet<TestRunner>();
57  	private Set<LoadTestRunner> runningLoadTests = new HashSet<LoadTestRunner>();
58  	private Set<MockRunner> runningMockServices = new HashSet<MockRunner>();
59  	private Map<String,TestRunner.Status> runStatusHistory = new HashMap<String, TestRunner.Status>();
60  	
61  	public TestMonitor()
62  	{
63  	}
64  	
65  	public TestRunner.Status getLastRunStatus( TestCase testCase )
66  	{
67  		return runStatusHistory.get( testCase.getId() );
68  	}
69  
70  	protected void notifyLoadTestStarted( LoadTestRunner runner )
71  	{
72  		runningLoadTests.add( runner );
73  
74  		if( listeners.isEmpty() )
75  			return;
76  
77  		TestMonitorListener[] l = listeners.toArray( new TestMonitorListener[listeners.size()] );
78  		for( int c = 0; c < l.length; c++ )
79  		{
80  			l[c].loadTestStarted( runner );
81  		}
82  	}
83  
84  	protected void notifyLoadTestFinished( LoadTestRunner runner )
85  	{
86  		runningLoadTests.remove( runner.getLoadTest().getTestCase() );
87  
88  		if( listeners.isEmpty() )
89  			return;
90  
91  		TestMonitorListener[] l = listeners.toArray( new TestMonitorListener[listeners.size()] );
92  		for( int c = 0; c < l.length; c++ )
93  		{
94  			l[c].loadTestFinished( runner );
95  		}
96  	}
97  
98  	protected void notifyTestCaseStarted( TestRunner runner )
99  	{
100 		if( listeners.isEmpty() )
101 			return;
102 
103 		TestMonitorListener[] l = listeners.toArray( new TestMonitorListener[listeners.size()] );
104 		for( int c = 0; c < l.length; c++ )
105 		{
106 			l[c].testCaseStarted( runner );
107 		}
108 	}
109 
110 	protected void notifyTestCaseFinished( TestRunner runner )
111 	{
112 		if( listeners.isEmpty() )
113 			return;
114 
115 		TestMonitorListener[] l = listeners.toArray( new TestMonitorListener[listeners.size()] );
116 		for( int c = 0; c < l.length; c++ )
117 		{
118 			l[c].testCaseFinished( runner );
119 		}
120 	}
121 
122 	protected void notifyMockServiceStarted( MockRunner runner )
123 	{
124 		if( listeners.isEmpty() )
125 			return;
126 
127 		TestMonitorListener[] l = listeners.toArray( new TestMonitorListener[listeners.size()] );
128 		for( int c = 0; c < l.length; c++ )
129 		{
130 			l[c].mockServiceStarted( runner );
131 		}
132 	}
133 
134 	protected void notifyMockServiceStopped( MockRunner runner )
135 	{
136 		if( listeners.isEmpty() )
137 			return;
138 
139 		TestMonitorListener[] l = listeners.toArray( new TestMonitorListener[listeners.size()] );
140 		for( int c = 0; c < l.length; c++ )
141 		{
142 			l[c].mockServiceStopped( runner );
143 		}
144 	}
145 
146 	public boolean hasRunningLoadTest( TestCase testCase )
147 	{
148 		Iterator<LoadTestRunner> iterator = runningLoadTests.iterator();
149 		while( iterator.hasNext() )
150 		{
151 			if( iterator.next().getLoadTest().getTestCase() == testCase )
152 				return true;
153 		}
154 
155 		return false;
156 	}
157 
158 	public boolean hasRunningTestCase( TestCase testCase )
159 	{
160 		Iterator<TestRunner> iterator = runningTestCases.iterator();
161 		while( iterator.hasNext() )
162 		{
163 			if( iterator.next().getTestCase() == testCase )
164 				return true;
165 		}
166 
167 		return false;
168 	}
169 
170 	public void addTestMonitorListener( TestMonitorListener listener )
171 	{
172 		listeners.add( listener );
173 	}
174 
175 	public void removeTestMonitorListener( TestMonitorListener listener )
176 	{
177 		listeners.remove( listener );
178 	}
179 
180 	private class InternalWorkspaceListener extends WorkspaceListenerAdapter
181 	{
182 		public void projectRemoved( Project project )
183 		{
184 			unmonitorProject( project );
185 		}
186 
187 		public void projectAdded( Project project )
188 		{
189 			monitorProject( project );
190 		}
191 	}
192 
193 	private class InternalProjectListener extends ProjectListenerAdapter
194 	{
195 		public void testSuiteRemoved( TestSuite testSuite )
196 		{
197 			unmonitorTestSuite( testSuite );
198 		}
199 
200 		public void testSuiteAdded( TestSuite testSuite )
201 		{
202 			monitorTestSuite( testSuite );
203 		}
204 
205 		@Override
206 		public void mockServiceAdded( MockService mockService )
207 		{
208 			monitorMockService( mockService );
209 		}
210 
211 		@Override
212 		public void mockServiceRemoved( MockService mockService )
213 		{
214 			unmonitorMockService( mockService );
215 		}
216 	}
217 
218 	private class InternalTestSuiteListener extends TestSuiteListenerAdapter
219 	{
220 		public void testCaseAdded( TestCase testCase )
221 		{
222 			monitorTestCase( testCase );
223 		}
224 
225 		public void testCaseRemoved( TestCase testCase )
226 		{
227 			unmonitorTestCase( testCase );
228 		}
229 
230 		public void loadTestAdded( LoadTest loadTest )
231 		{
232 			monitorLoadTest( loadTest );
233 		}
234 
235 		public void loadTestRemoved( LoadTest loadTest )
236 		{
237 			unmonitorLoadTest( loadTest );
238 		}
239 	}
240 
241 	private class InternalTestRunListener extends TestRunListenerAdapter
242 	{
243 		public void afterRun( TestRunner testRunner, TestRunContext runContext )
244 		{
245 			runStatusHistory.put( testRunner.getTestCase().getId(), testRunner.getStatus() );
246 			
247 			runningTestCases.remove( testRunner );
248 			notifyTestCaseFinished( testRunner );
249 		}
250 
251 		public void beforeRun( TestRunner testRunner, TestRunContext runContext )
252 		{
253 			runningTestCases.add( testRunner );
254 			notifyTestCaseStarted( testRunner );
255 		}
256 	}
257 
258 	private class InternalMockRunListener extends MockRunListenerAdapter
259 	{
260 		@Override
261 		public void onMockRunnerStart( MockRunner mockRunner )
262 		{
263 			runningMockServices.add( mockRunner );
264 			notifyMockServiceStarted( mockRunner );
265 		}
266 
267 		@Override
268 		public void onMockRunnerStop( MockRunner mockRunner )
269 		{
270 			runningMockServices.remove( mockRunner );
271 			notifyMockServiceStopped( mockRunner );
272 		}
273 	}
274 
275 	private class InternalLoadTestRunListener extends LoadTestRunListenerAdapter
276 	{
277 		public void afterLoadTest( LoadTestRunner testRunner, LoadTestRunContext context )
278 		{
279 			runningLoadTests.remove( testRunner );
280 			notifyLoadTestFinished( testRunner );
281 		}
282 
283 		public void beforeLoadTest( LoadTestRunner testRunner, LoadTestRunContext context )
284 		{
285 			runningLoadTests.add( testRunner );
286 			notifyLoadTestStarted( testRunner );
287 		}
288 	}
289 
290 	public LoadTestRunner[] getRunningLoadTest()
291 	{
292 		return runningLoadTests.toArray( new LoadTestRunner[runningLoadTests.size()] );
293 	}
294 
295 	public boolean hasRunningTest( TestCase testCase )
296 	{
297 		return hasRunningLoadTest( testCase ) || hasRunningTestCase( testCase );
298 	}
299 
300 	public void init( Workspace workspace )
301 	{
302 		for( int c = 0; c < workspace.getProjectCount(); c++ )
303 		{
304 			Project project = workspace.getProjectAt( c );
305 			monitorProject( project );
306 		}
307 
308 		workspace.addWorkspaceListener( workspaceListener );
309 	}
310 
311 	public void monitorProject( Project project )
312 	{
313 		project.addProjectListener( projectListener );
314 
315 		for( int i = 0; i < project.getTestSuiteCount(); i++ )
316 		{
317 			monitorTestSuite( project.getTestSuiteAt( i ) );
318 		}
319 
320 		for( int i = 0; i < project.getMockServiceCount(); i++ )
321 		{
322 			monitorMockService( project.getMockServiceAt( i ) );
323 		}
324 	}
325 
326 	private void monitorMockService( MockService mockService )
327 	{
328 		mockService.addMockRunListener( mockRunListener );
329 	}
330 
331 	private void monitorTestSuite( TestSuite testSuite )
332 	{
333 		testSuite.addTestSuiteListener( testSuiteListener );
334 
335 		for( int j = 0; j < testSuite.getTestCaseCount(); j++ )
336 		{
337 			monitorTestCase( testSuite.getTestCaseAt( j ) );
338 		}
339 	}
340 
341 	private void monitorTestCase( TestCase testCase )
342 	{
343 		testCase.addTestRunListener( testRunListener );
344 
345 		for( int v = 0; v < testCase.getLoadTestCount(); v++ )
346 		{
347 			testCase.getLoadTestAt( v ).addLoadTestRunListener( loadTestRunListener );
348 		}
349 	}
350 
351 	private void monitorLoadTest( LoadTest loadTest )
352 	{
353 		loadTest.addLoadTestRunListener( loadTestRunListener );
354 	}
355 
356 	public void unmonitorProject( Project project )
357 	{
358 		project.removeProjectListener( projectListener );
359 
360 		for( int c = 0; c < project.getTestSuiteCount(); c++ )
361 		{
362 			TestSuite testSuite = project.getTestSuiteAt( c );
363 			unmonitorTestSuite( testSuite );
364 		}
365 
366 		for( int c = 0; c < project.getMockServiceCount(); c++ )
367 		{
368 			unmonitorMockService( project.getMockServiceAt( c ) );
369 		}
370 	}
371 
372 	private void unmonitorMockService( MockService mockService )
373 	{
374 		mockService.removeMockRunListener( mockRunListener );
375 	}
376 
377 	private void unmonitorTestSuite( TestSuite testSuite )
378 	{
379 		testSuite.removeTestSuiteListener( testSuiteListener );
380 
381 		for( int j = 0; j < testSuite.getTestCaseCount(); j++ )
382 		{
383 			TestCase testCase = testSuite.getTestCaseAt( j );
384 			unmonitorTestCase( testCase );
385 		}
386 	}
387 
388 	private void unmonitorTestCase( TestCase testCase )
389 	{
390 		testCase.removeTestRunListener( testRunListener );
391 
392 		for( int c = 0; c < testCase.getLoadTestCount(); c++ )
393 		{
394 			unmonitorLoadTest( testCase.getLoadTestAt( c ) );
395 		}
396 	}
397 
398 	private void unmonitorLoadTest( LoadTest loadTest )
399 	{
400 		loadTest.removeLoadTestRunListener( loadTestRunListener );
401 	}
402 
403 	public boolean hasRunningTests()
404 	{
405 		return runningLoadTests.size() + runningTestCases.size() > 0;
406 	}
407 
408 	public boolean hasRunningMock( MockService mockService )
409 	{
410 		for( MockRunner runner : runningMockServices )
411 			if( runner.getMockService() == mockService )
412 				return true;
413 
414 		return false;
415 	}
416 
417 	public boolean hasRunningTests( WsdlProject project )
418 	{
419 		for( TestRunner testRunner : runningTestCases )
420 		{
421 			if( testRunner.getTestCase().getTestSuite().getProject() == project )
422 				return true;
423 		}
424 
425 		for( LoadTestRunner loadTestRunner : runningLoadTests )
426 		{
427 			if( loadTestRunner.getLoadTest().getTestCase().getTestSuite().getProject() == project )
428 				return true;
429 		}
430 
431 		// for( MockRunner mockRunner : runningMockServices )
432 		// {
433 		// if( mockRunner.getMockService().getProject() == project )
434 		// return true;
435 		// }
436 
437 		return false;
438 	}
439 
440 	public void cancelAllTests( String reason )
441 	{
442 		for( TestRunner testRunner : runningTestCases )
443 		{
444 			testRunner.cancel( reason );
445 		}
446 
447 		for( LoadTestRunner loadTestRunner : runningLoadTests )
448 		{
449 			loadTestRunner.cancel( reason );
450 		}
451 
452 		for( MockRunner mockRunner : runningMockServices )
453 		{
454 			mockRunner.stop();
455 		}
456 	}
457 
458 	public TestRunner getTestRunner( WsdlTestCase testCase )
459 	{
460 		Iterator<TestRunner> iterator = runningTestCases.iterator();
461 		while( iterator.hasNext() )
462 		{
463 			TestRunner testRunner = iterator.next();
464 			if( testRunner.getTestCase() == testCase )
465 				return testRunner;
466 		}
467 		
468 		return null;
469 	}
470 }