aboutsummaryrefslogtreecommitdiffstats
path: root/subprojects/store/src/test/java/tools/refinery/store/map/tests/fuzz/ContentEqualsFuzzTest.java
blob: c49911b802206dd7a1396f1af8873b2c111a05ed (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*
 * SPDX-FileCopyrightText: 2021-2023 The Refinery Authors <https://refinery.tools/>
 *
 * SPDX-License-Identifier: EPL-2.0
 */
package tools.refinery.store.map.tests.fuzz;

import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Timeout;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import tools.refinery.store.map.Cursor;
import tools.refinery.store.map.VersionedMap;
import tools.refinery.store.map.VersionedMapStore;
import tools.refinery.store.map.VersionedMapStoreFactoryBuilder;
import tools.refinery.store.map.tests.fuzz.utils.FuzzTestUtils;
import tools.refinery.store.map.tests.utils.MapTestEnvironment;

import java.util.AbstractMap.SimpleEntry;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.fail;
import static tools.refinery.store.map.tests.fuzz.utils.FuzzTestCollections.*;

class ContentEqualsFuzzTest {
	private void runFuzzTest(String scenario, int seed, int steps, int maxKey, int maxValue,
							 boolean nullDefault, int commitFrequency,
							 VersionedMapStoreFactoryBuilder<Integer, String> builder) {
		String[] values = MapTestEnvironment.prepareValues(maxValue, nullDefault);


		Random r = new Random(seed);

		iterativeRandomPutsAndCommitsThenCompare(scenario, builder, steps, maxKey, values, r, commitFrequency);
	}

	private void iterativeRandomPutsAndCommitsThenCompare(String scenario, VersionedMapStoreFactoryBuilder<Integer, String> builder,
														  int steps, int maxKey, String[] values, Random r,
														  int commitFrequency) {
		VersionedMapStore<Integer, String> store1 = builder.defaultValue(values[0]).build().createOne();
		VersionedMap<Integer, String> sut1 = store1.createMap();

		// Fill one map
		for (int i = 0; i < steps; i++) {
			int index1 = i + 1;
			int nextKey = r.nextInt(maxKey);
			String nextValue = values[r.nextInt(values.length)];
			try {
				sut1.put(nextKey, nextValue);
			} catch (Exception exception) {
				exception.printStackTrace();
				fail(scenario + ":" + index1 + ": exception happened: " + exception);
			}
			MapTestEnvironment.printStatus(scenario, index1, steps, "Fill");
			if (index1 % commitFrequency == 0) {
				sut1.commit();
			}
		}

		// Get the content of the first map
		List<SimpleEntry<Integer, String>> content = new LinkedList<>();
		Cursor<Integer, String> cursor = sut1.getAll();
		while (cursor.move()) {
			content.add(new SimpleEntry<>(cursor.getKey(), cursor.getValue()));
		}

		// Randomize the order of the content
		Collections.shuffle(content, r);

		VersionedMapStore<Integer, String> store2 = builder.defaultValue(values[0]).build().createOne();
		VersionedMap<Integer, String> sut2 = store2.createMap();
		int index2 = 1;
		for (SimpleEntry<Integer, String> entry : content) {
			sut2.put(entry.getKey(), entry.getValue());
			if (index2++ % commitFrequency == 0)
				sut2.commit();
		}

		// Check the integrity of the maps
		sut1.checkIntegrity();
		sut2.checkIntegrity();

		// Compare the two maps
		MapTestEnvironment.compareTwoMaps(scenario, sut1, sut2);
	}

	public static final String title = "Compare {index}/{0} Steps={1} Keys={2} Values={3} defaultNull={4} commit frequency={5}" +
			"seed={6} config={7}";

	@ParameterizedTest(name = title)
	@MethodSource
	@Timeout(value = 10)
	@Tag("fuzz")
	void parametrizedFastFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean nullDefault, int commitFrequency,
							  int seed, VersionedMapStoreFactoryBuilder<Integer, String> builder) {
		runFuzzTest("CompareS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues,
				nullDefault, commitFrequency, builder);
	}

	static Stream<Arguments> parametrizedFastFuzz() {
		return FuzzTestUtils.permutationWithSize(stepCounts, keyCounts, valueCounts, nullDefaultOptions,
				commitFrequencyOptions, randomSeedOptions, storeConfigs);
	}

	@ParameterizedTest(name = title)
	@MethodSource
	@Tag("fuzz")
	@Tag("slow")
	void parametrizedSlowFuzz(int ignoredTests, int steps, int noKeys, int noValues, boolean defaultNull, int commitFrequency,
							  int seed, VersionedMapStoreFactoryBuilder<Integer, String> builder) {
		runFuzzTest("CompareS" + steps + "K" + noKeys + "V" + noValues + "s" + seed, seed, steps, noKeys, noValues,
				defaultNull, commitFrequency, builder);
	}

	static Stream<Arguments> parametrizedSlowFuzz() {
		return FuzzTestUtils.changeStepCount(parametrizedFastFuzz(), 1);
	}
}