a159e41140442915c02d0a5d71913f20eaddd734
[oota-llvm.git] / lib / Fuzzer / test / FuzzerUnittest.cpp
1 #include "FuzzerInternal.h"
2 #include "gtest/gtest.h"
3 #include <set>
4
5 using namespace fuzzer;
6
7 // For now, have LLVMFuzzerTestOneInput just to make it link.
8 // Later we may want to make unittests that actually call LLVMFuzzerTestOneInput.
9 extern "C" void LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
10   abort();
11 }
12
13 TEST(Fuzzer, CrossOver) {
14   FuzzerRandomLibc Rand(0);
15   Unit A({0, 1, 2}), B({5, 6, 7});
16   Unit C;
17   Unit Expected[] = {
18        { 0 },
19        { 0, 1 },
20        { 0, 5 },
21        { 0, 1, 2 },
22        { 0, 1, 5 },
23        { 0, 5, 1 },
24        { 0, 5, 6 },
25        { 0, 1, 2, 5 },
26        { 0, 1, 5, 2 },
27        { 0, 1, 5, 6 },
28        { 0, 5, 1, 2 },
29        { 0, 5, 1, 6 },
30        { 0, 5, 6, 1 },
31        { 0, 5, 6, 7 },
32        { 0, 1, 2, 5, 6 },
33        { 0, 1, 5, 2, 6 },
34        { 0, 1, 5, 6, 2 },
35        { 0, 1, 5, 6, 7 },
36        { 0, 5, 1, 2, 6 },
37        { 0, 5, 1, 6, 2 },
38        { 0, 5, 1, 6, 7 },
39        { 0, 5, 6, 1, 2 },
40        { 0, 5, 6, 1, 7 },
41        { 0, 5, 6, 7, 1 },
42        { 0, 1, 2, 5, 6, 7 },
43        { 0, 1, 5, 2, 6, 7 },
44        { 0, 1, 5, 6, 2, 7 },
45        { 0, 1, 5, 6, 7, 2 },
46        { 0, 5, 1, 2, 6, 7 },
47        { 0, 5, 1, 6, 2, 7 },
48        { 0, 5, 1, 6, 7, 2 },
49        { 0, 5, 6, 1, 2, 7 },
50        { 0, 5, 6, 1, 7, 2 },
51        { 0, 5, 6, 7, 1, 2 }
52   };
53   for (size_t Len = 1; Len < 8; Len++) {
54     std::set<Unit> FoundUnits, ExpectedUnitsWitThisLength;
55     for (int Iter = 0; Iter < 3000; Iter++) {
56       C.resize(Len);
57       size_t NewSize = CrossOver(A.data(), A.size(), B.data(), B.size(),
58                                  C.data(), C.size(), Rand);
59       C.resize(NewSize);
60       FoundUnits.insert(C);
61     }
62     for (const Unit &U : Expected)
63       if (U.size() <= Len)
64         ExpectedUnitsWitThisLength.insert(U);
65     EXPECT_EQ(ExpectedUnitsWitThisLength, FoundUnits);
66   }
67 }
68
69 TEST(Fuzzer, Hash) {
70   uint8_t A[] = {'a', 'b', 'c'};
71   fuzzer::Unit U(A, A + sizeof(A));
72   EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", fuzzer::Hash(U));
73   U.push_back('d');
74   EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U));
75 }
76
77 typedef size_t (*Mutator)(uint8_t *Data, size_t Size, size_t MaxSize,
78                           FuzzerRandomBase &Rand);
79
80 void TestEraseByte(Mutator M, int NumIter) {
81   uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
82   uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
83   uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};
84   uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
85   uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77};
86   uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77};
87   uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};
88   uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
89   FuzzerRandomLibc Rand(0);
90   int FoundMask = 0;
91   for (int i = 0; i < NumIter; i++) {
92     uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
93     size_t NewSize = Mutate_EraseByte(T, sizeof(T), sizeof(T), Rand);
94     EXPECT_EQ(7UL, NewSize);
95     if (!memcmp(REM0, T, 7)) FoundMask |= 1 << 0;
96     if (!memcmp(REM1, T, 7)) FoundMask |= 1 << 1;
97     if (!memcmp(REM2, T, 7)) FoundMask |= 1 << 2;
98     if (!memcmp(REM3, T, 7)) FoundMask |= 1 << 3;
99     if (!memcmp(REM4, T, 7)) FoundMask |= 1 << 4;
100     if (!memcmp(REM5, T, 7)) FoundMask |= 1 << 5;
101     if (!memcmp(REM6, T, 7)) FoundMask |= 1 << 6;
102     if (!memcmp(REM7, T, 7)) FoundMask |= 1 << 7;
103   }
104   EXPECT_EQ(FoundMask, 255);
105 }
106
107 TEST(FuzzerMutate, EraseByte1) { TestEraseByte(Mutate_EraseByte, 50); }
108 TEST(FuzzerMutate, EraseByte2) { TestEraseByte(Mutate, 100); }