blob: 06fc5f0a26ca2bdf0a5c4d0d4fbc386c3db826e4 [file] [log] [blame]
Marshall Clowad7b0962018-01-18 16:52:19 +00001// -*- 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>
Marshall Clow226431c2018-01-18 17:01:34 +000025#include <iterator>
Marshall Clowad7b0962018-01-18 16:52:19 +000026#include <vector>
27#include <map>
28#include <chrono>
29
30#include "fuzzing.h"
31
32typedef int (*FuzzProc) (const uint8_t *data, size_t size);
33
34const std::map<std::string, FuzzProc> procs = {
35 {"sort", fuzzing::sort},
36 {"stable_sort", fuzzing::stable_sort},
37 {"partition", fuzzing::partition},
38 {"partition_copy", fuzzing::partition_copy},
39 {"stable_partition", fuzzing::stable_partition},
40 {"unique", fuzzing::unique},
41 {"unique_copy", fuzzing::unique_copy},
42 {"nth_element", fuzzing::nth_element},
43 {"partial_sort", fuzzing::partial_sort},
44 {"partial_sort_copy", fuzzing::partial_sort_copy},
45 {"make_heap", fuzzing::make_heap},
46 {"push_heap", fuzzing::push_heap},
47 {"pop_heap", fuzzing::pop_heap},
48 {"regex_ECMAScript", fuzzing::regex_ECMAScript},
49 {"regex_POSIX", fuzzing::regex_POSIX},
50 {"regex_extended", fuzzing::regex_extended},
51 {"regex_awk", fuzzing::regex_awk},
52 {"regex_grep", fuzzing::regex_grep},
53 {"regex_egrep", fuzzing::regex_egrep},
54 {"search", fuzzing::search}
55};
56
57
58
59bool verbose = false;
60
61void test_one(const char *filename, FuzzProc fp)
62{
63 std::vector<uint8_t> v;
64 std::ifstream f (filename, std::ios::binary);
65 if (!f.is_open())
66 std::cerr << "## Can't open '" << filename << "'" << std::endl;
67 else {
68 typedef std::istream_iterator<uint8_t> Iter;
69 std::copy(Iter(f), Iter(), std::back_inserter(v));
70 if (verbose)
71 std::cout << "File '" << filename << "' contains " << v.size() << " entries" << std::endl;
Marshall Clow226431c2018-01-18 17:01:34 +000072 const auto start_time = std::chrono::high_resolution_clock::now();
Marshall Clowad7b0962018-01-18 16:52:19 +000073 int ret = fp (v.data(), v.size());
Marshall Clow226431c2018-01-18 17:01:34 +000074 const auto finish_time = std::chrono::high_resolution_clock::now();
Marshall Clowad7b0962018-01-18 16:52:19 +000075 if (ret != 0)
76 std::cerr << "## Failure code: " << ret << std::endl;
77 if (verbose)
78 std::cout << "Execution time: "
79 << std::chrono::duration_cast<std::chrono::milliseconds>(finish_time - start_time).count()
80 << " milliseconds" << std::endl;
81 }
82}
83
84void usage (const char *name)
85{
86 std::cout << "Usage: " << name << " -r proc [-v] files..." << std::endl;
87 std::cout << "Supported routines:" << std::endl;
88 for (const auto &p : procs)
89 std::cout << " " << p.first << std::endl;
90 std::cout << std::endl;
91}
92
93// Poor man's command-line options
94const std::string dashR("-r");
95const std::string dashV("-v");
96
97int main(int argc, char *argv[])
98{
99 if (argc < 4 || dashR != argv[1] || procs.find(argv[2]) == procs.end())
100 usage(argv[0]);
101 else {
102 FuzzProc fp = procs.find(argv[2])->second;
103 int firstFile = 3;
104 if (dashV == argv[firstFile])
105 {
106 verbose = true;
107 ++firstFile;
108 }
109 for (int i = firstFile; i < argc; ++i)
110 test_one(argv[i], fp);
111 }
112}