Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.github.dakusui.jcunit8.factorspace.fsm.FsmDecomposer Maven / Gradle / Ivy
Go to download
Automated combinatorial testing framework on top of JUnit
package com.github.dakusui.jcunit8.factorspace.fsm;
import com.github.dakusui.jcunit.core.tuples.Tuple;
import com.github.dakusui.jcunit.fsm.*;
import com.github.dakusui.jcunit8.factorspace.Constraint;
import com.github.dakusui.jcunit8.factorspace.Factor;
import com.github.dakusui.jcunit8.factorspace.TestPredicate;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static com.github.dakusui.jcunit8.core.Utils.unique;
import static com.github.dakusui.jcunit8.pipeline.stages.Generator.VOID;
import static java.util.Arrays.asList;
import static java.util.stream.Collectors.toList;
import static java.util.stream.IntStream.range;
public class FsmDecomposer extends FsmTupleAccessor {
private final List factors;
private final List constraints;
private final int maxActionParams;
public FsmDecomposer(String name, FiniteStateMachine model, int scenarioLength) {
super(name, model, scenarioLength);
this.maxActionParams = model.actions().stream()
.mapToInt(value -> value.parameters().size())
.max()
.orElse(0);
this.constraints = buildConstraints();
this.factors = buildFactors();
}
public List getFactors() {
return this.factors;
}
public List getConstraints() {
return this.constraints;
}
private List buildFactors() {
return range(0, this.scenarioLength).mapToObj(
(int i) -> Stream.concat(Stream.of(
createFactorForState(name, i),
createFactorForAction(name, i)),
createFactorsForActionParams(name, i).stream()
).collect(toList()))
.flatMap(Collection::stream)
.collect(toList());
}
private Factor createFactorForState(String name, int i) {
return Factor.create(
composeStateFactorName(name, i),
model.states().toArray()
);
}
private Factor createFactorForAction(String name, int i) {
return Factor.create(
composeActionFactorName(name, i),
model.actions().toArray()
);
}
private List createFactorsForActionParams(String name, int i) {
List ret = new LinkedList<>();
for (int j = 0; j < this.maxActionParams; j++) {
ret.add(Factor.create(
composeActionParamFactorName(name, i, j),
new ArrayList(union(
model.actions().stream()
.map(Action::parameters)
.collect(Collectors.toList()),
j)) {{
add(VOID);
}}.toArray()
));
}
return ret;
}
private List union(List parametersList, int j) {
return unique(
parametersList.stream()
.filter((Parameters factors) -> factors.size() > j)
.flatMap((Parameters factors) -> factors.get(j).getLevels().stream())
.collect(toList())
);
}
private List buildConstraints() {
return IntStream.range(0, this.scenarioLength)
.mapToObj(i -> asList(
createConstraintForStateActionValidity(i),
createConstraintForActionArgs(i),
createConstraintForActionStateValidity(i),
createConstraintForNormality(i)
))
.flatMap(Collection::stream)
.collect(toList());
}
private Constraint createConstraintForActionArgs(int i) {
return new Constraint() {
@Override
public boolean test(Tuple tuple) {
Action action = getActionFromTuple(tuple, i);
for (int j = 0; j < action.numParameterFactors(); j++) {
Object level = getActionArgFromTuple(tuple, i, j);
if (Objects.equals(level, VOID))
return false;
if (!action.parameters().get(j).getLevels().contains(level)) {
return false;
}
}
for (int j = action.numParameterFactors(); j < maxActionParams; j++) {
if (getActionArgFromTuple(tuple, i, j) != VOID)
return false;
}
return true;
}
@Override
public List involvedKeys() {
return Stream.concat(
Stream.of(composeActionFactorName(name, i)),
IntStream.range(0, maxActionParams).mapToObj((int j) -> composeActionParamFactorName(name, i, j))
).collect(toList());
}
@Override
public String toString() {
return TestPredicate.toString(this);
}
};
}
private Constraint createConstraintForStateActionValidity(int i) {
return new Constraint() {
@Override
public boolean test(Tuple testObject) {
return allPossibleEdges(
sutState -> sutState.equals(getStateFromTuple(testObject, i)),
sutAction -> sutAction.equals(getActionFromTuple(testObject, i)),
sutState -> true
).findFirst().isPresent();
}
@Override
public List involvedKeys() {
return asList(
composeStateFactorName(name, i),
composeActionFactorName(name, i)
);
}
@Override
public String toString() {
return TestPredicate.toString(this);
}
};
}
private Constraint createConstraintForNormality(int i) {
return new Constraint() {
@Override
public boolean test(Tuple tuple) {
State state = getStateFromTuple(tuple, i);
Action action = getActionFromTuple(tuple, i);
Args args = getActionArgsFromTuple(tuple, i);
//noinspection SimplifiableIfStatement
if (args.containsVoid())
return false;
return state.expectation(action, args).getType() == OutputType.VALUE_RETURNED;
}
@Override
public List involvedKeys() {
return Stream.concat(
Stream.of(
composeStateFactorName(name, i),
composeActionFactorName(name, i)
),
IntStream.range(0, maxActionParams).mapToObj((int j) -> composeActionParamFactorName(name, i, j))
).collect(toList());
}
@Override
public String toString() {
return TestPredicate.toString(this);
}
};
}
private Constraint createConstraintForActionStateValidity(int i) {
return new Constraint() {
@Override
public boolean test(Tuple tuple) {
//noinspection SimplifiableConditionalExpression
return allPossibleEdges(
sutState -> true,
sutAction -> sutAction.equals(getActionFromTuple(tuple, i)),
sutState -> i + 1 < scenarioLength ?
sutState.equals(getStateFromTuple(tuple, i + 1)) :
true
).findFirst().isPresent();
}
@Override
public List involvedKeys() {
return i + 1 < scenarioLength ?
asList(composeActionFactorName(name, i), composeStateFactorName(name, i + 1)) :
Collections.singletonList(composeActionFactorName(name, i));
}
@Override
public String toString() {
return TestPredicate.toString(this);
}
};
}
}