View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 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.impl.wsdl.loadtest.log;
14  
15  import java.util.ArrayList;
16  import java.util.Collections;
17  import java.util.HashMap;
18  import java.util.List;
19  import java.util.Map;
20  import java.util.Queue;
21  import java.util.concurrent.ConcurrentLinkedQueue;
22  
23  import javax.swing.AbstractListModel;
24  
25  import com.eviware.soapui.SoapUI;
26  import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTest;
27  import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
28  import com.eviware.soapui.model.testsuite.TestStep;
29  
30  /***
31   * Log for LoadTest events
32   * 
33   * @author Ole.Matzura
34   */
35  
36  public class LoadTestLog extends AbstractListModel implements Runnable
37  {
38  	private List<LoadTestLogEntry> entries = Collections.synchronizedList( new ArrayList<LoadTestLogEntry>() );
39  	private final WsdlLoadTest loadTest;
40  	private int totalErrorCount;
41  	private Map<String, Integer> errorCounts = new HashMap<String, Integer>();
42  	private Queue<LoadTestLogEntry> entriesStack = new ConcurrentLinkedQueue<LoadTestLogEntry>();
43  	private Thread modelThread;
44  	private InternalTestSuiteListener testSuiteListener = new InternalTestSuiteListener();
45  
46  	public LoadTestLog( WsdlLoadTest loadTest )
47  	{
48  		this.loadTest = loadTest;
49  		loadTest.getTestCase().getTestSuite().addTestSuiteListener( testSuiteListener );
50  	}
51  
52  	public void release()
53  	{
54  		loadTest.getTestCase().getTestSuite().removeTestSuiteListener( testSuiteListener );
55  	}
56  
57  	public int getSize()
58  	{
59  		return entries.size();
60  	}
61  
62  	public Object getElementAt( int index )
63  	{
64  		return entries.get( index );
65  	}
66  
67  	public synchronized void addEntry( LoadTestLogEntry entry )
68  	{
69  		entriesStack.add( entry );
70  
71  		if( modelThread == null )
72  		{
73  			modelThread = new Thread( this, loadTest.getName() + " LoadTestLog Updater" );
74  			modelThread.start();
75  		}
76  	}
77  
78  	public void run()
79  	{
80  		// always run at least once
81  		while( true )
82  		{
83  			try
84  			{
85  				while( !entriesStack.isEmpty() )
86  				{
87  					int cnt = 0;
88  					while( cnt < 10 && !entriesStack.isEmpty() )
89  					{
90  						LoadTestLogEntry entry = entriesStack.poll();
91  						if( entry != null )
92  						{
93  							entries.add( entry );
94  							if( entry.isError() )
95  							{
96  								totalErrorCount++ ;
97  								String stepName = entry.getTargetStepName();
98  
99  								Integer errorCount = errorCounts.get( stepName );
100 								if( errorCount == null )
101 									errorCount = 1;
102 								else
103 									errorCount = errorCount + 1;
104 
105 								errorCounts.put( stepName, errorCount );
106 							}
107 
108 							cnt++ ;
109 						}
110 					}
111 
112 					if( cnt > 0 )
113 						fireIntervalAdded( this, entries.size() - cnt, entries.size() - 1 );
114 				}
115 
116 				// break if load test is not running
117 				if( !loadTest.isRunning() )
118 					break;
119 
120 				Thread.sleep( 200 );
121 			}
122 			catch( Exception e )
123 			{
124 				SoapUI.logError( e );
125 			}
126 		}
127 
128 		modelThread = null;
129 	}
130 
131 	public void clear()
132 	{
133 		entriesStack.clear();
134 
135 		if( !entries.isEmpty() )
136 		{
137 			int size = entries.size();
138 			entries.clear();
139 			fireIntervalRemoved( this, 0, size - 1 );
140 			totalErrorCount = 0;
141 			errorCounts.clear();
142 		}
143 	}
144 
145 	public void clearErrors()
146 	{
147 		int sz = entries.size();
148 
149 		for( int c = 0; c < entries.size(); c++ )
150 		{
151 			if( entries.get( c ).isError() )
152 			{
153 				entries.remove( c );
154 				c-- ;
155 			}
156 		}
157 
158 		totalErrorCount = 0;
159 		errorCounts.clear();
160 
161 		if( sz > entries.size() )
162 		{
163 			fireIntervalRemoved( this, entries.size(), sz );
164 			fireContentsChanged( this, 0, entries.size() );
165 		}
166 	}
167 
168 	public void clearEntries( TestStep testStep )
169 	{
170 		int sz = entries.size();
171 
172 		String testStepName = testStep.getName();
173 		for( int c = 0; c < entries.size(); c++ )
174 		{
175 			if( testStepName.equals( entries.get( c ).getTargetStepName() ) )
176 			{
177 				entries.remove( c );
178 				c-- ;
179 			}
180 		}
181 
182 		if( errorCounts.containsKey( testStepName ) )
183 		{
184 			totalErrorCount -= errorCounts.get( testStepName ).intValue();
185 			errorCounts.remove( testStepName );
186 		}
187 
188 		if( sz > entries.size() )
189 		{
190 			fireIntervalRemoved( this, entries.size(), sz );
191 			fireContentsChanged( this, 0, entries.size() );
192 		}
193 	}
194 
195 	public WsdlLoadTest getLoadTest()
196 	{
197 		return loadTest;
198 	}
199 
200 	public int getErrorCount( String stepName )
201 	{
202 		if( stepName == null )
203 			return totalErrorCount;
204 
205 		Integer counts = errorCounts.get( stepName );
206 		return counts == null ? 0 : counts;
207 	}
208 
209 	private final class InternalTestSuiteListener extends TestSuiteListenerAdapter
210 	{
211 		public void testStepRemoved( TestStep testStep, int index )
212 		{
213 			if( testStep.getTestCase() == loadTest.getTestCase() )
214 			{
215 				clearEntries( testStep );
216 			}
217 		}
218 	}
219 
220 	public List<LoadTestLogEntry> getEntries()
221 	{
222 		return entries;
223 	}
224 }