Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F139412020
D49463.id152580.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
D49463.id152580.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D49463: kyua: Add "kyua debug -p" option
Attached
Detach File
Event Timeline
Log In to Comment