Page MenuHomeFreeBSD

D49463.id152580.diff
No OneTemporary

D49463.id152580.diff

diff --git a/contrib/kyua/cli/cmd_debug.cpp b/contrib/kyua/cli/cmd_debug.cpp
--- a/contrib/kyua/cli/cmd_debug.cpp
+++ b/contrib/kyua/cli/cmd_debug.cpp
@@ -29,6 +29,7 @@
#include "cli/cmd_debug.hpp"
#include <cstdlib>
+#include <iostream>
#include "cli/common.ipp"
#include "drivers/debug_test.hpp"
@@ -38,13 +39,76 @@
#include "utils/cmdline/parser.ipp"
#include "utils/cmdline/ui.hpp"
#include "utils/format/macros.hpp"
+#include "utils/process/executor.hpp"
namespace cmdline = utils::cmdline;
namespace config = utils::config;
+namespace executor = utils::process::executor;
using cli::cmd_debug;
+namespace {
+
+
+const cmdline::bool_option pause_before_cleanup_option(
+ "pause-before-cleanup",
+ "Pauses right before the test cleanup");
+
+
+const cmdline::bool_option pause_before_cleanup_upon_fail_option(
+ 'p',
+ "pause-before-cleanup-upon-fail",
+ "Pauses right before the test cleanup upon fail");
+
+
+/// The debugger interface implementation.
+class dbg : public engine::debugger {
+ /// Object to interact with the I/O of the program.
+ cmdline::ui* _ui;
+
+ /// Representation of the command line to the subcommand.
+ const cmdline::parsed_cmdline& _cmdline;
+
+public:
+ /// Constructor.
+ ///
+ /// \param ui_ Object to interact with the I/O of the program.
+ /// \param cmdline Representation of the command line to the subcommand.
+ dbg(cmdline::ui* ui, const cmdline::parsed_cmdline& cmdline) :
+ _ui(ui), _cmdline(cmdline)
+ {}
+
+ void before_cleanup(
+ const model::test_program_ptr&,
+ const model::test_case&,
+ optional< model::test_result >& result,
+ executor::exit_handle& eh) const
+ {
+ if (_cmdline.has_option(pause_before_cleanup_upon_fail_option
+ .long_name())) {
+ if (result && !result.get().good()) {
+ _ui->out("The test failed and paused right before its cleanup "
+ "routine.");
+ _ui->out(F("Test work dir: %s") % eh.work_directory().str());
+ _ui->out("Press any key to continue...");
+ char _ = std::cin.get();
+ }
+ } else if (_cmdline.has_option(pause_before_cleanup_option
+ .long_name())) {
+ _ui->out("The test paused right before its cleanup routine.");
+ _ui->out(F("Test work dir: %s") % eh.work_directory().str());
+ _ui->out("Press any key to continue...");
+ char _ = std::cin.get();
+ }
+ };
+
+};
+
+
+} // anonymous namespace
+
+
/// Default constructor for cmd_debug.
cmd_debug::cmd_debug(void) : cli_command(
"debug", "test_case", 1, 1,
@@ -60,6 +124,9 @@
add_option(cmdline::path_option(
"stderr", "Where to direct the standard error of the test case",
"path", "/dev/stderr"));
+
+ add_option(pause_before_cleanup_option);
+ add_option(pause_before_cleanup_upon_fail_option);
}
@@ -82,7 +149,10 @@
const engine::test_filter filter = engine::test_filter::parse(
test_case_name);
+ auto debugger = std::shared_ptr< engine::debugger >(new dbg(ui, cmdline));
+
const drivers::debug_test::result result = drivers::debug_test::drive(
+ debugger,
kyuafile_path(cmdline), build_root_path(cmdline), filter, user_config,
cmdline.get_option< cmdline::path_option >("stdout"),
cmdline.get_option< cmdline::path_option >("stderr"));
diff --git a/contrib/kyua/doc/kyua-debug.1.in b/contrib/kyua/doc/kyua-debug.1.in
--- a/contrib/kyua/doc/kyua-debug.1.in
+++ b/contrib/kyua/doc/kyua-debug.1.in
@@ -37,6 +37,8 @@
.Op Fl -kyuafile Ar file
.Op Fl -stdout Ar path
.Op Fl -stderr Ar path
+.Op Fl -pause-before-cleanup
+.Op Fl -pause-before-cleanup-upon-fail
.Ar test_case
.Sh DESCRIPTION
The
@@ -98,6 +100,12 @@
.Pa /dev/stdout ,
which is a special character device that redirects the output to
standard output on the console.
+.It Fl -pause-before-cleanup
+Unconditionally pauses right before the test cleanup routine invocation.
+It works only with the test which declares a cleanup routine.
+.It Fl -pause-before-cleanup-upon-fail , Fl p
+Pauses right before the test cleanup routine invocation if the test fails.
+It works only with the test which declares a cleanup routine.
.El
.Pp
For example, consider the following Kyua session:
diff --git a/contrib/kyua/drivers/debug_test.hpp b/contrib/kyua/drivers/debug_test.hpp
--- a/contrib/kyua/drivers/debug_test.hpp
+++ b/contrib/kyua/drivers/debug_test.hpp
@@ -36,12 +36,15 @@
#if !defined(DRIVERS_DEBUG_TEST_HPP)
#define DRIVERS_DEBUG_TEST_HPP
+#include "engine/debugger.hpp"
#include "engine/filters.hpp"
#include "model/test_result.hpp"
#include "utils/config/tree_fwd.hpp"
#include "utils/fs/path_fwd.hpp"
#include "utils/optional_fwd.hpp"
+using engine::debugger;
+
namespace drivers {
namespace debug_test {
@@ -68,7 +71,8 @@
};
-result drive(const utils::fs::path&, const utils::optional< utils::fs::path >,
+result drive(std::shared_ptr< debugger >,
+ const utils::fs::path&, const utils::optional< utils::fs::path >,
const engine::test_filter&, const utils::config::tree&,
const utils::fs::path&, const utils::fs::path&);
diff --git a/contrib/kyua/drivers/debug_test.cpp b/contrib/kyua/drivers/debug_test.cpp
--- a/contrib/kyua/drivers/debug_test.cpp
+++ b/contrib/kyua/drivers/debug_test.cpp
@@ -63,7 +63,8 @@
///
/// \returns A structure with all results computed by this driver.
drivers::debug_test::result
-drivers::debug_test::drive(const fs::path& kyuafile_path,
+drivers::debug_test::drive(std::shared_ptr< debugger > debugger,
+ const fs::path& kyuafile_path,
const optional< fs::path > build_root,
const engine::test_filter& filter,
const config::tree& user_config,
@@ -92,6 +93,10 @@
const model::test_program_ptr test_program = match.get().first;
const std::string& test_case_name = match.get().second;
+ const model::test_case test_case = test_program->find(test_case_name);
+ if (debugger)
+ test_case.attach_debugger(debugger);
+
scheduler::result_handle_ptr result_handle = handle.debug_test(
test_program, test_case_name, user_config,
stdout_path, stderr_path);
diff --git a/contrib/kyua/drivers/debug_test.hpp b/contrib/kyua/engine/debugger.hpp
copy from contrib/kyua/drivers/debug_test.hpp
copy to contrib/kyua/engine/debugger.hpp
--- a/contrib/kyua/drivers/debug_test.hpp
+++ b/contrib/kyua/engine/debugger.hpp
@@ -1,4 +1,4 @@
-// Copyright 2011 The Kyua Authors.
+// Copyright 2025 The Kyua Authors.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -26,54 +26,42 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-/// \file drivers/debug_test.hpp
-/// Driver to run a single test in a controlled manner.
-///
-/// This driver module implements the logic to execute a particular test
-/// with hooks into the runtime procedure. This is to permit debugging the
-/// behavior of the test.
+/// \file engine/debugger.hpp
+/// The interface between the engine and the users outside.
-#if !defined(DRIVERS_DEBUG_TEST_HPP)
-#define DRIVERS_DEBUG_TEST_HPP
+#if !defined(ENGINE_DEBUGGER_HPP)
+#define ENGINE_DEBUGGER_HPP
-#include "engine/filters.hpp"
-#include "model/test_result.hpp"
-#include "utils/config/tree_fwd.hpp"
-#include "utils/fs/path_fwd.hpp"
+#include "model/test_case_fwd.hpp"
+#include "model/test_program_fwd.hpp"
+#include "model/test_result_fwd.hpp"
#include "utils/optional_fwd.hpp"
+#include "utils/process/executor_fwd.hpp"
-namespace drivers {
-namespace debug_test {
+namespace executor = utils::process::executor;
+using utils::optional;
-/// Tuple containing the results of this driver.
-class result {
-public:
- /// A filter matching the executed test case only.
- engine::test_filter test_case;
- /// The result of the test case.
- model::test_result test_result;
+namespace engine {
- /// Initializer for the tuple's fields.
- ///
- /// \param test_case_ The matched test case.
- /// \param test_result_ The result of the test case.
- result(const engine::test_filter& test_case_,
- const model::test_result& test_result_) :
- test_case(test_case_),
- test_result(test_result_)
- {
- }
-};
+/// Abstract debugger interface.
+class debugger {
+public:
+ debugger() {}
+ virtual ~debugger() {}
+
+ /// Called right before optional test cleanup.
+ virtual void before_cleanup(
+ const model::test_program_ptr&,
+ const model::test_case&,
+ optional< model::test_result >&,
+ executor::exit_handle&) const = 0;
+};
-result drive(const utils::fs::path&, const utils::optional< utils::fs::path >,
- const engine::test_filter&, const utils::config::tree&,
- const utils::fs::path&, const utils::fs::path&);
+} // namespace engine
-} // namespace debug_test
-} // namespace drivers
-#endif // !defined(DRIVERS_DEBUG_TEST_HPP)
+#endif // !defined(ENGINE_DEBUGGER_HPP)
diff --git a/contrib/kyua/engine/scheduler.cpp b/contrib/kyua/engine/scheduler.cpp
--- a/contrib/kyua/engine/scheduler.cpp
+++ b/contrib/kyua/engine/scheduler.cpp
@@ -39,6 +39,7 @@
#include <stdexcept>
#include "engine/config.hpp"
+#include "engine/debugger.hpp"
#include "engine/exceptions.hpp"
#include "engine/execenv/execenv.hpp"
#include "engine/requirements.hpp"
@@ -1398,6 +1399,13 @@
if (test_data->needs_cleanup) {
INV(test_case.get_metadata().has_cleanup());
+
+ std::shared_ptr< debugger > debugger = test_case.get_debugger();
+ if (debugger) {
+ debugger->before_cleanup(test_data->test_program, test_case,
+ result, handle);
+ }
+
// The test body has completed and we have processed it. If there
// is a cleanup routine, trigger it now and wait for any other test
// completion. The caller never knows about cleanup routines.
diff --git a/contrib/kyua/model/test_case.hpp b/contrib/kyua/model/test_case.hpp
--- a/contrib/kyua/model/test_case.hpp
+++ b/contrib/kyua/model/test_case.hpp
@@ -38,11 +38,14 @@
#include <ostream>
#include <string>
+#include "engine/debugger.hpp"
#include "model/metadata_fwd.hpp"
#include "model/test_result_fwd.hpp"
#include "utils/noncopyable.hpp"
#include "utils/optional_fwd.hpp"
+using engine::debugger;
+
namespace model {
@@ -71,6 +74,9 @@
const metadata& get_raw_metadata(void) const;
utils::optional< test_result > fake_result(void) const;
+ void attach_debugger(std::shared_ptr< debugger >) const;
+ std::shared_ptr< debugger > get_debugger() const;
+
bool operator==(const test_case&) const;
bool operator!=(const test_case&) const;
};
diff --git a/contrib/kyua/model/test_case.cpp b/contrib/kyua/model/test_case.cpp
--- a/contrib/kyua/model/test_case.cpp
+++ b/contrib/kyua/model/test_case.cpp
@@ -60,6 +60,9 @@
/// Fake result to return instead of running the test case.
optional< model::test_result > fake_result;
+ /// Optional pointer to a debugger attached.
+ std::shared_ptr< debugger > debugger;
+
/// Constructor.
///
/// \param name_ The name of the test case within the test program.
@@ -233,6 +236,24 @@
}
+/// Set pointer to a debugger interface implementation.
+void
+model::test_case::attach_debugger(std::shared_ptr< debugger > d) const
+{
+ _pimpl->debugger = d;
+}
+
+
+/// Gets the optional pointer to a debugger structure.
+///
+/// \return An optional pointer to a debugger structure.
+std::shared_ptr< debugger >
+model::test_case::get_debugger() const
+{
+ return _pimpl->debugger;
+}
+
+
/// Gets the fake result pre-stored for this test case.
///
/// \return A fake result, or none if not defined.

File Metadata

Mime Type
text/plain
Expires
Fri, Dec 12, 7:12 PM (11 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
26910004
Default Alt Text
D49463.id152580.diff (11 KB)

Event Timeline