diff options
Diffstat (limited to 'kernel/kapi/devices/bus.tests.cpp')
| -rw-r--r-- | kernel/kapi/devices/bus.tests.cpp | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/kernel/kapi/devices/bus.tests.cpp b/kernel/kapi/devices/bus.tests.cpp index 9f95513b..0a33df1a 100644 --- a/kernel/kapi/devices/bus.tests.cpp +++ b/kernel/kapi/devices/bus.tests.cpp @@ -92,3 +92,64 @@ SCENARIO("A bus shares ownership of its children, holding a weak link to its par } } } + +SCENARIO("Removing a child from a bus tears down the while subtree", "[devices][bus]") +{ + GIVEN("A bus with a child bus") + { + auto root = kstd::make_shared<test_bus>("bus_removal_root"); + auto middle = kstd::make_shared<test_bus>("bus_removal_middle"); + auto leaf_destroyed = false; + auto leaf = kstd::make_shared<flagging_device>("bus_removal_leaf", leaf_destroyed); + + root->add_child(middle); + middle->add_child(leaf); + + REQUIRE(root->children().size() == 1); + REQUIRE(middle->children().size() == 1); + + WHEN("the middle bus is removed from the root") + { + REQUIRE(root->remove_child(*middle)); + + THEN("the middle bus's own subtree was torn down") + { + REQUIRE(middle->children().empty()); + } + + THEN("the leaf is marked as removed but not destroyed") + { + REQUIRE(leaf->state() == kapi::devices::state::removed); + REQUIRE(leaf->parent() == nullptr); + REQUIRE_FALSE(leaf_destroyed); + } + + AND_WHEN("dropping the outside leaf reference") + { + leaf.reset(); + + THEN("the leaf is destroyed") + { + REQUIRE(leaf_destroyed); + } + } + + THEN("the root no longer considers the middle its child") + { + REQUIRE(root->children().empty()); + REQUIRE(middle->state() == kapi::devices::state::removed); + } + } + } + + GIVEN("A bus and a device that was never actually attached to it") + { + auto bus = kstd::make_shared<test_bus>("bus_removal_unrelated_bus"); + auto unrelated = kstd::make_shared<test_device>("bus_removal_unrelated_device"); + + THEN("removing the child fails") + { + REQUIRE_FALSE(bus->remove_child(*unrelated)); + } + } +} |
