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