#include "kernel/devices/block_device_utils.hpp" #include "kernel/test_support/cpu.hpp" #include "kernel/test_support/devices/block_device.hpp" #include #include #include #include #include #include SCENARIO("reading from a block device with block_device_utils", "[devices][block_device_utils]") { GIVEN("a block device with known data") { auto const block_size = 512; auto device = kstd::make_shared(0, 0, "test_block_device", block_size); kstd::vector block_data(block_size); for (size_t i = 0; i < block_data.size(); ++i) { block_data[i] = static_cast(i % 256); } device->write_block(0, block_data.data()); device->write_block(1, block_data.data()); WHEN("reading from the block device using block_device_utils") { kstd::vector read_buffer(block_size); auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 0, read_buffer.size()); THEN("the correct number of bytes is read") { REQUIRE(bytes_read == read_buffer.size()); } THEN("the data read matches the data written to the block device") { REQUIRE(read_buffer == block_data); } } WHEN("reading over block boundaries") { kstd::vector read_buffer(1024); auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 256, read_buffer.size()); THEN("the correct number of bytes is read") { REQUIRE(bytes_read == 1.5 * block_size); } THEN("the data read matches the expected data across block boundaries") { for (size_t i = 0; i < bytes_read; ++i) { uint8_t expected_value = static_cast((256 + i) % 256); REQUIRE(read_buffer[i] == expected_value); } } } WHEN("reading beyond the device capacity") { kstd::vector read_buffer(block_size); auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 1024, read_buffer.size()); THEN("no bytes are read") { REQUIRE(bytes_read == 0); } } WHEN("reading nothing") { kstd::vector read_buffer(block_size); auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 0, 0); THEN("no bytes are read") { REQUIRE(bytes_read == 0); } } WHEN("reading with a null buffer") { THEN("the system panics") { REQUIRE_THROWS_AS(kernel::devices::block_device_utils::read(device, nullptr, 0, 512), kernel::tests::cpu::halt); } } } } SCENARIO("writing to a block device using block_device_utils", "[devices][block_device_utils]") { GIVEN("a block device") { auto const block_size = 512; auto device = kstd::make_shared(0, 0, "test_block_device", block_size); device->data.resize(2 * block_size); WHEN("writing to the block device using block_device_utils") { kstd::vector write_buffer(block_size); for (size_t i = 0; i < write_buffer.size(); ++i) { write_buffer[i] = static_cast(i % 256); } auto bytes_written = kernel::devices::block_device_utils::write(device, write_buffer.data(), 0, write_buffer.size()); THEN("the correct number of bytes is written") { REQUIRE(bytes_written == write_buffer.size()); } THEN("the data written matches the data read back from the block device") { kstd::vector read_buffer(block_size); device->read_block(0, read_buffer.data()); REQUIRE(read_buffer == write_buffer); } } WHEN("writing over block boundaries") { kstd::vector write_buffer(2 * block_size); for (size_t i = 0; i < write_buffer.size(); ++i) { write_buffer[i] = static_cast(i % 256); } auto bytes_written = kernel::devices::block_device_utils::write(device, write_buffer.data(), 256, write_buffer.size()); THEN("the correct number of bytes is written") { REQUIRE(bytes_written == 1.5 * block_size); } THEN("the data written matches the data read back from the block device across block boundaries") { kstd::vector read_buffer(2 * block_size); auto bytes_read = kernel::devices::block_device_utils::read(device, read_buffer.data(), 256, 2 * block_size); for (size_t i = 0; i < bytes_read; ++i) { REQUIRE(read_buffer[i] == write_buffer[i]); } } } WHEN("writing beyond the device capacity") { kstd::vector write_buffer(block_size); auto bytes_written = kernel::devices::block_device_utils::write(device, write_buffer.data(), 1024, write_buffer.size()); THEN("no bytes are written") { REQUIRE(bytes_written == 0); } } WHEN("writing nothing") { kstd::vector write_buffer(block_size); auto bytes_written = kernel::devices::block_device_utils::write(device, write_buffer.data(), 0, 0); THEN("no bytes are written") { REQUIRE(bytes_written == 0); } } WHEN("writing with a null buffer") { THEN("the system panics") { REQUIRE_THROWS_AS(kernel::devices::block_device_utils::write(device, nullptr, 0, block_size), kernel::tests::cpu::halt); } } } }