aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store/src/test
diff options
context:
space:
mode:
authorLibravatar OszkarSemerath <semerath@mit.bme.hu>2023-07-18 15:38:59 +0200
committerLibravatar OszkarSemerath <semerath@mit.bme.hu>2023-07-18 15:38:59 +0200
commit89e142514ae45d793c7dbe38f728b33451261338 (patch)
tree17cebb157c5b3e65871384a0d71eb7f2dd54625b /subprojects/store/src/test
parentInitialization bugs with empty DeltaDiffCursor fixed (diff)
downloadrefinery-89e142514ae45d793c7dbe38f728b33451261338.tar.gz
refinery-89e142514ae45d793c7dbe38f728b33451261338.tar.zst
refinery-89e142514ae45d793c7dbe38f728b33451261338.zip
Fixing long-standing bug with state based diff cursor.
By implementing an InOrderMapCursor cursor, and a MapDiffCursor that synchronize two cursors.
Diffstat (limited to 'subprojects/store/src/test')
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/InOrderCursorTest.java49
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/DiffCursorFuzzTest.java128
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/utils/FuzzTestCollections.java12
-rw-r--r--subprojects/store/src/test/java/tools/refinery/store/map/tests/utils/MapTestEnvironment.java10
4 files changed, 136 insertions, 63 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..05cf5a74
--- /dev/null
+++ b/subprojects/store/src/test/java/tools/refinery/store/map/tests/InOrderCursorTest.java
@@ -0,0 +1,49 @@
1package tools.refinery.store.map.tests;
2
3import org.junit.jupiter.api.Test;
4import tools.refinery.store.map.VersionedMapStoreBuilder;
5import tools.refinery.store.map.internal.InOrderMapCursor;
6import tools.refinery.store.map.internal.VersionedMapImpl;
7import tools.refinery.store.map.tests.utils.MapTestEnvironment;
8
9import static org.junit.jupiter.api.Assertions.*;
10
11class InOrderCursorTest {
12 @Test
13 void testCursor() {
14 var store = VersionedMapStoreBuilder.<Integer,String>builder()
15 .setStrategy(VersionedMapStoreBuilder.StoreStrategy.STATE)
16 .setStateBasedImmutableWhenCommitting(true)
17 .setHashProvider(MapTestEnvironment.prepareHashProvider(false))
18 .setStateBasedNodeSharingStrategy(VersionedMapStoreBuilder.StateStorageStrategy.SHARED_NODE_CACHE)
19 .setDefaultValue("x")
20 .buildOne();
21
22 VersionedMapImpl<Integer,String> map = (VersionedMapImpl<Integer,String>) store.createMap();
23 checkMove(map,0);
24
25 map.put(1,"A");
26 map.commit();
27 checkMove(map,1);
28
29
30 map.put(2,"B");
31 map.commit();
32 checkMove(map,2);
33
34 map.put(3,"C");
35 map.commit();
36 checkMove(map,3);
37
38 }
39
40 private void checkMove(VersionedMapImpl<Integer,String> map, int num) {
41 InOrderMapCursor<Integer,String> cursor = new InOrderMapCursor<>(map);
42 for(int i=0; i<num; i++) {
43 assertTrue(cursor.move());
44 assertFalse(cursor.isTerminated());
45 }
46 assertFalse(cursor.move());
47 assertTrue(cursor.isTerminated());
48 }
49}
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 bf409a74..b087906d 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,7 +5,10 @@ import org.junit.jupiter.api.Timeout;
5import org.junit.jupiter.params.ParameterizedTest; 5import org.junit.jupiter.params.ParameterizedTest;
6import org.junit.jupiter.params.provider.Arguments; 6import org.junit.jupiter.params.provider.Arguments;
7import org.junit.jupiter.params.provider.MethodSource; 7import org.junit.jupiter.params.provider.MethodSource;
8import tools.refinery.store.map.*; 8import tools.refinery.store.map.DiffCursor;
9import tools.refinery.store.map.VersionedMap;
10import tools.refinery.store.map.VersionedMapStore;
11import tools.refinery.store.map.VersionedMapStoreBuilder;
9import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils; 12import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils;
10import tools.refinery.store.map.tests.utils.MapTestEnvironment; 13import tools.refinery.store.map.tests.utils.MapTestEnvironment;
11 14
@@ -16,87 +19,104 @@ import static org.junit.jupiter.api.Assertions.fail;
16import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*; 19import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*;
17 20
18class DiffCursorFuzzTest { 21class DiffCursorFuzzTest {
19 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue, 22 private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue, boolean nullDefault,
20 boolean nullDefault, int commitFrequency, VersionedMapStoreBuilder<Integer, String> builder) { 23 int commitFrequency, boolean commitBeforeDiffCursor,
24 VersionedMapStoreBuilder<Integer, String> builder) {
21 String[] values = MapTestEnvironment.prepareValues(maxValue, nullDefault); 25 String[] values = MapTestEnvironment.prepareValues(maxValue, nullDefault);
22 26
23 VersionedMapStore<Integer, String> store = builder.setDefaultValue(values[0]).buildOne(); 27 VersionedMapStore<Integer, String> store = builder.setDefaultValue(values[0]).buildOne();
24 iterativeRandomPutsAndCommitsThenDiffCursor(scenario, store, steps, maxKey, values, seed, commitFrequency); 28 iterativeRandomPutsAndCommitsThenDiffCursor(scenario, store, steps, maxKey, values, seed, commitFrequency,
29 commitBeforeDiffCursor);
25 } 30 }
26 31
27 private void iterativeRandomPutsAndCommitsThenDiffCursor(String scenario, VersionedMapStore<Integer, String> store, 32 private void iterativeRandomPutsAndCommitsThenDiffCursor(String scenario, VersionedMapStore<Integer, String> store,
28 int steps, int maxKey, String[] values, int seed, int commitFrequency) { 33 int steps, int maxKey, String[] values, int seed,
29 // 1. build a map with versions 34 int commitFrequency, boolean commitBeforeDiffCursor) {
30 Random r = new Random(seed); 35
31 VersionedMap<Integer, String> versioned = store.createMap();
32 int largestCommit = -1; 36 int largestCommit = -1;
33 37
34 for (int i = 0; i < steps; i++) { 38 {
35 int index = i + 1; 39 // 1. build a map with versions
36 int nextKey = r.nextInt(maxKey); 40 Random r = new Random(seed);
37 String nextValue = values[r.nextInt(values.length)]; 41 VersionedMap<Integer, String> versioned = store.createMap();
38 try { 42 for (int i = 0; i < steps; i++) {
39 versioned.put(nextKey, nextValue); 43 int index = i + 1;
40 } catch (Exception exception) { 44 int nextKey = r.nextInt(maxKey);
41 exception.printStackTrace(); 45 String nextValue = values[r.nextInt(values.length)];
42 fail(scenario + ":" + index + ": exception happened: " + exception);
43 }
44 if (index % commitFrequency == 0) {
45 long version = versioned.commit();
46 largestCommit = (int) version;
47 }
48 if (index % 10000 == 0)
49 System.out.println(scenario + ":" + index + "/" + steps + " building finished");
50 }
51 // 2. create a non-versioned map,
52 VersionedMap<Integer, String> moving = store.createMap();
53 Random r2 = new Random(seed + 1);
54
55 final int diffTravelFrequency = commitFrequency * 2;
56 for (int i = 0; i < steps; i++) {
57 int index = i + 1;
58 if (index % diffTravelFrequency == 0) {
59 // diff-travel
60 long travelToVersion = r2.nextInt(largestCommit + 1);
61 DiffCursor<Integer, String> diffCursor = moving.getDiffCursor(travelToVersion);
62 moving.putAll(diffCursor);
63
64 } else {
65 // random puts
66 int nextKey = r2.nextInt(maxKey);
67 String nextValue = values[r2.nextInt(values.length)];
68 try { 46 try {
69 moving.put(nextKey, nextValue); 47 versioned.put(nextKey, nextValue);
70 } catch (Exception exception) { 48 } catch (Exception exception) {
71 exception.printStackTrace(); 49 exception.printStackTrace();
72 fail(scenario + ":" + index + ": exception happened: " + exception); 50 fail(scenario + ":" + index + ": exception happened: " + exception);
73 } 51 }
74 if (index % commitFrequency == 0) { 52 if (index % commitFrequency == 0) {
75 versioned.commit(); 53 long version = versioned.commit();
54 largestCommit = (int) version;
76 } 55 }
77 if (index % 10000 == 0) 56 if (index % 10000 == 0)
78 System.out.println(scenario + ":" + index + "/" + steps + " building finished"); 57 System.out.println(scenario + ":" + index + "/" + steps + " building finished");
79 } 58 }
80 } 59 }
81 60
61 {
62 // 2. create a non-versioned map,
63 VersionedMap<Integer, String> moving = store.createMap();
64 Random r2 = new Random(seed + 1);
65
66 final int diffTravelFrequency = commitFrequency * 2;
67 for (int i = 0; i < steps; i++) {
68 int index = i + 1;
69 if (index % diffTravelFrequency == 0) {
70 // diff-travel
71 long travelToVersion = r2.nextInt(largestCommit + 1);
72
73 VersionedMap<Integer, String> oracle = store.createMap(travelToVersion);
74
75 if(commitBeforeDiffCursor) {
76 moving.commit();
77 }
78 DiffCursor<Integer, String> diffCursor = moving.getDiffCursor(travelToVersion);
79 moving.putAll(diffCursor);
80 moving.commit();
81
82 MapTestEnvironment.compareTwoMaps(scenario + ":c" + index, oracle, moving);
83
84 moving.restore(travelToVersion);
85
86 } else {
87 // random puts
88 int nextKey = r2.nextInt(maxKey);
89 String nextValue = values[r2.nextInt(values.length)];
90 try {
91 moving.put(nextKey, nextValue);
92 } catch (Exception exception) {
93 exception.printStackTrace();
94 fail(scenario + ":" + index + ": exception happened: " + exception);
95 }
96 if (index % 10000 == 0)
97 System.out.println(scenario + ":" + index + "/" + steps + " building finished");
98 }
99 }
100 }
82 } 101 }
83 102
84 public static final String title = "DiffCursor {index}/{0} Steps={1} Keys={2} Values={3} nullDefault={4} " + 103 public static final String title = "DiffCursor {index}/{0} Steps={1} Keys={2} Values={3} nullDefault={4} " +
85 "commit frequency={5} seed={6} config={7}"; 104 "commit frequency={5} seed={6} commit before diff={7} config={8}";
86 105
87 @ParameterizedTest(name = title) 106 @ParameterizedTest(name = title)
88 @MethodSource 107 @MethodSource
89 @Timeout(value = 10) 108 @Timeout(value = 10)
90 @Tag("fuzz") 109 @Tag("fuzz")
91 void parametrizedFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault, int commitFrequency, 110 void parametrizedFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault,
92 int seed, VersionedMapStoreBuilder<Integer, String> builder) { 111 int commitFrequency, int seed, boolean commitBeforeDiffCursor,
93 runFuzzTest("MutableImmutableCompareS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, 112 VersionedMapStoreBuilder<Integer, String> builder) {
94 noKeys, noValues, nullDefault, commitFrequency, builder); 113 runFuzzTest("DiffCursorS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps,
114 noKeys, noValues, nullDefault, commitFrequency, commitBeforeDiffCursor, builder);
95 } 115 }
96 116
97 static Stream<Arguments> parametrizedFuzz() { 117 static Stream<Arguments> parametrizedFuzz() {
98 return FuzzTestUtils.permutationWithSize(new Object[]{100}, keyCounts, valueCounts, nullDefaultOptions, 118 return FuzzTestUtils.permutationWithSize(new Object[]{500}, keyCounts, valueCounts, nullDefaultOptions,
99 commitFrequencyOptions, randomSeedOptions, storeConfigs); 119 commitFrequencyOptions, randomSeedOptions, new Object[]{false,true}, storeConfigs);
100 } 120 }
101 121
102 @ParameterizedTest(name = title) 122 @ParameterizedTest(name = title)
@@ -104,9 +124,9 @@ class DiffCursorFuzzTest {
104 @Tag("fuzz") 124 @Tag("fuzz")
105 @Tag("slow") 125 @Tag("slow")
106 void parametrizedSlowFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault, int commitFrequency, 126 void parametrizedSlowFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault, int commitFrequency,
107 int seed, VersionedMapStoreBuilder<Integer, String> builder) { 127 int seed, boolean commitBeforeDiffCursor, VersionedMapStoreBuilder<Integer, String> builder) {
108 runFuzzTest("MutableImmutableCompareS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues, 128 runFuzzTest("DiffCursorS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues,
109 nullDefault, commitFrequency, builder); 129 nullDefault, commitFrequency, commitBeforeDiffCursor, builder);
110 } 130 }
111 131
112 static Stream<Arguments> parametrizedSlowFuzz() { 132 static Stream<Arguments> parametrizedSlowFuzz() {
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
index fb6b28d8..b344d9b9 100644
--- 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
@@ -5,23 +5,25 @@ import tools.refinery.store.map.tests.utils.MapTestEnvironment;
5 5
6public final class FuzzTestCollections { 6public final class FuzzTestCollections {
7 public static final Object[] stepCounts = {FuzzTestUtils.FAST_STEP_COUNT}; 7 public static final Object[] stepCounts = {FuzzTestUtils.FAST_STEP_COUNT};
8 public static final Object[] keyCounts = {1, 32, 32 * 32}; 8 public static final Object[] keyCounts = {1 , 32, 32 * 32};
9 public static final Object[] valueCounts = {2, 3}; 9 public static final Object[] valueCounts = {2, 3};
10 public static final Object[] nullDefaultOptions = {false, true}; 10 public static final Object[] nullDefaultOptions = {false, true};
11 public static final Object[] commitFrequencyOptions = {10, 10, 100}; 11 public static final Object[] commitFrequencyOptions = {1, 10, 100};
12 public static final Object[] randomSeedOptions = {1/*, 2, 3*/}; 12 public static final Object[] randomSeedOptions = {1};
13 public static final Object[] storeConfigs = { 13 public static final Object[] storeConfigs = {
14 // State based 14 // State based
15 VersionedMapStoreBuilder.<Integer,String>builder() 15 VersionedMapStoreBuilder.<Integer,String>builder()
16 .setStrategy(VersionedMapStoreBuilder.StoreStrategy.STATE) 16 .setStrategy(VersionedMapStoreBuilder.StoreStrategy.STATE)
17 .setStateBasedImmutableWhenCommitting(true) 17 .setStateBasedImmutableWhenCommitting(true)
18 .setHashProvider(MapTestEnvironment.prepareHashProvider(false)) 18 .setHashProvider(MapTestEnvironment.prepareHashProvider(false))
19 .setStateBasedNodeSharingStrategy(VersionedMapStoreBuilder.StateStorageStrategy.SHARED_NODE_CACHE), 19 .setStateBasedNodeSharingStrategy(VersionedMapStoreBuilder.StateStorageStrategy
20 .SHARED_NODE_CACHE),
20 VersionedMapStoreBuilder.<Integer,String>builder() 21 VersionedMapStoreBuilder.<Integer,String>builder()
21 .setStrategy(VersionedMapStoreBuilder.StoreStrategy.STATE) 22 .setStrategy(VersionedMapStoreBuilder.StoreStrategy.STATE)
22 .setStateBasedImmutableWhenCommitting(true) 23 .setStateBasedImmutableWhenCommitting(true)
23 .setHashProvider(MapTestEnvironment.prepareHashProvider(true)) 24 .setHashProvider(MapTestEnvironment.prepareHashProvider(true))
24 .setStateBasedNodeSharingStrategy(VersionedMapStoreBuilder.StateStorageStrategy.SHARED_NODE_CACHE), 25 .setStateBasedNodeSharingStrategy(VersionedMapStoreBuilder.StateStorageStrategy
26 .SHARED_NODE_CACHE),
25 VersionedMapStoreBuilder.<Integer,String>builder() 27 VersionedMapStoreBuilder.<Integer,String>builder()
26 .setStrategy(VersionedMapStoreBuilder.StoreStrategy.STATE) 28 .setStrategy(VersionedMapStoreBuilder.StoreStrategy.STATE)
27 .setStateBasedImmutableWhenCommitting(false) 29 .setStateBasedImmutableWhenCommitting(false)
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 69ae811e..0e695aaa 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
@@ -57,13 +57,15 @@ public class MapTestEnvironment<K, V> {
57 VersionedMap<K, V> map2, List<Throwable> errors) { 57 VersionedMap<K, V> map2, List<Throwable> errors) {
58 map1.checkIntegrity(); 58 map1.checkIntegrity();
59 map2.checkIntegrity(); 59 map2.checkIntegrity();
60
61 assertContentEqualsList(map1, map2, title + ": map1.contentEquals(map2)", errors);
62 assertContentEqualsList(map2, map1, title + ": map2.contentEquals(map1)", errors);
60 assertEqualsList(map1.getSize(), map2.getSize(), title + ": Sizes not equal", errors); 63 assertEqualsList(map1.getSize(), map2.getSize(), title + ": Sizes not equal", errors);
64
61 for (var mode : ContentHashCode.values()) { 65 for (var mode : ContentHashCode.values()) {
62 assertEqualsList(map1.contentHashCode(mode), map2.contentHashCode(mode), 66 assertEqualsList(map1.contentHashCode(mode), map2.contentHashCode(mode),
63 title + ": " + mode + " hashCode check", errors); 67 title + ": " + mode + " hashCode check", errors);
64 } 68 }
65 assertContentEqualsList(map1, map2, title + ": map1.contentEquals(map2)", errors);
66 assertContentEqualsList(map2, map1, title + ": map2.contentEquals(map1)", errors);
67 } 69 }
68 70
69 private static void assertEqualsList(Object o1, Object o2, String message, List<Throwable> errors) { 71 private static void assertEqualsList(Object o1, Object o2, String message, List<Throwable> errors) {
@@ -177,7 +179,8 @@ public class MapTestEnvironment<K, V> {
177 K previous = null; 179 K previous = null;
178 Cursor<K, V> cursor = versionedMap.getAll(); 180 Cursor<K, V> cursor = versionedMap.getAll();
179 while (cursor.move()) { 181 while (cursor.move()) {
180 System.out.println(cursor.getKey() + " " + ((VersionedMapImpl<K, V>) versionedMap).getHashProvider().getHash(cursor.getKey(), 0)); 182 //System.out.println(cursor.getKey() + " " + ((VersionedMapImpl<K, V>) versionedMap).getHashProvider()
183 // .getHash(cursor.getKey(), 0));
181 if (previous != null) { 184 if (previous != null) {
182 int comparisonResult = ((VersionedMapImpl<K, V>) versionedMap).getHashProvider().compare(previous, 185 int comparisonResult = ((VersionedMapImpl<K, V>) versionedMap).getHashProvider().compare(previous,
183 cursor.getKey()); 186 cursor.getKey());
@@ -185,7 +188,6 @@ public class MapTestEnvironment<K, V> {
185 } 188 }
186 previous = cursor.getKey(); 189 previous = cursor.getKey();
187 } 190 }
188 System.out.println();
189 } 191 }
190 192
191 public void printComparison() { 193 public void printComparison() {