View Javadoc
1 /*** 2 * Redistribution and use of this software and associated documentation 3 * ("Software"), with or without modification, are permitted provided 4 * that the following conditions are met: 5 * 6 * 1. Redistributions of source code must retain copyright 7 * statements and notices. Redistributions must also contain a 8 * copy of this document. 9 * 10 * 2. Redistributions in binary form must reproduce the 11 * above copyright notice, this list of conditions and the 12 * following disclaimer in the documentation and/or other 13 * materials provided with the distribution. 14 * 15 * 3. The name "Exolab" must not be used to endorse or promote 16 * products derived from this Software without prior written 17 * permission of Exoffice Technologies. For written permission, 18 * please contact tma@netspace.net.au. 19 * 20 * 4. Products derived from this Software may not be called "Exolab" 21 * nor may "Exolab" appear in their names without prior written 22 * permission of Exoffice Technologies. Exolab is a registered 23 * trademark of Exoffice Technologies. 24 * 25 * 5. Due credit should be given to the Exolab Project 26 * (http://www.exolab.org/). 27 * 28 * THIS SOFTWARE IS PROVIDED BY EXOFFICE TECHNOLOGIES AND CONTRIBUTORS 29 * ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT 30 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 31 * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 32 * EXOFFICE TECHNOLOGIES OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 33 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 35 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 37 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 39 * OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Copyright 2003-2004 (C) Exoffice Technologies Inc. All Rights Reserved. 42 * 43 * $Id: AbstractTestRunner.java,v 1.7 2004/01/31 13:44:24 tanderson Exp $ 44 */ 45 package org.exolab.jmscts.core; 46 47 import java.io.FileReader; 48 import java.io.File; 49 import java.util.Enumeration; 50 import java.util.Iterator; 51 52 import junit.extensions.TestSetup; 53 import junit.framework.Test; 54 import junit.framework.TestResult; 55 import junit.framework.TestSuite; 56 57 import org.apache.commons.cli.CommandLine; 58 import org.apache.commons.cli.CommandLineParser; 59 import org.apache.commons.cli.GnuParser; 60 import org.apache.commons.cli.Options; 61 import org.apache.log4j.Category; 62 import org.apache.log4j.xml.DOMConfigurator; 63 64 import org.exolab.core.service.ServiceException; 65 import org.exolab.core.service.ServiceGroup; 66 import org.exolab.core.util.RmiRegistryService; 67 68 import org.exolab.jmscts.core.filter.Filter; 69 import org.exolab.jmscts.core.service.SnapshotService; 70 import org.exolab.jmscts.core.service.TestTerminatorService; 71 import org.exolab.jmscts.provider.Configuration; 72 import org.exolab.jmscts.provider.ProviderLoader; 73 74 75 /*** 76 * This class enables test cases to be run against different JMS providers 77 * <p> 78 * The provider configuration file path is passed at construction. This 79 * contains a list of providers to run the tests against. 80 * <p> 81 * <h3>Parameters</h3> 82 * <table border="1" cellpadding="2" cellspacing="0"> 83 * <tr> 84 * <td valign="top"><b>Argument</b></td> 85 * <td valign="top"><b>Description</b></td> 86 * <td align="center" valign="top"><b>Required</b></td> 87 * </tr> 88 * <tr> 89 * <td valign="top">config</td> 90 * <td valign="top">the provider configuration file path</td> 91 * <td valign="top" align="center">No</td> 92 * </tr> 93 * <tr> 94 * <td valign="top">output</td> 95 * <td valign="top">the report output directory</td> 96 * <td valign="top" align="center">No</td> 97 * </tr> 98 * <tr> 99 * <td valign="top">filter</td> 100 * <td valign="top">the test filter configuration file path</td> 101 * <td valign="top" align="center">No</td> 102 * </tr> 103 * <tr> 104 * <td valign="top">port</td> 105 * <td valign="top">the registry port</td> 106 * <td valign="top" align="center">No</td> 107 * </tr> 108 * </table> 109 * 110 * @version $Revision: 1.7 $ $Date: 2004/01/31 13:44:24 $ 111 * @author <a href="mailto:tma@netspace.net.au">Tim Anderson</a> 112 */ 113 public abstract class AbstractTestRunner extends TestSetup { 114 115 /*** 116 * The default registry port 117 */ 118 public static final String DEFAULT_PORT = "4000"; 119 120 /*** 121 * The configuration file path argument 122 */ 123 private static final String CONFIG = "config"; 124 125 /*** 126 * The test case filter path argument 127 */ 128 private static final String FILTER = "filter"; 129 130 /*** 131 * The coverage report output directory 132 */ 133 private static final String OUTPUT = "output"; 134 135 /*** 136 * The registry port argument 137 */ 138 private static final String PORT = "port"; 139 140 /*** 141 * The log4j configuration filename 142 */ 143 private static final String LOG4J = "log4j.xml"; 144 145 /*** 146 * The configuration for each provider 147 */ 148 private Configuration _config = null; 149 150 /*** 151 * The report output directory 152 */ 153 private String _output = null; 154 155 /*** 156 * The test case filter 157 */ 158 private Filter _filter = null; 159 160 /*** 161 * The command line arguments 162 */ 163 private final String[] _args; 164 165 /*** 166 * The test result 167 */ 168 private TestResult _result = null; 169 170 /*** 171 * The current provider being tested against 172 */ 173 private ProviderLoader _provider = null; 174 175 /*** 176 * The registry port 177 */ 178 private int _port; 179 180 /*** 181 * The services 182 */ 183 private ServiceGroup _services = new ServiceGroup(); 184 185 /*** 186 * The logger 187 */ 188 private static final Category log = 189 Category.getInstance(AbstractTestRunner.class.getName()); 190 191 192 /*** 193 * Construct an instance using the class of the test case, and the list 194 * of arguments to configure the test suite 195 * 196 * @param test a class implementing the {@link ConnectionFactoryTestCase} 197 * interface 198 * @param args command line arguments 199 */ 200 public AbstractTestRunner(Class test, String[] args) { 201 super(new TestSuite(test)); 202 if (args == null) { 203 throw new IllegalArgumentException("Argument 'args' is null"); 204 } 205 _args = args; 206 207 // configure the logger 208 DOMConfigurator.configure(getHome() + "/config/" + LOG4J); 209 } 210 211 /*** 212 * Construct an instance with the test to run, and the list of arguments 213 * to configure the test suite 214 * 215 * @param test the test to run 216 * @param args command line arguments 217 */ 218 public AbstractTestRunner(Test test, String[] args) { 219 super(test); 220 if (args == null) { 221 throw new IllegalArgumentException("Argument args is null"); 222 } 223 _args = args; 224 225 // configure the logger 226 DOMConfigurator.configure(getHome() + "/config/" + LOG4J); 227 } 228 229 /*** 230 * Generate a report 231 * 232 * @param path the path to write the report to 233 * @throws Exception for any error 234 */ 235 public abstract void report(String path) throws Exception; 236 237 /*** 238 * Snapshot the current state of the test 239 * 240 * @param path the path to write the report to 241 * @throws Exception for any error 242 */ 243 public void snapshot(String path) throws Exception { 244 report(path); 245 } 246 247 /*** 248 * Generate a report and stop the test 249 */ 250 public void stop() { 251 if (_result != null) { 252 _result.stop(); 253 } 254 try { 255 report(_output); 256 } catch (Exception exception) { 257 log.error("Failed to produce report", exception); 258 } 259 } 260 261 /*** 262 * Generate a report, and abort the test 263 */ 264 public void abort() { 265 try { 266 report(_output); 267 } catch (Exception exception) { 268 log.error("Failed to produce report", exception); 269 } 270 System.exit(1); 271 } 272 273 /*** 274 * Creates a test context 275 * 276 * @return a new test context 277 */ 278 public abstract TestContext createContext(); 279 280 /*** 281 * Runs the test case against each provider 282 * 283 * @param result the instance to collect results in 284 */ 285 public void basicRun(TestResult result) { 286 TestFilter filter = (_filter != null) ? new TestFilter(_filter) : null; 287 _result = result; 288 289 Iterator iterator = _config.getProviders().iterator(); 290 while (iterator.hasNext() && !result.shouldStop()) { 291 _provider = (ProviderLoader) iterator.next(); 292 293 TestSuite suite = new TestSuite(); 294 mergeSuites(suite, getTest()); 295 296 TestContext context = createContext(); 297 298 // run the tests against the provider configuration 299 ProviderTestRunner runner = new ProviderTestRunner(suite); 300 runner.setContext(context); 301 runner.setFilter(filter); 302 runner.setProvider(_provider); 303 runner.run(result); 304 305 // generate a results report 306 try { 307 report(_output); 308 } catch (Exception exception) { 309 log.error(exception, exception); 310 } 311 } 312 } 313 314 /*** 315 * Returns the registry port 316 * 317 * @return the registry port 318 */ 319 public int getPort() { 320 return _port; 321 } 322 323 /*** 324 * Reads the provider configuration 325 * 326 * @throws Exception if the configuration cannot be initialised 327 */ 328 protected void setUp() throws Exception { 329 // parse the command line 330 Options options = new Options(); 331 options.addOption(CONFIG, true, "the provider configuration path"); 332 options.addOption(OUTPUT, true, "the output path"); 333 options.addOption(FILTER, true, "the test case filter path"); 334 options.addOption(PORT, true, "registry port"); 335 336 CommandLineParser parser = new GnuParser(); 337 CommandLine commands = parser.parse(options, _args); 338 339 String config = commands.getOptionValue( 340 CONFIG, getHome() + "/config/providers.xml"); 341 342 _output = (String) commands.getOptionValue( 343 OUTPUT, getHome() + "/report"); 344 File dir = new File(_output); 345 if (!dir.isDirectory()) { 346 throw new Exception("Invalid output directory: " + _output); 347 } 348 if (!dir.canWrite()) { 349 throw new Exception("Cannot write to output directory: " 350 + _output); 351 } 352 353 String filter = commands.getOptionValue(FILTER); 354 _port = Integer.parseInt(commands.getOptionValue(PORT, DEFAULT_PORT)); 355 356 // load the provider configuration 357 _config = Configuration.read(config); 358 359 // load the filter (if supplied) 360 loadFilter(filter); 361 362 // initialise and start the services 363 startServices(); 364 } 365 366 /*** 367 * Returns the current provider being tested against 368 * 369 * @return the current provider being tested against, or <code>null</code> 370 * if no test is being run 371 */ 372 protected ProviderLoader getProvider() { 373 return _provider; 374 } 375 376 /*** 377 * Clean up any resources allocated 378 * 379 * @throws Exception for any error 380 */ 381 protected void tearDown() throws Exception { 382 _config = null; 383 if (_services != null) { 384 _services.stopAll(); 385 } 386 } 387 388 /*** 389 * Start the services 390 * 391 * @throws Exception for any error 392 */ 393 protected void startServices() throws Exception { 394 registerServices(_services); 395 _services.startAll(); 396 } 397 398 /*** 399 * Register services 400 * 401 * @param services the service group to register the services with 402 * @throws ServiceException for any error 403 */ 404 protected void registerServices(ServiceGroup services) 405 throws ServiceException { 406 407 RmiRegistryService registry = new RmiRegistryService(_port); 408 services.add(registry.getName(), registry); 409 410 SnapshotService snapshot = new SnapshotService(this, _port); 411 services.add(snapshot.getName(), snapshot); 412 413 TestTerminatorService terminator = new TestTerminatorService( 414 this, _port); 415 services.add(terminator.getName(), terminator); 416 417 services.startAll(); 418 } 419 420 /*** 421 * Returns the value of the <code>jmscts.home</code> system property, 422 * defaulting to the value of <code>user.dir</code> if its not set 423 * 424 * @return the value of the <code>jmscts.home</code> system property 425 */ 426 protected String getHome() { 427 return System.getProperty("jmscts.home", 428 System.getProperty("user.dir")); 429 } 430 431 /*** 432 * Removes nested TestSuite instances from <code>test</code>, adding the 433 * contained Test instances to <code>suite</code>, in order for the 434 * ProviderTestRunner to be invoked successfully. 435 * 436 * @param suite the resulting test suite 437 * @param test if an instance of TestSuite, this method will be called 438 * recursively with each contained Test; else the test will be added 439 * directly to <code>suite</code> 440 */ 441 protected void mergeSuites(TestSuite suite, Test test) { 442 if (test instanceof TestSuite) { 443 Enumeration iter = ((TestSuite) test).tests(); 444 while (iter.hasMoreElements()) { 445 mergeSuites(suite, (Test) iter.nextElement()); 446 } 447 } else { 448 suite.addTest(test); 449 } 450 } 451 452 /*** 453 * Loads the filter configuration file 454 * 455 * @param filter the filter configuration file path 456 * @throws Exception for any error 457 */ 458 private void loadFilter(String filter) throws Exception { 459 if (filter != null) { 460 FileReader filterReader = null; 461 try { 462 filterReader = new FileReader(filter); 463 _filter = Filter.unmarshal(filterReader); 464 } finally { 465 if (filterReader != null) { 466 filterReader.close(); 467 } 468 } 469 } 470 } 471 472 }

This page was automatically generated by Maven