diff options
author | Norbert Schneider <norbert.schneider@code-intelligence.com> | 2023-04-19 16:54:10 +0200 |
---|---|---|
committer | Norbert Schneider <mail@bertschneider.de> | 2023-05-19 16:17:07 +0200 |
commit | b1ec11226a540192f99117a6570f52636ce4cdc7 (patch) | |
tree | 41824bf1ae852b74556fd253a7daf05f305ad367 /src/test | |
parent | 5a9c9c0cb4d331f2367d88629a669e7b208940c8 (diff) | |
download | jazzer-api-b1ec11226a540192f99117a6570f52636ce4cdc7.tar.gz |
mutator: Add custom cross over base functionality
Add custom cross over functionality in libFuzzer integration and mutator
framework APIs. Concrete cross over implementations are added later on.
Diffstat (limited to 'src/test')
3 files changed, 87 insertions, 0 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 61579205..9a5bafd8 100644 --- a/src/test/java/com/code_intelligence/jazzer/mutation/ArgumentsMutatorTest.java +++ b/src/test/java/com/code_intelligence/jazzer/mutation/ArgumentsMutatorTest.java @@ -24,12 +24,15 @@ import static java.util.Collections.singletonList; import com.code_intelligence.jazzer.mutation.annotation.NotNull; import com.code_intelligence.jazzer.mutation.mutator.Mutators; import com.code_intelligence.jazzer.mutation.support.TestSupport.MockPseudoRandom; +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; import java.lang.reflect.Method; import java.util.List; import java.util.Optional; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.parallel.ResourceLock; +@SuppressWarnings("OptionalGetWithoutIsPresent") class ArgumentsMutatorTest { private static List<List<Boolean>> fuzzThisFunctionArgument1; private static List<Boolean> fuzzThisFunctionArgument2; @@ -243,4 +246,53 @@ class ArgumentsMutatorTest { assertThat(mutableFuzzThisFunctionArgument1).containsExactly(singletonList(true)); assertThat(mutableFuzzThisFunctionArgument2).containsExactly(false); } + + @SuppressWarnings("unused") + public void crossOverFunction(List<Boolean> list) {} + + @Test + @SuppressWarnings("unchecked") + void testCrossOver() throws Throwable { + Method method = ArgumentsMutatorTest.class.getMethod("crossOverFunction", List.class); + Optional<ArgumentsMutator> maybeMutator = + ArgumentsMutator.forInstanceMethod(Mutators.newFactory(), this, method); + assertThat(maybeMutator).isPresent(); + ArgumentsMutator mutator = maybeMutator.get(); + + try (MockPseudoRandom prng = mockPseudoRandom( + // list not null + false, + // list size 1 + 1, + // not null, + false, + // boolean + true)) { + mutator.init(prng); + } + ByteArrayOutputStream baos1 = new ByteArrayOutputStream(); + mutator.write(baos1); + byte[] out1 = baos1.toByteArray(); + + try (MockPseudoRandom prng = mockPseudoRandom( + // list not null + false, + // list size 1 + 1, + // not null + false, + // boolean + false)) { + mutator.init(prng); + } + ByteArrayOutputStream baos2 = new ByteArrayOutputStream(); + mutator.write(baos2); + byte[] out2 = baos1.toByteArray(); + + mutator.crossOver(new ByteArrayInputStream(out1), new ByteArrayInputStream(out2), 12345); + Object[] arguments = mutator.getArguments(); + + assertThat(arguments).isNotEmpty(); + assertThat((List<Boolean>) arguments[0]).isNotEmpty(); + } } diff --git a/src/test/java/com/code_intelligence/jazzer/mutation/combinator/MutatorCombinatorsTest.java b/src/test/java/com/code_intelligence/jazzer/mutation/combinator/MutatorCombinatorsTest.java index a8424ecb..ccf893d2 100644 --- a/src/test/java/com/code_intelligence/jazzer/mutation/combinator/MutatorCombinatorsTest.java +++ b/src/test/java/com/code_intelligence/jazzer/mutation/combinator/MutatorCombinatorsTest.java @@ -79,6 +79,10 @@ class MutatorCombinatorsTest { } @Override + public void crossOverInPlace( + List<Integer> reference, List<Integer> otherReference, PseudoRandom prng) {} + + @Override public String toDebugString(Predicate<Debuggable> isInCycle) { return "List<Integer>"; } @@ -122,6 +126,10 @@ class MutatorCombinatorsTest { } @Override + public void crossOverInPlace( + List<Integer> reference, List<Integer> otherReference, PseudoRandom prng) {} + + @Override public String toDebugString(Predicate<Debuggable> isInCycle) { return "List<Integer>"; } diff --git a/src/test/java/com/code_intelligence/jazzer/mutation/support/TestSupport.java b/src/test/java/com/code_intelligence/jazzer/mutation/support/TestSupport.java index 9a39f186..d4e15a78 100644 --- a/src/test/java/com/code_intelligence/jazzer/mutation/support/TestSupport.java +++ b/src/test/java/com/code_intelligence/jazzer/mutation/support/TestSupport.java @@ -136,6 +136,11 @@ public final class TestSupport { } @Override + public T crossOver(T value, T otherValue, PseudoRandom prng) { + return value; + } + + @Override public String toDebugString(Predicate<Debuggable> isInCycle) { T initialValue = nextInitialValue(); if (initialValue == null) { @@ -301,6 +306,28 @@ public final class TestSupport { } @Override + public <T> T pickValue( + T value, T otherValue, Supplier<T> supplier, int inverseSupplierFrequency) { + assertThat(elements).isNotEmpty(); + switch ((int) elements.poll()) { + case 0: + return value; + case 1: + return otherValue; + case 2: + return producer.get(); + default: + throw new AssertionError("Invalid pickValue element"); + } + } + + @Override + public long nextLong() { + assertThat(elements).isNotEmpty(); + return (long) elements.poll(); + } + + @Override public void close() { assertThat(elements).isEmpty(); } |