#include "kernel/devices/storage/ram_disk/device.hpp" #include "kapi/boot_module/boot_module.hpp" #include "kapi/memory.hpp" #include "catch2/matchers/catch_matchers.hpp" #include "catch2/matchers/catch_matchers_range_equals.hpp" #include #include #include #include #include SCENARIO("RAM Disk Device Construction and Initialization", "[ram_disk_device]") { GIVEN("an empty boot module") { kapi::boot_modules::boot_module boot_module{}; boot_module.start_address = kapi::memory::linear_address{nullptr}; boot_module.size = 0; WHEN("constructing the device") { kernel::devices::storage::ram_disk::device device{boot_module, 0, 0}; THEN("init return false") { REQUIRE_FALSE(device.init()); } } } GIVEN("a boot module with a valid start address and size") { kapi::boot_modules::boot_module boot_module{}; boot_module.start_address = kapi::memory::linear_address{reinterpret_cast(0x1000)}; boot_module.size = 512; WHEN("constructing the device") { kernel::devices::storage::ram_disk::device device{boot_module, 0, 0}; THEN("init return true") { REQUIRE(device.init()); } } } } SCENARIO("RAM Disk Device Read and Write", "[ram_disk_device]") { GIVEN("a device initialized with a valid boot module") { auto storage = std::vector{4096, std::byte{0xff}}; auto module = kapi::boot_modules::boot_module{"test_module", kapi::memory::linear_address{storage.data()}, storage.size()}; auto device = kernel::devices::storage::ram_disk::device{module, 0, 0}; REQUIRE(device.init()); WHEN("reading a full block from the device") { auto buffer = std::vector(device.block_size()); device.read_block(0, buffer.data()); THEN("the buffer is filled with the module data") { REQUIRE_THAT(buffer, Catch::Matchers::RangeEquals(std::views::take(storage, device.block_size()))); } } WHEN("reading from a block index beyond the module size") { auto buffer = std::vector(device.block_size()); device.read_block(10, buffer.data()); THEN("the buffer is filled with zeros") { REQUIRE_THAT(buffer, Catch::Matchers::RangeEquals(std::vector(device.block_size(), std::byte{0}))); } } WHEN("reading into a null buffer") { REQUIRE_THROWS_AS(device.read_block(0, nullptr), std::runtime_error); } WHEN("writing to a full block") { auto buffer = std::vector(device.block_size(), std::byte{0x01}); device.write_block(0, buffer.data()); THEN("the module data is updated") { REQUIRE_THAT(std::views::take(storage, device.block_size()), Catch::Matchers::RangeEquals(buffer)); } } WHEN("writing to a block index beyond the module size") { auto buffer = std::vector(device.block_size(), std::byte{0x01}); device.write_block(10, buffer.data()); THEN("the module data is not updated") { REQUIRE_THAT(storage, Catch::Matchers::RangeEquals(std::vector{4096, std::byte{0xff}})); } } WHEN("writing from a null buffer") { REQUIRE_THROWS_AS(device.write_block(0, nullptr), std::runtime_error); } } }