xref: /netbsd-src/external/gpl3/gdb/dist/gdbsupport/selftest.cc (revision 5ba1f45f2a09259cc846f20c7c5501604d633c90)
1 /* GDB self-testing.
2    Copyright (C) 2016-2024 Free Software Foundation, Inc.
3 
4    This file is part of GDB.
5 
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 3 of the License, or
9    (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
18 
19 #include "common-exceptions.h"
20 #include "common-debug.h"
21 #include "selftest.h"
22 #include <functional>
23 
24 namespace selftests
25 {
26 /* All the tests that have been registered.  Using an std::set allows keeping
27    the order of tests stable and easily looking up whether a test name
28    exists.  */
29 
30 static selftests_registry tests;
31 
32 /* Set of callback functions used to register selftests after GDB is fully
33    initialized.  */
34 
35 static std::vector<selftests_generator> lazy_generators;
36 
37 /* See selftest.h.  */
38 
39 void
40 register_test (const std::string &name,
41 	       std::function<void(void)> function)
42 {
43   /* Check that no test with this name already exist.  */
44   auto status = tests.emplace (name, std::move (function));
45   if (!status.second)
46     gdb_assert_not_reached ("Test already registered");
47 }
48 
49 /* See selftest.h.  */
50 
51 void
52 add_lazy_generator (selftests_generator generator)
53 {
54   lazy_generators.push_back (std::move (generator));
55 }
56 
57 /* See selftest.h.  */
58 
59 static bool run_verbose_ = false;
60 
61 /* See selftest.h.  */
62 
63 bool
64 run_verbose ()
65 {
66   return run_verbose_;
67 }
68 
69 /* See selftest.h.  */
70 
71 void
72 run_tests (gdb::array_view<const char *const> filters, bool verbose)
73 {
74   int ran = 0;
75   run_verbose_ = verbose;
76   std::vector<const char *> failed;
77 
78   for (const auto &test : all_selftests ())
79     {
80       bool run = false;
81 
82       if (filters.empty ())
83 	run = true;
84       else
85 	{
86 	  for (const char *filter : filters)
87 	    {
88 	      if (test.name.find (filter) != std::string::npos)
89 		run = true;
90 	    }
91 	}
92 
93       if (!run)
94 	continue;
95 
96       try
97 	{
98 	  debug_printf (_("Running selftest %s.\n"), test.name.c_str ());
99 	  ++ran;
100 	  test.test ();
101 	}
102       catch (const gdb_exception_error &ex)
103 	{
104 	  debug_printf ("Self test failed: %s\n", ex.what ());
105 	  failed.push_back (test.name.c_str ());
106 	}
107 
108       reset ();
109     }
110 
111   if (!failed.empty ())
112     {
113       debug_printf ("\nFailures:\n");
114 
115       for (const char *name : failed)
116 	debug_printf ("  %s\n", name);
117 
118       debug_printf ("\n");
119     }
120 
121   debug_printf (_("Ran %d unit tests, %zu failed\n"),
122 		ran, failed.size ());
123 }
124 
125 /* See selftest.h.  */
126 
127 selftests_range
128 all_selftests ()
129 {
130   /* Execute any function which might still want to register tests.  Once each
131      function has been executed, clear lazy_generators to ensure that
132      callback functions are only executed once.  */
133   for (const auto &generator : lazy_generators)
134     for (selftest &test : generator ())
135       register_test (std::move (test.name), std::move (test.test));
136   lazy_generators.clear ();
137 
138   return selftests_range (tests.cbegin (), tests.cend ());
139 }
140 
141 } // namespace selftests
142