From 6f68e16380bce9f34928ba10cbf0b92aeec393e5 Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 24 Jul 2026 09:03:14 +0200 Subject: kernel: generalize test fix --- kernel/CMakeLists.txt | 1 + kernel/kernel/filesystem/device_inode.tests.cpp | 22 +----- .../filesystem/device_number_registry.tests.cpp | 90 ++++++++++++++-------- kernel/kernel/test_support/devices/driver.cpp | 40 ++++++++++ kernel/kernel/test_support/devices/driver.hpp | 33 ++++++++ 5 files changed, 134 insertions(+), 52 deletions(-) create mode 100644 kernel/kernel/test_support/devices/driver.cpp create mode 100644 kernel/kernel/test_support/devices/driver.hpp diff --git a/kernel/CMakeLists.txt b/kernel/CMakeLists.txt index 72283587..700cde8f 100644 --- a/kernel/CMakeLists.txt +++ b/kernel/CMakeLists.txt @@ -157,6 +157,7 @@ if(BUILD_TESTING) "kernel/test_support/devices/block_device.cpp" "kernel/test_support/devices/character_device.cpp" + "kernel/test_support/devices/driver.cpp" "kernel/test_support/filesystem/inode.cpp" "kernel/test_support/filesystem/filesystem.cpp" diff --git a/kernel/kernel/filesystem/device_inode.tests.cpp b/kernel/kernel/filesystem/device_inode.tests.cpp index aa97f8ca..f36bb4dc 100644 --- a/kernel/kernel/filesystem/device_inode.tests.cpp +++ b/kernel/kernel/filesystem/device_inode.tests.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -21,7 +22,6 @@ #include #include -#include #include using namespace kstd::units_literals; @@ -36,21 +36,6 @@ namespace } }; - struct test_driver final : kapi::devices::driver - { - [[nodiscard]] auto probe(kapi::devices::device &) -> kstd::result override - { - return kstd::success(); - } - - auto unbind(kapi::devices::device &) -> void override {} - - [[nodiscard]] auto claimed_major() const -> std::optional override - { - return std::uint8_t{1}; - } - }; - struct mock_origin_inode : kernel::filesystem::inode { auto read(void *, kstd::units::bytes, kstd::units::bytes) const -> kstd::result override @@ -184,9 +169,8 @@ SCENARIO("Device inode raw_device()", "[filesystem][device-inode]") GIVEN("A block device that has been published and numbered") { auto device = kstd::make_shared("ram0", 512_B); - auto driver = kstd::make_shared(); - device->bind_driver(driver); - device->set_state(kapi::devices::state::bound); + + CHECK(kernel::tests::devices::bind(*device, std::uint8_t{1})); REQUIRE(kapi::devices::interface_registry::get().publish(device, "ram0")); diff --git a/kernel/kernel/filesystem/device_number_registry.tests.cpp b/kernel/kernel/filesystem/device_number_registry.tests.cpp index d6c6e261..d48ca269 100644 --- a/kernel/kernel/filesystem/device_number_registry.tests.cpp +++ b/kernel/kernel/filesystem/device_number_registry.tests.cpp @@ -2,53 +2,35 @@ #include #include +#include #include #include -#include +#include #include #include +#include #include #include -#include +#include using namespace kstd::units_literals; namespace { - struct test_driver final : kapi::devices::driver - { - explicit test_driver(std::optional major) - : m_major{major} - {} - - [[nodiscard]] auto probe(kapi::devices::device &) -> kstd::result override - { - return kstd::success(); - } - - auto unbind(kapi::devices::device &) -> void override {} - - [[nodiscard]] auto claimed_major() const -> std::optional override - { - return m_major; - } - - private: - std::optional m_major; - }; - auto make_bound_block_device(kapi::devices::interface_registry & interfaces, kstd::string const & name, - kstd::units::bytes block_size, kstd::shared_ptr const & driver) + kstd::units::bytes block_size, std::optional major) -> kstd::shared_ptr { auto device = kstd::make_shared(name, block_size); - device->bind_driver(driver); - device->set_state(kapi::devices::state::bound); - std::ignore = interfaces.publish(device, name); + [[maybe_unused]] auto driver = kernel::tests::devices::bind(*device, major); + if (!interfaces.publish(device, name)) + { + throw std::runtime_error{"failed to publish block device!"}; + } return device; } } // namespace @@ -58,7 +40,6 @@ SCENARIO("Device number registry resolves and numbers published block devices", { auto interfaces = kapi::devices::interface_registry{}; auto registry = kernel::filesystem::device_number_registry{interfaces}; - auto ram_disk_driver = kstd::make_shared(std::uint8_t{1}); GIVEN("No devices have been published") { @@ -68,9 +49,9 @@ SCENARIO("Device number registry resolves and numbers published block devices", } } - GIVEN("A single block device has been published") + GIVEN("A single block device has been published, bound to a driver claiming major 1") { - auto device = make_bound_block_device(interfaces, "ram0", 512_B, ram_disk_driver); + auto device = make_bound_block_device(interfaces, "ram0", 512_B, std::uint8_t{1}); THEN("all() returns a vector with one element") { @@ -82,7 +63,7 @@ SCENARIO("Device number registry resolves and numbers published block devices", REQUIRE(all[0].name == "ram0"); } - AND_THEN("resolve() finds the device by numer") + AND_THEN("resolve() finds the device by number") { REQUIRE(registry.resolve(all[0].number, kernel::filesystem::file_type::block)); } @@ -114,7 +95,7 @@ SCENARIO("Device number registry resolves and numbers published block devices", GIVEN("A device was published") { - auto device = make_bound_block_device(interfaces, "ram0", 512_B, ram_disk_driver); + auto device = make_bound_block_device(interfaces, "ram0", 512_B, std::uint8_t{1}); auto number = registry.number_of(*device); WHEN("destroying it with no further owner") @@ -127,4 +108,47 @@ SCENARIO("Device number registry resolves and numbers published block devices", } } } + + GIVEN("Two block-capable drivers claiming different majors") + { + make_bound_block_device(interfaces, "ramA0", 512_B, std::uint8_t{1}); + make_bound_block_device(interfaces, "ramB0", 512_B, std::uint8_t{2}); + + THEN("their minors are numbered independently, starting at 0 for each driver") + { + auto all = registry.all(); + REQUIRE(all.size() == 2); + + auto entry_a = std::ranges::find_if(all, [](auto const & entry) { return entry.name == "ramA0"; }); + auto entry_b = std::ranges::find_if(all, [](auto const & entry) { return entry.name == "ramB0"; }); + REQUIRE(entry_a != all.end()); + REQUIRE(entry_b != all.end()); + + CHECK(entry_a->number.major == 1); + CHECK(entry_a->number.minor == 0); + CHECK(entry_b->number.major == 2); + CHECK(entry_b->number.minor == 0); + } + } + + GIVEN("A driver that never overrides claimed_major()") + { + make_bound_block_device(interfaces, "unnumbered0", 512_B, std::nullopt); + + THEN("it is never numbered, regardless of what it publishes") + { + REQUIRE(registry.all().empty()); + } + } + + GIVEN("A published device with no bound driver at all") + { + auto device = kstd::make_shared("unbound0", 512_B); + CHECK(interfaces.publish(device, "unbound0")); + + THEN("it is never numbered") + { + REQUIRE(registry.all().empty()); + } + } } diff --git a/kernel/kernel/test_support/devices/driver.cpp b/kernel/kernel/test_support/devices/driver.cpp new file mode 100644 index 00000000..878c199f --- /dev/null +++ b/kernel/kernel/test_support/devices/driver.cpp @@ -0,0 +1,40 @@ +#include + +#include + +#include +#include + +#include +#include + +namespace kernel::tests::devices +{ + + driver::driver(std::optional major) + : m_major(major) + {} + + auto driver::probe(kapi::devices::device &) -> kstd::result + { + return kstd::success(); + } + + auto driver::unbind(kapi::devices::device &) -> void {} + + auto driver::claimed_major() const -> std::optional + { + return m_major; + } + + auto bind(kapi::devices::device & device, std::optional major) + -> kstd::shared_ptr + { + auto instance = kstd::make_shared(major); + device.bind_driver(instance); + device.set_state(kapi::devices::state::bound); + device.set_driver_data(instance); + return instance; + } + +} // namespace kernel::tests::devices diff --git a/kernel/kernel/test_support/devices/driver.hpp b/kernel/kernel/test_support/devices/driver.hpp new file mode 100644 index 00000000..d95708e2 --- /dev/null +++ b/kernel/kernel/test_support/devices/driver.hpp @@ -0,0 +1,33 @@ +#ifndef TEACHOS_KERNEL_TEST_SUPPORT_DEVICES_DRIVER_HPP +#define TEACHOS_KERNEL_TEST_SUPPORT_DEVICES_DRIVER_HPP + +#include + +#include +#include + +#include +#include + +namespace kernel::tests::devices +{ + + struct driver final : kapi::devices::driver + { + explicit driver(std::optional major = std::nullopt); + + [[nodiscard]] auto probe(kapi::devices::device &) -> kstd::result override; + auto unbind(kapi::devices::device &) -> void override; + + [[nodiscard]] auto claimed_major() const -> std::optional override; + + private: + std::optional m_major; + }; + + [[nodiscard]] auto bind(kapi::devices::device & device, std::optional major = std::uint8_t{1}) + -> kstd::shared_ptr; + +} // namespace kernel::tests::devices + +#endif -- cgit v1.2.3