From nobody Sun Aug 23 23:57:42 2026 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4hSrZb0YMyz6pxyn for ; Sun, 23 Aug 2026 23:57:43 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hSrZb05n0z3qk9 for ; Sun, 23 Aug 2026 23:57:43 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1787529463; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=pud+cZX9GEOPcaLlDU8AbncMN3GBLiKtDp8+yaMfAiw=; b=j86Zoe94GiSFRqTvLKLOaeekXkBJbzWXiukCtbkS7ZVmOJ7tngpy78na8I6tDeyMSv+X5k lG8+N6tmM4LSPe+FaZFvLT5jKCqcvUkXtJuh4c6M0G944Y+HQszmKS03ltchiXtzD6w7ph M4OjkGcswQcjBs5e7P5A10Cod1p7WG4/7zzAAFHj5HDbZeQJUkFndi44Y/MuAJBQBYCzSV DoV7daD9KKJ/YXYflRlbzAaSoI27NIik6YjGjFYNqzSgj9jerviAj2sLxIHOKrzfn05Ao6 eVoF1pYJ+ksMNmYEJ8A/Czio1cGlshfmBNT0efXkgjkCViAX28q88cAfz1iGNg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1787529463; a=rsa-sha256; cv=none; b=x32ynrbpMvcGnMdFFYAzL8bY5a58bmogX1B1XgToTOMg+dMOQnEEivO/LySvLRrShasVW2 sUm3KERUsBNH9fhM1A8QNN2bC+/BLXIey5EDnO2Y0wYtXSJGRXFB0ecqFagnGcGiVEgtXF BXq4tDkqBRcRneTaa+Zkz9fhWUFa9Wh2BF7s6ca4tfzk2Jjtj9pngXRrF9ITpzE6tBcQrg Ca0/MA0rWykNcz7lL67VDfGmXZMV53Vk2vre4Nf+edzah8pOKwqQGvcw4tdtFqLZaX/3Y9 NwJwkJIWyJihJSdZapJt24fUT5vgbf12/Z1JVHPlt6xkBcZ59KPlu3aiw7cmyw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1787529463; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=pud+cZX9GEOPcaLlDU8AbncMN3GBLiKtDp8+yaMfAiw=; b=LXB5jTUoJ2E1ynwM9Jfiix35XE8VKAcFgKhFl2BUyS3VGLJm6nEToDBGIFM8EEsN11xWvg K7LNUBrqP3zqvxK+UWfat+0pth56KdvIekXP1JnRAqVOUV5AQp+KIj0tc2kJ3yLexvgvVw DKkPDe9O56K0yxylt+NfgQRxwTVolR6mBHfbN4z5fcL5GFt01/z5qL7lvVFKhUNqhMu1nm y8/9EUNmFAEgz0ojwdz4nZ21lAasararRcUDtfZ6cPeAbtaNyMJsfepQ5pn/az4xiCatUw BJjWO6hEXzReVjZpM7FCfU0ZuvtR8jT3IRmQaH9S0yrJZGIDHPABR+GUoON7wg== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hSrZZ5jDNzgZJ for ; Sun, 23 Aug 2026 23:57:42 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 22969 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Sun, 23 Aug 2026 23:57:42 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Igor Ostapenko Subject: git: edb230c4af49 - main - kyua: Add "prepare" command List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: igoro X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: edb230c4af499203d7a6894b3711fe6574b26040 Auto-Submitted: auto-generated Date: Sun, 23 Aug 2026 23:57:42 +0000 Message-Id: <6a8b88f6.22969.20896d44@gitrepo.freebsd.org> The branch main has been updated by igoro: URL: https://cgit.FreeBSD.org/src/commit/?id=edb230c4af499203d7a6894b3711fe6574b26040 commit edb230c4af499203d7a6894b3711fe6574b26040 Author: Igor Ostapenko AuthorDate: 2026-08-23 22:42:48 +0000 Commit: Igor Ostapenko CommitDate: 2026-08-23 22:54:14 +0000 kyua: Add "prepare" command This introduces the requirement preparation handler concept, with the first handler implemented to load the required kernel modules. Running without arguments lists all available handlers: kyua prepare Currently there are only two handlers: all: runs all available handlers kmods: loads the modules declared by required_kmods metadata The dry run option lists the required modules without actual loading: kyua prepare { --dry-run | -n } kmods The "prepare" command traverses only the given tree of tests, i.e., the following invocation lists all required modules for the whole test suite: kyua prepare -k /usr/tests/Kyuafile -n kmods , while this one is limited to the pf tests only: kyua prepare -k /usr/tests/sys/netpfil/pf/Kyuafile -n kmods Reviewed by: ngie Differential Revision: https://reviews.freebsd.org/D48087 --- contrib/kyua/cli/cmd_prepare.cpp | 76 +++++++++++++++ contrib/kyua/cli/cmd_prepare.hpp | 53 +++++++++++ contrib/kyua/cli/main.cpp | 2 + contrib/kyua/doc/kyuafile.5.in | 1 + contrib/kyua/engine/prepare/prepare.cpp | 83 ++++++++++++++++ contrib/kyua/engine/prepare/prepare.hpp | 107 +++++++++++++++++++++ contrib/kyua/engine/prepare/prepare_all.cpp | 66 +++++++++++++ contrib/kyua/engine/prepare/prepare_all.hpp | 53 +++++++++++ contrib/kyua/model/metadata.cpp | 47 +++++---- contrib/kyua/model/metadata.hpp | 4 +- contrib/kyua/os/freebsd/main.cpp | 8 ++ contrib/kyua/os/freebsd/prepare_kmods.cpp | 143 ++++++++++++++++++++++++++++ contrib/kyua/os/freebsd/prepare_kmods.hpp | 55 +++++++++++ usr.bin/kyua/Makefile | 8 +- 14 files changed, 686 insertions(+), 20 deletions(-) diff --git a/contrib/kyua/cli/cmd_prepare.cpp b/contrib/kyua/cli/cmd_prepare.cpp new file mode 100644 index 000000000000..a3ba5c3285a1 --- /dev/null +++ b/contrib/kyua/cli/cmd_prepare.cpp @@ -0,0 +1,76 @@ +// Copyright 2024 The Kyua Authors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "cli/cmd_prepare.hpp" + +#include "cli/common.ipp" +#include "engine/prepare/prepare.hpp" +#include "utils/cmdline/options.hpp" + +namespace cmdline = utils::cmdline; +namespace config = utils::config; +namespace prepare = engine::prepare; + +using cli::cmd_prepare; + + +/// Default constructor for cmd_prepare. +cmd_prepare::cmd_prepare(void) : cli_command( + "prepare", "[handler-name ...]", 0, -1, + "Prepares environment and declared requirements before testing") +{ + add_option(kyuafile_option); + add_option(build_root_option); + add_option(cmdline::bool_option('n', "dry-run", "Do not alter the system")); +} + + +/// Entry point for the "prepare" subcommand. +/// +/// \param ui Object to interact with the I/O of the program. +/// \param cmdline Representation of the command line to the subcommand. +/// \param user_config The runtime configuration of the program. +/// +/// \return 0 if successful, 1 otherwise. +int +cmd_prepare::run(cmdline::ui* ui, const cmdline::parsed_cmdline& cmdline, + const config::tree& user_config) +{ + // List available preparation handlers + if (cmdline.arguments().empty()) { + for (auto& h : prepare::handlers()) { + ui->out(h->name(), false); + ui->out("\t\t\t", false); + ui->out(h->description()); + } + return EXIT_SUCCESS; + } + + // Or run the given ones + return prepare::run(cmdline.arguments(), ui, cmdline, user_config); +} diff --git a/contrib/kyua/cli/cmd_prepare.hpp b/contrib/kyua/cli/cmd_prepare.hpp new file mode 100644 index 000000000000..322b2baf9e8f --- /dev/null +++ b/contrib/kyua/cli/cmd_prepare.hpp @@ -0,0 +1,53 @@ +// Copyright 2024 The Kyua Authors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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 cli/cmd_prepare.hpp +/// Provides the cmd_prepare class. + +#if !defined(CLI_CMD_PREPARE_HPP) +#define CLI_CMD_PREPARE_HPP + +#include "cli/common.hpp" + +namespace cli { + + +/// Implementation of the "prepare" subcommand. +class cmd_prepare : public cli_command +{ +public: + cmd_prepare(void); + + int run(utils::cmdline::ui*, const utils::cmdline::parsed_cmdline&, + const utils::config::tree&); +}; + + +} // namespace cli + +#endif // !defined(CLI_CMD_PREPARE_HPP) diff --git a/contrib/kyua/cli/main.cpp b/contrib/kyua/cli/main.cpp index dd7ce939e162..ad679f0949b3 100644 --- a/contrib/kyua/cli/main.cpp +++ b/contrib/kyua/cli/main.cpp @@ -49,6 +49,7 @@ extern "C" { #include "cli/cmd_debug.hpp" #include "cli/cmd_help.hpp" #include "cli/cmd_list.hpp" +#include "cli/cmd_prepare.hpp" #include "cli/cmd_report.hpp" #include "cli/cmd_report_html.hpp" #include "cli/cmd_report_junit.hpp" @@ -191,6 +192,7 @@ safe_main(cmdline::ui* ui, int argc, const char* const argv[], commands.insert(new cli::cmd_debug(), "Workspace"); commands.insert(new cli::cmd_list(), "Workspace"); + commands.insert(new cli::cmd_prepare(), "Workspace"); commands.insert(new cli::cmd_test(), "Workspace"); commands.insert(new cli::cmd_report(), "Reporting"); diff --git a/contrib/kyua/doc/kyuafile.5.in b/contrib/kyua/doc/kyuafile.5.in index a9106e95d790..eddb8f92cb86 100644 --- a/contrib/kyua/doc/kyuafile.5.in +++ b/contrib/kyua/doc/kyuafile.5.in @@ -300,6 +300,7 @@ Supported platforms: .Pp ATF: .Va require.kmods +(appends to the list declared at the Kyuafile level instead of overwriting it) .It Va required_memory Amount of physical memory that the test needs to run successfully. .Pp diff --git a/contrib/kyua/engine/prepare/prepare.cpp b/contrib/kyua/engine/prepare/prepare.cpp new file mode 100644 index 000000000000..218b236450c0 --- /dev/null +++ b/contrib/kyua/engine/prepare/prepare.cpp @@ -0,0 +1,83 @@ +// Copyright 2024 The Kyua Authors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "engine/prepare/prepare.hpp" + +#include "engine/prepare/prepare_all.hpp" + +namespace prepare = engine::prepare; + + +/// List of registered requirement preparation handlers. +/// +/// Use register_handler() to add an entry to this global list. +static std::vector< std::shared_ptr< prepare::handler > > _handlers = { + std::shared_ptr< prepare::handler >(new prepare::prepare_all()) +}; + + +void +prepare::register_handler(const std::shared_ptr< handler > handler) +{ + _handlers.push_back(handler); +} + + +const std::vector< std::shared_ptr< prepare::handler > > +prepare::handlers() +{ + return _handlers; +} + + +int +prepare::run(const std::vector< std::string >& handler_names, + cmdline::ui* ui, + const cmdline::parsed_cmdline& cmdline, + const config::tree& user_config) +{ + for (auto& hname : handler_names) { + std::shared_ptr< prepare::handler > handler = nullptr; + for (auto& h : prepare::handlers()) + if (h->name() == hname) { + handler = h; + break; + } + + if (handler == nullptr) { + ui->out(F("Unknown requirement preparation handler: %s") % hname); + return EXIT_FAILURE; + } + + if (handler->exec(ui, cmdline, user_config) != 0) + // suppress the actual code -- main limits possible exit codes + return EXIT_FAILURE; + } + + return EXIT_SUCCESS; +} diff --git a/contrib/kyua/engine/prepare/prepare.hpp b/contrib/kyua/engine/prepare/prepare.hpp new file mode 100644 index 000000000000..2ee12b11a623 --- /dev/null +++ b/contrib/kyua/engine/prepare/prepare.hpp @@ -0,0 +1,107 @@ +// Copyright 2024 The Kyua Authors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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 engine/prepare/prepare.hpp +/// Requirement preparation subsystem interface. + +#if !defined(ENGINE_PREPARE_HPP) +#define ENGINE_PREPARE_HPP + +#include +#include + +#include "utils/cmdline/parser.ipp" +#include "utils/cmdline/ui.hpp" +#include "utils/config/tree.ipp" + +namespace cmdline = utils::cmdline; +namespace config = utils::config; + + +namespace engine { +namespace prepare { + + +/// Abstract interface of a requirement preparation handler. +class handler { +public: + /// Constructor. + handler() {} + + /// Destructor. + virtual ~handler() {} + + /// Returns name of the handler. + virtual const std::string& name() const = 0; + + /// Returns short description of the handler. + virtual const std::string& description() const = 0; + + /// Runs the requirement preparation handler. + /// + /// \param ui Object to interact with the I/O of the program. + /// \param cmdline Representation of the command line to the subcommand. + /// \param user_config The runtime configuration of the program. + /// + /// \return 0 to indicate success. + virtual int exec(cmdline::ui* ui, + const cmdline::parsed_cmdline& cmdline, + const config::tree& user_config) const = 0; +}; + + +/// Registers a requirement preparation handler. +/// +/// \param handler A requirement preparation handler. +void register_handler(const std::shared_ptr< handler > handler); + + +/// Returns the list of registered requirement preparation handlers. +/// +/// \return A vector of pointers to requirement preparation handlers. +const std::vector< std::shared_ptr< handler > > handlers(); + + +/// Run named handlers. +/// +/// \param handler_names Names of the handlers to run. +/// \param ui Object to interact with the I/O of the program. +/// \param cmdline Representation of the command line to the subcommand. +/// \param user_config The runtime configuration of the program. +/// +/// \return 0 to indicate success. +int run(const std::vector< std::string >& handler_names, + cmdline::ui* ui, + const cmdline::parsed_cmdline& cmdline, + const config::tree& user_config); + + +} // namespace prepare +} // namespace engine + +#endif // !defined(ENGINE_PREPARE_HPP) diff --git a/contrib/kyua/engine/prepare/prepare_all.cpp b/contrib/kyua/engine/prepare/prepare_all.cpp new file mode 100644 index 000000000000..db8ea330a51e --- /dev/null +++ b/contrib/kyua/engine/prepare/prepare_all.cpp @@ -0,0 +1,66 @@ +// Copyright 2024 The Kyua Authors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "engine/prepare/prepare_all.hpp" + +static const std::string _name = "all"; +static const std::string _description = "Run all preparations"; + +namespace prepare = engine::prepare; + + +const std::string& +prepare::prepare_all::name() const +{ + return _name; +} + + +const std::string& +prepare::prepare_all::description() const +{ + return _description; +} + + +int +prepare::prepare_all::exec(cmdline::ui* ui, + const cmdline::parsed_cmdline& cmdline, + const config::tree& user_config) const +{ + for (auto& handler : prepare::handlers()) { + if (handler->name() == this->name()) + continue; + + int error = handler->exec(ui, cmdline, user_config); + if (error != EXIT_SUCCESS) + return error; + } + + return EXIT_SUCCESS; +} diff --git a/contrib/kyua/engine/prepare/prepare_all.hpp b/contrib/kyua/engine/prepare/prepare_all.hpp new file mode 100644 index 000000000000..7c5c54fe269c --- /dev/null +++ b/contrib/kyua/engine/prepare/prepare_all.hpp @@ -0,0 +1,53 @@ +// Copyright 2024 The Kyua Authors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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 engine/prepare/prepare_all.hpp +/// The requirement preparation handler which runs all registered handlers. + +#if !defined(ENGINE_PREPARE_ALL_HPP) +#define ENGINE_PREPARE_ALL_HPP + +#include "engine/prepare/prepare.hpp" + +namespace engine { +namespace prepare { + + +class prepare_all : public prepare::handler { +public: + const std::string& name() const; + const std::string& description() const; + int exec(cmdline::ui*, const cmdline::parsed_cmdline&, + const config::tree&) const; +}; + + +} // namespace prepare +} // namespace engine + +#endif // !defined(ENGINE_PREPARE_ALL_HPP) diff --git a/contrib/kyua/model/metadata.cpp b/contrib/kyua/model/metadata.cpp index afb31435a238..708a01667bbb 100644 --- a/contrib/kyua/model/metadata.cpp +++ b/contrib/kyua/model/metadata.cpp @@ -255,8 +255,8 @@ init_tree(config::tree& tree) tree.define< config::strings_set_node >("required_configs"); tree.define< bytes_node >("required_disk_space"); tree.define< paths_set_node >("required_files"); - tree.define< bytes_node >("required_memory"); tree.define< config::strings_set_node >("required_kmods"); + tree.define< bytes_node >("required_memory"); tree.define< paths_set_node >("required_programs"); tree.define< user_node >("required_user"); tree.define< delta_node >("timeout"); @@ -282,8 +282,8 @@ set_defaults(config::tree& tree) model::strings_set()); tree.set< bytes_node >("required_disk_space", units::bytes(0)); tree.set< paths_set_node >("required_files", model::paths_set()); - tree.set< bytes_node >("required_memory", units::bytes(0)); tree.set< config::strings_set_node >("required_kmods", model::strings_set()); + tree.set< bytes_node >("required_memory", units::bytes(0)); tree.set< paths_set_node >("required_programs", model::paths_set()); tree.set< user_node >("required_user", ""); // TODO(jmmv): We shouldn't be setting a default timeout like this. See @@ -585,20 +585,6 @@ model::metadata::required_files(void) const } -/// Returns the amount of memory required by the test. -/// -/// \return Number of bytes, or 0 if this does not apply. -const units::bytes& -model::metadata::required_memory(void) const -{ - if (_pimpl->props.is_set("required_memory")) { - return _pimpl->props.lookup< bytes_node >("required_memory"); - } else { - return get_defaults().lookup< bytes_node >("required_memory"); - } -} - - /// Returns the list of kernel modules needed by the test. /// /// \return Set of kernel module names. @@ -615,6 +601,20 @@ model::metadata::required_kmods(void) const } +/// Returns the amount of memory required by the test. +/// +/// \return Number of bytes, or 0 if this does not apply. +const units::bytes& +model::metadata::required_memory(void) const +{ + if (_pimpl->props.is_set("required_memory")) { + return _pimpl->props.lookup< bytes_node >("required_memory"); + } else { + return get_defaults().lookup< bytes_node >("required_memory"); + } +} + + /// Returns the list of programs needed by the test. /// /// \return Set of paths. @@ -1059,6 +1059,21 @@ model::metadata_builder::set_required_files(const model::paths_set& files) } +/// Sets the list of required kernel modules. +/// +/// \param vars Set of kernel module names. +/// +/// \return A reference to this builder. +/// +/// \throw model::error If the value is invalid. +model::metadata_builder& +model::metadata_builder::set_required_kmods(const model::strings_set& kmods) +{ + set< config::strings_set_node >(_pimpl->props, "required_kmods", kmods); + return *this; +} + + /// Sets the amount of memory required by the test. /// /// \param bytes Number of bytes. diff --git a/contrib/kyua/model/metadata.hpp b/contrib/kyua/model/metadata.hpp index eee7eaf0f7c4..d915677eb41d 100644 --- a/contrib/kyua/model/metadata.hpp +++ b/contrib/kyua/model/metadata.hpp @@ -75,8 +75,8 @@ public: const strings_set& required_configs(void) const; const utils::units::bytes& required_disk_space(void) const; const paths_set& required_files(void) const; - const utils::units::bytes& required_memory(void) const; const strings_set& required_kmods(void) const; + const utils::units::bytes& required_memory(void) const; const paths_set& required_programs(void) const; const std::string& required_user(void) const; const utils::datetime::delta& timeout(void) const; @@ -121,8 +121,8 @@ public: metadata_builder& set_required_configs(const strings_set&); metadata_builder& set_required_disk_space(const utils::units::bytes&); metadata_builder& set_required_files(const paths_set&); - metadata_builder& set_required_memory(const utils::units::bytes&); metadata_builder& set_required_kmods(const strings_set&); + metadata_builder& set_required_memory(const utils::units::bytes&); metadata_builder& set_required_programs(const paths_set&); metadata_builder& set_required_user(const std::string&); metadata_builder& set_string(const std::string&, const std::string&); diff --git a/contrib/kyua/os/freebsd/main.cpp b/contrib/kyua/os/freebsd/main.cpp index 700284b64b78..30f1a3fa7142 100644 --- a/contrib/kyua/os/freebsd/main.cpp +++ b/contrib/kyua/os/freebsd/main.cpp @@ -34,7 +34,12 @@ #include "engine/requirements.hpp" #include "os/freebsd/reqs_checker_kmods.hpp" +#include "engine/prepare/prepare.hpp" +#include "os/freebsd/prepare_kmods.hpp" + namespace execenv = engine::execenv; +namespace prepare = engine::prepare; + /// FreeBSD related features initialization. /// @@ -59,6 +64,9 @@ freebsd::main(const int, const char* const* const) new freebsd::reqs_checker_kmods() ) ); + + prepare::register_handler( + std::shared_ptr< prepare::handler >(new freebsd::prepare_kmods())); #endif return 0; diff --git a/contrib/kyua/os/freebsd/prepare_kmods.cpp b/contrib/kyua/os/freebsd/prepare_kmods.cpp new file mode 100644 index 000000000000..91771f3aedfd --- /dev/null +++ b/contrib/kyua/os/freebsd/prepare_kmods.cpp @@ -0,0 +1,143 @@ +// Copyright 2024 The Kyua Authors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "os/freebsd/prepare_kmods.hpp" + +#include "cli/common.hpp" +#include "drivers/list_tests.hpp" +#include "engine/filters.hpp" +#include "model/metadata.hpp" +#include "model/test_case.hpp" +#include "model/test_program.hpp" + +#include + +// FreeBSD kldload syscall +extern "C" { +#include +#include +} + + +namespace { + + +static const std::string _name = "kmods"; +static const std::string _description = "FreeBSD: load modules specified " + "in the required_kmods metadata"; + + +/// Hooks for list_tests to examine test cases as they come. +class list_hooks : public drivers::list_tests::base_hooks { + /// Collected names of required kernel modules. + std::set< std::string >& _modules; + +public: + /// Initializes the hooks. + /// + /// \param modules_ The set of modules to fill. + list_hooks(std::set< std::string >& modules_) : + _modules(modules_) + { + } + + /// Examine a test case as soon as it is found. + /// + /// \param test_program The test program containing the test case. + /// \param test_case_name The name of the located test case. + void + got_test_case(const model::test_program& test_program, + const std::string& test_case_name) + { + auto test_case = test_program.find(test_case_name); + auto kmods = test_case.get_metadata().required_kmods(); + _modules.insert(kmods.begin(), kmods.end()); + } +}; + + +} // anonymous namespace + + +namespace freebsd { + + +const std::string& +prepare_kmods::name() const +{ + return _name; +} + + +const std::string& +prepare_kmods::description() const +{ + return _description; +} + + +int +prepare_kmods::exec(cmdline::ui* ui, const cmdline::parsed_cmdline& cmdline, + const config::tree& user_config) const +{ + int err = 0; + + // Collect required modules + std::set< std::string > modules; + list_hooks hooks(modules); + const std::set< engine::test_filter > nofilters; + const drivers::list_tests::result result = drivers::list_tests::drive( + cli::kyuafile_path(cmdline), cli::build_root_path(cmdline), + nofilters, user_config, hooks); + + // Nothing to do + if (modules.empty()) + return 0; + + // Announce the work + ui->out("kldload", false); + for (auto& m : modules) + ui->out(F(" %s") % m, false); + ui->out(""); + + if (cmdline.has_option("dry-run")) + return 0; + + // Load the modules + for (auto& m : modules) { + if (::kldload(m.c_str()) != -1 || errno == EEXIST) + continue; + ui->out(F("WARN: cannot kldload %s") % m); + err = EINVAL; + } + + return err; +} + + +} // namespace freebsd diff --git a/contrib/kyua/os/freebsd/prepare_kmods.hpp b/contrib/kyua/os/freebsd/prepare_kmods.hpp new file mode 100644 index 000000000000..36a3236a4e2d --- /dev/null +++ b/contrib/kyua/os/freebsd/prepare_kmods.hpp @@ -0,0 +1,55 @@ +// Copyright 2024 The Kyua Authors. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of Google Inc. nor the names of its contributors +// may be used to endorse or promote products derived from this software +// without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (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 os/freebsd/prepare_kmods.hpp +/// The preparation handler which loads FreeBSD modules declared via +/// "required_kmods" metadata. + +#if !defined(FREEBSD_PREPARE_KMODS_HPP) +#define FREEBSD_PREPARE_KMODS_HPP + +#include "engine/prepare/prepare.hpp" + +namespace prepare = engine::prepare; + + +namespace freebsd { + + +class prepare_kmods : public prepare::handler { +public: + const std::string& name() const; + const std::string& description() const; + int exec(cmdline::ui*, const cmdline::parsed_cmdline&, + const config::tree&) const; +}; + + +} // namespace freebsd + +#endif // !defined(FREEBSD_PREPARE_KMODS_HPP) diff --git a/usr.bin/kyua/Makefile b/usr.bin/kyua/Makefile index aa0e5cbbcad2..083f3a8ec038 100644 --- a/usr.bin/kyua/Makefile +++ b/usr.bin/kyua/Makefile @@ -128,11 +128,14 @@ SRCS+= engine/atf.cpp \ engine/tap_parser.cpp \ engine/scheduler.cpp \ engine/execenv/execenv.cpp \ - engine/execenv/execenv_host.cpp + engine/execenv/execenv_host.cpp \ + engine/prepare/prepare.cpp \ + engine/prepare/prepare_all.cpp SRCS+= os/freebsd/execenv_jail_manager.cpp \ os/freebsd/main.cpp \ - os/freebsd/reqs_checker_kmods.cpp + os/freebsd/reqs_checker_kmods.cpp \ + os/freebsd/prepare_kmods.cpp SRCS+= store/dbtypes.cpp \ store/exceptions.cpp \ @@ -157,6 +160,7 @@ SRCS+= cli/cmd_about.cpp \ cli/cmd_debug.cpp \ cli/cmd_help.cpp \ cli/cmd_list.cpp \ + cli/cmd_prepare.cpp \ cli/cmd_report.cpp \ cli/cmd_report_html.cpp \ cli/cmd_report_junit.cpp \