diff options
Diffstat (limited to 'gdb/common')
-rw-r--r-- | gdb/common/selftest.c | 68 | ||||
-rw-r--r-- | gdb/common/selftest.h | 26 |
2 files changed, 80 insertions, 14 deletions
diff --git a/gdb/common/selftest.c b/gdb/common/selftest.c index 0fb8f2a..6518e58 100644 --- a/gdb/common/selftest.c +++ b/gdb/common/selftest.c @@ -20,35 +20,72 @@ #include "common-exceptions.h" #include "common-debug.h" #include "selftest.h" -#include <vector> +#include <map> namespace selftests { +/* All the tests that have been registered. Using an std::map allows keeping + the order of tests stable and easily looking up whether a test name + exists. */ -/* All the tests that have been registered. */ +static std::map<std::string, std::unique_ptr<selftest>> tests; -static std::vector<self_test_function *> tests; +/* A selftest that calls the test function without arguments. */ + +struct simple_selftest : public selftest +{ + simple_selftest (self_test_function *function_) + : function (function_) + {} + + void operator() () const override + { + function (); + } + + self_test_function *function; +}; /* See selftest.h. */ void -register_test (self_test_function *function) +register_test (const std::string &name, selftest *test) { - tests.push_back (function); + /* Check that no test with this name already exist. */ + gdb_assert (tests.find (name) == tests.end ()); + + tests[name] = std::unique_ptr<selftest> (test); } /* See selftest.h. */ void -run_tests (void) +register_test (const std::string &name, self_test_function *function) { - int failed = 0; + register_test (name, new simple_selftest (function)); +} + +/* See selftest.h. */ - for (int i = 0; i < tests.size (); ++i) +void +run_tests (const char *filter) +{ + int ran = 0, failed = 0; + + for (const auto &pair : tests) { + const std::string &name = pair.first; + const std::unique_ptr<selftest> &test = pair.second; + + if (filter != NULL && *filter != '\0' + && name.find (filter) == std::string::npos) + continue; + TRY { - tests[i] (); + debug_printf (_("Running selftest %s.\n"), name.c_str ()); + ++ran; + (*test) (); } CATCH (ex, RETURN_MASK_ERROR) { @@ -60,7 +97,16 @@ run_tests (void) reset (); } - debug_printf ("Ran %lu unit tests, %d failed\n", - (long) tests.size (), failed); + debug_printf (_("Ran %d unit tests, %d failed\n"), + ran, failed); } + +/* See selftest.h. */ + +void for_each_selftest (for_each_selftest_ftype func) +{ + for (const auto &pair : tests) + func (pair.first); +} + } // namespace selftests diff --git a/gdb/common/selftest.h b/gdb/common/selftest.h index e211c34..35a344f 100644 --- a/gdb/common/selftest.h +++ b/gdb/common/selftest.h @@ -27,18 +27,38 @@ typedef void self_test_function (void); namespace selftests { +/* Interface for the various kinds of selftests. */ + +struct selftest +{ + virtual void operator() () const = 0; +}; + /* Register a new self-test. */ -extern void register_test (self_test_function *function); +extern void register_test (const std::string &name, selftest *test); + +/* Register a new self-test. */ + +extern void register_test (const std::string &name, + self_test_function *function); /* Run all the self tests. This print a message describing the number - of test and the number of failures. */ + of test and the number of failures. + + If FILTER is not NULL and not empty, only tests with names containing FILTER + will be ran. */ -extern void run_tests (void); +extern void run_tests (const char *filter); /* Reset GDB or GDBserver's internal state. */ extern void reset (); +typedef void for_each_selftest_ftype (const std::string &name); + +/* Call FUNC for each registered selftest. */ + +extern void for_each_selftest (for_each_selftest_ftype func); } /* Check that VALUE is true, and, if not, throw an exception. */ |