diff options
author | Fabian Meumertzheim <meumertzheim@code-intelligence.com> | 2023-04-12 15:03:08 +0200 |
---|---|---|
committer | Fabian Meumertzheim <fabian@meumertzhe.im> | 2023-04-13 13:15:47 +0200 |
commit | 0420f57d2b03eb93fa52eea1aa306e33c68288e8 (patch) | |
tree | 5adbf319f260dedbe6d8950ca1dab0b8cbd7f496 /src/test/java/com | |
parent | 2d199ed4c1913685f78c32a27979c7bf5a2a6880 (diff) | |
download | jazzer-api-0420f57d2b03eb93fa52eea1aa306e33c68288e8.tar.gz |
mutation: Simplify the `detach` concept and make lists mutable
Detaching confusingly meant two things at once, but failed at both:
1. It was meant to rid fuzz test arguments of state shared with the
mutator so that fuzz test body and future mutations couldn't
affect each other. This wasn't working correctly for lists, which
provided a shallowly immutable view on potentially mutable contents.
2. It also promised "mutable values where possible", which wasn't really
well-defined and also doesn't match common use cases: If a function
accepts a `List<Foo>`, it should generally be able to expect the list
to permit modifications.
Instead, `detach` now always returns an object that shares no mutable
state, not even transitively, with the original object. Apart from
simplifying the implementation, this allows mutators to copy values by
applying `detach`, which previously could have resulted in shared state
that couldn't be mutated independently.
Since we are currently reading in the fuzz test arguments from the raw
byte representation in every iteration, there is no need to detach and
we can also return mutable lists directly. If we get rid of the
re-reads, we would have to detach, which is now verified by a new
consistency check in `ArgumentsMutator`.
We might be able to optimize e.g. `List<String>` to avoid all copies in
the future via a new annotation (e.g. `@Immutable`). The current
implementation would already avoid copying the strings and would only
recreate the list, which is most likely negligible overhead.
Diffstat (limited to 'src/test/java/com')
-rw-r--r-- | src/test/java/com/code_intelligence/jazzer/mutation/ArgumentsMutatorTest.java | 29 |
1 files changed, 12 insertions, 17 deletions
diff --git a/src/test/java/com/code_intelligence/jazzer/mutation/ArgumentsMutatorTest.java b/src/test/java/com/code_intelligence/jazzer/mutation/ArgumentsMutatorTest.java index 5d5ba08f..03b592f1 100644 --- a/src/test/java/com/code_intelligence/jazzer/mutation/ArgumentsMutatorTest.java +++ b/src/test/java/com/code_intelligence/jazzer/mutation/ArgumentsMutatorTest.java @@ -20,10 +20,8 @@ import static com.code_intelligence.jazzer.mutation.support.TestSupport.mockPseu import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth8.assertThat; import static java.util.Collections.singletonList; -import static org.junit.jupiter.api.Assertions.assertThrows; import com.code_intelligence.jazzer.mutation.annotation.NotNull; -import com.code_intelligence.jazzer.mutation.annotation.SafeToMutate; import com.code_intelligence.jazzer.mutation.mutator.Mutators; import com.code_intelligence.jazzer.mutation.support.TestSupport.MockPseudoRandom; import java.lang.reflect.Method; @@ -36,8 +34,7 @@ class ArgumentsMutatorTest { private static List<List<Boolean>> fuzzThisFunctionArgument1; private static List<Boolean> fuzzThisFunctionArgument2; - public static void fuzzThisFunction( - @SafeToMutate List<List<@NotNull Boolean>> list, List<Boolean> otherList) { + public static void fuzzThisFunction(List<List<@NotNull Boolean>> list, List<Boolean> otherList) { fuzzThisFunctionArgument1 = list; fuzzThisFunctionArgument2 = otherList; } @@ -76,7 +73,7 @@ class ArgumentsMutatorTest { fuzzThisFunctionArgument1 = null; fuzzThisFunctionArgument2 = null; - mutator.invoke(); + mutator.invoke(true); assertThat(fuzzThisFunctionArgument1).containsExactly(singletonList(true)); assertThat(fuzzThisFunctionArgument2).containsExactly(false); @@ -100,13 +97,13 @@ class ArgumentsMutatorTest { fuzzThisFunctionArgument1 = null; fuzzThisFunctionArgument2 = null; - mutator.invoke(); + mutator.invoke(true); assertThat(fuzzThisFunctionArgument1).containsExactly(singletonList(false)); assertThat(fuzzThisFunctionArgument2).containsExactly(false); // Modify the arguments passed to the function. - fuzzThisFunctionArgument1.clear(); - assertThrows(UnsupportedOperationException.class, () -> fuzzThisFunctionArgument2.clear()); + fuzzThisFunctionArgument1.get(0).clear(); + fuzzThisFunctionArgument2.clear(); try (MockPseudoRandom prng = mockPseudoRandom( // mutate first argument @@ -128,7 +125,7 @@ class ArgumentsMutatorTest { fuzzThisFunctionArgument1 = null; fuzzThisFunctionArgument2 = null; - mutator.invoke(); + mutator.invoke(false); assertThat(fuzzThisFunctionArgument1).containsExactly(singletonList(true)); assertThat(fuzzThisFunctionArgument2).containsExactly(false); } @@ -136,8 +133,7 @@ class ArgumentsMutatorTest { private List<List<Boolean>> mutableFuzzThisFunctionArgument1; private List<Boolean> mutableFuzzThisFunctionArgument2; - public void mutableFuzzThisFunction( - @SafeToMutate List<List<@NotNull Boolean>> list, List<Boolean> otherList) { + public void mutableFuzzThisFunction(List<List<@NotNull Boolean>> list, List<Boolean> otherList) { mutableFuzzThisFunctionArgument1 = list; mutableFuzzThisFunctionArgument2 = otherList; } @@ -175,7 +171,7 @@ class ArgumentsMutatorTest { mutableFuzzThisFunctionArgument1 = null; mutableFuzzThisFunctionArgument2 = null; - mutator.invoke(); + mutator.invoke(true); assertThat(mutableFuzzThisFunctionArgument1).containsExactly(singletonList(true)); assertThat(mutableFuzzThisFunctionArgument2).containsExactly(false); @@ -199,14 +195,13 @@ class ArgumentsMutatorTest { mutableFuzzThisFunctionArgument1 = null; mutableFuzzThisFunctionArgument2 = null; - mutator.invoke(); + mutator.invoke(true); assertThat(mutableFuzzThisFunctionArgument1).containsExactly(singletonList(false)); assertThat(mutableFuzzThisFunctionArgument2).containsExactly(false); // Modify the arguments passed to the function. - mutableFuzzThisFunctionArgument1.clear(); - assertThrows( - UnsupportedOperationException.class, () -> mutableFuzzThisFunctionArgument2.clear()); + mutableFuzzThisFunctionArgument1.get(0).clear(); + mutableFuzzThisFunctionArgument2.clear(); try (MockPseudoRandom prng = mockPseudoRandom( // mutate first argument @@ -228,7 +223,7 @@ class ArgumentsMutatorTest { mutableFuzzThisFunctionArgument1 = null; mutableFuzzThisFunctionArgument2 = null; - mutator.invoke(); + mutator.invoke(false); assertThat(mutableFuzzThisFunctionArgument1).containsExactly(singletonList(true)); assertThat(mutableFuzzThisFunctionArgument2).containsExactly(false); } |