All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.dakusui.jcunit.generators.Replayer Maven / Gradle / Ivy

package com.github.dakusui.jcunit.generators;

import com.github.dakusui.jcunit.core.*;
import com.github.dakusui.jcunit.core.rules.Recorder;
import com.github.dakusui.jcunit.core.tuples.Tuple;
import com.github.dakusui.jcunit.core.tuples.TupleUtils;

import java.io.File;
import java.io.FilenameFilter;
import java.lang.annotation.Annotation;
import java.util.Arrays;
import java.util.Iterator;
import java.util.SortedMap;
import java.util.TreeMap;

/**
 * @see Replayer#parameterTypes() for parameters definition.
 */
public class Replayer extends TupleGeneratorBase {
  private final GenerationMode         generationMode;
  private       SortedMap tuples;
  private       TupleGeneratorBase     fallbackGenerator;

  /**
   * Creates an object of this class.
   */
  public Replayer() {
    this.generationMode = SystemProperties.isReplayerEnabled() ?
        GenerationMode.Replay :
        GenerationMode.Fallback;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public Tuple getTuple(int tupleId) {
    return this.generationMode.getTuple(this, tupleId);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected long initializeTuples(Object[] params) {
    return this.generationMode.initializeTuples(this, params);
  }

  private long getIdFromDirName(String dirName) {
    return Long.parseLong(dirName.substring(dirName.lastIndexOf('-') + 1));
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public long nextId(long tupleId) {
    assert this.generationMode != null;
    return this.generationMode.nextId(this, tupleId);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  public long firstId() {
    assert this.generationMode != null;
    return this.generationMode.firstId(this);
  }

  private File[] getRecordedTupleDirectories(final ReplayMode mode,
      File baseDir,
      final FoundTupleObserver obs
  ) {
    return baseDir.listFiles(new FilenameFilter() {
                               @Override
                               public boolean accept(File dir, String s) {
                                 String prefix = "data-";
                                 if (!s.startsWith(prefix)) {
                                   return false;
                                 }
                                 if (!new File(dir, s).isDirectory()) {
                                   return false;
                                 }
                                 try {
                                   int i = Integer
                                       .parseInt(s.substring(prefix.length()));
                                   if (i < 0) {
                                     return false;
                                   }
                                 } catch (NumberFormatException e) {
                                   return false;
                                 }
                                 File f = new File(dir, s);
                                 obs.found(f);
                                 return mode.shouldBeReplayed(f);
                               }
                             }
    );
  }

  /**
   * Returns definitions of the parameters for this class.
   * Below is the list of parameters.
   * 
    *
  • 0: Replay mode. 'All' or 'FailedOnly'. Note that 'FailedOnly' is only effective for * generated test cases. So, test cases returned by '@CustomTestCase' annotated methods or * {@code ConstraintManager#getViolations} will be executed regardless of this value. Remove * the annotation or make the methods return empty lists to suppress then.
  • *
  • 1: Base directory of test data. By default, null (, which then defaults to .jcunit).
  • *
  • 2: Class name of a fall back tuple generator. By default IPO2TupleGenerator.
  • *
  • 3...: Parameters passed to fallback tuple generator.
  • *
*/ @Override public ParamType[] parameterTypes() { return new ParamType[] { new ParamType.NonArrayType() { @Override protected Object parse(String str) { return ReplayMode.valueOf(str); } @Override public String toString() { return Replayer.class.getCanonicalName() + ".ReplayMode"; } }.withDefaultValue(ReplayMode.All), ParamType.String.withDefaultValue(null), new ParamType.NonArrayType() { @SuppressWarnings("unchecked") @Override protected Class parse( String str) { try { Class ret = java.lang.Class.forName(str); Checks.checktest( TupleGeneratorBase.class.isAssignableFrom(ret), "'%s' isn't a sub class of '%s'", ret.getClass(), TupleGeneratorBase.class ); return (Class) ret; } catch (ClassNotFoundException e) { Checks.checktest(false, "The class '%s' you specified as a tuple generator was not found in the class path.", str); } // This line will never be executed. assert false; return null; } }.withDefaultValue(IPO2TupleGenerator.class), new ParamType() { @Override public Object parse(final String[] values) { return new Param() { @Override public String[] value() { return values; } @Override public Class annotationType() { return Param.class; } }; } @Override public boolean isVarArgs() { return true; } } }; } public enum GenerationMode { Replay { @Override long initializeTuples(Replayer tupleReplayer, Object[] params) { File baseDir = Recorder .testClassDataDirFor((String) params[1], tupleReplayer.getTargetClass()); final int[] work = new int[] { 0 }; File[] tupleDirs = tupleReplayer .getRecordedTupleDirectories((ReplayMode) params[0], baseDir, new FoundTupleObserver() { @Override public void found(File f) { work[0]++; } }); int numFoundTuples = work[0]; Checks.checktest(tupleDirs != null, "Test hasn't been run with 'JCUnitRecorder' rule yet. No tuple containing directory under '%s' was found.", baseDir ); tupleReplayer.tuples = new TreeMap(); for (File dir : tupleDirs) { Tuple tuple = TupleUtils.load( Utils.openForRead( new File(dir, Recorder.TESTCASE_FILENAME))); tupleReplayer.tuples .put(tupleReplayer.getIdFromDirName(dir.getName()), tuple); } //// // Returning number of total recorded test cases. return numFoundTuples; } @Override Tuple getTuple(Replayer tuplePlayer, int tupleId) { Checks.checkcond(tuplePlayer.tuples.containsKey((long) tupleId)); return tuplePlayer.tuples.get((long) tupleId); } @Override long nextId(Replayer tuplePlayer, long tupleId) { Checks.checkcond(tuplePlayer.tuples.containsKey(tupleId)); Iterator tail = tuplePlayer.tuples.tailMap(tupleId).keySet() .iterator(); Checks.checkcond(tail.hasNext()); tail.next(); if (!tail.hasNext()) { return -1; } return tail.next(); } @Override long firstId(Replayer tuplePlayer) { if (tuplePlayer.tuples.size() == 0) { return -1; } return tuplePlayer.tuples.firstKey(); } }, Fallback { @SuppressWarnings("unchecked") @Override long initializeTuples( Replayer tupleReplayer, Object[] params) { //// // Create fallbackGenerator instance. try { tupleReplayer.fallbackGenerator = ((Class) params[2]) .newInstance(); } catch (InstantiationException e) { Checks.rethrowpluginerror(e, "The class '%s' cannot be instantiated.", params[2]); } catch (IllegalAccessException e) { Checks.rethrowpluginerror(e, "A no-parameter constructor of '%s' is too less open. Make it public.", params[2]); } //// // Extract parameters to be passed to fallbackGenerator. Param[] paramsToFallbackGenerator; if (params.length >= 4) { paramsToFallbackGenerator = Arrays .copyOfRange(params, 3, params.length, Param[].class); } else { paramsToFallbackGenerator = new Param[0]; } //// // Wire TupleGeneratorBase generator = tupleReplayer.fallbackGenerator; generator.setFactors(tupleReplayer.getFactors()); generator.setConstraintManager(tupleReplayer.getConstraintManager()); generator.setTargetClass(tupleReplayer.getTargetClass()); generator.init(ParamType.processParams( generator.parameterTypes(), paramsToFallbackGenerator )); return generator.size(); } @Override Tuple getTuple(Replayer tuplePlayer, int tupleId) { return tuplePlayer.fallbackGenerator.getTuple(tupleId); } @Override long nextId(Replayer tuplePlayer, long tupleId) { return tuplePlayer.fallbackGenerator.nextId(tupleId); } @Override long firstId(Replayer tuplePlayer) { return tuplePlayer.fallbackGenerator.firstId(); } }; abstract long initializeTuples(Replayer tupleReplayer, Object[] params); abstract Tuple getTuple(Replayer tuplePlayer, int tupleId); abstract long nextId(Replayer tuplePlayer, long tupleId); abstract long firstId(Replayer tuplePlayer); } public static enum ReplayMode { All { @Override public boolean shouldBeReplayed(File testStoreDir) { return true; } }, FailedOnly { @Override public boolean shouldBeReplayed(File testStoreDir) { return new File(testStoreDir, Recorder.FAILED_FILENAME) .exists(); } }; public abstract boolean shouldBeReplayed(File testStoreDir); } private static interface FoundTupleObserver { void found(File f); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy