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