Skip to content

Commit 4f0de28

Browse files
committed
A simple program for testing OSS-Fuzz test cases locally.
llvm-svn: 322863
1 parent 0a21930 commit 4f0de28

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

libcxx/fuzzing/fuzz_test.cpp

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// -*- C++ -*-
2+
//===------------------------- fuzz_test.cpp ------------------------------===//
3+
//
4+
// The LLVM Compiler Infrastructure
5+
//
6+
// This file is dual licensed under the MIT and the University of Illinois Open
7+
// Source Licenses. See LICENSE.TXT for details.
8+
//
9+
//===----------------------------------------------------------------------===//
10+
11+
// A simple program for running regressions on the fuzzing routines.
12+
// This code is not part of any shipping product.
13+
//
14+
// To build:
15+
// clang++ -std=c++11 fuzz_test.cpp fuzzing.cpp
16+
//
17+
// To use:
18+
// fuzz_test -r partial_sort [-v] files...
19+
//
20+
// Each file should contain a test case.
21+
22+
23+
#include <iostream>
24+
#include <fstream>
25+
#include <vector>
26+
#include <map>
27+
#include <chrono>
28+
29+
#include "fuzzing.h"
30+
31+
typedef int (*FuzzProc) (const uint8_t *data, size_t size);
32+
33+
const std::map<std::string, FuzzProc> procs = {
34+
{"sort", fuzzing::sort},
35+
{"stable_sort", fuzzing::stable_sort},
36+
{"partition", fuzzing::partition},
37+
{"partition_copy", fuzzing::partition_copy},
38+
{"stable_partition", fuzzing::stable_partition},
39+
{"unique", fuzzing::unique},
40+
{"unique_copy", fuzzing::unique_copy},
41+
{"nth_element", fuzzing::nth_element},
42+
{"partial_sort", fuzzing::partial_sort},
43+
{"partial_sort_copy", fuzzing::partial_sort_copy},
44+
{"make_heap", fuzzing::make_heap},
45+
{"push_heap", fuzzing::push_heap},
46+
{"pop_heap", fuzzing::pop_heap},
47+
{"regex_ECMAScript", fuzzing::regex_ECMAScript},
48+
{"regex_POSIX", fuzzing::regex_POSIX},
49+
{"regex_extended", fuzzing::regex_extended},
50+
{"regex_awk", fuzzing::regex_awk},
51+
{"regex_grep", fuzzing::regex_grep},
52+
{"regex_egrep", fuzzing::regex_egrep},
53+
{"search", fuzzing::search}
54+
};
55+
56+
57+
58+
bool verbose = false;
59+
60+
void test_one(const char *filename, FuzzProc fp)
61+
{
62+
std::vector<uint8_t> v;
63+
std::ifstream f (filename, std::ios::binary);
64+
if (!f.is_open())
65+
std::cerr << "## Can't open '" << filename << "'" << std::endl;
66+
else {
67+
typedef std::istream_iterator<uint8_t> Iter;
68+
std::copy(Iter(f), Iter(), std::back_inserter(v));
69+
if (verbose)
70+
std::cout << "File '" << filename << "' contains " << v.size() << " entries" << std::endl;
71+
const auto start_time = std::chrono::steady_clock::now();
72+
int ret = fp (v.data(), v.size());
73+
const auto finish_time = std::chrono::steady_clock::now();
74+
if (ret != 0)
75+
std::cerr << "## Failure code: " << ret << std::endl;
76+
if (verbose)
77+
std::cout << "Execution time: "
78+
<< std::chrono::duration_cast<std::chrono::milliseconds>(finish_time - start_time).count()
79+
<< " milliseconds" << std::endl;
80+
}
81+
}
82+
83+
void usage (const char *name)
84+
{
85+
std::cout << "Usage: " << name << " -r proc [-v] files..." << std::endl;
86+
std::cout << "Supported routines:" << std::endl;
87+
for (const auto &p : procs)
88+
std::cout << " " << p.first << std::endl;
89+
std::cout << std::endl;
90+
}
91+
92+
// Poor man's command-line options
93+
const std::string dashR("-r");
94+
const std::string dashV("-v");
95+
96+
int main(int argc, char *argv[])
97+
{
98+
if (argc < 4 || dashR != argv[1] || procs.find(argv[2]) == procs.end())
99+
usage(argv[0]);
100+
else {
101+
FuzzProc fp = procs.find(argv[2])->second;
102+
int firstFile = 3;
103+
if (dashV == argv[firstFile])
104+
{
105+
verbose = true;
106+
++firstFile;
107+
}
108+
for (int i = firstFile; i < argc; ++i)
109+
test_one(argv[i], fp);
110+
}
111+
}

0 commit comments

Comments
 (0)