View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 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.actions.iface.tools.soapui;
14  
15  import java.io.File;
16  import java.io.IOException;
17  import java.util.ArrayList;
18  import java.util.Arrays;
19  import java.util.List;
20  
21  import javax.swing.Action;
22  
23  import org.apache.log4j.Logger;
24  
25  import com.eviware.soapui.SoapUI;
26  import com.eviware.soapui.impl.wsdl.WsdlProject;
27  import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
28  import com.eviware.soapui.impl.wsdl.actions.iface.tools.support.AbstractToolsAction;
29  import com.eviware.soapui.impl.wsdl.actions.iface.tools.support.ArgumentBuilder;
30  import com.eviware.soapui.impl.wsdl.actions.iface.tools.support.ProcessToolRunner;
31  import com.eviware.soapui.impl.wsdl.actions.iface.tools.support.ToolHost;
32  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
33  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
34  import com.eviware.soapui.model.iface.Interface;
35  import com.eviware.soapui.model.support.ModelSupport;
36  import com.eviware.soapui.model.testsuite.TestCase;
37  import com.eviware.soapui.model.testsuite.TestSuite;
38  import com.eviware.soapui.support.StringUtils;
39  import com.eviware.soapui.support.UISupport;
40  import com.eviware.soapui.support.types.StringToStringMap;
41  import com.eviware.x.form.XForm;
42  import com.eviware.x.form.XFormDialog;
43  import com.eviware.x.form.XFormDialogBuilder;
44  import com.eviware.x.form.XFormFactory;
45  import com.eviware.x.form.XFormField;
46  import com.eviware.x.form.XFormFieldListener;
47  
48  /***
49   * Invokes soapUI TestRunner tool
50   * 
51   * @author Ole.Matzura
52   */
53  
54  public class TestRunnerAction extends AbstractToolsAction<WsdlProject>
55  {
56  	private static final String ALL_VALUE = "<all>";
57  	private static final String ENDPOINT = "Endpoint";
58  	private static final String HOSTPORT = "Host:Port";
59  	private static final String TESTSUITE = "TestSuite";
60  	private static final String TESTCASE = "TestCase";
61  	private static final String USERNAME = "Username";
62  	private static final String PASSWORD = "Password";
63  	private static final String WSSTYPE = "WSS Password Type";
64  	private static final String DOMAIN = "Domain";
65  	private static final String PRINTREPORT = "Print Report";
66  	private static final String ROOTFOLDER = "Root Folder";
67  	private static final String EXPORTJUNITRESULTS = "Export JUnit Results";
68  	private static final String EXPORTALL = "Export All";
69  	private static final String ENABLEUI = "Enable UI";
70  	private static final String TESTRUNNERPATH = "TestRunner Path";
71  	private static final String SAVEPROJECT = "Save Project";
72  	private static final String ADDSETTINGS = "Add Settings";
73  	private static final String OPEN_REPORT = "Open Report";
74  	
75  	private XForm mainForm;
76  	private final static Logger log = Logger.getLogger(TestRunnerAction.class);
77  	public static final String SOAPUI_ACTION_ID = "TestRunnerAction";
78  	private XForm advForm;
79  	private List<TestSuite> testSuites;
80  	
81     public TestRunnerAction()
82     {
83        super( "Launch TestRunner", "Launch command-line TestRunner for this project");
84     }
85  
86     protected XFormDialog buildDialog( WsdlProject modelItem)
87  	{
88     	if( modelItem == null )
89     		return null;
90     	
91        XFormDialogBuilder builder = XFormFactory.createDialogBuilder("Launch TestRunner");
92  
93  		mainForm = builder.createForm( "Basic" );
94  		mainForm.addComboBox( TESTSUITE, new String[] {}, "The TestSuite to run" ).addFormFieldListener( new XFormFieldListener() {
95  
96  			public void valueChanged( XFormField sourceField, String newValue, String oldValue )
97  			{
98  				List<String> testCases = new ArrayList<String>();
99  				String tc = mainForm.getComponentValue( TESTCASE );
100 				
101 				if( newValue.equals( ALL_VALUE ))
102 				{
103 					for( TestSuite	testSuite : testSuites )
104 					{
105 						for( TestCase testCase : testSuite.getTestCaseList() )
106 						{
107 							if( !testCases.contains( testCase.getName() ))
108 								testCases.add( testCase.getName()  );
109 						}
110 					}
111 				}
112 				else
113 				{
114 					TestSuite testSuite = getModelItem().getTestSuiteByName( newValue );
115 					if( testSuite != null )
116 						testCases.addAll( Arrays.asList( ModelSupport.getNames( testSuite.getTestCaseList() ) ));
117 				}
118 				
119 				testCases.add( 0, ALL_VALUE );
120 				mainForm.setOptions( TESTCASE, testCases.toArray() );
121 				
122 				if( testCases.contains( tc ))
123 				{
124 					mainForm.getFormField( TESTCASE ).setValue( tc );
125 				}
126 			}} );
127 		
128 		mainForm.addComboBox( TESTCASE, new String[] {}, "The TestCase to run" );
129 		mainForm.addSeparator();
130 		mainForm.addCheckBox( PRINTREPORT, "Prints a summary report to the console" );
131 		mainForm.addCheckBox( EXPORTJUNITRESULTS, "Exports results to a JUnit-Style report" );
132 		mainForm.addCheckBox( EXPORTALL, "Exports all results (not only errors)" );
133 		mainForm.addTextField( ROOTFOLDER, "Folder to export to", XForm.FieldType.FOLDER );
134 		mainForm.addCheckBox( OPEN_REPORT, "Open generated HTML report in browser (soapUI Pro only)" );
135 		mainForm.addSeparator();
136 		mainForm.addCheckBox( ENABLEUI, "Enables UI components in scripts" );
137 		mainForm.addTextField( TESTRUNNERPATH, "Folder containing TestRunner.bat to use", XForm.FieldType.FOLDER );
138 		mainForm.addCheckBox( SAVEPROJECT, "Saves project before running" );
139 		mainForm.addCheckBox( ADDSETTINGS, "Adds global settings to command-line" );
140 		
141 		advForm = builder.createForm( "Overrides" );
142 		advForm.addComboBox( ENDPOINT, new String[] {""}, "endpoint to forward to" );
143 		advForm.addTextField( HOSTPORT, "Host:Port to use for requests", XForm.FieldType.TEXT );
144 		advForm.addSeparator();
145 		advForm.addTextField( USERNAME, "The username to set for all requests", XForm.FieldType.TEXT );
146 		advForm.addTextField( PASSWORD, "The password to set for all requests", XForm.FieldType.PASSWORD );
147 		advForm.addTextField( DOMAIN, "The domain to set for all requests", XForm.FieldType.TEXT );
148 		advForm.addComboBox( WSSTYPE, new String[] {"", "Text", "Digest"},
149 					"The username to set for all requests" );
150       
151 		setToolsSettingsAction( null );
152 		buildArgsForm( builder, false, "TestRunner" );
153 		
154 		return builder.buildDialog( buildDefaultActions(HelpUrls.TESTRUNNER_HELP_URL, modelItem),
155       		"Specify arguments for launching soapUI TestRunner", UISupport.TOOL_ICON );
156 	}
157    
158 	protected Action createRunOption( WsdlProject modelItem)
159 	{
160 		Action action = super.createRunOption( modelItem );
161 		action.putValue( Action.NAME, "Launch" );
162 		return action;
163 	}
164 
165 	protected StringToStringMap initValues(WsdlProject modelItem, Object param)
166 	{
167 		if( modelItem != null && mainForm != null )
168 		{
169 			List<String> endpoints = new ArrayList<String>();
170 			
171 			for( Interface iface : modelItem.getInterfaceList())
172 			{
173 				for( String endpoint : iface.getEndpoints() )
174 				{
175 					if( !endpoints.contains( endpoint ))
176 						endpoints.add( endpoint );
177 				}
178 			}
179 			
180 			endpoints.add( 0, null );
181 			advForm.setOptions( ENDPOINT, endpoints.toArray() );
182 			
183 			testSuites = modelItem.getTestSuiteList();
184 			for( int c = 0; c < testSuites.size(); c++ )
185 			{
186 				if( testSuites.get( c ).getTestCaseCount() == 0 )
187 				{
188 					testSuites.remove( c );
189 					c--;
190 				}
191 			}
192 			
193 			mainForm.setOptions( TESTSUITE, ModelSupport.getNames( new String[]{ALL_VALUE}, testSuites ) );
194 
195 			List<String> testCases = new ArrayList<String>();
196 			
197 			for( TestSuite	testSuite : testSuites )
198 			{
199 				for( TestCase testCase : testSuite.getTestCaseList() )
200 				{
201 					if( !testCases.contains( testCase.getName() ))
202 						testCases.add( testCase.getName()  );
203 				}
204 			}
205 			
206 			testCases.add( 0, ALL_VALUE );
207 			mainForm.setOptions( TESTCASE, testCases.toArray() );
208 		}
209 		else if( mainForm != null )
210 		{
211 			mainForm.setOptions( ENDPOINT, new String[] { null } );
212 		}
213 		
214 		StringToStringMap values = super.initValues( modelItem,  param );
215 
216 		if( mainForm != null )
217 		{
218 			if( param instanceof WsdlTestCase )
219 			{
220 				mainForm.getFormField( TESTSUITE ).setValue( ((WsdlTestCase)param).getTestSuite().getName() );
221 				mainForm.getFormField( TESTCASE ).setValue( ((WsdlTestCase)param).getName() );
222 				
223 				values.put( TESTSUITE, ((WsdlTestCase)param).getTestSuite().getName());
224 				values.put( TESTCASE, ((WsdlTestCase)param).getName() );
225 			}
226 			else if( param instanceof WsdlTestSuite )
227 			{
228 				mainForm.getFormField( TESTSUITE ).setValue( ((WsdlTestSuite)param).getName() );
229 				values.put( TESTSUITE, ((WsdlTestSuite)param).getName());
230 			}
231 		}
232 		
233 		return values;
234 	}
235 	
236 	protected void generate(StringToStringMap values, ToolHost toolHost, WsdlProject modelItem ) throws Exception
237 	{
238 		String testRunnerDir = mainForm.getComponentValue( TESTRUNNERPATH );
239 		
240 		ProcessBuilder builder = new ProcessBuilder();
241 		ArgumentBuilder args = buildArgs(modelItem);
242 		builder.command(args.getArgs());
243 		if( StringUtils.isNullOrEmpty( testRunnerDir))
244 			builder.directory(new File("."));
245 		else
246 			builder.directory(new File(testRunnerDir));
247 		
248 		if( mainForm.getComponentValue( SAVEPROJECT ).equals( Boolean.TRUE.toString() ))
249 		{
250 			modelItem.save();
251 		}
252 		
253 		if( log.isDebugEnabled() )
254 			log.debug( "Launching testrunner in directory [" + builder.directory() + "] with arguments [" +
255 					args.toString() + "]" );
256 		
257 		toolHost.run( new ProcessToolRunner( builder, "soapUI TestRunner", modelItem ));
258 	}
259 
260 	private ArgumentBuilder buildArgs(WsdlProject modelItem) throws IOException
261 	{
262 		if( dialog == null )
263 		{
264 			ArgumentBuilder builder = new ArgumentBuilder( new StringToStringMap() );
265 			builder.startScript( "testrunner", ".bat", ".sh" );
266 			return builder;
267 		}
268 		
269 		StringToStringMap values = dialog.getValues();
270 		
271 		ArgumentBuilder builder = new ArgumentBuilder( values );
272 		
273 		builder.startScript( "testrunner", ".bat", ".sh" );
274 
275 		builder.addString( ENDPOINT, "-e", "" );
276 		builder.addString( HOSTPORT, "-h", "" );
277 		
278 		if( !values.get( TESTSUITE ).equals( ALL_VALUE ))
279 			builder.addString( TESTSUITE, "-s", "" );
280 		
281 		if( !values.get( TESTCASE ).equals( ALL_VALUE ))
282 			builder.addString( TESTCASE, "-c", "" );
283 		
284 		builder.addString( USERNAME, "-u", "" );
285 		builder.addString( PASSWORD, "-p", "" );
286 		builder.addString( DOMAIN, "-d", "" );
287 		builder.addString( WSSTYPE, "-w", "" );
288 		
289 		builder.addBoolean( PRINTREPORT, "-r" );
290 		builder.addBoolean( EXPORTALL, "-a" );
291 		builder.addBoolean( EXPORTJUNITRESULTS, "-j" );
292 		builder.addString( ROOTFOLDER, "-f" );
293 		builder.addBoolean( OPEN_REPORT, "-o" );
294 		
295 		if( dialog.getBooleanValue( ADDSETTINGS ))
296 		{
297 			try
298 			{
299 				builder.addBoolean( ADDSETTINGS, "-t" + SoapUI.saveSettings() );
300 			}
301 			catch( Exception e )
302 			{
303 				SoapUI.logError( e );
304 			}
305 		}
306 		
307 		builder.addBoolean( ENABLEUI, "-i" );		
308 		builder.addArgs( new String [] {modelItem.getPath()} );
309 		
310 		addToolArgs( values, builder );
311 		
312 		return builder;
313 	}
314 }