1 | // Copyright 2009 The RE2 Authors. All Rights Reserved. |
2 | // Use of this source code is governed by a BSD-style |
3 | // license that can be found in the LICENSE file. |
4 | |
5 | #ifndef RE2_TESTING_EXHAUSTIVE_TESTER_H_ |
6 | #define RE2_TESTING_EXHAUSTIVE_TESTER_H_ |
7 | |
8 | #include <stdint.h> |
9 | #include <string> |
10 | #include <vector> |
11 | |
12 | #include "util/util.h" |
13 | #include "re2/testing/regexp_generator.h" |
14 | #include "re2/testing/string_generator.h" |
15 | |
16 | namespace re2 { |
17 | |
18 | // Doing this simplifies the logic below. |
19 | #ifndef __has_feature |
20 | #define __has_feature(x) 0 |
21 | #endif |
22 | |
23 | #if !defined(NDEBUG) |
24 | // We are in a debug build. |
25 | const bool RE2_DEBUG_MODE = true; |
26 | #elif __has_feature(address_sanitizer) || __has_feature(memory_sanitizer) || __has_feature(thread_sanitizer) |
27 | // Not a debug build, but still under sanitizers. |
28 | const bool RE2_DEBUG_MODE = true; |
29 | #else |
30 | const bool RE2_DEBUG_MODE = false; |
31 | #endif |
32 | |
33 | // Exhaustive regular expression test: generate all regexps within parameters, |
34 | // then generate all strings of a given length over a given alphabet, |
35 | // then check that NFA, DFA, and PCRE agree about whether each regexp matches |
36 | // each possible string, and if so, where the match is. |
37 | // |
38 | // Can also be used in a "random" mode that generates a given number |
39 | // of random regexp and strings, allowing testing of larger expressions |
40 | // and inputs. |
41 | class ExhaustiveTester : public RegexpGenerator { |
42 | public: |
43 | ExhaustiveTester(int maxatoms, |
44 | int maxops, |
45 | const std::vector<std::string>& alphabet, |
46 | const std::vector<std::string>& ops, |
47 | int maxstrlen, |
48 | const std::vector<std::string>& stralphabet, |
49 | const std::string& wrapper, |
50 | const std::string& topwrapper) |
51 | : RegexpGenerator(maxatoms, maxops, alphabet, ops), |
52 | strgen_(maxstrlen, stralphabet), |
53 | wrapper_(wrapper), |
54 | topwrapper_(topwrapper), |
55 | regexps_(0), tests_(0), failures_(0), |
56 | randomstrings_(0), stringseed_(0), stringcount_(0) { } |
57 | |
58 | int regexps() { return regexps_; } |
59 | int tests() { return tests_; } |
60 | int failures() { return failures_; } |
61 | |
62 | // Needed for RegexpGenerator interface. |
63 | void HandleRegexp(const std::string& regexp); |
64 | |
65 | // Causes testing to generate random input strings. |
66 | void RandomStrings(int32_t seed, int32_t count) { |
67 | randomstrings_ = true; |
68 | stringseed_ = seed; |
69 | stringcount_ = count; |
70 | } |
71 | |
72 | private: |
73 | StringGenerator strgen_; |
74 | std::string wrapper_; // Regexp wrapper - either empty or has one %s. |
75 | std::string topwrapper_; // Regexp top-level wrapper. |
76 | int regexps_; // Number of HandleRegexp calls |
77 | int tests_; // Number of regexp tests. |
78 | int failures_; // Number of tests failed. |
79 | |
80 | bool randomstrings_; // Whether to use random strings |
81 | int32_t stringseed_; // If so, the seed. |
82 | int stringcount_; // If so, how many to generate. |
83 | |
84 | ExhaustiveTester(const ExhaustiveTester&) = delete; |
85 | ExhaustiveTester& operator=(const ExhaustiveTester&) = delete; |
86 | }; |
87 | |
88 | // Runs an exhaustive test on the given parameters. |
89 | void ExhaustiveTest(int maxatoms, int maxops, |
90 | const std::vector<std::string>& alphabet, |
91 | const std::vector<std::string>& ops, |
92 | int maxstrlen, |
93 | const std::vector<std::string>& stralphabet, |
94 | const std::string& wrapper, |
95 | const std::string& topwrapper); |
96 | |
97 | // Runs an exhaustive test using the given parameters and |
98 | // the basic egrep operators. |
99 | void EgrepTest(int maxatoms, int maxops, const std::string& alphabet, |
100 | int maxstrlen, const std::string& stralphabet, |
101 | const std::string& wrapper); |
102 | |
103 | } // namespace re2 |
104 | |
105 | #endif // RE2_TESTING_EXHAUSTIVE_TESTER_H_ |
106 | |