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.teststeps;
14  
15  import java.util.ArrayList;
16  import java.util.List;
17  
18  import javax.swing.SwingUtilities;
19  
20  import com.eviware.soapui.SoapUI;
21  import com.eviware.soapui.config.TestStepConfig;
22  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
23  import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
24  import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
25  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContainer;
26  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
27  import com.eviware.soapui.model.support.DefaultTestStepProperty;
28  import com.eviware.soapui.model.testsuite.TestCaseRunContext;
29  import com.eviware.soapui.model.testsuite.TestCaseRunner;
30  import com.eviware.soapui.model.testsuite.TestStepResult;
31  import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus;
32  import com.eviware.soapui.support.UISupport;
33  import com.eviware.soapui.support.xml.XmlObjectConfigurationBuilder;
34  import com.eviware.soapui.support.xml.XmlObjectConfigurationReader;
35  
36  /***
37   * TestStep that delays execution for a number of milliseconds
38   * 
39   * @author ole.matzura
40   */
41  
42  public class WsdlDelayTestStep extends WsdlTestStepWithProperties implements PropertyExpansionContainer
43  {
44  	private static final String DEFAULT_DELAY = "1000";
45  	private static final int DELAY_CHUNK = 100;
46  	private int delay = 0;
47  	private String delayString = WsdlDelayTestStep.DEFAULT_DELAY;
48  	private int timeWaited = 0;
49  	private boolean canceled;
50  	private boolean running;
51  
52  	public WsdlDelayTestStep( WsdlTestCase testCase, TestStepConfig config, boolean forLoadTest )
53  	{
54  		super( testCase, config, false, forLoadTest );
55  
56  		if( !forLoadTest )
57  		{
58  			setIcon( UISupport.createImageIcon( "/wait.gif" ) );
59  		}
60  
61  		if( config.getConfig() == null )
62  		{
63  			if( !forLoadTest )
64  				saveDelay( config );
65  		}
66  		else
67  		{
68  			readConfig( config );
69  		}
70  
71  		addProperty( new DefaultTestStepProperty( "delay", true, new DefaultTestStepProperty.PropertyHandlerAdapter()
72  		{
73  
74  			@Override
75  			public String getValue( DefaultTestStepProperty property )
76  			{
77  				return getDelayString();
78  			}
79  
80  			@Override
81  			public void setValue( DefaultTestStepProperty property, String value )
82  			{
83  				setDelayString( value );
84  			}
85  		}, this ) );
86  	}
87  
88  	private void readConfig( TestStepConfig config )
89  	{
90  		XmlObjectConfigurationReader reader = new XmlObjectConfigurationReader( config.getConfig() );
91  		delayString = reader.readString( "delay", DEFAULT_DELAY );
92  	}
93  
94  	@Override
95  	public String getLabel()
96  	{
97  		String str = running ? super.getName() + " [" + ( delay - timeWaited ) + "ms]" : super.getName() + " ["
98  				+ delayString + "]";
99  
100 		if( isDisabled() )
101 			str += " (disabled)";
102 
103 		return str;
104 	}
105 
106 	@Override
107 	public String getDefaultSourcePropertyName()
108 	{
109 		return "delay";
110 	}
111 
112 	@Override
113 	public String getDefaultTargetPropertyName()
114 	{
115 		return "delay";
116 	}
117 
118 	public PropertyExpansion[] getPropertyExpansions()
119 	{
120 		List<PropertyExpansion> result = new ArrayList<PropertyExpansion>();
121 		result.addAll( PropertyExpansionUtils.extractPropertyExpansions( this, this, "delayString" ) );
122 		return result.toArray( new PropertyExpansion[result.size()] );
123 	}
124 
125 	private void saveDelay( TestStepConfig config )
126 	{
127 		XmlObjectConfigurationBuilder builder = new XmlObjectConfigurationBuilder();
128 		builder.add( "delay", delayString );
129 		config.setConfig( builder.finish() );
130 	}
131 
132 	@Override
133 	public void resetConfigOnMove( TestStepConfig config )
134 	{
135 		super.resetConfigOnMove( config );
136 		readConfig( config );
137 	}
138 
139 	public void setDelayString( String delayString )
140 	{
141 		if( this.delayString.equals( delayString ) )
142 			return;
143 
144 		String oldLabel = getLabel();
145 
146 		this.delayString = delayString;
147 		saveDelay( getConfig() );
148 		notifyPropertyChanged( WsdlTestStep.LABEL_PROPERTY, oldLabel, getLabel() );
149 	}
150 
151 	public String getDelayString()
152 	{
153 		return delayString;
154 	}
155 
156 	public int getDelay()
157 	{
158 		try
159 		{
160 			return Integer.parseInt( PropertyExpander.expandProperties( this, delayString ) );
161 		}
162 		catch( NumberFormatException e )
163 		{
164 			return -1;
165 		}
166 	}
167 
168 	public void setDelay( int delay )
169 	{
170 		String oldLabel = getLabel();
171 
172 		this.delayString = String.valueOf( delay );
173 		saveDelay( getConfig() );
174 		notifyPropertyChanged( WsdlTestStep.LABEL_PROPERTY, oldLabel, getLabel() );
175 	}
176 
177 	public TestStepResult run( TestCaseRunner testRunner, TestCaseRunContext context )
178 	{
179 		WsdlTestStepResult result = new WsdlTestStepResult( this );
180 		result.startTimer();
181 		String oldLabel = getLabel();
182 
183 		try
184 		{
185 			canceled = false;
186 			running = true;
187 
188 			try
189 			{
190 				delay = Integer.parseInt( PropertyExpander.expandProperties( context, delayString ) );
191 			}
192 			catch( NumberFormatException e )
193 			{
194 				delay = Integer.parseInt( DEFAULT_DELAY );
195 			}
196 
197 			// sleep in chunks for canceling
198 			final long stopTime = System.nanoTime() + ( long )delay * 1000000;
199 			int lastUpdate = 0;
200 			while( !canceled && timeWaited < delay )
201 			{
202 				if( timeWaited - lastUpdate > 1000 && context.getProperty( TestCaseRunContext.LOAD_TEST_RUNNER ) == null )
203 				{
204 					String newLabel = getLabel();
205 					if( !UISupport.isHeadless() )
206 					{
207 						final String finalOldLabel = oldLabel, finalNewLabel = newLabel;
208 						SwingUtilities.invokeLater( new Runnable()
209 						{
210 							public void run()
211 							{
212 								notifyPropertyChanged( WsdlTestStep.LABEL_PROPERTY, finalOldLabel, finalNewLabel );
213 							}
214 						} );
215 					}
216 					oldLabel = newLabel;
217 					lastUpdate = timeWaited;
218 				}
219 
220 				Thread.sleep( Math.min( DELAY_CHUNK, delay - timeWaited ) );
221 				timeWaited = delay - ( int )( ( stopTime - System.nanoTime() ) / 1000000 );
222 			}
223 		}
224 		catch( InterruptedException e )
225 		{
226 			SoapUI.logError( e );
227 		}
228 
229 		result.stopTimer();
230 		result.setStatus( canceled ? TestStepStatus.CANCELED : TestStepStatus.OK );
231 
232 		timeWaited = 0;
233 		running = false;
234 
235 		if( context.getProperty( TestCaseRunContext.LOAD_TEST_RUNNER ) == null )
236 			notifyPropertyChanged( WsdlTestStep.LABEL_PROPERTY, oldLabel, getLabel() );
237 
238 		return result;
239 	}
240 
241 	@Override
242 	public boolean cancel()
243 	{
244 		canceled = true;
245 		return true;
246 	}
247 }