diff options
Diffstat (limited to 'subprojects/store/src/test')
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 @@ | |||
1 | package tools.refinery.store.map.tests; | ||
2 | |||
3 | import org.junit.jupiter.api.Test; | ||
4 | import tools.refinery.store.map.VersionedMapStore; | ||
5 | import tools.refinery.store.map.VersionedMapStoreFactoryBuilder; | ||
6 | import tools.refinery.store.map.internal.InOrderMapCursor; | ||
7 | import tools.refinery.store.map.internal.VersionedMapImpl; | ||
8 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; | ||
9 | |||
10 | import static org.junit.jupiter.api.Assertions.*; | ||
11 | |||
12 | class 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 | */ |
6 | package tools.refinery.store.map.tests.fuzz; | 6 | package tools.refinery.store.map.tests.fuzz; |
7 | 7 | ||
8 | import static org.junit.jupiter.api.Assertions.fail; | ||
9 | |||
10 | import java.util.Random; | ||
11 | import java.util.stream.Stream; | ||
12 | |||
13 | import org.junit.jupiter.api.Tag; | 8 | import org.junit.jupiter.api.Tag; |
14 | import org.junit.jupiter.api.Timeout; | 9 | import org.junit.jupiter.api.Timeout; |
15 | import org.junit.jupiter.params.ParameterizedTest; | 10 | import org.junit.jupiter.params.ParameterizedTest; |
16 | import org.junit.jupiter.params.provider.Arguments; | 11 | import org.junit.jupiter.params.provider.Arguments; |
17 | import org.junit.jupiter.params.provider.MethodSource; | 12 | import org.junit.jupiter.params.provider.MethodSource; |
18 | |||
19 | import tools.refinery.store.map.ContinousHashProvider; | ||
20 | import tools.refinery.store.map.VersionedMapStore; | 13 | import tools.refinery.store.map.VersionedMapStore; |
21 | import tools.refinery.store.map.VersionedMapStoreImpl; | 14 | import tools.refinery.store.map.VersionedMapStoreFactoryBuilder; |
22 | import tools.refinery.store.map.internal.VersionedMapImpl; | ||
23 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; | 15 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; |
24 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; | 16 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; |
25 | 17 | ||
18 | import java.util.Random; | ||
19 | import java.util.stream.Stream; | ||
20 | |||
21 | import static org.junit.jupiter.api.Assertions.fail; | ||
22 | import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*; | ||
23 | |||
26 | class CommitFuzzTest { | 24 | class 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; | |||
10 | import org.junit.jupiter.params.ParameterizedTest; | 10 | import org.junit.jupiter.params.ParameterizedTest; |
11 | import org.junit.jupiter.params.provider.Arguments; | 11 | import org.junit.jupiter.params.provider.Arguments; |
12 | import org.junit.jupiter.params.provider.MethodSource; | 12 | import org.junit.jupiter.params.provider.MethodSource; |
13 | import tools.refinery.store.map.*; | 13 | import tools.refinery.store.map.Cursor; |
14 | import tools.refinery.store.map.internal.VersionedMapImpl; | 14 | import tools.refinery.store.map.VersionedMap; |
15 | import tools.refinery.store.map.VersionedMapStore; | ||
16 | import tools.refinery.store.map.VersionedMapStoreFactoryBuilder; | ||
15 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; | 17 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; |
16 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; | 18 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; |
17 | 19 | ||
@@ -22,23 +24,25 @@ import java.util.List; | |||
22 | import java.util.Random; | 24 | import java.util.Random; |
23 | import java.util.stream.Stream; | 25 | import java.util.stream.Stream; |
24 | 26 | ||
25 | import static org.junit.jupiter.api.Assertions.*; | 27 | import static org.junit.jupiter.api.Assertions.fail; |
28 | import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*; | ||
26 | 29 | ||
27 | class ContentEqualsFuzzTest { | 30 | class 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 | */ |
6 | package tools.refinery.store.map.tests.fuzz; | 6 | package tools.refinery.store.map.tests.fuzz; |
7 | 7 | ||
8 | import static org.junit.jupiter.api.Assertions.fail; | ||
9 | |||
10 | import java.util.Random; | ||
11 | import java.util.stream.Stream; | ||
12 | |||
13 | import org.junit.jupiter.api.Tag; | 8 | import org.junit.jupiter.api.Tag; |
14 | import org.junit.jupiter.api.Timeout; | 9 | import org.junit.jupiter.api.Timeout; |
15 | import org.junit.jupiter.params.ParameterizedTest; | 10 | import org.junit.jupiter.params.ParameterizedTest; |
16 | import org.junit.jupiter.params.provider.Arguments; | 11 | import org.junit.jupiter.params.provider.Arguments; |
17 | import org.junit.jupiter.params.provider.MethodSource; | 12 | import org.junit.jupiter.params.provider.MethodSource; |
18 | |||
19 | import tools.refinery.store.map.ContinousHashProvider; | ||
20 | import tools.refinery.store.map.DiffCursor; | 13 | import tools.refinery.store.map.DiffCursor; |
14 | import tools.refinery.store.map.VersionedMap; | ||
21 | import tools.refinery.store.map.VersionedMapStore; | 15 | import tools.refinery.store.map.VersionedMapStore; |
22 | import tools.refinery.store.map.VersionedMapStoreImpl; | 16 | import tools.refinery.store.map.VersionedMapStoreFactoryBuilder; |
23 | import tools.refinery.store.map.internal.VersionedMapImpl; | ||
24 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; | 17 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; |
25 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; | 18 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; |
26 | 19 | ||
20 | import java.util.Random; | ||
21 | import java.util.stream.Stream; | ||
22 | |||
23 | import static org.junit.jupiter.api.Assertions.fail; | ||
24 | import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*; | ||
25 | |||
27 | class DiffCursorFuzzTest { | 26 | class 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 | */ |
6 | package tools.refinery.store.map.tests.fuzz; | 6 | package tools.refinery.store.map.tests.fuzz; |
7 | 7 | ||
8 | import static org.junit.jupiter.api.Assertions.assertEquals; | ||
9 | import static org.junit.jupiter.api.Assertions.fail; | ||
10 | |||
11 | import java.util.Collections; | ||
12 | import java.util.LinkedList; | ||
13 | import java.util.List; | ||
14 | import java.util.stream.Stream; | ||
15 | |||
16 | import org.junit.jupiter.api.Tag; | 8 | import org.junit.jupiter.api.Tag; |
17 | import org.junit.jupiter.api.Timeout; | 9 | import org.junit.jupiter.api.Timeout; |
18 | import org.junit.jupiter.params.ParameterizedTest; | 10 | import org.junit.jupiter.params.ParameterizedTest; |
19 | import org.junit.jupiter.params.provider.Arguments; | 11 | import org.junit.jupiter.params.provider.Arguments; |
20 | import org.junit.jupiter.params.provider.MethodSource; | 12 | import org.junit.jupiter.params.provider.MethodSource; |
21 | |||
22 | import tools.refinery.store.map.ContinousHashProvider; | ||
23 | import tools.refinery.store.map.VersionedMapStore; | 13 | import tools.refinery.store.map.VersionedMapStore; |
24 | import tools.refinery.store.map.VersionedMapStoreImpl; | 14 | import tools.refinery.store.map.VersionedMapStoreFactoryBuilder; |
25 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; | 15 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; |
26 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; | 16 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; |
27 | 17 | ||
18 | import java.util.Collections; | ||
19 | import java.util.LinkedList; | ||
20 | import java.util.List; | ||
21 | import java.util.stream.Stream; | ||
22 | |||
23 | import static org.junit.jupiter.api.Assertions.assertEquals; | ||
24 | import static org.junit.jupiter.api.Assertions.fail; | ||
25 | import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*; | ||
26 | |||
28 | class MultiThreadFuzzTest { | 27 | class 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; | |||
13 | import java.util.Map; | 13 | import java.util.Map; |
14 | import java.util.Random; | 14 | import java.util.Random; |
15 | 15 | ||
16 | import tools.refinery.store.map.VersionedMap; | ||
16 | import tools.refinery.store.map.VersionedMapStore; | 17 | import tools.refinery.store.map.VersionedMapStore; |
17 | import tools.refinery.store.map.internal.VersionedMapImpl; | ||
18 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; | 18 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; |
19 | 19 | ||
20 | public class MultiThreadTestRunnable implements Runnable { | 20 | public 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 @@ | |||
6 | package tools.refinery.store.map.tests.fuzz; | 6 | package tools.refinery.store.map.tests.fuzz; |
7 | 7 | ||
8 | import static org.junit.jupiter.api.Assertions.fail; | 8 | import static org.junit.jupiter.api.Assertions.fail; |
9 | import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*; | ||
9 | 10 | ||
10 | import java.util.Random; | 11 | import java.util.Random; |
11 | import java.util.stream.Stream; | 12 | import java.util.stream.Stream; |
@@ -16,21 +17,18 @@ import org.junit.jupiter.params.ParameterizedTest; | |||
16 | import org.junit.jupiter.params.provider.Arguments; | 17 | import org.junit.jupiter.params.provider.Arguments; |
17 | import org.junit.jupiter.params.provider.MethodSource; | 18 | import org.junit.jupiter.params.provider.MethodSource; |
18 | 19 | ||
19 | import tools.refinery.store.map.ContinousHashProvider; | 20 | import tools.refinery.store.map.*; |
20 | import tools.refinery.store.map.VersionedMapStore; | ||
21 | import tools.refinery.store.map.VersionedMapStoreImpl; | ||
22 | import tools.refinery.store.map.internal.VersionedMapImpl; | ||
23 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; | 21 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; |
24 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; | 22 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; |
25 | 23 | ||
26 | class MutableFuzzTest { | 24 | class 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 @@ | |||
6 | package tools.refinery.store.map.tests.fuzz; | 6 | package tools.refinery.store.map.tests.fuzz; |
7 | 7 | ||
8 | import static org.junit.jupiter.api.Assertions.fail; | 8 | import static org.junit.jupiter.api.Assertions.fail; |
9 | import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*; | ||
9 | 10 | ||
10 | import java.util.Random; | 11 | import java.util.Random; |
11 | import java.util.stream.Stream; | 12 | import java.util.stream.Stream; |
@@ -24,12 +25,12 @@ import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; | |||
24 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; | 25 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; |
25 | 26 | ||
26 | class MutableImmutableCompareFuzzTest { | 27 | class 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 | */ |
6 | package tools.refinery.store.map.tests.fuzz; | 6 | package tools.refinery.store.map.tests.fuzz; |
7 | 7 | ||
8 | import static org.junit.jupiter.api.Assertions.fail; | ||
9 | |||
10 | import java.util.HashMap; | ||
11 | import java.util.Map; | ||
12 | import java.util.Random; | ||
13 | import java.util.stream.Stream; | ||
14 | |||
15 | import org.junit.jupiter.api.Tag; | 8 | import org.junit.jupiter.api.Tag; |
16 | import org.junit.jupiter.api.Timeout; | 9 | import org.junit.jupiter.api.Timeout; |
17 | import org.junit.jupiter.params.ParameterizedTest; | 10 | import org.junit.jupiter.params.ParameterizedTest; |
18 | import org.junit.jupiter.params.provider.Arguments; | 11 | import org.junit.jupiter.params.provider.Arguments; |
19 | import org.junit.jupiter.params.provider.MethodSource; | 12 | import org.junit.jupiter.params.provider.MethodSource; |
20 | 13 | import tools.refinery.store.map.VersionedMap; | |
21 | import tools.refinery.store.map.ContinousHashProvider; | ||
22 | import tools.refinery.store.map.VersionedMapStore; | 14 | import tools.refinery.store.map.VersionedMapStore; |
23 | import tools.refinery.store.map.VersionedMapStoreImpl; | 15 | import tools.refinery.store.map.VersionedMapStoreFactoryBuilder; |
24 | import tools.refinery.store.map.internal.VersionedMapImpl; | ||
25 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; | 16 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; |
26 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; | 17 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; |
27 | 18 | ||
19 | import java.util.HashMap; | ||
20 | import java.util.Map; | ||
21 | import java.util.Random; | ||
22 | import java.util.stream.Stream; | ||
23 | |||
24 | import static org.junit.jupiter.api.Assertions.fail; | ||
25 | import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*; | ||
26 | |||
28 | class RestoreFuzzTest { | 27 | class 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; | |||
25 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; | 25 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; |
26 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; | 26 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; |
27 | 27 | ||
28 | import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*; | ||
29 | |||
28 | class SharedStoreFuzzTest { | 30 | class 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 @@ | |||
1 | package tools.refinery.store.map.tests.fuzz; | ||
2 | |||
3 | import org.junit.jupiter.api.Tag; | ||
4 | import org.junit.jupiter.api.Timeout; | ||
5 | import org.junit.jupiter.params.ParameterizedTest; | ||
6 | import org.junit.jupiter.params.provider.Arguments; | ||
7 | import org.junit.jupiter.params.provider.MethodSource; | ||
8 | import tools.refinery.store.map.VersionedMapStore; | ||
9 | import tools.refinery.store.map.VersionedMapStoreFactoryBuilder; | ||
10 | import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; | ||
11 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; | ||
12 | |||
13 | import java.util.stream.Stream; | ||
14 | |||
15 | import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*; | ||
16 | |||
17 | class 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 @@ | |||
1 | package tools.refinery.store.map.tests.fuzz.utils; | ||
2 | |||
3 | import tools.refinery.store.map.VersionedMapStore; | ||
4 | import tools.refinery.store.map.VersionedMapStoreFactoryBuilder; | ||
5 | import tools.refinery.store.map.tests.utils.MapTestEnvironment; | ||
6 | |||
7 | public 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; | |||
13 | import org.junit.jupiter.params.provider.Arguments; | 13 | import org.junit.jupiter.params.provider.Arguments; |
14 | 14 | ||
15 | public final class FuzzTestUtils { | 15 | public 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 @@ | |||
6 | package tools.refinery.store.map.tests.fuzz.utils; | 6 | package tools.refinery.store.map.tests.fuzz.utils; |
7 | 7 | ||
8 | import static org.junit.jupiter.api.Assertions.assertEquals; | 8 | import static org.junit.jupiter.api.Assertions.assertEquals; |
9 | import static org.junit.jupiter.api.Assertions.assertTrue; | ||
9 | 10 | ||
10 | import java.util.List; | 11 | import java.util.List; |
12 | import java.util.Optional; | ||
11 | 13 | ||
12 | import org.junit.jupiter.api.Test; | 14 | import org.junit.jupiter.api.Test; |
15 | import org.junit.jupiter.params.provider.Arguments; | ||
13 | 16 | ||
14 | class FuzzTestUtilsTest { | 17 | class 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; | |||
14 | import static org.junit.jupiter.api.Assertions.*; | 14 | import static org.junit.jupiter.api.Assertions.*; |
15 | 15 | ||
16 | public class MapTestEnvironment<K, V> { | 16 | public 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() { |