aboutsummaryrefslogtreecommitdiff
path: root/src/test/java/com/code_intelligence/jazzer/mutation/mutator/collection/MapMutatorTest.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/test/java/com/code_intelligence/jazzer/mutation/mutator/collection/MapMutatorTest.java')
-rw-r--r--src/test/java/com/code_intelligence/jazzer/mutation/mutator/collection/MapMutatorTest.java355
1 files changed, 355 insertions, 0 deletions
diff --git a/src/test/java/com/code_intelligence/jazzer/mutation/mutator/collection/MapMutatorTest.java b/src/test/java/com/code_intelligence/jazzer/mutation/mutator/collection/MapMutatorTest.java
new file mode 100644
index 00000000..4c2c14f9
--- /dev/null
+++ b/src/test/java/com/code_intelligence/jazzer/mutation/mutator/collection/MapMutatorTest.java
@@ -0,0 +1,355 @@
+/*
+ * Copyright 2023 Code Intelligence GmbH
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.code_intelligence.jazzer.mutation.mutator.collection;
+
+import static com.code_intelligence.jazzer.mutation.support.TestSupport.asMap;
+import static com.code_intelligence.jazzer.mutation.support.TestSupport.asMutableList;
+import static com.code_intelligence.jazzer.mutation.support.TestSupport.mockPseudoRandom;
+import static com.google.common.truth.Truth.assertThat;
+import static java.util.Collections.emptyMap;
+
+import com.code_intelligence.jazzer.mutation.annotation.NotNull;
+import com.code_intelligence.jazzer.mutation.annotation.WithSize;
+import com.code_intelligence.jazzer.mutation.api.ChainedMutatorFactory;
+import com.code_intelligence.jazzer.mutation.api.MutatorFactory;
+import com.code_intelligence.jazzer.mutation.api.SerializingMutator;
+import com.code_intelligence.jazzer.mutation.mutator.lang.LangMutators;
+import com.code_intelligence.jazzer.mutation.support.TestSupport.MockPseudoRandom;
+import com.code_intelligence.jazzer.mutation.support.TypeHolder;
+import java.lang.reflect.AnnotatedType;
+import java.util.List;
+import java.util.Map;
+import org.junit.jupiter.api.Test;
+
+@SuppressWarnings("unchecked")
+class MapMutatorTest {
+ public static final MutatorFactory FACTORY =
+ new ChainedMutatorFactory(LangMutators.newFactory(), CollectionMutators.newFactory());
+
+ private static SerializingMutator<Map<Integer, Integer>> defaultTestMapMutator() {
+ AnnotatedType type =
+ new TypeHolder<@NotNull Map<@NotNull Integer, @NotNull Integer>>() {}.annotatedType();
+ return (SerializingMutator<Map<Integer, Integer>>) FACTORY.createOrThrow(type);
+ }
+
+ @Test
+ void mapInitInsert() {
+ AnnotatedType type =
+ new TypeHolder<@NotNull @WithSize(max = 3) Map<@NotNull String, @NotNull String>>(){}
+ .annotatedType();
+ SerializingMutator<Map<String, String>> mutator =
+ (SerializingMutator<Map<String, String>>) FACTORY.createOrThrow(type);
+ assertThat(mutator.toString()).isEqualTo("Map<String,String>");
+
+ // Initialize new map
+ Map<String, String> map;
+ try (MockPseudoRandom prng = mockPseudoRandom(
+ // Initial map size
+ 1,
+ // Key 1 size
+ 4,
+ // Key 1 value
+ "Key1".getBytes(),
+ // Value size
+ 6,
+ // Value value
+ "Value1".getBytes())) {
+ map = mutator.init(prng);
+ }
+ assertThat(map).containsExactly("Key1", "Value1");
+
+ // Add 2 new entries
+ try (MockPseudoRandom prng = mockPseudoRandom(
+ // grow chunk
+ 1,
+ // ChunkSize
+ 2,
+ // Key 2 size
+ 4,
+ // Key 2 value
+ "Key2".getBytes(),
+ // Value size
+ 6,
+ // Value value
+ "Value2".getBytes(),
+ // Key 3 size
+ 4,
+ // Key 3 value
+ "Key3".getBytes(),
+ // Value size
+ 6,
+ // Value value
+ "Value3".getBytes())) {
+ map = mutator.mutate(map, prng);
+ }
+ assertThat(map).containsExactly("Key1", "Value1", "Key2", "Value2", "Key3", "Value3").inOrder();
+ }
+
+ @Test
+ void mapDelete() {
+ AnnotatedType type =
+ new TypeHolder<@NotNull Map<@NotNull Integer, @NotNull Integer>>() {}.annotatedType();
+ SerializingMutator<Map<Integer, Integer>> mutator =
+ (SerializingMutator<Map<Integer, Integer>>) FACTORY.createOrThrow(type);
+ assertThat(mutator.toString()).isEqualTo("Map<Integer,Integer>");
+
+ Map<Integer, Integer> map = asMap(1, 10, 2, 20, 3, 30, 4, 40, 5, 50, 6, 60);
+
+ try (MockPseudoRandom prng = mockPseudoRandom(
+ // delete chunk
+ 0,
+ // chunk size
+ 2,
+ // chunk position
+ 3)) {
+ map = mutator.mutate(map, prng);
+ }
+ assertThat(map).containsExactly(1, 10, 2, 20, 3, 30, 6, 60).inOrder();
+ }
+
+ @Test
+ void mapMutateValues() {
+ AnnotatedType type =
+ new TypeHolder<@NotNull Map<@NotNull Integer, @NotNull Integer>>() {}.annotatedType();
+ SerializingMutator<Map<Integer, Integer>> mutator =
+ (SerializingMutator<Map<Integer, Integer>>) FACTORY.createOrThrow(type);
+ assertThat(mutator.toString()).isEqualTo("Map<Integer,Integer>");
+
+ Map<Integer, Integer> map = asMap(1, 10, 2, 20, 3, 30, 4, 40, 5, 50, 6, 60);
+
+ try (MockPseudoRandom prng = mockPseudoRandom(
+ // change chunk
+ 2,
+ // mutate values,
+ true,
+ // chunk size
+ 2,
+ // chunk position
+ 3,
+ // uniform pick
+ 2,
+ // random integer
+ 41L,
+ // uniform pick
+ 2,
+ // random integer
+ 51L)) {
+ map = mutator.mutate(map, prng);
+ }
+ assertThat(map).containsExactly(1, 10, 2, 20, 3, 30, 4, 41, 5, 51, 6, 60).inOrder();
+ }
+
+ @Test
+ void mapMutateKeys() {
+ AnnotatedType type =
+ new TypeHolder<@NotNull Map<@NotNull Integer, @NotNull Integer>>() {}.annotatedType();
+ SerializingMutator<Map<Integer, Integer>> mutator =
+ (SerializingMutator<Map<Integer, Integer>>) FACTORY.createOrThrow(type);
+ assertThat(mutator.toString()).isEqualTo("Map<Integer,Integer>");
+
+ Map<Integer, Integer> map = asMap(1, 10, 2, 20, 3, 30, 4, 40, 5, 50, 6, 60);
+
+ try (MockPseudoRandom prng = mockPseudoRandom(
+ // change chunk
+ 2,
+ // mutate keys,
+ false,
+ // chunk size
+ 2,
+ // chunk position
+ 3,
+ // uniform pick
+ 2,
+ // integer
+ 7L,
+ // uniform pick
+ 2,
+ // random integer
+ 8L)) {
+ map = mutator.mutate(map, prng);
+ }
+ assertThat(map).containsExactly(1, 10, 2, 20, 3, 30, 6, 60, 7, 40, 8, 50).inOrder();
+ }
+
+ @Test
+ void mapMutateKeysFallbackToValues() {
+ AnnotatedType type =
+ new TypeHolder<@NotNull Map<@NotNull Boolean, @NotNull Boolean>>() {}.annotatedType();
+ SerializingMutator<Map<Boolean, Boolean>> mutator =
+ (SerializingMutator<Map<Boolean, Boolean>>) FACTORY.createOrThrow(type);
+ assertThat(mutator.toString()).isEqualTo("Map<Boolean,Boolean>");
+
+ // No new keys can be generated for this map.
+ Map<Boolean, Boolean> map = asMap(false, false, true, false);
+
+ try (MockPseudoRandom prng = mockPseudoRandom(
+ // change chunk
+ 2,
+ // mutate keys,
+ false,
+ // chunk size
+ 1,
+ // chunk position
+ 0,
+ // chunk size for fallback to mutate values
+ 2,
+ // chunk position for fallback
+ 0)) {
+ map = mutator.mutate(map, prng);
+ }
+ assertThat(map).containsExactly(false, true, true, true).inOrder();
+ }
+
+ @Test
+ void testCrossOverEmptyMaps() {
+ SerializingMutator<@NotNull Map<@NotNull Integer, @NotNull Integer>> mutator =
+ defaultTestMapMutator();
+
+ try (MockPseudoRandom prng = mockPseudoRandom()) {
+ Map<Integer, Integer> map = mutator.crossOver(emptyMap(), emptyMap(), prng);
+ assertThat(map).isEmpty();
+ }
+ }
+
+ @Test
+ void testCrossOverInsertChunk() {
+ SerializingMutator<@NotNull Map<@NotNull Integer, @NotNull Integer>> mutator =
+ defaultTestMapMutator();
+
+ Map<Integer, Integer> map = asMap(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6);
+ Map<Integer, Integer> otherMap = asMap(1, 1, 2, 2, 3, 3, 40, 40, 50, 50, 60, 60);
+
+ try (MockPseudoRandom prng = mockPseudoRandom(
+ // insert action
+ 0,
+ // chunk size
+ 3,
+ // from chunk offset, will skip first element of chunk as it is already present in map
+ 3,
+ // to chunk offset, unused
+ 0)) {
+ map = mutator.crossOver(map, otherMap, prng);
+ assertThat(map)
+ .containsExactly(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 40, 40, 50, 50, 60, 60)
+ .inOrder();
+ }
+ }
+
+ @Test
+ void testCrossOverOverwriteChunk() {
+ SerializingMutator<@NotNull Map<@NotNull Integer, @NotNull Integer>> mutator =
+ defaultTestMapMutator();
+
+ Map<Integer, Integer> map = asMap(1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6);
+ Map<Integer, Integer> otherMap = asMap(1, 1, 2, 2, 3, 3, 40, 40, 50, 50, 60, 60);
+
+ try (MockPseudoRandom prng = mockPseudoRandom(
+ // overwrite action
+ 1,
+ // chunk size
+ 3,
+ // from chunk offset
+ 2,
+ // to chunk offset, will not change first element as values are equal
+ 2)) {
+ map = mutator.crossOver(map, otherMap, prng);
+ assertThat(map).containsExactly(1, 1, 2, 2, 3, 3, 4, 40, 5, 50, 6, 6).inOrder();
+ }
+ }
+
+ @Test
+ void testCrossOverCrossOverChunkKeys() {
+ AnnotatedType type =
+ new TypeHolder<@NotNull Map<@NotNull List<@NotNull Integer>, @NotNull Integer>>() {
+ }.annotatedType();
+ SerializingMutator<@NotNull Map<@NotNull List<@NotNull Integer>, @NotNull Integer>> mutator =
+ (SerializingMutator<@NotNull Map<@NotNull List<@NotNull Integer>, @NotNull Integer>>)
+ FACTORY.createOrThrow(type);
+
+ Map<List<Integer>, Integer> map = asMap(asMutableList(1), 1, asMutableList(2), 2,
+ asMutableList(3), 3, asMutableList(4), 4, asMutableList(5), 5, asMutableList(6), 6);
+ Map<List<Integer>, Integer> otherMap = asMap(asMutableList(1), 1, asMutableList(2), 2,
+ asMutableList(3), 3, asMutableList(40), 4, asMutableList(50), 5, asMutableList(60), 6);
+
+ try (MockPseudoRandom prng = mockPseudoRandom(
+ // cross over action
+ 2,
+ // keys
+ true,
+ // chunk size
+ 3,
+ // from chunk offset
+ 2,
+ // to chunk offset,
+ // first keys ("3") are equal and will be overwritten
+ 2,
+ // first key, delegate to list cross over, overwrite 1 entry at offset 0 from offset 0
+ 1, 1, 0, 0,
+ // second key, delegate to list cross over, overwrite 1 entry at offset 0 from offset 0
+ 1, 1, 0, 0,
+ // third key, delegate to list cross over, overwrite 1 entry at offset 0 from offset 0
+ 1, 1, 0, 0)) {
+ map = mutator.crossOver(map, otherMap, prng);
+ assertThat(map)
+ .containsExactly(asMutableList(1), 1, asMutableList(2), 2, asMutableList(6), 6,
+ // Overwritten keys after here
+ asMutableList(3), 3, asMutableList(40), 4, asMutableList(50), 5)
+ .inOrder();
+ }
+ }
+
+ @Test
+ void testCrossOverCrossOverChunkValues() {
+ AnnotatedType type =
+ new TypeHolder<@NotNull Map<@NotNull Integer, @NotNull List<@NotNull Integer>>>() {
+ }.annotatedType();
+ SerializingMutator<@NotNull Map<@NotNull Integer, @NotNull List<@NotNull Integer>>> mutator =
+ (SerializingMutator<@NotNull Map<@NotNull Integer, @NotNull List<@NotNull Integer>>>)
+ FACTORY.createOrThrow(type);
+
+ Map<Integer, List<Integer>> map = asMap(1, asMutableList(1), 2, asMutableList(2), 3,
+ asMutableList(3), 4, asMutableList(4), 5, asMutableList(5), 6, asMutableList(6));
+ Map<Integer, List<Integer>> otherMap = asMap(1, asMutableList(1), 2, asMutableList(2), 3,
+ asMutableList(30), 40, asMutableList(40), 50, asMutableList(50), 60, asMutableList(60));
+
+ try (
+ MockPseudoRandom prng = mockPseudoRandom(
+ // cross over action
+ 2,
+ // values
+ false,
+ // chunk size
+ 3,
+ // from chunk offset
+ 2,
+ // to chunk offset,
+ 2,
+ // first value, delegate to list cross over, overwrite 1 entry at offset 0 from offset 0
+ 1, 1, 0, 0,
+ // second value, delegate to list cross over, overwrite 1 entry at offset 0 from offset
+ // 0
+ 1, 1, 0, 0,
+ // third value, delegate to list cross over, overwrite 1 entry at offset 0 from offset 0
+ 1, 1, 0, 0)) {
+ map = mutator.crossOver(map, otherMap, prng);
+ assertThat(map)
+ .containsExactly(1, asMutableList(1), 2, asMutableList(2), 3, asMutableList(30), 4,
+ asMutableList(40), 5, asMutableList(50), 6, asMutableList(6))
+ .inOrder();
+ }
+ }
+}