Example #1
0
 @Override
 public FSMTransition choose(TestSuite suite, List<FSMTransition> choices) {
   int testIndex = suite.getAllTestCases().size();
   List<String> path = suite.getCurrentTest().getAllStepNames();
   log.d("path for the current (explored) test:" + path);
   log.i("Exploring step " + testIndex + "." + path.size());
   TestCoverage suiteCoverage = suite.getCoverage();
   // create trace if DOT graph is wanted
   TraceNode[] trace = initTrace(path, testIndex);
   ExplorationState state = new ExplorationState(config, suiteCoverage);
   String choice = null;
   if (choices.size() == 1) {
     // this handles the scenario startup, where there is always just one choice (and other similar
     // scenarios)
     choice = choices.get(0).getStringName();
     path.add(choice);
   } else {
     // initiate exploration of the possible paths
     choice = exploreLocal(suite, state, path, trace[1]);
   }
   writeDot(path, trace[0]);
   // we have to find the transition here based on string matching because returning the actual
   // FSMTransition
   // object would give a reference to the wrong instance of the model object
   for (FSMTransition transition : choices) {
     if (transition.getStringName().equals(choice)) {
       return transition;
     }
   }
   throw new IllegalStateException(
       "Exploration choice (" + choice + ") not available. OSMO is bugging?");
 }
 private boolean checkProbability(long mySeed) {
   // need a separate randomizer, with predictable but changing seed to allow for parallel runs
   // using same endcondition
   Randomizer rand = new Randomizer(mySeed);
   // finally we go with random values to allow progress beyond end if so desired
   double v = rand.nextDouble();
   log.d("randomizing..:" + v);
   return v < fallbackProbability;
 }
 @Override
 public void createModelObjects(TestModels models) {
   for (Class aClass : classes) {
     try {
       models.add(aClass.newInstance());
     } catch (Exception e) {
       log.e("Failed to create a model class instance. Exiting.", e);
       e.printStackTrace();
       throw new RuntimeException(e);
     }
   }
 }
Example #4
0
 /**
  * Creates the representation of the generation/exploration trace for using with DOT trace
  * writing.
  *
  * @param script The script for the test case.
  * @return index[0] = root, index[1] = current step from which exploration continues.
  */
 private TraceNode[] initTrace(Collection<String> script, int testIndex) {
   if (dot.getTestIndex() != testIndex) {
     log.d("New test started, creating new DOT tracer.");
     dot = new DOTWriter(testIndex);
   }
   TraceNode.reset();
   TraceNode[] nodes = new TraceNode[2];
   TraceNode root = new TraceNode("init", null, false);
   nodes[0] = root;
   TraceNode node = root;
   for (String step : script) {
     node = node.add(step, false);
   }
   nodes[1] = node;
   return nodes;
 }
Example #5
0
 /**
  * Calculate length of text to generate next.
  *
  * @return Length defined.
  */
 private int length() {
   int length = -1;
   if (!invalid) {
     length = rand.nextInt(min, max);
   } else {
     if (zeroSize && !zeroDone) {
       log.d("Giving zero length");
       zeroDone = true;
       previousLength = 0;
       return 0;
     }
     int offset = rand.nextInt(minOffset, maxOffset);
     if (previousLength < min) {
       length = max + offset;
     } else {
       length = min - offset;
     }
     if (length < 0) {
       length = 0;
     }
   }
   previousLength = length;
   return length;
 }
  @Override
  public boolean endTest(TestSuite suite, FSM fsm) {
    if (scenarioEndCondition != null) {
      // if scenario is not yet done, we do not end no matter what
      if (!scenarioEndCondition.endTest(suite, fsm)) return false;
    }
    if (isTimedOut()) {
      log.d("Exploration timeout");
      return true;
    }

    int max = config.getMaxTestLength();
    int testSteps = suite.currentSteps();
    if (max > 0) {
      if (testSteps >= max) {
        log.d("test over maximum length");
        return true;
      }
    }
    // have we achieved defined minimum length yet?
    int min = config.getMinTestLength();
    if (min > 0) {
      if (testSteps < min) {
        return false;
      }
    }
    long mySeed = seed + suite.totalSteps();
    // plateau should take precedence over score limit otherwise it never happens. thus the ordering
    // with this here
    int plateauThreshold = config.getTestPlateauThreshold();

    if (plateauThreshold > 0) {
      if (isTestPlateau(suite, config.getTestPlateauLength())) {
        log.d("test has plateaued");
        return checkProbability(mySeed);
      }
    }

    // have we achieved minimum defined added test coverage yet?
    int minScore = config.getMinTestScore();
    if (minScore > 0) {
      if (suiteCoverage == null) suiteCoverage = suite.getCoverage();
      TestCase test = suite.getCurrentTest();
      TestCaseStep step = test.getCurrentStep();
      // this is the case when starting generation
      if (step == null) return false;
      int added = step.getAddedCoverage();

      if (added < minScore) {
        return false;
      }
    }

    // exploration only works nice and shiny until the end condition hits, then we have to go with
    // the pössis
    // this is because if we evaluate paths for overall score and one of them is longer but only due
    // to having
    // a different random "v" (below) value generated, it "seems" better although in fact should not
    // (or should it ?:)
    // for example: ++-+-+++++++++  //<-evaluates one step later for the random "v" and gets a
    // different value
    //             ++-+++++++   //<-evaluates one step before for the random "v" and gets a
    // different value
    if (exploring) return true;
    return checkProbability(mySeed);
  }