com.github.dakusui.jcunit.plugins.caengines.ipo2.IPO2 Maven / Gradle / Ivy
package com.github.dakusui.jcunit.plugins.caengines.ipo2;
import com.github.dakusui.jcunit.core.Checks;
import com.github.dakusui.jcunit.core.Utils;
import com.github.dakusui.jcunit.core.factor.Factor;
import com.github.dakusui.jcunit.core.factor.Factors;
import com.github.dakusui.jcunit.core.tuples.Tuple;
import com.github.dakusui.jcunit.core.tuples.TupleImpl;
import com.github.dakusui.jcunit.core.tuples.TupleUtils;
import com.github.dakusui.jcunit.core.tuples.Tuples;
import com.github.dakusui.jcunit.exceptions.GiveUp;
import com.github.dakusui.jcunit.exceptions.UndefinedSymbol;
import com.github.dakusui.jcunit.plugins.constraints.ConstraintChecker;
import com.github.dakusui.jcunit.plugins.caengines.ipo2.optimizers.IPO2Optimizer;
import java.util.*;
public class IPO2 {
public static final Object DontCare = new Object() {
@Override
public String toString() {
return "D/C";
}
};
private final ConstraintChecker constraintChecker;
private final Factors factors;
private final int strength;
private final IPO2Optimizer optimizer;
private List result;
private List remainders;
public IPO2(Factors factors, int strength,
ConstraintChecker constraintChecker,
IPO2Optimizer optimizer) {
Checks.checknotnull(factors);
Checks.checkcond(factors.size() >= 2, "There must be 2 or more factors.");
Checks.checkcond(factors.size() >= strength,
"The strength must be greater than 1 and less than %d.",
factors.size());
Checks.checkcond(strength >= 2,
"The strength must be greater than 1 and less than %d.",
factors.size());
Checks.checknotnull(constraintChecker);
Checks.checknotnull(optimizer);
this.factors = factors;
this.strength = strength;
this.result = null;
this.remainders = null;
this.constraintChecker = constraintChecker;
this.optimizer = optimizer;
}
private static List lookup(
List tuples, Tuple q) {
List ret = new LinkedList();
for (Tuple cur : tuples) {
if (matches(cur, q)) {
ret.add(cur.cloneTuple());
}
}
return ret;
}
private static boolean matches(Tuple tuple,
Tuple q) {
for (String k : q.keySet()) {
if (!tuple.containsKey(k) || !Utils.eq(q.get(k), tuple.get(k))) {
return false;
}
}
return true;
}
private List filterInvalidTuples(
List tuples) {
List ret = new ArrayList(tuples.size());
for (Tuple cur : tuples) {
if (checkConstraints(cur)) {
ret.add(cur);
}
}
return ret;
}
public void ipo() {
if (this.strength < this.factors.size()) {
this.remainders = new LinkedList();
this.result = initialTestCases(
factors.head(factors.get(this.strength).name)
);
} else if (factors.size() == this.strength) {
this.remainders = new LinkedList();
this.result = initialTestCases(this.factors);
return;
}
Set leftOver = new LinkedHashSet();
for (String factorName :
this.factors.tail(this.factors.get(this.strength).name)
.getFactorNames()) {
////
// Initialize a set that holds all the tuples to be covered in this
// iteration.
Tuples leftTuples = new Tuples(factors.head(factorName),
factors.get(factorName),
this.strength);
leftTuples.addAll(leftOver);
////
// Expand test case set horizontally and get the list of test cases
// that are proven to be invalid.
leftOver = hg(result, leftTuples, factors.get(factorName));
if (leftTuples.isEmpty()) {
continue;
}
////
// Expand test case set vertically.
if (factors.isLastKey(factorName)) {
leftOver = vg(result, leftTuples, factors);
} else {
leftOver = vg(result, leftTuples,
factors.head(factors.nextKey(factorName)));
}
}
////
// As a result of replacing don't care values, multiple test cases can be identical.
// By registering all the members to a new temporary set and adding them back to
// the original one, I'm removing those duplicates.
LinkedHashSet tmp = new LinkedHashSet(result);
this.result.clear();
this.result.addAll(tmp);
this.remainders.addAll(leftOver);
}
public List getResult() {
Checks.checkcond(this.result != null, "Execute ipo() method first");
return Collections.unmodifiableList(this.result);
}
public List getRemainders() {
Checks.checkcond(this.result != null, "Execute ipo() method first");
return Collections.unmodifiableList(this.remainders);
}
private List initialTestCases(
Factors factors) {
TupleUtils.CartesianTuples initialTestCases = TupleUtils
.enumerateCartesianProduct(
new TupleImpl(),
factors.asFactorList()
.toArray(new Factor[factors.asFactorList().size()])
);
List ret = new ArrayList((int) initialTestCases.size());
for (Tuple tuple : initialTestCases) {
ret.add(tuple);
}
return ret;
}
/*
* Returns a list of test cases in {@code result} which are proven to be not
* possible under given constraints.
*/
private Set hg(
List result, Tuples leftTuples, Factor factor) {
Set leftOver = new LinkedHashSet();
List invalidTests = new LinkedList();
String factorName = factor.name;
// Factor levels to cover in this method.
for (int i = 0; i < result.size(); i++) {
Tuple cur = result.get(i);
Object chosenLevel;
// Since Arrays.asList returns an unmodifiable list,
// create another list to hold
List © 2015 - 2025 Weber Informatics LLC | Privacy Policy