Clover coverage report -
Coverage timestamp: Sat Jul 7 2007 16:41:13 CEST
file stats: LOC: 466   Methods: 33
NCLOC: 180   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
AbstractRunnerAncestor.java 66.7% 86.3% 78.8% 83%
coverage coverage
 1    /**
 2    * JTRunner is free software; you can redistribute it and/or modify it under the
 3    * terms of the GNU General Public License as published by the Free Software
 4    * Foundation; either version 2, or (at your option) any later version.
 5    */
 6   
 7    package jtr.runners;
 8   
 9    import java.io.ByteArrayOutputStream;
 10    import java.io.IOException;
 11    import java.io.ObjectOutputStream;
 12    import java.util.Date;
 13    import jtr.config.ParametersMap;
 14    import jtr.config.enterprise.EnterpriseConfig;
 15    import jtr.pool.RunnerPool;
 16    import jtr.assigner.IParamsAssigner;
 17    import jtr.test.ITestCompletionListener;
 18    import jtr.test.TestOutcomeTable;
 19    import jtr.test.IOutcomeFactory;
 20    import jtr.test.IOutcome;
 21    import jtr.test.IOutcome.OutcomeType;
 22    import static jtr.test.IOutcome.OutcomeType.*;
 23   
 24    import org.apache.log4j.Logger;
 25   
 26    /**
 27    * This base abstract class is the ancestor common to every JTR abstract runner.
 28    * It is not meant to be available to test-suite developers.
 29    *
 30    * @author Francesco Russo (frusso@dev.java.net)
 31    * @version 4.0
 32    * @since 1.1
 33    */
 34    public abstract class AbstractRunnerAncestor implements IRunner {
 35    /**
 36    * This method cleans all the configurations/parameters assigned to the
 37    * current <code>IRunner</code>. It should be overridden by an
 38    * application-level runner using the delegation pattern for adding the
 39    * clean up of resources. This method is invoked every time an
 40    * <code>IRunner</code> implementation completes one of its runs. It is
 41    * used for reinitializing a runner between two consecutive runs if this is
 42    * required by the associated assignment policy (i.e. cyclic).<br>
 43    * This method is not intended for finalizing "expensive resources": you
 44    * might want to avoid the reinitialization of a JDBC or JMS connection
 45    * every time a run completes, maybe because you think it would be too much
 46    * expensive obtaining it every time.<br>
 47    * In such a case you should avoid putting such clean up activity in this
 48    * method: you should think about using the
 49    * <code>IRunnerPooled.cleanupResources()</code> method instead.
 50    *
 51    *
 52    *
 53    * @return IRunnerClean The same runner in the <code>CLEAN</code> state.
 54    * @see IRunnerPooled#cleanupResources
 55    */
 56  15965 public IRunnerClean clean() {
 57  15966 logger.debug("Cleaning state...");
 58  15968 setEnterprise(null);
 59  15970 setParameters(null);
 60  15970 setSleepTime(0L);
 61  15969 logger.debug("... done");
 62  15969 return (IRunnerClean) this;
 63    }
 64   
 65    /**
 66    * Assign the current epoch to the <code>IRunner</code>
 67    *
 68    * @param epoch
 69    * The current epoch
 70    */
 71  4900 public void setEpoch(int epoch) {
 72  4900 this.epoch = epoch;
 73    }
 74   
 75    /**
 76    * Return the current epoch assigned to the <code>IRunner</code>
 77    *
 78    * @return int The current epoch
 79    */
 80  10000 public int getEpoch() {
 81  10000 return epoch;
 82    }
 83   
 84    /**
 85    * Set the name of the <code>IRunner</code>. This is by default its FQN
 86    * followed by an increasing integer stating that this is the i-th
 87    * <code>IRunner</code> of that class.
 88    *
 89    * @param name
 90    * The name
 91    */
 92  98 public void setName(String name) {
 93  98 this.name = name;
 94    }
 95   
 96    /**
 97    * Return the name of the <code>IRunner</code>
 98    *
 99    * @return String
 100    */
 101  116900 public String getName() {
 102  116899 return name;
 103    }
 104   
 105    /**
 106    * Get the default name provided by <code>this.getClass().getName()</code>
 107    *
 108    * @return String The default name.
 109    */
 110  98 public String getDefaultName() {
 111  98 return this.getClass().getName();
 112    }
 113   
 114    /**
 115    * Return the enterprise configuration assigned to the current
 116    * <code>IRunner</code>
 117    *
 118    * @return EnterpriseConfig The enterprise configuration
 119    */
 120  34939 public EnterpriseConfig getEnterprise() {
 121  34937 return this.enterpriseConfig;
 122    }
 123   
 124    /**
 125    * Assign the given enterprise configuration to the current
 126    * <code>IRunner</code>
 127    *
 128    * @param enterprise
 129    * The enterprise configuration
 130    */
 131  32034 public void setEnterprise(EnterpriseConfig enterprise) {
 132  32038 this.enterpriseConfig = enterprise;
 133    }
 134   
 135    /**
 136    * Set the number of instances that must be active, according to the
 137    * jtr.xml, during the test-suite.
 138    *
 139    * @param i The number of instances
 140    */
 141  16068 public void setInstanceCount(int i) {
 142  16068 instanceCount = i;
 143    }
 144   
 145    /**
 146    * Get the number of instances that must be active, according to the
 147    * jtr.xml, during the test-suite.
 148    *
 149    * @return int The number of instances
 150    */
 151  9999 public int getInstanceCount() {
 152  9999 return instanceCount;
 153    }
 154   
 155    /**
 156    * Return the number of runs assigned to the <code>IRunner</code>
 157    *
 158    * @return int The number of runs
 159    */
 160  98579 public int getRuns() {
 161  98592 return runs;
 162    }
 163   
 164    /**
 165    * Set the number of runs assigned to the <code>IRunner</code>
 166    *
 167    * @param runs
 168    * The number of runs
 169    */
 170  16068 public void setRuns(int runs) {
 171  16068 this.runs = runs;
 172    }
 173   
 174    /**
 175    * Get the sleep runDuration assigned to this <code>IRunner</code>
 176    *
 177    *
 178    *
 179    * @return long The sleep runDuration
 180    */
 181  79000 public long getSleepTime() {
 182  79000 return sleepTime;
 183    }
 184   
 185    /**
 186    * Get the sleep runDuration assigned to this <code>IRunner</code>
 187    *
 188    *
 189    *
 190    * @param sleepTime
 191    * The sleep runDuration
 192    */
 193  32037 public void setSleepTime(long sleepTime) {
 194  32037 this.sleepTime = sleepTime;
 195    }
 196   
 197    /**
 198    * Provides the <code>IRunner</code> with its runtime parameters.
 199    *
 200    * @param params
 201    * The parameters
 202    */
 203  32037 public void setParameters(ParametersMap params) {
 204  32037 this.params = params;
 205    }
 206   
 207    /**
 208    * Return the set of runtime parameters configured for the
 209    * <code>IRunner</code>
 210    *
 211    * @return ParametersMap
 212    */
 213  0 public ParametersMap getParameters() {
 214  0 return params;
 215    }
 216   
 217    /**
 218    * Set the pool this <code>IRunner</code> will belong to
 219    *
 220    * @param pool
 221    * The pool
 222    * @return IRunnerPooled The same runner in its <code>POOLED</code> state
 223    */
 224  4998 public IRunnerPooled setPool(RunnerPool pool) {
 225  4998 this.pool = pool;
 226  4998 return (IRunnerPooled) this;
 227    }
 228   
 229    /**
 230    * Get the pool this <code>IRunner</code> belongs to
 231    *
 232    * @return RunnerPool The pool
 233    */
 234  0 public RunnerPool getPool() {
 235  0 return pool;
 236    }
 237   
 238    /**
 239    * Get the <code>IParamsAssigner</code> in charge of assigning parameters
 240    * to the current <code>IRunner</code>
 241    *
 242    * @return IParamsAssigner The assigner
 243    */
 244  6272 public IParamsAssigner getParamsAssigner() {
 245  6272 return paramsAssigner;
 246    }
 247   
 248    /**
 249    * Set the <code>IParamsAssigner</code> in charge of assigning parameters
 250    * to the current <code>IRunner</code>
 251    *
 252    * @param paramsAssigner
 253    * IParamsAssigner
 254    */
 255  16068 public void setParamsAssigner(IParamsAssigner paramsAssigner) {
 256  16068 this.paramsAssigner = paramsAssigner;
 257    }
 258   
 259    /**
 260    * Get the number of failures
 261    *
 262    * @return int The failures
 263    */
 264  0 public int getFailures() {
 265  0 return failedRuns;
 266    }
 267   
 268    /**
 269    * Get the number of successes.
 270    *
 271    * @return int The successes
 272    */
 273  0 public int getSuccesses() {
 274  0 return getCurrentRun() - getFailures();
 275    }
 276   
 277    /**
 278    * Return the current <code>TestOutcomeTable</code>
 279    *
 280    * @return TestOutcomeTable
 281    */
 282  0 public TestOutcomeTable getTestOutcomeTable() {
 283  0 return testOutcomeTable;
 284    }
 285   
 286    /**
 287    * Set the current <code>TestOutcomeTable</code>
 288    *
 289    * @param testOutcomeTable
 290    * TestOutcomeTable
 291    */
 292  98 public void setTestOutcomeTable(TestOutcomeTable testOutcomeTable) {
 293  98 this.testOutcomeTable = testOutcomeTable;
 294    }
 295   
 296    /**
 297    * Get the current <code>IOutcomeTable</code>
 298    *
 299    * @return IOutcomeFactory
 300    */
 301  0 public IOutcomeFactory getOutcomeFactory() {
 302  0 return outcomeFactory;
 303    }
 304   
 305    /**
 306    * Set the current <code>IOutcomeTable</code>
 307    *
 308    * @param outcomeFactory
 309    * IOutcomeFactory
 310    */
 311  98 public void setOutcomeFactory(IOutcomeFactory outcomeFactory) {
 312  98 this.outcomeFactory = outcomeFactory;
 313    }
 314   
 315    /**
 316    * This method assigns an <code>ITestCompletionListener</code> instance
 317    * to a runner in <code>CLEAN</code> state. This assignment can be performed
 318    * for just one time in a JTR test-session for each runner instance.<br>
 319    * <b>Note:</b> it is legal for this instance to be always <code>null</code>
 320    * for runner instances started on JTR passive-nodes.
 321    *
 322    * @param testComplLsnr The listener instance
 323    */
 324  98 public void setTestCompletionListener(ITestCompletionListener testComplLsnr) {
 325  98 if(testCompletionLsnr==null)
 326  98 testCompletionLsnr = testComplLsnr;
 327    }
 328   
 329    /**
 330    * This method is in charge of actually starting the test by calling
 331    * the user defined <code>test()</code> method over the user-defined
 332    * runner instances. Doing this, runDuration information is collected and
 333    * at the end of the run, a new <code>IOutcome</code> instance is obtained
 334    * from the configured <code>IOutcomeFactory</code>. Thus the outcome
 335    * is passed to the <code>enrichOutcome()</code> method.<br>
 336    * Should a user-defined outcome be in use, the developer is required
 337    * to override the <code>enrichOutcome()</code> method.<br>
 338    * <br>
 339    * <b>Nota:</b> the <code>enrichOutcome()</code> method can alse be used to
 340    * set a user-message into each run's outcome.
 341    * @throws java.lang.Throwable
 342    */
 343  44380 protected final void doRunTest() throws Throwable {
 344  44389 initializeTimers();
 345  44391 try {
 346  44396 test();
 347    }
 348    finally {
 349  44380 runDuration = System.currentTimeMillis() - runDuration;
 350  44369 if(testCompletionLsnr!=null)
 351  22182 testCompletionLsnr.updateLocalRuns();
 352    }
 353  32396 IOutcome res = prepareOutcome(SUCCESS);
 354  32396 testOutcomeTable.put(getName(),res);
 355    }
 356   
 357    /**
 358    * Thie method is required to prevent that errors happening before the
 359    * doRunTest() method is invoked have negative impacts on the computation
 360    * of the time spent during tests.
 361    */
 362  44406 protected final void initializeTimers() {
 363  44407 runDuration = System.currentTimeMillis();
 364  44407 timestamp = new Date(runDuration);
 365    }
 366   
 367    /**
 368    * Whenever an exception is caught during the execution of the
 369    * <code>test()</code> method of the <code>IRunner</code> interface, the
 370    * <code>AbstractRunner</code> takes care of instantiating a new
 371    * <code>IOutcome</code> and of adding it to the current
 372    * <code>TestOutcomeTable</code>.<br>
 373    * Once this steps have been performed, the
 374    * <code>receiveFailureNotification(Throwable,String)"</code> of the
 375    * <code>IRunner</code> interface is called. At this point your custom
 376    * <code>IRunner</code> gets notified of the exception and can decide what
 377    * to do with it.
 378    *
 379    * @param run
 380    * The run of the exception
 381    * @param t
 382    * The exceptioin
 383    */
 384  12003 protected final void handleFailure(int run, Throwable t) {
 385  12003 failedRuns++;
 386  12004 String msg = "Exception occourred in IRunner " + getName() + " at thread run # " + run + " Actual parameters are: " + enterpriseConfig + " " + params + " "
 387    + ". Exception caught: proceeding with the next run...";
 388  12004 IOutcome outcome = prepareOutcome(FAILURE);
 389  12002 if(isSerializable(t)) {
 390  11995 outcome.setException(t);
 391    } else {
 392  0 NotSerializableErrorException e = new NotSerializableErrorException("Original exception was not Serializable, reporting only the original top-level message:\n"+t.getMessage(),null);
 393  0 e.setStackTrace(t.getStackTrace());
 394  0 outcome.setException(e);
 395    }
 396  11997 testOutcomeTable.put(getName(), outcome);
 397  12004 logger.error(msg, t);
 398  12004 receiveFailureNotification(t, "Exception occourred");
 399    }
 400   
 401    /**
 402    * This method verifies whether the given exception could be sent over
 403    * the network or not.
 404    */
 405  12003 private boolean isSerializable(Throwable t) {
 406  12002 boolean res = true;
 407  12004 try {
 408  12004 ObjectOutputStream os = new ObjectOutputStream(new ByteArrayOutputStream());
 409  11997 os.writeObject(t);
 410    } catch (IOException ex) {
 411  0 res = false;
 412    }
 413  12000 return res;
 414    }
 415   
 416    /**
 417    * Prepares an outcome, filling it in with all the required information.
 418    * This method takes care of calling the <code>enrichOutcome()</code> method too.
 419    */
 420  44398 private IOutcome prepareOutcome(OutcomeType type) {
 421  44398 IOutcome outcome = outcomeFactory.getInstance();
 422  44396 outcome.setEnterpriseConfig(enterpriseConfig);
 423  44398 outcome.setEpoch(epoch);
 424    //outcome.setNode(???);
 425  44400 outcome.setParametersMap(params);
 426  44399 outcome.setRun(getCurrentRun());
 427  44400 outcome.setRunDuration(runDuration);
 428  44400 outcome.setRunnerCategory(this.getClass());
 429  44398 outcome.setRunnerId(this.getName());
 430  44400 outcome.setTimeStamp(timestamp);
 431  44400 outcome.setType(type);
 432  44399 enrichOutcome(outcome);
 433  44396 return outcome;
 434    }
 435   
 436    /**
 437    * This abstract method must be used either when the user needs to enrich the given
 438    * outcome with a <i>JTR UserObject</i> or in case the default <code>IOutcomeFactory</code>
 439    * has been replaced with a custom one. Responsability of this method is filling in the
 440    * provided <code>IOutcome</code> instance. That instance will then be put into the
 441    * <code>TestOutcomeTable</code> by the JTR runtime.
 442    *
 443    * @param outcome The empty outcome of a single run
 444    */
 445  0 public void enrichOutcome(IOutcome outcome) {
 446    // nop by default
 447    }
 448   
 449    private long runDuration;
 450    private Date timestamp;
 451    protected int epoch;
 452    private int failedRuns;
 453    private String name;
 454    private EnterpriseConfig enterpriseConfig;
 455    private int runs;
 456    private int instanceCount;
 457    private long sleepTime;
 458    private ParametersMap params;
 459    protected IParamsAssigner paramsAssigner;
 460    protected RunnerPool pool;
 461    protected Logger logger;
 462    private TestOutcomeTable testOutcomeTable;
 463    private IOutcomeFactory<? extends IOutcome> outcomeFactory;
 464    // NOTE: this instance can be always null for remotely started runners
 465    private ITestCompletionListener testCompletionLsnr;
 466    }