Skip to content

Commit e655c11

Browse files
authored
Expand generic dispatch differential fuzz coverage (#1275)
* Expand generic dispatch differential fuzz coverage * Randomize required dispatch fuzz shapes
1 parent cc12992 commit e655c11

1 file changed

Lines changed: 39 additions & 10 deletions

File tree

de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/LuaBackendAuditTests.java

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.io.IOException;
2222
import java.util.ArrayList;
2323
import java.util.Collections;
24+
import java.util.EnumSet;
2425
import java.util.List;
2526
import java.util.Random;
2627

@@ -1544,7 +1545,10 @@ public void randomizedClassInterfaceModuleDispatchMatchesAllBackends() {
15441545
public void randomizedGenericTupleDispatchMatchesJassAndLua() {
15451546
Random random = new Random(0x71A9D15CL);
15461547
for (int caseIndex = 0; caseIndex < 8; caseIndex++) {
1547-
List<String> source = genericTupleDispatchCase(random, caseIndex);
1548+
EnumSet<GenericDispatchShape> covered = EnumSet.noneOf(GenericDispatchShape.class);
1549+
List<String> source = genericTupleDispatchCase(random, covered);
1550+
assertEquals("dispatch fuzz case must cover every semantic specialization shape",
1551+
EnumSet.allOf(GenericDispatchShape.class), covered);
15481552
String[] lines = source.toArray(new String[0]);
15491553
try {
15501554
test().executeProg().lines(lines);
@@ -1565,6 +1569,17 @@ public void randomizedGenericTupleDispatchMatchesJassAndLua() {
15651569
}
15661570
}
15671571

1572+
private enum GenericDispatchShape {
1573+
TUPLE_INT,
1574+
TUPLE_TEXT,
1575+
NESTED_TUPLE_INT,
1576+
NESTED_TUPLE_TEXT,
1577+
CLASS_PREDICATE,
1578+
OTHER_CLASS_PREDICATE,
1579+
OTHER_CLASS_PREDICATE_SECOND_TYPE,
1580+
CLASS_IMPLEMENTATION
1581+
}
1582+
15681583
/** A user method beginning with {@code destroy} is ordinary virtual dispatch, not lifecycle
15691584
* destruction. The lifecycle slot is identified from the generated OnDestroy function. */
15701585
@Test
@@ -1592,7 +1607,8 @@ public void ordinaryDestroyNamedMethodDoesNotUseLifecycleDispatchSlot() throws I
15921607
assertFalse(dispatchBody.contains(".__wurst_destroy"));
15931608
}
15941609

1595-
private List<String> genericTupleDispatchCase(Random random, int caseIndex) {
1610+
private List<String> genericTupleDispatchCase(Random random,
1611+
EnumSet<GenericDispatchShape> covered) {
15961612
List<String> source = new ArrayList<>();
15971613
Collections.addAll(source,
15981614
"package Test",
@@ -1636,46 +1652,59 @@ private List<String> genericTupleDispatchCase(Random random, int caseIndex) {
16361652
" int successes = 0");
16371653

16381654
int expected = 0;
1655+
List<GenericDispatchShape> shapes = new ArrayList<>(
1656+
EnumSet.allOf(GenericDispatchShape.class));
1657+
Collections.shuffle(shapes, random);
16391658
for (int i = 0; i < 16; i++) {
16401659
int value = random.nextInt(100) + 1;
1641-
switch (random.nextInt(7)) {
1642-
case 0 -> {
1660+
GenericDispatchShape shape = i < shapes.size()
1661+
? shapes.get(i)
1662+
: shapes.get(random.nextInt(shapes.size()));
1663+
covered.add(shape);
1664+
switch (shape) {
1665+
case TUPLE_INT -> {
16431666
source.add(" let value" + i + " = new Box<PairInt>(PairInt(" + value + ", " + (value + 1) + "))");
16441667
source.add(" if value" + i + ".matches(x -> x.a == " + value + ")");
16451668
source.add(" successes++");
16461669
source.add(" destroy value" + i);
16471670
}
1648-
case 1 -> {
1671+
case TUPLE_TEXT -> {
16491672
source.add(" let value" + i + " = new Box<PairText>(PairText(\"v" + value + "\", " + value + "))");
16501673
source.add(" if value" + i + ".matches(x -> x.a == \"v" + value + "\")");
16511674
source.add(" successes++");
16521675
source.add(" destroy value" + i);
16531676
}
1654-
case 2 -> {
1677+
case NESTED_TUPLE_INT -> {
16551678
source.add(" let value" + i + " = new Nested<PairInt>(PairInt(" + value + ", " + (value + 2) + "))");
16561679
source.add(" if value" + i + ".matches(x -> x.b == " + (value + 2) + ")");
16571680
source.add(" successes++");
16581681
source.add(" destroy value" + i);
16591682
}
1660-
case 3 -> {
1683+
case NESTED_TUPLE_TEXT -> {
1684+
source.add(" let value" + i + " = new Nested<PairText>(PairText(\"v" + value + "\", " + value + "))");
1685+
source.add(" if value" + i + ".matches(x -> x.a == \"v" + value + "\")");
1686+
source.add(" successes++");
1687+
source.add(" destroy value" + i);
1688+
}
1689+
case CLASS_PREDICATE -> {
16611690
source.add(" let value" + i + " = new Box<Foo>(new Foo())");
16621691
source.add(" if value" + i + ".matches(x -> x != null)");
16631692
source.add(" successes++");
16641693
source.add(" destroy value" + i);
16651694
}
1666-
case 4 -> {
1695+
case OTHER_CLASS_PREDICATE -> {
16671696
source.add(" let value" + i + " = new OtherBox<Foo>(new Foo())");
16681697
source.add(" if value" + i + ".matches(x -> x != null)");
16691698
source.add(" successes++");
16701699
source.add(" destroy value" + i);
16711700
}
1672-
case 5 -> {
1701+
case OTHER_CLASS_PREDICATE_SECOND_TYPE -> {
16731702
source.add(" let value" + i + " = new OtherBox<Bar>(new Bar())");
16741703
source.add(" if value" + i + ".matches(x -> x != null)");
16751704
source.add(" successes++");
16761705
source.add(" destroy value" + i);
16771706
}
1678-
default -> {
1707+
case CLASS_IMPLEMENTATION -> {
16791708
source.add(" let value" + i + " = new Box<Foo>(new Foo())");
16801709
source.add(" if value" + i + ".matches(new FooPredicate())");
16811710
source.add(" successes++");

0 commit comments

Comments
 (0)