18dffb485Schristos /* GDB self-testing. 2*5ba1f45fSchristos Copyright (C) 2016-2024 Free Software Foundation, Inc. 38dffb485Schristos 48dffb485Schristos This file is part of GDB. 58dffb485Schristos 68dffb485Schristos This program is free software; you can redistribute it and/or modify 78dffb485Schristos it under the terms of the GNU General Public License as published by 88dffb485Schristos the Free Software Foundation; either version 3 of the License, or 98dffb485Schristos (at your option) any later version. 108dffb485Schristos 118dffb485Schristos This program is distributed in the hope that it will be useful, 128dffb485Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 138dffb485Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 148dffb485Schristos GNU General Public License for more details. 158dffb485Schristos 168dffb485Schristos You should have received a copy of the GNU General Public License 178dffb485Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 188dffb485Schristos 198dffb485Schristos #include "common-exceptions.h" 208dffb485Schristos #include "common-debug.h" 218dffb485Schristos #include "selftest.h" 224b169a6bSchristos #include <functional> 238dffb485Schristos 248dffb485Schristos namespace selftests 258dffb485Schristos { 264b169a6bSchristos /* All the tests that have been registered. Using an std::set allows keeping 278dffb485Schristos the order of tests stable and easily looking up whether a test name 288dffb485Schristos exists. */ 298dffb485Schristos 304b169a6bSchristos static selftests_registry tests; 318dffb485Schristos 324b169a6bSchristos /* Set of callback functions used to register selftests after GDB is fully 334b169a6bSchristos initialized. */ 348dffb485Schristos 354b169a6bSchristos static std::vector<selftests_generator> lazy_generators; 368dffb485Schristos 378dffb485Schristos /* See selftest.h. */ 388dffb485Schristos 398dffb485Schristos void 404b169a6bSchristos register_test (const std::string &name, 414b169a6bSchristos std::function<void(void)> function) 428dffb485Schristos { 438dffb485Schristos /* Check that no test with this name already exist. */ 444b169a6bSchristos auto status = tests.emplace (name, std::move (function)); 454b169a6bSchristos if (!status.second) 464b169a6bSchristos gdb_assert_not_reached ("Test already registered"); 478dffb485Schristos } 488dffb485Schristos 498dffb485Schristos /* See selftest.h. */ 508dffb485Schristos 518dffb485Schristos void 524b169a6bSchristos add_lazy_generator (selftests_generator generator) 538dffb485Schristos { 544b169a6bSchristos lazy_generators.push_back (std::move (generator)); 554b169a6bSchristos } 564b169a6bSchristos 574b169a6bSchristos /* See selftest.h. */ 584b169a6bSchristos 594b169a6bSchristos static bool run_verbose_ = false; 604b169a6bSchristos 614b169a6bSchristos /* See selftest.h. */ 624b169a6bSchristos 634b169a6bSchristos bool 644b169a6bSchristos run_verbose () 654b169a6bSchristos { 664b169a6bSchristos return run_verbose_; 678dffb485Schristos } 688dffb485Schristos 698dffb485Schristos /* See selftest.h. */ 708dffb485Schristos 718dffb485Schristos void 724b169a6bSchristos run_tests (gdb::array_view<const char *const> filters, bool verbose) 738dffb485Schristos { 74*5ba1f45fSchristos int ran = 0; 754b169a6bSchristos run_verbose_ = verbose; 76*5ba1f45fSchristos std::vector<const char *> failed; 778dffb485Schristos 784b169a6bSchristos for (const auto &test : all_selftests ()) 798dffb485Schristos { 808dffb485Schristos bool run = false; 818dffb485Schristos 828dffb485Schristos if (filters.empty ()) 838dffb485Schristos run = true; 848dffb485Schristos else 858dffb485Schristos { 868dffb485Schristos for (const char *filter : filters) 878dffb485Schristos { 884b169a6bSchristos if (test.name.find (filter) != std::string::npos) 898dffb485Schristos run = true; 908dffb485Schristos } 918dffb485Schristos } 928dffb485Schristos 938dffb485Schristos if (!run) 948dffb485Schristos continue; 958dffb485Schristos 968dffb485Schristos try 978dffb485Schristos { 984b169a6bSchristos debug_printf (_("Running selftest %s.\n"), test.name.c_str ()); 998dffb485Schristos ++ran; 1004b169a6bSchristos test.test (); 1018dffb485Schristos } 1028dffb485Schristos catch (const gdb_exception_error &ex) 1038dffb485Schristos { 1048dffb485Schristos debug_printf ("Self test failed: %s\n", ex.what ()); 105*5ba1f45fSchristos failed.push_back (test.name.c_str ()); 1068dffb485Schristos } 1078dffb485Schristos 1088dffb485Schristos reset (); 1098dffb485Schristos } 1108dffb485Schristos 111*5ba1f45fSchristos if (!failed.empty ()) 112*5ba1f45fSchristos { 113*5ba1f45fSchristos debug_printf ("\nFailures:\n"); 114*5ba1f45fSchristos 115*5ba1f45fSchristos for (const char *name : failed) 116*5ba1f45fSchristos debug_printf (" %s\n", name); 117*5ba1f45fSchristos 118*5ba1f45fSchristos debug_printf ("\n"); 119*5ba1f45fSchristos } 120*5ba1f45fSchristos 121*5ba1f45fSchristos debug_printf (_("Ran %d unit tests, %zu failed\n"), 122*5ba1f45fSchristos ran, failed.size ()); 1238dffb485Schristos } 1248dffb485Schristos 1258dffb485Schristos /* See selftest.h. */ 1268dffb485Schristos 1274b169a6bSchristos selftests_range 1284b169a6bSchristos all_selftests () 1298dffb485Schristos { 1304b169a6bSchristos /* Execute any function which might still want to register tests. Once each 1314b169a6bSchristos function has been executed, clear lazy_generators to ensure that 1324b169a6bSchristos callback functions are only executed once. */ 1334b169a6bSchristos for (const auto &generator : lazy_generators) 1344b169a6bSchristos for (selftest &test : generator ()) 1354b169a6bSchristos register_test (std::move (test.name), std::move (test.test)); 1364b169a6bSchristos lazy_generators.clear (); 1374b169a6bSchristos 1384b169a6bSchristos return selftests_range (tests.cbegin (), tests.cend ()); 1398dffb485Schristos } 1408dffb485Schristos 1418dffb485Schristos } // namespace selftests 142