1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.tools;
14
15 import java.io.File;
16 import java.io.OutputStreamWriter;
17 import java.util.ArrayList;
18 import java.util.List;
19
20 import org.apache.commons.cli.CommandLine;
21 import org.apache.commons.cli.CommandLineParser;
22 import org.apache.commons.cli.HelpFormatter;
23 import org.apache.commons.cli.Options;
24 import org.apache.commons.cli.PosixParser;
25 import org.apache.log4j.ConsoleAppender;
26 import org.apache.log4j.Logger;
27 import org.apache.log4j.PatternLayout;
28
29 import com.eviware.soapui.DefaultSoapUICore;
30 import com.eviware.soapui.SoapUI;
31 import com.eviware.soapui.SoapUICore;
32 import com.eviware.soapui.SoapUIExtensionClassLoader;
33 import com.eviware.soapui.SoapUIExtensionClassLoader.SoapUIClassLoaderState;
34 import com.eviware.soapui.StandaloneSoapUICore;
35 import com.eviware.soapui.impl.wsdl.WsdlProject;
36 import com.eviware.soapui.impl.wsdl.support.PathUtils;
37 import com.eviware.soapui.model.ModelItem;
38 import com.eviware.soapui.model.project.Project;
39 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
40 import com.eviware.soapui.support.StringUtils;
41 import com.eviware.soapui.support.UISupport;
42
43 public abstract class AbstractSoapUIRunner implements CmdLineRunner
44 {
45 private boolean groovyLogInitialized;
46 private String projectFile;
47 protected final Logger log = Logger.getLogger( getClass() );
48 private String settingsFile;
49 private String soapUISettingsPassword;
50
51 private boolean enableUI;
52 private String outputFolder;
53 private String[] projectProperties;
54
55 public AbstractSoapUIRunner( String title )
56 {
57 if( title != null )
58 System.out.println( title );
59
60 SoapUI.setCmdLineRunner( this );
61 }
62
63 protected void initGroovyLog()
64 {
65 if( !groovyLogInitialized )
66 {
67 Logger logger = Logger.getLogger( "groovy.log" );
68
69 ConsoleAppender appender = new ConsoleAppender();
70 appender.setWriter( new OutputStreamWriter( System.out ) );
71 appender.setLayout( new PatternLayout( "%d{ABSOLUTE} %-5p [%c{1}] %m%n" ) );
72 logger.addAppender( appender );
73
74 groovyLogInitialized = true;
75 }
76 }
77
78 public int runFromCommandLine( String[] args )
79 {
80 try
81 {
82 if( initFromCommandLine( args, true ) )
83 {
84 if( run() )
85 {
86 return 0;
87 }
88 }
89 }
90 catch( Throwable e )
91 {
92 log.error( e );
93 SoapUI.logError( e );
94 }
95
96 return -1;
97 }
98
99 public boolean initFromCommandLine( String[] args, boolean printHelp ) throws Exception
100 {
101 SoapUIOptions options = initCommandLineOptions();
102
103 CommandLineParser parser = new PosixParser();
104 CommandLine cmd = parser.parse( options, args );
105
106 if( options.requiresProject() )
107 {
108 args = cmd.getArgs();
109
110 if( args.length != 1 )
111 {
112 if( printHelp )
113 {
114 HelpFormatter formatter = new HelpFormatter();
115 formatter.printHelp( options.getRunnerName() + " [options] <soapui-project-file>", options );
116 }
117
118 System.err.println( "Missing soapUI project file.." );
119 return false;
120 }
121
122 setProjectFile( args[0] );
123 }
124
125 return processCommandLine( cmd );
126 }
127
128 /***
129 * Main method to use for running the configured tests. Call after setting
130 * properties, etc as desired.
131 *
132 * @return true if execution should be blocked
133 * @throws Exception
134 * if an error or failure occurs during test execution
135 */
136
137 public final boolean run() throws Exception
138 {
139 if( SoapUI.getSoapUICore() == null )
140 {
141 SoapUI.setSoapUICore( createSoapUICore(), true );
142 SoapUI.initGCTimer();
143 }
144
145 SoapUIClassLoaderState state = SoapUIExtensionClassLoader.ensure();
146
147 try
148 {
149 return runRunner();
150 }
151 finally
152 {
153 state.restore();
154 }
155 }
156
157 protected SoapUICore createSoapUICore()
158 {
159 if( enableUI )
160 {
161 StandaloneSoapUICore core = new StandaloneSoapUICore( settingsFile );
162 log.info( "Enabling UI Components" );
163 core.prepareUI();
164 UISupport.setMainFrame( null );
165 return core;
166 }
167 else
168 {
169 return new DefaultSoapUICore( null, settingsFile, soapUISettingsPassword );
170 }
171 }
172
173 protected abstract boolean processCommandLine( CommandLine cmd );
174
175 protected abstract SoapUIOptions initCommandLineOptions();
176
177 protected abstract boolean runRunner() throws Exception;
178
179 protected String getCommandLineOptionSubstSpace( CommandLine cmd, String key )
180 {
181 return cmd.getOptionValue( key ).replaceAll( "%20", " " );
182 }
183
184
185
186
187 @Override
188 public String getProjectFile()
189 {
190 return projectFile;
191 }
192
193
194
195
196 @Override
197 public String getSettingsFile()
198 {
199 return settingsFile;
200 }
201
202 public void setOutputFolder( String outputFolder )
203 {
204 this.outputFolder = outputFolder;
205 }
206
207
208
209
210 @Override
211 public String getOutputFolder()
212 {
213 return this.outputFolder;
214 }
215
216 public String getAbsoluteOutputFolder( ModelItem modelItem )
217 {
218 String folder = outputFolder;
219
220 if( StringUtils.isNullOrEmpty( folder ) )
221 {
222 folder = PathUtils.getExpandedResourceRoot( modelItem );
223 }
224 else if( PathUtils.isRelativePath( folder ) )
225 {
226 folder = PathUtils.resolveResourcePath( folder, modelItem );
227 }
228
229 return folder;
230 }
231
232 public String getModelItemOutputFolder( ModelItem modelItem )
233 {
234 List<ModelItem> chain = new ArrayList<ModelItem>();
235 ModelItem p = modelItem;
236
237 while( !( p instanceof Project ) )
238 {
239 chain.add( 0, p );
240 p = p.getParent();
241 }
242
243 File dir = new File( getAbsoluteOutputFolder( modelItem ) );
244 dir.mkdir();
245
246 for( ModelItem item : chain )
247 {
248 dir = new File( dir, StringUtils.createFileName( item.getName(), '-' ) );
249 dir.mkdir();
250 }
251
252 return dir.getAbsolutePath();
253 }
254
255 protected void ensureOutputFolder( ModelItem modelItem )
256 {
257 ensureFolder( getAbsoluteOutputFolder( modelItem ) );
258 }
259
260 public void ensureFolder( String path )
261 {
262 if( path == null )
263 return;
264
265 File folder = new File( path );
266 if( !folder.exists() || !folder.isDirectory() )
267 folder.mkdirs();
268 }
269
270 /***
271 * Sets the soapUI project file containing the tests to run
272 *
273 * @param projectFile
274 * the soapUI project file containing the tests to run
275 */
276
277 public void setProjectFile( String projectFile )
278 {
279 this.projectFile = projectFile;
280 }
281
282 /***
283 * Sets the soapUI settings file containing the tests to run
284 *
285 * @param settingsFile
286 * the soapUI settings file to use
287 */
288
289 public void setSettingsFile( String settingsFile )
290 {
291 this.settingsFile = settingsFile;
292 }
293
294 public void setEnableUI( boolean enableUI )
295 {
296 this.enableUI = enableUI;
297 }
298
299 public static class SoapUIOptions extends Options
300 {
301 private final String runnerName;
302
303 public SoapUIOptions( String runnerName )
304 {
305 this.runnerName = runnerName;
306 }
307
308 public String getRunnerName()
309 {
310 return runnerName;
311 }
312
313 public boolean requiresProject()
314 {
315 return true;
316 }
317 }
318
319 public String getSoapUISettingsPassword()
320 {
321 return soapUISettingsPassword;
322 }
323
324 public void setSoapUISettingsPassword( String soapUISettingsPassword )
325 {
326 this.soapUISettingsPassword = soapUISettingsPassword;
327 }
328
329 public void setSystemProperties( String[] optionValues )
330 {
331 for( String option : optionValues )
332 {
333 int ix = option.indexOf( '=' );
334 if( ix != -1 )
335 {
336 System.setProperty( option.substring( 0, ix ), option.substring( ix + 1 ) );
337 }
338 }
339 }
340
341 public void setGlobalProperties( String[] optionValues )
342 {
343 for( String option : optionValues )
344 {
345 int ix = option.indexOf( '=' );
346 if( ix != -1 )
347 {
348 String name = option.substring( 0, ix );
349 String value = option.substring( ix + 1 );
350 log.info( "Setting global property [" + name + "] to [" + value + "]" );
351 PropertyExpansionUtils.getGlobalProperties().setPropertyValue( name, value );
352 }
353 }
354 }
355
356 public void setProjectProperties( String[] projectProperties )
357 {
358 this.projectProperties = projectProperties;
359 }
360
361
362
363
364 @Override
365 public Logger getLog()
366 {
367 return log;
368 }
369
370
371
372
373 @Override
374 public String[] getProjectProperties()
375 {
376 return projectProperties;
377 }
378
379 protected void initProjectProperties( WsdlProject project )
380 {
381 if( projectProperties != null )
382 {
383 for( String option : projectProperties )
384 {
385 int ix = option.indexOf( '=' );
386 if( ix != -1 )
387 {
388 String name = option.substring( 0, ix );
389 String value = option.substring( ix + 1 );
390 log.info( "Setting project property [" + name + "] to [" + value + "]" );
391 project.setPropertyValue( name, value );
392 }
393 }
394 }
395 }
396
397 public boolean isEnableUI()
398 {
399 return enableUI;
400 }
401 }