xref: /netbsd-src/external/gpl3/gdb/dist/gdbsupport/selftest.cc (revision 5ba1f45f2a09259cc846f20c7c5501604d633c90)
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