aboutsummaryrefslogtreecommitdiff
path: root/gdb/common
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/common')
-rw-r--r--gdb/common/selftest.c68
-rw-r--r--gdb/common/selftest.h26
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. */