aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'subprojects/store/src/test')
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/InOrderCursorTest.java51
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/MapUnitTests.java71
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/CommitFuzzTest.java70
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/ContentEqualsFuzzTest.java57
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/DiffCursorFuzzTest.java156
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MultiThreadFuzzTest.java91
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MultiThreadTestRunnable.java54
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MutableFuzzTest.java60
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MutableImmutableCompareFuzzTest.java36
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/RestoreFuzzTest.java61
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/SharedStoreFuzzTest.java49
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/SingleThreadFuzzTest.java61
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/utils/FuzzTestCollections.java39
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/utils/FuzzTestUtils.java12
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/utils/FuzzTestUtilsTest.java19
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/utils/MapTestEnvironment.java78
16 files changed, 603 insertions, 362 deletions
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/InOrderCursorTest.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/InOrderCursorTest.java
new file mode 100644
index 00000000..993e5531
--- /dev/null
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/InOrderCursorTest.java
@@ -0,0 +1,51 @@
1package tools.refinery.store.map.tests;
2
3import org.junit.jupiter.api.Test;
4import tools.refinery.store.map.VersionedMapStore;
5import tools.refinery.store.map.VersionedMapStoreFactoryBuilder;
6import tools.refinery.store.map.internal.InOrderMapCursor;
7import tools.refinery.store.map.internal.VersionedMapImpl;
8import tools.refinery.store.map.tests.utils.MapTestEnvironment;
9
10import static org.junit.jupiter.api.Assertions.*;
11
12class InOrderCursorTest {
13 @Test
14 void testCursor() {
15 var store = VersionedMapStore.<Integer,String>builder()
16 .strategy(VersionedMapStoreFactoryBuilder.StoreStrategy.STATE)
17 .stateBasedImmutableWhenCommitting(true)
18 .stateBasedHashProvider(MapTestEnvironment.prepareHashProvider(false))
19 .stateBasedSharingStrategy(VersionedMapStoreFactoryBuilder.SharingStrategy.SHARED_NODE_CACHE)
20 .defaultValue("x")
21 .build()
22 .createOne();
23
24 VersionedMapImpl<Integer,String> map = (VersionedMapImpl<Integer,String>) store.createMap();
25 checkMove(map,0);
26
27 map.put(1,"A");
28 map.commit();
29 checkMove(map,1);
30
31
32 map.put(2,"B");
33 map.commit();
34 checkMove(map,2);
35
36 map.put(3,"C");
37 map.commit();
38 checkMove(map,3);
39
40 }
41
42 private void checkMove(VersionedMapImpl<Integer,String> map, int num) {
43 InOrderMapCursor<Integer,String> cursor = new InOrderMapCursor<>(map);
44 for(int i=0; i<num; i++) {
45 assertTrue(cursor.move());
46 assertFalse(cursor.isTerminated());
47 }
48 assertFalse(cursor.move());
49 assertTrue(cursor.isTerminated());
50 }
51}
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/MapUnitTests.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/MapUnitTests.java
index 153f2e78..2be49bd9 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/MapUnitTests.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/MapUnitTests.java
@@ -23,4 +23,75 @@ class MapUnitTests {
23 var out2 = map.put(Tuple.of(1), true); 23 var out2 = map.put(Tuple.of(1), true);
24 assertEquals(false, out2); 24 assertEquals(false, out2);
25 } 25 }
26
27 @Test
28 void deltaRestoreTest() {
29 VersionedMapStore<Integer,String> store =
30 VersionedMapStore.<Integer,String>builder().defaultValue("x").build().createOne();
31 var map = store.createMap();
32 map.put(1,"val");
33 var version1 = map.commit();
34 map.put(1,"x");
35 map.restore(version1);
36 System.out.println(map.getSize());
37 assertEquals(1,map.getSize());
38 }
39
40 @Test
41 void deltaRestoreTest2() {
42 VersionedMapStore<Integer,String> store =
43 VersionedMapStore.<Integer,String>builder().defaultValue("x").build().createOne();
44 var map = store.createMap();
45 map.put(1,"x");
46 var version1 = map.commit();
47 map.put(1,"1");
48 map.restore(version1);
49 System.out.println(map.getSize());
50 assertEquals(0,map.getSize());
51 }
52 @Test
53 void deltaRestoreTest3() {
54 VersionedMapStore<Integer,String> store =
55 VersionedMapStore.<Integer,String>builder().defaultValue("x").build().createOne();
56 var map = store.createMap();
57 map.commit();
58 map.put(1,"1");
59 map.put(2,"x");
60 assertEquals(1,map.getSize());
61 var version1 = map.commit();
62 map.put(1,"x");
63 assertEquals(0,map.getSize());
64 map.put(2,"2");
65 assertEquals(1,map.getSize());
66 map.put(2,"x");
67 assertEquals(0,map.getSize());
68 var version2 = map.commit();
69 map.restore(version1);
70 assertEquals(1,map.getSize());
71 map.restore(version2);
72 assertEquals(0,map.getSize());
73 }
74
75 @Test
76 void deltaRestoreTest4() {
77 VersionedMapStore<Integer,String> store =
78 VersionedMapStore.<Integer,String>builder().defaultValue("x").build().createOne();
79 var map = store.createMap();
80 map.commit();
81 map.put(1,"1");
82 map.put(2,"x");
83 assertEquals(1,map.getSize());
84 var version1 = map.commit();
85 map.put(1,"x");
86 assertEquals(0,map.getSize());
87 map.put(2,"2");
88 assertEquals(1,map.getSize());
89 map.put(2,"x");
90 assertEquals(0,map.getSize());
91 var version2 = map.commit();
92 map.restore(version1);
93 assertEquals(1,map.getSize());
94 map.restore(version2);
95 assertEquals(0,map.getSize());
96 }
26} 97}
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/CommitFuzzTest.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/CommitFuzzTest.java
index eabe5bd1..58206eda 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/CommitFuzzTest.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/CommitFuzzTest.java
@@ -5,33 +5,32 @@
5 */ 5 */
6package tools.refinery.store.map.tests.fuzz; 6package tools.refinery.store.map.tests.fuzz;
7 7
8import static org.junit.jupiter.api.Assertions.fail;
9
10import java.util.Random;
11import java.util.stream.Stream;
12
13import org.junit.jupiter.api.Tag; 8import org.junit.jupiter.api.Tag;
14import org.junit.jupiter.api.Timeout; 9import org.junit.jupiter.api.Timeout;
15import org.junit.jupiter.params.ParameterizedTest; 10import org.junit.jupiter.params.ParameterizedTest;
16import org.junit.jupiter.params.provider.Arguments; 11import org.junit.jupiter.params.provider.Arguments;
17import org.junit.jupiter.params.provider.MethodSource; 12import org.junit.jupiter.params.provider.MethodSource;
18
19import tools.refinery.store.map.ContinousHashProvider;
20import tools.refinery.store.map.VersionedMapStore; 13import tools.refinery.store.map.VersionedMapStore;
21import tools.refinery.store.map.VersionedMapStoreImpl; 14import tools.refinery.store.map.VersionedMapStoreFactoryBuilder;
22import tools.refinery.store.map.internal.VersionedMapImpl;
23import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; 15import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils;
24import tools.refinery.store.map.tests.utils.MapTestEnvironment; 16import tools.refinery.store.map.tests.utils.MapTestEnvironment;
25 17
18import java.util.Random;
19import java.util.stream.Stream;
20
21import static org.junit.jupiter.api.Assertions.fail;
22import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*;
23
26class CommitFuzzTest { 24class CommitFuzzTest {
27 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue, int commitFrequency,
28 boolean evilHash) {
29 String[] values = MapTestEnvironment.prepareValues(maxValue);
30 ContinousHashProvider<Integer> chp = MapTestEnvironment.prepareHashProvider(evilHash);
31 25
32 VersionedMapStore<Integer, String> store = new VersionedMapStoreImpl<Integer, String>(chp, values[0]); 26 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue,
33 VersionedMapImpl<Integer, String> sut = (VersionedMapImpl<Integer, String>) store.createMap(); 27 boolean nullDefault, int commitFrequency,
34 MapTestEnvironment<Integer, String> e = new MapTestEnvironment<Integer, String>(sut); 28 VersionedMapStoreFactoryBuilder<Integer, String> builder) {
29 String[] values = MapTestEnvironment.prepareValues(maxValue, nullDefault);
30
31 VersionedMapStore<Integer, String> store = builder.defaultValue(values[0]).build().createOne();
32 var sut = store.createMap();
33 MapTestEnvironment<Integer, String> e = new MapTestEnvironment<>(sut);
35 34
36 Random r = new Random(seed); 35 Random r = new Random(seed);
37 36
@@ -39,24 +38,13 @@ class CommitFuzzTest {
39 } 38 }
40 39
41 private void iterativeRandomPutsAndCommits(String scenario, int steps, int maxKey, String[] values, 40 private void iterativeRandomPutsAndCommits(String scenario, int steps, int maxKey, String[] values,
42 MapTestEnvironment<Integer, String> e, Random r, int commitFrequency) { 41 MapTestEnvironment<Integer, String> e, Random r, int commitFrequency) {
43 int stopAt = -1;
44 for (int i = 0; i < steps; i++) { 42 for (int i = 0; i < steps; i++) {
45 int index = i + 1; 43 int index = i + 1;
46 int nextKey = r.nextInt(maxKey); 44 int nextKey = r.nextInt(maxKey);
47 String nextValue = values[r.nextInt(values.length)]; 45 String nextValue = values[r.nextInt(values.length)];
48 if (index == stopAt) {
49 System.out.println("issue!");
50 System.out.println("State before:");
51 e.printComparison();
52 e.sut.prettyPrint();
53 System.out.println("Next: put(" + nextKey + "," + nextValue + ")");
54 }
55 try { 46 try {
56 e.put(nextKey, nextValue); 47 e.put(nextKey, nextValue);
57 if (index == stopAt) {
58 e.sut.prettyPrint();
59 }
60 e.checkEquivalence(scenario + ":" + index); 48 e.checkEquivalence(scenario + ":" + index);
61 } catch (Exception exception) { 49 } catch (Exception exception) {
62 exception.printStackTrace(); 50 exception.printStackTrace();
@@ -64,35 +52,37 @@ class CommitFuzzTest {
64 } 52 }
65 MapTestEnvironment.printStatus(scenario, index, steps, null); 53 MapTestEnvironment.printStatus(scenario, index, steps, null);
66 if (index % commitFrequency == 0) { 54 if (index % commitFrequency == 0) {
67 e.sut.commit(); 55 e.commit();
68 } 56 }
69 } 57 }
70 } 58 }
71 59
72 @ParameterizedTest(name = "Commit {index}/{0} Steps={1} Keys={2} Values={3} commit frequency={4} seed={5} evil-hash={6}") 60 public static final String title = "Commit {index}/{0} Steps={1} Keys={2} Values={3} nullDefault={4} commit frequency={5} " +
61 "seed={6} config={7}";
62
63 @ParameterizedTest(name = title)
73 @MethodSource 64 @MethodSource
74 @Timeout(value = 10) 65 @Timeout(value = 10)
75 @Tag("fuzz") 66 @Tag("fuzz")
76 void parametrizedFastFuzz(int tests, int steps, int noKeys, int noValues, int commitFrequency, int seed, 67 void parametrizedFastFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault, int commitFrequency,
77 boolean evilHash) { 68 int seed, VersionedMapStoreFactoryBuilder<Integer, String> builder) {
78 runFuzzTest("CommitS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues, 69 runFuzzTest("CommitS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues,
79 commitFrequency, evilHash); 70 nullDefault, commitFrequency, builder);
80 } 71 }
81 72
82 static Stream<Arguments> parametrizedFastFuzz() { 73 static Stream<Arguments> parametrizedFastFuzz() {
83 return FuzzTestUtils.permutationWithSize(new Object[] { FuzzTestUtils.FAST_STEP_COUNT }, new Object[] { 3, 32, 32 * 32 }, 74 return FuzzTestUtils.permutationWithSize(stepCounts, keyCounts, valueCounts, nullDefaultOptions,
84 new Object[] { 2, 3 }, new Object[] { 1, 10, 100 }, new Object[] { 1, 2, 3 }, 75 commitFrequencyOptions, randomSeedOptions, storeConfigs);
85 new Object[] { false, true });
86 } 76 }
87 77
88 @ParameterizedTest(name = "Commit {index}/{0} Steps={1} Keys={2} Values={3} commit frequency={4} seed={5} evil-hash={6}") 78 @ParameterizedTest(name = title)
89 @MethodSource 79 @MethodSource
90 @Tag("fuzz") 80 @Tag("fuzz")
91 @Tag("slow") 81 @Tag("slow")
92 void parametrizedSlowFuzz(int tests, int steps, int noKeys, int noValues, int commitFrequency, int seed, 82 void parametrizedSlowFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault, int commitFrequency,
93 boolean evilHash) { 83 int seed, VersionedMapStoreFactoryBuilder<Integer, String> builder) {
94 runFuzzTest("CommitS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues, 84 runFuzzTest("CommitS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues,
95 commitFrequency, evilHash); 85 nullDefault, commitFrequency, builder);
96 } 86 }
97 87
98 static Stream<Arguments> parametrizedSlowFuzz() { 88 static Stream<Arguments> parametrizedSlowFuzz() {
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/ContentEqualsFuzzTest.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/ContentEqualsFuzzTest.java
index b0502a2b..c49911b8 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/ContentEqualsFuzzTest.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/ContentEqualsFuzzTest.java
@@ -10,8 +10,10 @@ import org.junit.jupiter.api.Timeout;
10import org.junit.jupiter.params.ParameterizedTest; 10import org.junit.jupiter.params.ParameterizedTest;
11import org.junit.jupiter.params.provider.Arguments; 11import org.junit.jupiter.params.provider.Arguments;
12import org.junit.jupiter.params.provider.MethodSource; 12import org.junit.jupiter.params.provider.MethodSource;
13import tools.refinery.store.map.*; 13import tools.refinery.store.map.Cursor;
14import tools.refinery.store.map.internal.VersionedMapImpl; 14import tools.refinery.store.map.VersionedMap;
15import tools.refinery.store.map.VersionedMapStore;
16import tools.refinery.store.map.VersionedMapStoreFactoryBuilder;
15import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; 17import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils;
16import tools.refinery.store.map.tests.utils.MapTestEnvironment; 18import tools.refinery.store.map.tests.utils.MapTestEnvironment;
17 19
@@ -22,23 +24,25 @@ import java.util.List;
22import java.util.Random; 24import java.util.Random;
23import java.util.stream.Stream; 25import java.util.stream.Stream;
24 26
25import static org.junit.jupiter.api.Assertions.*; 27import static org.junit.jupiter.api.Assertions.fail;
28import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*;
26 29
27class ContentEqualsFuzzTest { 30class ContentEqualsFuzzTest {
28 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue, int commitFrequency, 31 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue,
29 boolean evilHash) { 32 boolean nullDefault, int commitFrequency,
30 String[] values = MapTestEnvironment.prepareValues(maxValue); 33 VersionedMapStoreFactoryBuilder<Integer, String> builder) {
31 ContinousHashProvider<Integer> chp = MapTestEnvironment.prepareHashProvider(evilHash); 34 String[] values = MapTestEnvironment.prepareValues(maxValue, nullDefault);
35
32 36
33 Random r = new Random(seed); 37 Random r = new Random(seed);
34 38
35 iterativeRandomPutsAndCommitsThenCompare(scenario, chp, steps, maxKey, values, r, commitFrequency); 39 iterativeRandomPutsAndCommitsThenCompare(scenario, builder, steps, maxKey, values, r, commitFrequency);
36 } 40 }
37 41
38 private void iterativeRandomPutsAndCommitsThenCompare(String scenario, ContinousHashProvider<Integer> chp, 42 private void iterativeRandomPutsAndCommitsThenCompare(String scenario, VersionedMapStoreFactoryBuilder<Integer, String> builder,
39 int steps, int maxKey, String[] values, Random r, 43 int steps, int maxKey, String[] values, Random r,
40 int commitFrequency) { 44 int commitFrequency) {
41 VersionedMapStore<Integer, String> store1 = new VersionedMapStoreImpl<Integer, String>(chp, values[0]); 45 VersionedMapStore<Integer, String> store1 = builder.defaultValue(values[0]).build().createOne();
42 VersionedMap<Integer, String> sut1 = store1.createMap(); 46 VersionedMap<Integer, String> sut1 = store1.createMap();
43 47
44 // Fill one map 48 // Fill one map
@@ -68,7 +72,7 @@ class ContentEqualsFuzzTest {
68 // Randomize the order of the content 72 // Randomize the order of the content
69 Collections.shuffle(content, r); 73 Collections.shuffle(content, r);
70 74
71 VersionedMapStore<Integer, String> store2 = new VersionedMapStoreImpl<Integer, String>(chp, values[0]); 75 VersionedMapStore<Integer, String> store2 = builder.defaultValue(values[0]).build().createOne();
72 VersionedMap<Integer, String> sut2 = store2.createMap(); 76 VersionedMap<Integer, String> sut2 = store2.createMap();
73 int index2 = 1; 77 int index2 = 1;
74 for (SimpleEntry<Integer, String> entry : content) { 78 for (SimpleEntry<Integer, String> entry : content) {
@@ -78,40 +82,39 @@ class ContentEqualsFuzzTest {
78 } 82 }
79 83
80 // Check the integrity of the maps 84 // Check the integrity of the maps
81 ((VersionedMapImpl<Integer, String>) sut1).checkIntegrity(); 85 sut1.checkIntegrity();
82 ((VersionedMapImpl<Integer, String>) sut2).checkIntegrity(); 86 sut2.checkIntegrity();
83 87
84 // Compare the two maps 88 // Compare the two maps
85 MapTestEnvironment.compareTwoMaps(scenario, sut1, sut2); 89 MapTestEnvironment.compareTwoMaps(scenario, sut1, sut2);
86 } 90 }
87 91
88 @ParameterizedTest(name = "Compare {index}/{0} Steps={1} Keys={2} Values={3} commit frequency={4} seed={5} " + 92 public static final String title = "Compare {index}/{0} Steps={1} Keys={2} Values={3} defaultNull={4} commit frequency={5}" +
89 "evil-hash={6}") 93 "seed={6} config={7}";
94
95 @ParameterizedTest(name = title)
90 @MethodSource 96 @MethodSource
91 @Timeout(value = 10) 97 @Timeout(value = 10)
92 @Tag("fuzz") 98 @Tag("fuzz")
93 void parametrizedFastFuzz(int tests, int steps, int noKeys, int noValues, int commitFrequency, int seed, 99 void parametrizedFastFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault, int commitFrequency,
94 boolean evilHash) { 100 int seed, VersionedMapStoreFactoryBuilder<Integer, String> builder) {
95 runFuzzTest("CompareS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues, 101 runFuzzTest("CompareS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues,
96 commitFrequency, evilHash); 102 nullDefault, commitFrequency, builder);
97 } 103 }
98 104
99 static Stream<Arguments> parametrizedFastFuzz() { 105 static Stream<Arguments> parametrizedFastFuzz() {
100 return FuzzTestUtils.permutationWithSize(new Object[]{FuzzTestUtils.FAST_STEP_COUNT}, new Object[]{3, 32, 106 return FuzzTestUtils.permutationWithSize(stepCounts, keyCounts, valueCounts, nullDefaultOptions,
101 32 * 32}, 107 commitFrequencyOptions, randomSeedOptions, storeConfigs);
102 new Object[]{2, 3}, new Object[]{1, 10, 100}, new Object[]{1, 2, 3},
103 new Object[]{false, true});
104 } 108 }
105 109
106 @ParameterizedTest(name = "Compare {index}/{0} Steps={1} Keys={2} Values={3} commit frequency={4} seed={5} " + 110 @ParameterizedTest(name = title)
107 "evil-hash={6}")
108 @MethodSource 111 @MethodSource
109 @Tag("fuzz") 112 @Tag("fuzz")
110 @Tag("slow") 113 @Tag("slow")
111 void parametrizedSlowFuzz(int tests, int steps, int noKeys, int noValues, int commitFrequency, int seed, 114 void parametrizedSlowFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean defaultNull, int commitFrequency,
112 boolean evilHash) { 115 int seed, VersionedMapStoreFactoryBuilder<Integer, String> builder) {
113 runFuzzTest("CompareS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues, 116 runFuzzTest("CompareS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues,
114 commitFrequency, evilHash); 117 defaultNull, commitFrequency, builder);
115 } 118 }
116 119
117 static Stream<Arguments> parametrizedSlowFuzz() { 120 static Stream<Arguments> parametrizedSlowFuzz() {
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/DiffCursorFuzzTest.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/DiffCursorFuzzTest.java
index 8274336e..5a4f8038 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/DiffCursorFuzzTest.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/DiffCursorFuzzTest.java
@@ -5,115 +5,133 @@
5 */ 5 */
6package tools.refinery.store.map.tests.fuzz; 6package tools.refinery.store.map.tests.fuzz;
7 7
8import static org.junit.jupiter.api.Assertions.fail;
9
10import java.util.Random;
11import java.util.stream.Stream;
12
13import org.junit.jupiter.api.Tag; 8import org.junit.jupiter.api.Tag;
14import org.junit.jupiter.api.Timeout; 9import org.junit.jupiter.api.Timeout;
15import org.junit.jupiter.params.ParameterizedTest; 10import org.junit.jupiter.params.ParameterizedTest;
16import org.junit.jupiter.params.provider.Arguments; 11import org.junit.jupiter.params.provider.Arguments;
17import org.junit.jupiter.params.provider.MethodSource; 12import org.junit.jupiter.params.provider.MethodSource;
18
19import tools.refinery.store.map.ContinousHashProvider;
20import tools.refinery.store.map.DiffCursor; 13import tools.refinery.store.map.DiffCursor;
14import tools.refinery.store.map.VersionedMap;
21import tools.refinery.store.map.VersionedMapStore; 15import tools.refinery.store.map.VersionedMapStore;
22import tools.refinery.store.map.VersionedMapStoreImpl; 16import tools.refinery.store.map.VersionedMapStoreFactoryBuilder;
23import tools.refinery.store.map.internal.VersionedMapImpl;
24import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; 17import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils;
25import tools.refinery.store.map.tests.utils.MapTestEnvironment; 18import tools.refinery.store.map.tests.utils.MapTestEnvironment;
26 19
20import java.util.Random;
21import java.util.stream.Stream;
22
23import static org.junit.jupiter.api.Assertions.fail;
24import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*;
25
27class DiffCursorFuzzTest { 26class DiffCursorFuzzTest {
28 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue, int commitFrequency, 27 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue, boolean nullDefault,
29 boolean evilHash) { 28 int commitFrequency, boolean commitBeforeDiffCursor,
30 String[] values = MapTestEnvironment.prepareValues(maxValue); 29 VersionedMapStoreFactoryBuilder<Integer, String> builder) {
31 ContinousHashProvider<Integer> chp = MapTestEnvironment.prepareHashProvider(evilHash); 30 String[] values = MapTestEnvironment.prepareValues(maxValue, nullDefault);
32 31
33 VersionedMapStore<Integer, String> store = new VersionedMapStoreImpl<Integer, String>(chp, values[0]); 32 VersionedMapStore<Integer, String> store = builder.defaultValue(values[0]).build().createOne();
34 iterativeRandomPutsAndCommitsThenDiffcursor(scenario, store, steps, maxKey, values, seed, commitFrequency); 33 iterativeRandomPutsAndCommitsThenDiffCursor(scenario, store, steps, maxKey, values, seed, commitFrequency,
34 commitBeforeDiffCursor);
35 } 35 }
36 36
37 private void iterativeRandomPutsAndCommitsThenDiffcursor(String scenario, VersionedMapStore<Integer, String> store, 37 private void iterativeRandomPutsAndCommitsThenDiffCursor(String scenario, VersionedMapStore<Integer, String> store,
38 int steps, int maxKey, String[] values, int seed, int commitFrequency) { 38 int steps, int maxKey, String[] values, int seed,
39 // 1. build a map with versions 39 int commitFrequency, boolean commitBeforeDiffCursor) {
40 Random r = new Random(seed); 40
41 VersionedMapImpl<Integer, String> versioned = (VersionedMapImpl<Integer, String>) store.createMap();
42 int largestCommit = -1; 41 int largestCommit = -1;
43 42
44 for (int i = 0; i < steps; i++) { 43 {
45 int index = i + 1; 44 // 1. build a map with versions
46 int nextKey = r.nextInt(maxKey); 45 Random r = new Random(seed);
47 String nextValue = values[r.nextInt(values.length)]; 46 VersionedMap<Integer, String> versioned = store.createMap();
48 try { 47 for (int i = 0; i < steps; i++) {
49 versioned.put(nextKey, nextValue); 48 int index = i + 1;
50 } catch (Exception exception) { 49 int nextKey = r.nextInt(maxKey);
51 exception.printStackTrace(); 50 String nextValue = values[r.nextInt(values.length)];
52 fail(scenario + ":" + index + ": exception happened: " + exception);
53 }
54 if (index % commitFrequency == 0) {
55 long version = versioned.commit();
56 largestCommit = (int) version;
57 }
58 if (index % 10000 == 0)
59 System.out.println(scenario + ":" + index + "/" + steps + " building finished");
60 }
61 // 2. create a non-versioned map,
62 VersionedMapImpl<Integer, String> moving = (VersionedMapImpl<Integer, String>) store.createMap();
63 Random r2 = new Random(seed + 1);
64
65 final int diffTravelFrequency = commitFrequency * 2;
66 for (int i = 0; i < steps; i++) {
67 int index = i + 1;
68 if (index % diffTravelFrequency == 0) {
69 // difftravel
70 long travelToVersion = r2.nextInt(largestCommit + 1);
71 DiffCursor<Integer, String> diffCursor = moving.getDiffCursor(travelToVersion);
72 moving.putAll(diffCursor);
73
74 } else {
75 // random puts
76 int nextKey = r2.nextInt(maxKey);
77 String nextValue = values[r2.nextInt(values.length)];
78 try { 51 try {
79 moving.put(nextKey, nextValue); 52 versioned.put(nextKey, nextValue);
80 } catch (Exception exception) { 53 } catch (Exception exception) {
81 exception.printStackTrace(); 54 exception.printStackTrace();
82 fail(scenario + ":" + index + ": exception happened: " + exception); 55 fail(scenario + ":" + index + ": exception happened: " + exception);
83 } 56 }
84 if (index % commitFrequency == 0) { 57 if (index % commitFrequency == 0) {
85 versioned.commit(); 58 long version = versioned.commit();
59 largestCommit = (int) version;
86 } 60 }
87 if (index % 10000 == 0) 61 if (index % 10000 == 0)
88 System.out.println(scenario + ":" + index + "/" + steps + " building finished"); 62 System.out.println(scenario + ":" + index + "/" + steps + " building finished");
89 } 63 }
90 } 64 }
91 65
66 {
67 // 2. create a non-versioned map,
68 VersionedMap<Integer, String> moving = store.createMap();
69 Random r2 = new Random(seed + 1);
70
71 final int diffTravelFrequency = commitFrequency * 2;
72 for (int i = 0; i < steps; i++) {
73 int index = i + 1;
74 if (index % diffTravelFrequency == 0) {
75 // diff-travel
76 long travelToVersion = r2.nextInt(largestCommit + 1);
77
78 VersionedMap<Integer, String> oracle = store.createMap(travelToVersion);
79
80 if(commitBeforeDiffCursor) {
81 moving.commit();
82 }
83 DiffCursor<Integer, String> diffCursor = moving.getDiffCursor(travelToVersion);
84 moving.putAll(diffCursor);
85 moving.commit();
86
87 MapTestEnvironment.compareTwoMaps(scenario + ":c" + index, oracle, moving);
88
89 moving.restore(travelToVersion);
90
91 } else {
92 // random puts
93 int nextKey = r2.nextInt(maxKey);
94 String nextValue = values[r2.nextInt(values.length)];
95 try {
96 moving.put(nextKey, nextValue);
97 } catch (Exception exception) {
98 exception.printStackTrace();
99 fail(scenario + ":" + index + ": exception happened: " + exception);
100 }
101 if (index % 10000 == 0)
102 System.out.println(scenario + ":" + index + "/" + steps + " building finished");
103 }
104 }
105 }
92 } 106 }
93 107
94 @ParameterizedTest(name = "Mutable-Immutable Compare {index}/{0} Steps={1} Keys={2} Values={3} commit frequency={4} seed={5} evil-hash={6}") 108 public static final String title = "DiffCursor {index}/{0} Steps={1} Keys={2} Values={3} nullDefault={4} " +
109 "commit frequency={5} seed={6} commit before diff={7} config={8}";
110
111 @ParameterizedTest(name = title)
95 @MethodSource 112 @MethodSource
96 @Timeout(value = 10) 113 @Timeout(value = 10)
97 @Tag("fuzz") 114 @Tag("fuzz")
98 void parametrizedFuzz(int tests, int steps, int noKeys, int noValues, int commitFrequency, int seed, 115 void parametrizedFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault,
99 boolean evilHash) { 116 int commitFrequency, int seed, boolean commitBeforeDiffCursor,
100 runFuzzTest("MutableImmutableCompareS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, 117 VersionedMapStoreFactoryBuilder<Integer, String> builder) {
101 noKeys, noValues, commitFrequency, evilHash); 118 runFuzzTest("DiffCursorS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps,
119 noKeys, noValues, nullDefault, commitFrequency, commitBeforeDiffCursor, builder);
102 } 120 }
103 121
104 static Stream<Arguments> parametrizedFuzz() { 122 static Stream<Arguments> parametrizedFuzz() {
105 return FuzzTestUtils.permutationWithSize(new Object[] { FuzzTestUtils.FAST_STEP_COUNT }, new Object[] { 3, 32, 32 * 32 }, 123 return FuzzTestUtils.permutationWithSize(new Object[]{100}, keyCounts, valueCounts, nullDefaultOptions,
106 new Object[] { 2, 3 }, new Object[] { 1, 10, 100 }, new Object[] { 1, 2, 3 }, 124 commitFrequencyOptions, randomSeedOptions, new Object[]{false,true}, storeConfigs);
107 new Object[] { false, true });
108 } 125 }
109 @ParameterizedTest(name = "Mutable-Immutable Compare {index}/{0} Steps={1} Keys={2} Values={3} commit frequency={4} seed={5} evil-hash={6}") 126
127 @ParameterizedTest(name = title)
110 @MethodSource 128 @MethodSource
111 @Tag("fuzz") 129 @Tag("fuzz")
112 @Tag("slow") 130 @Tag("slow")
113 void parametrizedSlowFuzz(int tests, int steps, int noKeys, int noValues, int commitFrequency, int seed, 131 void parametrizedSlowFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault, int commitFrequency,
114 boolean evilHash) { 132 int seed, boolean commitBeforeDiffCursor, VersionedMapStoreFactoryBuilder<Integer, String> builder) {
115 runFuzzTest("MutableImmutableCompareS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues, 133 runFuzzTest("DiffCursorS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues,
116 commitFrequency, evilHash); 134 nullDefault, commitFrequency, commitBeforeDiffCursor, builder);
117 } 135 }
118 136
119 static Stream<Arguments> parametrizedSlowFuzz() { 137 static Stream<Arguments> parametrizedSlowFuzz() {
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MultiThreadFuzzTest.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MultiThreadFuzzTest.java
index ab2b9435..3b55434c 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MultiThreadFuzzTest.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MultiThreadFuzzTest.java
@@ -5,95 +5,96 @@
5 */ 5 */
6package tools.refinery.store.map.tests.fuzz; 6package tools.refinery.store.map.tests.fuzz;
7 7
8import static org.junit.jupiter.api.Assertions.assertEquals;
9import static org.junit.jupiter.api.Assertions.fail;
10
11import java.util.Collections;
12import java.util.LinkedList;
13import java.util.List;
14import java.util.stream.Stream;
15
16import org.junit.jupiter.api.Tag; 8import org.junit.jupiter.api.Tag;
17import org.junit.jupiter.api.Timeout; 9import org.junit.jupiter.api.Timeout;
18import org.junit.jupiter.params.ParameterizedTest; 10import org.junit.jupiter.params.ParameterizedTest;
19import org.junit.jupiter.params.provider.Arguments; 11import org.junit.jupiter.params.provider.Arguments;
20import org.junit.jupiter.params.provider.MethodSource; 12import org.junit.jupiter.params.provider.MethodSource;
21
22import tools.refinery.store.map.ContinousHashProvider;
23import tools.refinery.store.map.VersionedMapStore; 13import tools.refinery.store.map.VersionedMapStore;
24import tools.refinery.store.map.VersionedMapStoreImpl; 14import tools.refinery.store.map.VersionedMapStoreFactoryBuilder;
25import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; 15import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils;
26import tools.refinery.store.map.tests.utils.MapTestEnvironment; 16import tools.refinery.store.map.tests.utils.MapTestEnvironment;
27 17
18import java.util.Collections;
19import java.util.LinkedList;
20import java.util.List;
21import java.util.stream.Stream;
22
23import static org.junit.jupiter.api.Assertions.assertEquals;
24import static org.junit.jupiter.api.Assertions.fail;
25import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*;
26
28class MultiThreadFuzzTest { 27class MultiThreadFuzzTest {
29 public static final int noThreads = 32; 28 public static final int noThreads = 10;
30 29
31 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue, int commitFrequency, 30 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue, boolean nullDefault, int commitFrequency, VersionedMapStoreFactoryBuilder<Integer, String> builder) {
32 boolean evilHash) { 31 String[] values = MapTestEnvironment.prepareValues(maxValue, nullDefault);
33 String[] values = MapTestEnvironment.prepareValues(maxValue); 32
34 ContinousHashProvider<Integer> chp = MapTestEnvironment.prepareHashProvider(evilHash); 33 VersionedMapStore<Integer, String> store = builder.defaultValue(values[0]).build().createOne();
35 34
36 VersionedMapStore<Integer, String> store = new VersionedMapStoreImpl<Integer, String>(chp, values[0]);
37
38 // initialize runnables 35 // initialize runnables
39 MultiThreadTestRunnable[] runnables = new MultiThreadTestRunnable[noThreads]; 36 MultiThreadTestRunnable[] runnables = new MultiThreadTestRunnable[noThreads];
40 for(int i = 0; i<noThreads; i++) { 37 for (int i = 0; i < noThreads; i++) {
41 runnables[i] = new MultiThreadTestRunnable(scenario+"-T"+(i+1), store, steps, maxKey, values, seed, commitFrequency); 38 runnables[i] = new MultiThreadTestRunnable(scenario + "-T" + (i + 1), store, steps, maxKey, values, seed
39 , commitFrequency);
42 } 40 }
43 41
44 // initialize threads 42 // initialize threads
45 Thread[] threads = new Thread[noThreads]; 43 Thread[] threads = new Thread[noThreads];
46 for(int i = 0; i<noThreads; i++) { 44 for (int i = 0; i < noThreads; i++) {
47 threads[i] = new Thread(runnables[i]); 45 threads[i] = new Thread(runnables[i]);
48 } 46 }
49 47
50 // start threads; 48 // start threads;
51 for(int i = 0; i<noThreads; i++) { 49 for (int i = 0; i < noThreads; i++) {
52 threads[i].start(); 50 runnables[i].run();
51 //threads[i].start();
53 } 52 }
54 53
55 // wait all the threads; 54 // wait all the threads;
56 for(int i = 0; i<noThreads; i++) { 55 for (int i = 0; i < noThreads; i++) {
57 try { 56 try {
58 threads[i].join(); 57 threads[i].join();
59 } catch (InterruptedException e) { 58 } catch (InterruptedException e) {
60 fail("Thread "+i+" interrupted."); 59 fail("Thread " + i + " interrupted.");
61 } 60 }
62 } 61 }
63 62
64 // collect errors 63 // collect errors
65 List<Throwable> errors = new LinkedList<>(); 64 List<Throwable> errors = new LinkedList<>();
66 for(int i = 0; i<noThreads; i++) { 65 for (int i = 0; i < noThreads; i++) {
67 errors.addAll(runnables[i].getErrors()); 66 errors.addAll(runnables[i].getErrors());
68 } 67 }
69 68
70 assertEquals(Collections.EMPTY_LIST, errors); 69 assertEquals(Collections.EMPTY_LIST, errors);
71 } 70 }
72 71
73 @ParameterizedTest(name = "Multithread {index}/{0} Steps={1} Keys={2} Values={3} commit frequency={4} seed={5} evil-hash={6}") 72 static final String title = "MultiThread {index}/{0} Steps={1} Keys={2} Values={3} defaultNull={4} commit " +
73 "frequency={5} seed={6} config={7}";
74
75 @ParameterizedTest(name = title)
74 @MethodSource 76 @MethodSource
75 @Timeout(value = 10) 77 @Timeout(value = 10)
76 @Tag("fuzz") 78 @Tag("fuzz")
77 void parametrizedFastFuzz(int tests, int steps, int noKeys, int noValues, int commitFrequency, int seed, 79 void parametrizedFastFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean defaultNull,
78 boolean evilHash) { 80 int commitFrequency, int seed, VersionedMapStoreFactoryBuilder<Integer, String> builder) {
79 runFuzzTest("MultithreadS" + steps + "K" + noKeys + "V" + noValues + "CF" + commitFrequency + "s" + seed, seed, steps, noKeys, noValues, 81 runFuzzTest("MultiThreadS" + steps + "K" + noKeys + "V" + noValues + defaultNull + "CF" + commitFrequency +
80 commitFrequency, evilHash); 82 "s" + seed, seed, steps, noKeys, noValues, defaultNull, commitFrequency, builder);
81 } 83 }
82 84
83 static Stream<Arguments> parametrizedFastFuzz() { 85 static Stream<Arguments> parametrizedFastFuzz() {
84 return FuzzTestUtils.permutationWithSize(new Object[] { FuzzTestUtils.FAST_STEP_COUNT }, new Object[] { 3, 32, 32 * 32 }, 86 return FuzzTestUtils.permutationWithSize(stepCounts, keyCounts, valueCounts, nullDefaultOptions,
85 new Object[] { 2, 3 }, new Object[] { 10, 100 }, new Object[] { 1, 2, 3 }, 87 new Object[]{10, 100}, randomSeedOptions, storeConfigs);
86 new Object[] { false, true });
87 } 88 }
88 89
89 @ParameterizedTest(name = "Multithread {index}/{0} Steps={1} Keys={2} Values={3} commit frequency={4} seed={5} evil-hash={6}") 90 @ParameterizedTest(name = title)
90 @MethodSource 91 @MethodSource
91 @Tag("fuzz") 92 @Tag("fuzz")
92 @Tag("slow") 93 @Tag("slow")
93 void parametrizedSlowFuzz(int tests, int steps, int noKeys, int noValues, int commitFrequency, int seed, 94 void parametrizedSlowFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault,
94 boolean evilHash) { 95 int commitFrequency, int seed, VersionedMapStoreFactoryBuilder<Integer, String> builder) {
95 runFuzzTest("RestoreS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues, 96 runFuzzTest("RestoreS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues,
96 commitFrequency, evilHash); 97 nullDefault, commitFrequency, builder);
97 } 98 }
98 99
99 static Stream<Arguments> parametrizedSlowFuzz() { 100 static Stream<Arguments> parametrizedSlowFuzz() {
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MultiThreadTestRunnable.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MultiThreadTestRunnable.java
index 502c8362..9b2e591a 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MultiThreadTestRunnable.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MultiThreadTestRunnable.java
@@ -13,22 +13,22 @@ import java.util.List;
13import java.util.Map; 13import java.util.Map;
14import java.util.Random; 14import java.util.Random;
15 15
16import tools.refinery.store.map.VersionedMap;
16import tools.refinery.store.map.VersionedMapStore; 17import tools.refinery.store.map.VersionedMapStore;
17import tools.refinery.store.map.internal.VersionedMapImpl;
18import tools.refinery.store.map.tests.utils.MapTestEnvironment; 18import tools.refinery.store.map.tests.utils.MapTestEnvironment;
19 19
20public class MultiThreadTestRunnable implements Runnable { 20public class MultiThreadTestRunnable implements Runnable {
21 String scenario; 21 final String scenario;
22 VersionedMapStore<Integer, String> store; 22 final VersionedMapStore<Integer, String> store;
23 int steps; 23 final int steps;
24 int maxKey; 24 final int maxKey;
25 String[] values; 25 final String[] values;
26 int seed; 26 final int seed;
27 int commitFrequency; 27 final int commitFrequency;
28 List<Throwable> errors = new LinkedList<>(); 28 final List<Throwable> errors = new LinkedList<>();
29 29
30 public MultiThreadTestRunnable(String scenario, VersionedMapStore<Integer, String> store, int steps, 30 public MultiThreadTestRunnable(String scenario, VersionedMapStore<Integer, String> store, int steps,
31 int maxKey, String[] values, int seed, int commitFrequency) { 31 int maxKey, String[] values, int seed, int commitFrequency) {
32 super(); 32 super();
33 this.scenario = scenario; 33 this.scenario = scenario;
34 this.store = store; 34 this.store = store;
@@ -43,16 +43,24 @@ public class MultiThreadTestRunnable implements Runnable {
43 AssertionError error = new AssertionError(message); 43 AssertionError error = new AssertionError(message);
44 errors.add(error); 44 errors.add(error);
45 } 45 }
46 46
47 public List<Throwable> getErrors() { 47 public List<Throwable> getErrors() {
48 return errors; 48 return errors;
49 } 49 }
50 50
51 @Override 51 @Override
52 public void run() { 52 public void run() {
53 try{
54 task();
55 } catch(Exception e) {
56 e.printStackTrace();
57 }
58 }
59
60 private void task() {
53 // 1. build a map with versions 61 // 1. build a map with versions
54 Random r = new Random(seed); 62 Random r = new Random(seed);
55 VersionedMapImpl<Integer, String> versioned = (VersionedMapImpl<Integer, String>) store.createMap(); 63 VersionedMap<Integer, String> versioned = store.createMap();
56 Map<Integer, Long> index2Version = new HashMap<>(); 64 Map<Integer, Long> index2Version = new HashMap<>();
57 65
58 for (int i = 0; i < steps; i++) { 66 for (int i = 0; i < steps; i++) {
@@ -71,10 +79,10 @@ public class MultiThreadTestRunnable implements Runnable {
71 } 79 }
72 MapTestEnvironment.printStatus(scenario, index, steps, "building"); 80 MapTestEnvironment.printStatus(scenario, index, steps, "building");
73 } 81 }
74 // 2. create a non-versioned 82 // 2. create a non-versioned
75 VersionedMapImpl<Integer, String> reference = (VersionedMapImpl<Integer, String>) store.createMap(); 83 VersionedMap<Integer, String> reference = store.createMap();
76 r = new Random(seed); 84 r = new Random(seed);
77 Random r2 = new Random(seed+1); 85 Random r2 = new Random(seed + 1);
78 86
79 for (int i = 0; i < steps; i++) { 87 for (int i = 0; i < steps; i++) {
80 int index = i + 1; 88 int index = i + 1;
@@ -89,13 +97,17 @@ public class MultiThreadTestRunnable implements Runnable {
89 // go back to an existing state and compare to the reference 97 // go back to an existing state and compare to the reference
90 if (index % (commitFrequency) == 0) { 98 if (index % (commitFrequency) == 0) {
91 versioned.restore(index2Version.get(i)); 99 versioned.restore(index2Version.get(i));
92 MapTestEnvironment.compareTwoMaps(scenario + ":" + index, reference, versioned,errors); 100 MapTestEnvironment.compareTwoMaps(scenario + ":" + index, reference, versioned, null);
93 101
94 // go back to a random state (probably created by another thread) 102 // go back to a random state (probably created by another thread)
95 List<Long> states = new ArrayList<>(store.getStates()); 103 List<Long> states = new ArrayList<>(store.getStates());
104 states.sort(Long::compare);
96 Collections.shuffle(states, r2); 105 Collections.shuffle(states, r2);
97 for(Long state : states.subList(0, Math.min(states.size(), 100))) { 106 for (Long state : states.subList(0, Math.min(states.size(), 100))) {
98 versioned.restore(state); 107 long x = state;
108 versioned.restore(x);
109 var clean = store.createMap(x);
110 MapTestEnvironment.compareTwoMaps(scenario + ":" + index, clean, versioned, null);
99 } 111 }
100 versioned.restore(index2Version.get(i)); 112 versioned.restore(index2Version.get(i));
101 } 113 }
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MutableFuzzTest.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MutableFuzzTest.java
index 32dde0da..fdcd7f9f 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MutableFuzzTest.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MutableFuzzTest.java
@@ -6,6 +6,7 @@
6package tools.refinery.store.map.tests.fuzz; 6package tools.refinery.store.map.tests.fuzz;
7 7
8import static org.junit.jupiter.api.Assertions.fail; 8import static org.junit.jupiter.api.Assertions.fail;
9import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*;
9 10
10import java.util.Random; 11import java.util.Random;
11import java.util.stream.Stream; 12import java.util.stream.Stream;
@@ -16,21 +17,18 @@ import org.junit.jupiter.params.ParameterizedTest;
16import org.junit.jupiter.params.provider.Arguments; 17import org.junit.jupiter.params.provider.Arguments;
17import org.junit.jupiter.params.provider.MethodSource; 18import org.junit.jupiter.params.provider.MethodSource;
18 19
19import tools.refinery.store.map.ContinousHashProvider; 20import tools.refinery.store.map.*;
20import tools.refinery.store.map.VersionedMapStore;
21import tools.refinery.store.map.VersionedMapStoreImpl;
22import tools.refinery.store.map.internal.VersionedMapImpl;
23import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; 21import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils;
24import tools.refinery.store.map.tests.utils.MapTestEnvironment; 22import tools.refinery.store.map.tests.utils.MapTestEnvironment;
25 23
26class MutableFuzzTest { 24class MutableFuzzTest {
27 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue, boolean evilHash) { 25 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue,
28 String[] values = MapTestEnvironment.prepareValues(maxValue); 26 boolean nullDefault, VersionedMapStoreFactoryBuilder<Integer, String> builder) {
29 ContinousHashProvider<Integer> chp = MapTestEnvironment.prepareHashProvider(evilHash); 27 String[] values = MapTestEnvironment.prepareValues(maxValue, nullDefault);
30 28
31 VersionedMapStore<Integer, String> store = new VersionedMapStoreImpl<Integer, String>(chp, values[0]); 29 VersionedMapStore<Integer, String> store = builder.defaultValue(values[0]).build().createOne();
32 VersionedMapImpl<Integer, String> sut = (VersionedMapImpl<Integer, String>) store.createMap(); 30 VersionedMap<Integer, String> sut = store.createMap();
33 MapTestEnvironment<Integer, String> e = new MapTestEnvironment<Integer, String>(sut); 31 MapTestEnvironment<Integer, String> e = new MapTestEnvironment<>(sut);
34 32
35 Random r = new Random(seed); 33 Random r = new Random(seed);
36 34
@@ -38,24 +36,14 @@ class MutableFuzzTest {
38 } 36 }
39 37
40 private void iterativeRandomPuts(String scenario, int steps, int maxKey, String[] values, 38 private void iterativeRandomPuts(String scenario, int steps, int maxKey, String[] values,
41 MapTestEnvironment<Integer, String> e, Random r) { 39 MapTestEnvironment<Integer, String> e, Random r) {
42 int stopAt = -1;
43 for (int i = 0; i < steps; i++) { 40 for (int i = 0; i < steps; i++) {
44 int index = i + 1; 41 int index = i + 1;
45 int nextKey = r.nextInt(maxKey); 42 int nextKey = r.nextInt(maxKey);
46 String nextValue = values[r.nextInt(values.length)]; 43 String nextValue = values[r.nextInt(values.length)];
47 if (index == stopAt) { 44
48 System.out.println("issue!");
49 System.out.println("State before:");
50 e.printComparison();
51 e.sut.prettyPrint();
52 System.out.println("Next: put(" + nextKey + "," + nextValue + ")");
53 }
54 try { 45 try {
55 e.put(nextKey, nextValue); 46 e.put(nextKey, nextValue);
56 if (index == stopAt) {
57 e.sut.prettyPrint();
58 }
59 e.checkEquivalence(scenario + ":" + index); 47 e.checkEquivalence(scenario + ":" + index);
60 } catch (Exception exception) { 48 } catch (Exception exception) {
61 exception.printStackTrace(); 49 exception.printStackTrace();
@@ -65,30 +53,34 @@ class MutableFuzzTest {
65 } 53 }
66 } 54 }
67 55
68 @ParameterizedTest(name = "Mutable {index}/{0} Steps={1} Keys={2} Values={3} seed={4} evil-hash={5}") 56 final String title = "Mutable {index}/{0} Steps={1} Keys={2} Values={3} defaultNull={4} seed={5} " +
57 "config={6}";
58
59 @ParameterizedTest(name = title)
69 @MethodSource 60 @MethodSource
70 @Timeout(value = 10) 61 @Timeout(value = 10)
71 @Tag("fuzz") 62 @Tag("fuzz")
72 void parametrizedFuzz(int test, int steps, int noKeys, int noValues, int seed, boolean evilHash) { 63 void parametrizedFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean defaultNull, int seed,
64 VersionedMapStoreFactoryBuilder<Integer, String> builder) {
73 runFuzzTest( 65 runFuzzTest(
74 "MutableS" + steps + "K" + noKeys + "V" + noValues + "s" + seed + "H" + (evilHash ? "Evil" : "Normal"), 66 "MutableS" + steps + "K" + noKeys + "V" + noValues + "s" + seed,
75 seed, steps, noKeys, noValues, evilHash); 67 seed, steps, noKeys, noValues, defaultNull, builder);
76 } 68 }
77 69
78 static Stream<Arguments> parametrizedFuzz() { 70 static Stream<Arguments> parametrizedFuzz() {
79 return FuzzTestUtils.permutationWithSize(new Object[] { FuzzTestUtils.FAST_STEP_COUNT }, 71 return FuzzTestUtils.permutationWithSize(stepCounts, keyCounts, valueCounts, nullDefaultOptions,
80 new Object[] { 3, 32, 32 * 32, 32 * 32 * 32 * 32 }, new Object[] { 2, 3 }, new Object[] { 1, 2, 3 }, 72 randomSeedOptions, storeConfigs);
81 new Object[] { false, true });
82 } 73 }
83 74
84 @ParameterizedTest(name = "Mutable {index}/{0} Steps={1} Keys={2} Values={3} seed={4} evil-hash={5}") 75 @ParameterizedTest(name = title)
85 @MethodSource 76 @MethodSource
86 @Tag("fuzz") 77 @Tag("fuzz")
87 @Tag("slow") 78 @Tag("slow")
88 void parametrizedSlowFuzz(int test, int steps, int noKeys, int noValues, int seed, boolean evilHash) { 79 void parametrizedSlowFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault, int seed,
80 VersionedMapStoreFactoryBuilder<Integer, String> builder) {
89 runFuzzTest( 81 runFuzzTest(
90 "MutableS" + steps + "K" + noKeys + "V" + noValues + "s" + seed + "H" + (evilHash ? "Evil" : "Normal"), 82 "MutableS" + steps + "K" + noKeys + "V" + noValues + "s" + seed,
91 seed, steps, noKeys, noValues, evilHash); 83 seed, steps, noKeys, noValues, nullDefault, builder);
92 } 84 }
93 85
94 static Stream<Arguments> parametrizedSlowFuzz() { 86 static Stream<Arguments> parametrizedSlowFuzz() {
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MutableImmutableCompareFuzzTest.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MutableImmutableCompareFuzzTest.java
index 347c49be..420dade6 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MutableImmutableCompareFuzzTest.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/MutableImmutableCompareFuzzTest.java
@@ -6,6 +6,7 @@
6package tools.refinery.store.map.tests.fuzz; 6package tools.refinery.store.map.tests.fuzz;
7 7
8import static org.junit.jupiter.api.Assertions.fail; 8import static org.junit.jupiter.api.Assertions.fail;
9import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*;
9 10
10import java.util.Random; 11import java.util.Random;
11import java.util.stream.Stream; 12import java.util.stream.Stream;
@@ -24,12 +25,12 @@ import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils;
24import tools.refinery.store.map.tests.utils.MapTestEnvironment; 25import tools.refinery.store.map.tests.utils.MapTestEnvironment;
25 26
26class MutableImmutableCompareFuzzTest { 27class MutableImmutableCompareFuzzTest {
27 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue, int commitFrequency, 28 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue,
28 boolean evilHash) { 29 boolean nullDefault, int commitFrequency, boolean evilHash) {
29 String[] values = MapTestEnvironment.prepareValues(maxValue); 30 String[] values = MapTestEnvironment.prepareValues(maxValue, nullDefault);
30 ContinousHashProvider<Integer> chp = MapTestEnvironment.prepareHashProvider(evilHash); 31 ContinousHashProvider<Integer> chp = MapTestEnvironment.prepareHashProvider(evilHash);
31 32
32 VersionedMapStore<Integer, String> store = new VersionedMapStoreImpl<Integer, String>(chp, values[0]); 33 VersionedMapStore<Integer, String> store = new VersionedMapStoreImpl<>(chp, values[0]);
33 VersionedMapImpl<Integer, String> immutable = (VersionedMapImpl<Integer, String>) store.createMap(); 34 VersionedMapImpl<Integer, String> immutable = (VersionedMapImpl<Integer, String>) store.createMap();
34 VersionedMapImpl<Integer, String> mutable = (VersionedMapImpl<Integer, String>) store.createMap(); 35 VersionedMapImpl<Integer, String> mutable = (VersionedMapImpl<Integer, String>) store.createMap();
35 36
@@ -40,8 +41,8 @@ class MutableImmutableCompareFuzzTest {
40 } 41 }
41 42
42 private void iterativeRandomPutsAndCommitsAndCompare(String scenario, VersionedMapImpl<Integer, String> immutable, 43 private void iterativeRandomPutsAndCommitsAndCompare(String scenario, VersionedMapImpl<Integer, String> immutable,
43 VersionedMapImpl<Integer, String> mutable, int steps, int maxKey, String[] values, Random r, 44 VersionedMapImpl<Integer, String> mutable, int steps, int maxKey, String[] values, Random r,
44 int commitFrequency) { 45 int commitFrequency) {
45 for (int i = 0; i < steps; i++) { 46 for (int i = 0; i < steps; i++) {
46 int index = i + 1; 47 int index = i + 1;
47 int nextKey = r.nextInt(maxKey); 48 int nextKey = r.nextInt(maxKey);
@@ -62,30 +63,31 @@ class MutableImmutableCompareFuzzTest {
62 } 63 }
63 } 64 }
64 65
65 @ParameterizedTest(name = "Mutable-Immutable Compare {index}/{0} Steps={1} Keys={2} Values={3} commit frequency={4} seed={5} evil-hash={6}") 66 @ParameterizedTest(name = "Mutable-Immutable Compare {index}/{0} Steps={1} Keys={2} Values={3} nullDefault={4} " +
67 "commit frequency={5} seed={6} evil-hash={7}")
66 @MethodSource 68 @MethodSource
67 @Timeout(value = 10) 69 @Timeout(value = 10)
68 @Tag("fuzz") 70 @Tag("fuzz")
69 void parametrizedFastFuzz(int tests, int steps, int noKeys, int noValues, int commitFrequency, int seed, 71 void parametrizedFastFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault, int commitFrequency,
70 boolean evilHash) { 72 int seed, boolean evilHash) {
71 runFuzzTest("MutableImmutableCompareS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, 73 runFuzzTest("MutableImmutableCompareS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps,
72 noKeys, noValues, commitFrequency, evilHash); 74 noKeys, noValues, nullDefault, commitFrequency, evilHash);
73 } 75 }
74 76
75 static Stream<Arguments> parametrizedFastFuzz() { 77 static Stream<Arguments> parametrizedFastFuzz() {
76 return FuzzTestUtils.permutationWithSize(new Object[] { FuzzTestUtils.FAST_STEP_COUNT }, new Object[] { 3, 32, 32 * 32 }, 78 return FuzzTestUtils.permutationWithSize(stepCounts, keyCounts, valueCounts, nullDefaultOptions,
77 new Object[] { 2, 3 }, new Object[] { 1, 10, 100 }, new Object[] { 1, 2, 3 }, 79 commitFrequencyOptions, randomSeedOptions, new Object[]{false, true});
78 new Object[] { false, true });
79 } 80 }
80 81
81 @ParameterizedTest(name = "Mutable-Immutable Compare {index}/{0} Steps={1} Keys={2} Values={3} commit frequency={4} seed={5} evil-hash={6}") 82 @ParameterizedTest(name = "Mutable-Immutable Compare {index}/{0} Steps={1} Keys={2} Values={3} nullDefault={4} " +
83 "commit frequency={5} seed={6} evil-hash={7}")
82 @MethodSource 84 @MethodSource
83 @Tag("fuzz") 85 @Tag("fuzz")
84 @Tag("slow") 86 @Tag("slow")
85 void parametrizedSlowFuzz(int tests, int steps, int noKeys, int noValues, int commitFrequency, int seed, 87 void parametrizedSlowFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault, int commitFrequency,
86 boolean evilHash) { 88 int seed, boolean evilHash) {
87 runFuzzTest("MutableImmutableCompareS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, 89 runFuzzTest("MutableImmutableCompareS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps,
88 noKeys, noValues, commitFrequency, evilHash); 90 noKeys, noValues, nullDefault, commitFrequency, evilHash);
89 } 91 }
90 92
91 static Stream<Arguments> parametrizedSlowFuzz() { 93 static Stream<Arguments> parametrizedSlowFuzz() {
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/RestoreFuzzTest.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/RestoreFuzzTest.java
index f7b9d61e..0b399c3a 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/RestoreFuzzTest.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/RestoreFuzzTest.java
@@ -5,42 +5,41 @@
5 */ 5 */
6package tools.refinery.store.map.tests.fuzz; 6package tools.refinery.store.map.tests.fuzz;
7 7
8import static org.junit.jupiter.api.Assertions.fail;
9
10import java.util.HashMap;
11import java.util.Map;
12import java.util.Random;
13import java.util.stream.Stream;
14
15import org.junit.jupiter.api.Tag; 8import org.junit.jupiter.api.Tag;
16import org.junit.jupiter.api.Timeout; 9import org.junit.jupiter.api.Timeout;
17import org.junit.jupiter.params.ParameterizedTest; 10import org.junit.jupiter.params.ParameterizedTest;
18import org.junit.jupiter.params.provider.Arguments; 11import org.junit.jupiter.params.provider.Arguments;
19import org.junit.jupiter.params.provider.MethodSource; 12import org.junit.jupiter.params.provider.MethodSource;
20 13import tools.refinery.store.map.VersionedMap;
21import tools.refinery.store.map.ContinousHashProvider;
22import tools.refinery.store.map.VersionedMapStore; 14import tools.refinery.store.map.VersionedMapStore;
23import tools.refinery.store.map.VersionedMapStoreImpl; 15import tools.refinery.store.map.VersionedMapStoreFactoryBuilder;
24import tools.refinery.store.map.internal.VersionedMapImpl;
25import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; 16import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils;
26import tools.refinery.store.map.tests.utils.MapTestEnvironment; 17import tools.refinery.store.map.tests.utils.MapTestEnvironment;
27 18
19import java.util.HashMap;
20import java.util.Map;
21import java.util.Random;
22import java.util.stream.Stream;
23
24import static org.junit.jupiter.api.Assertions.fail;
25import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*;
26
28class RestoreFuzzTest { 27class RestoreFuzzTest {
29 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue, int commitFrequency, 28 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue,
30 boolean evilHash) { 29 boolean nullDefault, int commitFrequency,
31 String[] values = MapTestEnvironment.prepareValues(maxValue); 30 VersionedMapStoreFactoryBuilder<Integer, String> builder) {
32 ContinousHashProvider<Integer> chp = MapTestEnvironment.prepareHashProvider(evilHash); 31 String[] values = MapTestEnvironment.prepareValues(maxValue, nullDefault);
33 32
34 VersionedMapStore<Integer, String> store = new VersionedMapStoreImpl<Integer, String>(chp, values[0]); 33 VersionedMapStore<Integer, String> store = builder.defaultValue(values[0]).build().createOne();
35 34
36 iterativeRandomPutsAndCommitsThenRestore(scenario, store, steps, maxKey, values, seed, commitFrequency); 35 iterativeRandomPutsAndCommitsThenRestore(scenario, store, steps, maxKey, values, seed, commitFrequency);
37 } 36 }
38 37
39 private void iterativeRandomPutsAndCommitsThenRestore(String scenario, VersionedMapStore<Integer, String> store, 38 private void iterativeRandomPutsAndCommitsThenRestore(String scenario, VersionedMapStore<Integer, String> store,
40 int steps, int maxKey, String[] values, int seed, int commitFrequency) { 39 int steps, int maxKey, String[] values, int seed, int commitFrequency) {
41 // 1. build a map with versions 40 // 1. build a map with versions
42 Random r = new Random(seed); 41 Random r = new Random(seed);
43 VersionedMapImpl<Integer, String> versioned = (VersionedMapImpl<Integer, String>) store.createMap(); 42 VersionedMap<Integer, String> versioned = store.createMap();
44 Map<Integer, Long> index2Version = new HashMap<>(); 43 Map<Integer, Long> index2Version = new HashMap<>();
45 44
46 for (int i = 0; i < steps; i++) { 45 for (int i = 0; i < steps; i++) {
@@ -60,7 +59,7 @@ class RestoreFuzzTest {
60 MapTestEnvironment.printStatus(scenario, index, steps, "building"); 59 MapTestEnvironment.printStatus(scenario, index, steps, "building");
61 } 60 }
62 // 2. create a non-versioned and 61 // 2. create a non-versioned and
63 VersionedMapImpl<Integer, String> reference = (VersionedMapImpl<Integer, String>) store.createMap(); 62 VersionedMap<Integer, String> reference = store.createMap();
64 r = new Random(seed); 63 r = new Random(seed);
65 64
66 for (int i = 0; i < steps; i++) { 65 for (int i = 0; i < steps; i++) {
@@ -82,30 +81,32 @@ class RestoreFuzzTest {
82 81
83 } 82 }
84 83
85 @ParameterizedTest(name = "Restore {index}/{0} Steps={1} Keys={2} Values={3} commit frequency={4} seed={5} evil-hash={6}") 84 public static final String title = "Commit {index}/{0} Steps={1} Keys={2} Values={3} nullDefault={4} commit frequency={5} " +
85 "seed={6} config={7}";
86
87 @ParameterizedTest(name = title)
86 @MethodSource 88 @MethodSource
87 @Timeout(value = 10) 89 @Timeout(value = 10)
88 @Tag("smoke") 90 @Tag("smoke")
89 void parametrizedFastFuzz(int tests, int steps, int noKeys, int noValues, int commitFrequency, int seed, 91 void parametrizedFastFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault, int commitFrequency,
90 boolean evilHash) { 92 int seed, VersionedMapStoreFactoryBuilder<Integer, String> builder) {
91 runFuzzTest("RestoreS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues, 93 runFuzzTest("RestoreS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues,
92 commitFrequency, evilHash); 94 nullDefault, commitFrequency, builder);
93 } 95 }
94 96
95 static Stream<Arguments> parametrizedFastFuzz() { 97 static Stream<Arguments> parametrizedFastFuzz() {
96 return FuzzTestUtils.permutationWithSize(new Object[] { FuzzTestUtils.FAST_STEP_COUNT }, new Object[] { 3, 32, 32 * 32 }, 98 return FuzzTestUtils.permutationWithSize(stepCounts, keyCounts, valueCounts, nullDefaultOptions,
97 new Object[] { 2, 3 }, new Object[] { 1, 10, 100 }, new Object[] { 1, 2, 3 }, 99 commitFrequencyOptions, randomSeedOptions, storeConfigs);
98 new Object[] { false, true });
99 } 100 }
100 101
101 @ParameterizedTest(name = "Restore {index}/{0} Steps={1} Keys={2} Values={3} commit frequency={4} seed={5} evil-hash={6}") 102 @ParameterizedTest(name = title)
102 @MethodSource 103 @MethodSource
103 @Tag("smoke") 104 @Tag("smoke")
104 @Tag("slow") 105 @Tag("slow")
105 void parametrizedSlowFuzz(int tests, int steps, int noKeys, int noValues, int commitFrequency, int seed, 106 void parametrizedSlowFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault, int commitFrequency,
106 boolean evilHash) { 107 int seed, VersionedMapStoreFactoryBuilder<Integer, String> builder) {
107 runFuzzTest("RestoreS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues, 108 runFuzzTest("RestoreS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues,
108 commitFrequency, evilHash); 109 nullDefault, commitFrequency, builder);
109 } 110 }
110 111
111 static Stream<Arguments> parametrizedSlowFuzz() { 112 static Stream<Arguments> parametrizedSlowFuzz() {
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/SharedStoreFuzzTest.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/SharedStoreFuzzTest.java
index 4b4172d0..680d962d 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/SharedStoreFuzzTest.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/SharedStoreFuzzTest.java
@@ -25,10 +25,12 @@ import tools.refinery.store.map.internal.VersionedMapImpl;
25import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; 25import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils;
26import tools.refinery.store.map.tests.utils.MapTestEnvironment; 26import tools.refinery.store.map.tests.utils.MapTestEnvironment;
27 27
28import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*;
29
28class SharedStoreFuzzTest { 30class SharedStoreFuzzTest {
29 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue, int commitFrequency, 31 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue,
30 boolean evilHash) { 32 boolean nullDefault, int commitFrequency, boolean evilHash) {
31 String[] values = MapTestEnvironment.prepareValues(maxValue); 33 String[] values = MapTestEnvironment.prepareValues(maxValue, nullDefault);
32 ContinousHashProvider<Integer> chp = MapTestEnvironment.prepareHashProvider(evilHash); 34 ContinousHashProvider<Integer> chp = MapTestEnvironment.prepareHashProvider(evilHash);
33 35
34 List<VersionedMapStore<Integer, String>> stores = VersionedMapStoreImpl.createSharedVersionedMapStores(5, chp, values[0]); 36 List<VersionedMapStore<Integer, String>> stores = VersionedMapStoreImpl.createSharedVersionedMapStores(5, chp, values[0]);
@@ -37,22 +39,22 @@ class SharedStoreFuzzTest {
37 } 39 }
38 40
39 private void iterativeRandomPutsAndCommitsThenRestore(String scenario, List<VersionedMapStore<Integer, String>> stores, 41 private void iterativeRandomPutsAndCommitsThenRestore(String scenario, List<VersionedMapStore<Integer, String>> stores,
40 int steps, int maxKey, String[] values, int seed, int commitFrequency) { 42 int steps, int maxKey, String[] values, int seed, int commitFrequency) {
41 // 1. maps with versions 43 // 1. maps with versions
42 Random r = new Random(seed); 44 Random r = new Random(seed);
43 List<VersionedMapImpl<Integer, String>> versioneds = new LinkedList<>(); 45 List<VersionedMapImpl<Integer, String>> versioneds = new LinkedList<>();
44 for(VersionedMapStore<Integer, String> store : stores) { 46 for (VersionedMapStore<Integer, String> store : stores) {
45 versioneds.add((VersionedMapImpl<Integer, String>) store.createMap()); 47 versioneds.add((VersionedMapImpl<Integer, String>) store.createMap());
46 } 48 }
47 49
48 List<Map<Integer, Long>> index2Version = new LinkedList<>(); 50 List<Map<Integer, Long>> index2Version = new LinkedList<>();
49 for(int i = 0; i<stores.size(); i++) { 51 for (int i = 0; i < stores.size(); i++) {
50 index2Version.add(new HashMap<>()); 52 index2Version.add(new HashMap<>());
51 } 53 }
52 54
53 for (int i = 0; i < steps; i++) { 55 for (int i = 0; i < steps; i++) {
54 int stepIndex = i + 1; 56 int stepIndex = i + 1;
55 for (int storeIndex = 0; storeIndex<versioneds.size(); storeIndex++) { 57 for (int storeIndex = 0; storeIndex < versioneds.size(); storeIndex++) {
56 int nextKey = r.nextInt(maxKey); 58 int nextKey = r.nextInt(maxKey);
57 String nextValue = values[r.nextInt(values.length)]; 59 String nextValue = values[r.nextInt(values.length)];
58 versioneds.get(storeIndex).put(nextKey, nextValue); 60 versioneds.get(storeIndex).put(nextKey, nextValue);
@@ -61,18 +63,18 @@ class SharedStoreFuzzTest {
61 index2Version.get(storeIndex).put(i, version); 63 index2Version.get(storeIndex).put(i, version);
62 } 64 }
63 MapTestEnvironment.printStatus(scenario, stepIndex, steps, "building"); 65 MapTestEnvironment.printStatus(scenario, stepIndex, steps, "building");
64 } 66 }
65 } 67 }
66 // 2. create a non-versioned and 68 // 2. create a non-versioned and
67 List<VersionedMapImpl<Integer, String>> reference = new LinkedList<>(); 69 List<VersionedMapImpl<Integer, String>> reference = new LinkedList<>();
68 for(VersionedMapStore<Integer, String> store : stores) { 70 for (VersionedMapStore<Integer, String> store : stores) {
69 reference.add((VersionedMapImpl<Integer, String>) store.createMap()); 71 reference.add((VersionedMapImpl<Integer, String>) store.createMap());
70 } 72 }
71 r = new Random(seed); 73 r = new Random(seed);
72 74
73 for (int i = 0; i < steps; i++) { 75 for (int i = 0; i < steps; i++) {
74 int index = i + 1; 76 int index = i + 1;
75 for (int storeIndex = 0; storeIndex<versioneds.size(); storeIndex++) { 77 for (int storeIndex = 0; storeIndex < versioneds.size(); storeIndex++) {
76 int nextKey = r.nextInt(maxKey); 78 int nextKey = r.nextInt(maxKey);
77 String nextValue = values[r.nextInt(values.length)]; 79 String nextValue = values[r.nextInt(values.length)];
78 reference.get(storeIndex).put(nextKey, nextValue); 80 reference.get(storeIndex).put(nextKey, nextValue);
@@ -81,35 +83,36 @@ class SharedStoreFuzzTest {
81 MapTestEnvironment.compareTwoMaps(scenario + ":" + index, reference.get(storeIndex), versioneds.get(storeIndex)); 83 MapTestEnvironment.compareTwoMaps(scenario + ":" + index, reference.get(storeIndex), versioneds.get(storeIndex));
82 } 84 }
83 } 85 }
84 MapTestEnvironment.printStatus(scenario, index, steps, "comparison"); 86 MapTestEnvironment.printStatus(scenario, index, steps, "comparison");
85 } 87 }
86 88
87 } 89 }
88 90
89 @ParameterizedTest(name = "Shared Store {index}/{0} Steps={1} Keys={2} Values={3} commit frequency={4} seed={5} evil-hash={6}") 91 @ParameterizedTest(name = "Shared Store {index}/{0} Steps={1} Keys={2} Values={3} nullDefault={4} commit " +
92 "frequency={4} seed={5} evil-hash={6}")
90 @MethodSource 93 @MethodSource
91 @Timeout(value = 10) 94 @Timeout(value = 10)
92 @Tag("smoke") 95 @Tag("smoke")
93 void parametrizedFastFuzz(int tests, int steps, int noKeys, int noValues, int commitFrequency, int seed, 96 void parametrizedFastFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault, int commitFrequency,
94 boolean evilHash) { 97 int seed, boolean evilHash) {
95 runFuzzTest("SharedS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues, 98 runFuzzTest("SharedS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues,
96 commitFrequency, evilHash); 99 nullDefault, commitFrequency, evilHash);
97 } 100 }
98 101
99 static Stream<Arguments> parametrizedFastFuzz() { 102 static Stream<Arguments> parametrizedFastFuzz() {
100 return FuzzTestUtils.permutationWithSize(new Object[] { FuzzTestUtils.FAST_STEP_COUNT }, new Object[] { 3, 32, 32 * 32 }, 103 return FuzzTestUtils.permutationWithSize(stepCounts, keyCounts, valueCounts, nullDefaultOptions,
101 new Object[] { 2, 3 }, new Object[] { 1, 10, 100 }, new Object[] { 1, 2, 3 }, 104 commitFrequencyOptions, randomSeedOptions, new Object[]{false, true});
102 new Object[] { false, true });
103 } 105 }
104 106
105 @ParameterizedTest(name = "Shared Store {index}/{0} Steps={1} Keys={2} Values={3} commit frequency={4} seed={5} evil-hash={6}") 107 @ParameterizedTest(name = "Shared Store {index}/{0} Steps={1} Keys={2} Values={3} nullDefault={4} commit " +
108 "frequency={4} seed={5} evil-hash={6}")
106 @MethodSource 109 @MethodSource
107 @Tag("smoke") 110 @Tag("smoke")
108 @Tag("slow") 111 @Tag("slow")
109 void parametrizedSlowFuzz(int tests, int steps, int noKeys, int noValues, int commitFrequency, int seed, 112 void parametrizedSlowFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault, int commitFrequency,
110 boolean evilHash) { 113 int seed, boolean evilHash) {
111 runFuzzTest("SharedS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues, 114 runFuzzTest("SharedS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues,
112 commitFrequency, evilHash); 115 nullDefault, commitFrequency, evilHash);
113 } 116 }
114 117
115 static Stream<Arguments> parametrizedSlowFuzz() { 118 static Stream<Arguments> parametrizedSlowFuzz() {
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/SingleThreadFuzzTest.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/SingleThreadFuzzTest.java
new file mode 100644
index 00000000..0e1f9f9f
--- /dev/null
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/SingleThreadFuzzTest.java
@@ -0,0 +1,61 @@
1package tools.refinery.store.map.tests.fuzz;
2
3import org.junit.jupiter.api.Tag;
4import org.junit.jupiter.api.Timeout;
5import org.junit.jupiter.params.ParameterizedTest;
6import org.junit.jupiter.params.provider.Arguments;
7import org.junit.jupiter.params.provider.MethodSource;
8import tools.refinery.store.map.VersionedMapStore;
9import tools.refinery.store.map.VersionedMapStoreFactoryBuilder;
10import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils;
11import tools.refinery.store.map.tests.utils.MapTestEnvironment;
12
13import java.util.stream.Stream;
14
15import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*;
16
17class SingleThreadFuzzTest {
18 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue, boolean nullDefault, int commitFrequency, VersionedMapStoreFactoryBuilder<Integer, String> builder) {
19 String[] values = MapTestEnvironment.prepareValues(maxValue, nullDefault);
20
21 VersionedMapStore<Integer, String> store = builder.defaultValue(values[0]).build().createOne();
22
23 // initialize runnables
24 MultiThreadTestRunnable runnable = new MultiThreadTestRunnable(scenario, store, steps, maxKey, values, seed, commitFrequency);
25
26 // start threads;
27 runnable.run();
28 }
29
30 static final String title = "SingleThread {index}/{0} Steps={1} Keys={2} Values={3} defaultNull={4} commit " +
31 "frequency={5} seed={6} config={7}";
32
33 @ParameterizedTest(name = title)
34 @MethodSource
35 @Timeout(value = 10)
36 @Tag("fuzz")
37 void parametrizedFastFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean defaultNull,
38 int commitFrequency, int seed, VersionedMapStoreFactoryBuilder<Integer, String> builder) {
39 runFuzzTest("SingleThreadS" + steps + "K" + noKeys + "V" + noValues + defaultNull + "CF" + commitFrequency +
40 "s" + seed, seed, steps, noKeys, noValues, defaultNull, commitFrequency, builder);
41 }
42
43 static Stream<Arguments> parametrizedFastFuzz() {
44 return FuzzTestUtils.permutationWithSize(stepCounts, keyCounts, valueCounts, nullDefaultOptions,
45 new Object[]{10, 100}, randomSeedOptions, storeConfigs);
46 }
47
48 @ParameterizedTest(name = title)
49 @MethodSource
50 @Tag("fuzz")
51 @Tag("slow")
52 void parametrizedSlowFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault,
53 int commitFrequency, int seed, VersionedMapStoreFactoryBuilder<Integer, String> builder) {
54 runFuzzTest("SingleThreadS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues,
55 nullDefault, commitFrequency, builder);
56 }
57
58 static Stream<Arguments> parametrizedSlowFuzz() {
59 return FuzzTestUtils.changeStepCount(RestoreFuzzTest.parametrizedFastFuzz(), 1);
60 }
61}
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/utils/FuzzTestCollections.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/utils/FuzzTestCollections.java
new file mode 100644
index 00000000..94c9cba7
--- /dev/null
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/utils/FuzzTestCollections.java
@@ -0,0 +1,39 @@
1package tools.refinery.store.map.tests.fuzz.utils;
2
3import tools.refinery.store.map.VersionedMapStore;
4import tools.refinery.store.map.VersionedMapStoreFactoryBuilder;
5import tools.refinery.store.map.tests.utils.MapTestEnvironment;
6
7public final class FuzzTestCollections {
8 public static final Object[] stepCounts = {FuzzTestUtils.FAST_STEP_COUNT};
9 public static final Object[] keyCounts = {1 , 32, 32 * 32};
10 public static final Object[] valueCounts = {2, 3};
11 public static final Object[] nullDefaultOptions = {false, true};
12 public static final Object[] commitFrequencyOptions = {1, 10, 100};
13 public static final Object[] randomSeedOptions = {1};
14 public static final Object[] storeConfigs = {
15 // State based
16 VersionedMapStore.<Integer,String>builder()
17 .stateBasedImmutableWhenCommitting(true)
18 .stateBasedHashProvider(MapTestEnvironment.prepareHashProvider(false))
19 .stateBasedSharingStrategy(VersionedMapStoreFactoryBuilder.SharingStrategy.SHARED_NODE_CACHE),
20 VersionedMapStore.<Integer,String>builder()
21 .stateBasedImmutableWhenCommitting(true)
22 .stateBasedHashProvider(MapTestEnvironment.prepareHashProvider(true))
23 .stateBasedSharingStrategy(VersionedMapStoreFactoryBuilder.SharingStrategy.SHARED_NODE_CACHE),
24 VersionedMapStore.<Integer,String>builder()
25 .stateBasedImmutableWhenCommitting(false)
26 .stateBasedHashProvider(MapTestEnvironment.prepareHashProvider(false))
27 .stateBasedSharingStrategy(VersionedMapStoreFactoryBuilder.SharingStrategy.SHARED_NODE_CACHE),
28 VersionedMapStore.<Integer,String>builder()
29 .stateBasedImmutableWhenCommitting(false)
30 .stateBasedHashProvider(MapTestEnvironment.prepareHashProvider(false))
31 .stateBasedSharingStrategy(VersionedMapStoreFactoryBuilder.SharingStrategy.NO_NODE_CACHE),
32
33 // Delta based
34 VersionedMapStore.<Integer,String>builder()
35 .deltaTransactionStrategy(VersionedMapStoreFactoryBuilder.DeltaTransactionStrategy.SET),
36 VersionedMapStore.<Integer,String>builder()
37 .deltaTransactionStrategy(VersionedMapStoreFactoryBuilder.DeltaTransactionStrategy.LIST)
38 };
39}
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/utils/FuzzTestUtils.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/utils/FuzzTestUtils.java
index a819d348..32675635 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/utils/FuzzTestUtils.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/utils/FuzzTestUtils.java
@@ -13,7 +13,7 @@ import java.util.stream.Stream;
13import org.junit.jupiter.params.provider.Arguments; 13import org.junit.jupiter.params.provider.Arguments;
14 14
15public final class FuzzTestUtils { 15public final class FuzzTestUtils {
16 public static final int FAST_STEP_COUNT = 500; 16 public static final int FAST_STEP_COUNT = 250;
17 public static final int SLOW_STEP_COUNT = 32 * 32 * 32 * 32; 17 public static final int SLOW_STEP_COUNT = 32 * 32 * 32 * 32;
18 18
19 private FuzzTestUtils() { 19 private FuzzTestUtils() {
@@ -56,14 +56,12 @@ public final class FuzzTestUtils {
56 56
57 public static Stream<Arguments> permutationWithSize(Object[]... valueOption) { 57 public static Stream<Arguments> permutationWithSize(Object[]... valueOption) {
58 int size = 1; 58 int size = 1;
59 for (int i = 0; i < valueOption.length; i++) { 59 for (Object[] objects : valueOption) {
60 size *= valueOption[i].length; 60 size *= objects.length;
61 } 61 }
62 Object[][] newValueOption = new Object[valueOption.length + 1][]; 62 Object[][] newValueOption = new Object[valueOption.length + 1][];
63 newValueOption[0] = new Object[] { size }; 63 newValueOption[0] = new Object[]{size};
64 for (int i = 1; i < newValueOption.length; i++) { 64 System.arraycopy(valueOption, 0, newValueOption, 1, newValueOption.length - 1);
65 newValueOption[i] = valueOption[i - 1];
66 }
67 return permutation(newValueOption); 65 return permutation(newValueOption);
68 } 66 }
69} 67}
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/utils/FuzzTestUtilsTest.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/utils/FuzzTestUtilsTest.java
index dc621574..951d6336 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/utils/FuzzTestUtilsTest.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/utils/FuzzTestUtilsTest.java
@@ -6,31 +6,36 @@
6package tools.refinery.store.map.tests.fuzz.utils; 6package tools.refinery.store.map.tests.fuzz.utils;
7 7
8import static org.junit.jupiter.api.Assertions.assertEquals; 8import static org.junit.jupiter.api.Assertions.assertEquals;
9import static org.junit.jupiter.api.Assertions.assertTrue;
9 10
10import java.util.List; 11import java.util.List;
12import java.util.Optional;
11 13
12import org.junit.jupiter.api.Test; 14import org.junit.jupiter.api.Test;
15import org.junit.jupiter.params.provider.Arguments;
13 16
14class FuzzTestUtilsTest { 17class FuzzTestUtilsTest {
15 @Test 18 @Test
16 void permutationInternalTest() { 19 void permutationInternalTest() {
17 List<List<Object>> res = FuzzTestUtils.permutationInternal(0, new Object[] { 1, 2, 3 }, 20 List<List<Object>> res = FuzzTestUtils.permutationInternal(0, new Object[]{1, 2, 3},
18 new Object[] { 'a', 'b', 'c' }, new Object[] { "alpha", "beta", "gamma", "delta" }); 21 new Object[]{'a', 'b', 'c'}, new Object[]{"alpha", "beta", "gamma", "delta"});
19 assertEquals(3 * 3 * 4, res.size()); 22 assertEquals(3 * 3 * 4, res.size());
20 } 23 }
21 24
22 @Test 25 @Test
23 void permutationTest1() { 26 void permutationTest1() {
24 var res = FuzzTestUtils.permutation(new Object[] { 1, 2, 3 }, new Object[] { 'a', 'b', 'c' }, 27 var res = FuzzTestUtils.permutation(new Object[]{1, 2, 3}, new Object[]{'a', 'b', 'c'},
25 new Object[] { "alpha", "beta", "gamma", "delta" }); 28 new Object[]{"alpha", "beta", "gamma", "delta"});
26 assertEquals(3 * 3 * 4, res.count()); 29 assertEquals(3 * 3 * 4, res.count());
27 } 30 }
28 31
29 @Test 32 @Test
30 void permutationTest2() { 33 void permutationTest2() {
31 var res = FuzzTestUtils.permutation(new Object[] { 1, 2, 3 }, new Object[] { 'a', 'b', 'c' }, 34 var res = FuzzTestUtils.permutation(new Object[]{1, 2, 3}, new Object[]{'a', 'b', 'c'},
32 new Object[] { "alpha", "beta", "gamma", "delta" }); 35 new Object[]{"alpha", "beta", "gamma", "delta"});
33 var arguments = res.findFirst().get().get(); 36 Optional<Arguments> first = res.findFirst();
37 assertTrue(first.isPresent());
38 var arguments = first.get().get();
34 assertEquals(1, arguments[0]); 39 assertEquals(1, arguments[0]);
35 assertEquals('a', arguments[1]); 40 assertEquals('a', arguments[1]);
36 assertEquals("alpha", arguments[2]); 41 assertEquals("alpha", arguments[2]);
diff --git a/subprojects/store/src/test/java/tools/refinery/store/map/tests/utils/MapTestEnvironment.java b/subprojects/store/src/test/java/tools/refinery/store/map/tests/utils/MapTestEnvironment.java
index f861f496..e7348370 100644
--- a/subprojects/store/src/test/java/tools/refinery/store/map/tests/utils/MapTestEnvironment.java
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/utils/MapTestEnvironment.java
@@ -14,9 +14,14 @@ import java.util.Map.Entry;
14import static org.junit.jupiter.api.Assertions.*; 14import static org.junit.jupiter.api.Assertions.*;
15 15
16public class MapTestEnvironment<K, V> { 16public class MapTestEnvironment<K, V> {
17 public static String[] prepareValues(int maxValue) { 17 public static String[] prepareValues(int maxValue, boolean nullDefault) {
18 String[] values = new String[maxValue]; 18 String[] values = new String[maxValue];
19 values[0] = "DEFAULT"; 19 if (nullDefault) {
20 values[0] = null;
21 } else {
22 values[0] = "DEFAULT";
23 }
24
20 for (int i = 1; i < values.length; i++) { 25 for (int i = 1; i < values.length; i++) {
21 values[i] = "VAL" + i; 26 values[i] = "VAL" + i;
22 } 27 }
@@ -26,23 +31,18 @@ public class MapTestEnvironment<K, V> {
26 public static ContinousHashProvider<Integer> prepareHashProvider(final boolean evil) { 31 public static ContinousHashProvider<Integer> prepareHashProvider(final boolean evil) {
27 // Use maxPrime = 2147483629 32 // Use maxPrime = 2147483629
28 33
29 ContinousHashProvider<Integer> chp = new ContinousHashProvider<Integer>() { 34 return (key, index) -> {
30 35 if (evil && index < 15 && index < key / 3) {
31 @Override 36 return 7;
32 public int getHash(Integer key, int index) { 37 }
33 if (evil && index < 15 && index < key / 3) { 38 int result = 1;
34 return 7; 39 final int prime = 31;
35 }
36 int result = 1;
37 final int prime = 31;
38 40
39 result = prime * result + key; 41 result = prime * result + key;
40 result = prime * result + index; 42 result = prime * result + index;
41 43
42 return result; 44 return result;
43 }
44 }; 45 };
45 return chp;
46 } 46 }
47 47
48 public static void printStatus(String scenario, int actual, int max, String stepName) { 48 public static void printStatus(String scenario, int actual, int max, String stepName) {
@@ -60,29 +60,17 @@ public class MapTestEnvironment<K, V> {
60 60
61 public static <K, V> void compareTwoMaps(String title, VersionedMap<K, V> map1, 61 public static <K, V> void compareTwoMaps(String title, VersionedMap<K, V> map1,
62 VersionedMap<K, V> map2, List<Throwable> errors) { 62 VersionedMap<K, V> map2, List<Throwable> errors) {
63 assertEqualsList(map1.getSize(), map2.getSize(), title + ": Sizes not equal", errors); 63 map1.checkIntegrity();
64 map2.checkIntegrity();
64 65
65 Cursor<K, V> cursor1 = map1.getAll(); 66 assertContentEqualsList(map1, map2, title + ": map1.contentEquals(map2)", errors);
66 Cursor<K, V> cursor2 = map2.getAll(); 67 assertContentEqualsList(map2, map1, title + ": map2.contentEquals(map1)", errors);
67 while (!cursor1.isTerminated()) { 68 assertEqualsList(map1.getSize(), map2.getSize(), title + ": Sizes not equal", errors);
68 if (cursor2.isTerminated()) {
69 fail("cursor 2 terminated before cursor1");
70 }
71 assertEqualsList(cursor1.getKey(), cursor2.getKey(), title + ": Keys not equal", errors);
72 assertEqualsList(cursor2.getValue(), cursor2.getValue(), title + ": Values not equal", errors);
73 cursor1.move();
74 cursor2.move();
75 }
76 if (!cursor2.isTerminated()) {
77 fail("cursor 1 terminated before cursor 2");
78 }
79 69
80 for (var mode : ContentHashCode.values()) { 70 for (var mode : ContentHashCode.values()) {
81 assertEqualsList(map1.contentHashCode(mode), map2.contentHashCode(mode), 71 assertEqualsList(map1.contentHashCode(mode), map2.contentHashCode(mode),
82 title + ": " + mode + " hashCode check", errors); 72 title + ": " + mode + " hashCode check", errors);
83 } 73 }
84 assertContentEqualsList(map1, map2, title + ": map1.contentEquals(map2)", errors);
85 assertContentEqualsList(map2, map1, title + ": map2.contentEquals(map1)", errors);
86 } 74 }
87 75
88 private static void assertEqualsList(Object o1, Object o2, String message, List<Throwable> errors) { 76 private static void assertEqualsList(Object o1, Object o2, String message, List<Throwable> errors) {
@@ -112,29 +100,35 @@ public class MapTestEnvironment<K, V> {
112 } 100 }
113 } 101 }
114 102
115 public VersionedMapImpl<K, V> sut; 103 final private VersionedMap<K, V> sut;
116 Map<K, V> oracle = new HashMap<K, V>(); 104 final private V defaultValue;
105 Map<K, V> oracle = new HashMap<>();
117 106
118 public MapTestEnvironment(VersionedMapImpl<K, V> sut) { 107 public MapTestEnvironment(VersionedMap<K, V> sut) {
119 this.sut = sut; 108 this.sut = sut;
109 this.defaultValue = sut.getDefaultValue();
120 } 110 }
121 111
122 public void put(K key, V value) { 112 public void put(K key, V value) {
123 V oldSutValue = sut.put(key, value); 113 V oldSutValue = sut.put(key, value);
124 V oldOracleValue; 114 V oldOracleValue;
125 if (value != sut.getDefaultValue()) { 115 if (value != defaultValue) {
126 oldOracleValue = oracle.put(key, value); 116 oldOracleValue = oracle.put(key, value);
127 } else { 117 } else {
128 oldOracleValue = oracle.remove(key); 118 oldOracleValue = oracle.remove(key);
129 } 119 }
130 if (oldSutValue == sut.getDefaultValue() && oldOracleValue != null) { 120 if (oldSutValue == defaultValue && oldOracleValue != null) {
131 fail("After put, SUT old nodeId was default, but oracle old value was " + oldOracleValue); 121 fail("After put, SUT old nodeId was default, but oracle old value was " + oldOracleValue);
132 } 122 }
133 if (oldSutValue != sut.getDefaultValue()) { 123 if (oldSutValue != defaultValue) {
134 assertEquals(oldOracleValue, oldSutValue); 124 assertEquals(oldOracleValue, oldSutValue);
135 } 125 }
136 } 126 }
137 127
128 public long commit(){
129 return sut.commit();
130 }
131
138 public void checkEquivalence(String title) { 132 public void checkEquivalence(String title) {
139 // 0. Checking integrity 133 // 0. Checking integrity
140 try { 134 try {
@@ -181,7 +175,7 @@ public class MapTestEnvironment<K, V> {
181 long sutSize = sut.getSize(); 175 long sutSize = sut.getSize();
182 if (oracleSize != sutSize || oracleSize != elementsInSutEntrySet) { 176 if (oracleSize != sutSize || oracleSize != elementsInSutEntrySet) {
183 printComparison(); 177 printComparison();
184 fail(title + ": Non-equivalent size() result: SUT.getSize()=" + sutSize + ", SUT.entryset.size=" 178 fail(title + ": Non-equivalent size() result: SUT.getSize()=" + sutSize + ", SUT.entrySet.size="
185 + elementsInSutEntrySet + ", Oracle=" + oracleSize + "!"); 179 + elementsInSutEntrySet + ", Oracle=" + oracleSize + "!");
186 } 180 }
187 } 181 }
@@ -190,7 +184,8 @@ public class MapTestEnvironment<K, V> {
190 K previous = null; 184 K previous = null;
191 Cursor<K, V> cursor = versionedMap.getAll(); 185 Cursor<K, V> cursor = versionedMap.getAll();
192 while (cursor.move()) { 186 while (cursor.move()) {
193 System.out.println(cursor.getKey() + " " + ((VersionedMapImpl<K, V>) versionedMap).getHashProvider().getHash(cursor.getKey(), 0)); 187 //System.out.println(cursor.getKey() + " " + ((VersionedMapImpl<K, V>) versionedMap).getHashProvider()
188 // .getHash(cursor.getKey(), 0));
194 if (previous != null) { 189 if (previous != null) {
195 int comparisonResult = ((VersionedMapImpl<K, V>) versionedMap).getHashProvider().compare(previous, 190 int comparisonResult = ((VersionedMapImpl<K, V>) versionedMap).getHashProvider().compare(previous,
196 cursor.getKey()); 191 cursor.getKey());
@@ -198,7 +193,6 @@ public class MapTestEnvironment<K, V> {
198 } 193 }
199 previous = cursor.getKey(); 194 previous = cursor.getKey();
200 } 195 }
201 System.out.println();
202 } 196 }
203 197
204 public void printComparison() { 198 public void printComparison() {