| 15 | #include "vfs.hpp" |
| 16 | |
| 17 | auto fatfs_test() -> bool { |
| 18 | klog::Info("fatfs_test: start"); |
| 19 | |
| 20 | // T1: Get virtio-blk device via DeviceManager |
| 21 | DeviceNode* blk_nodes[4]{}; |
| 22 | const size_t blk_count = DeviceManagerSingleton::instance().FindDevicesByType( |
| 23 | DeviceType::kBlock, blk_nodes, 4); |
| 24 | if (blk_count == 0 || blk_nodes[0]->block_device == nullptr) { |
| 25 | klog::Info( |
| 26 | "fatfs_test: SKIP — no virtio-blk device " |
| 27 | "available"); |
| 28 | return true; // Graceful skip, not a failure |
| 29 | } |
| 30 | vfs::BlockDevice* blk = blk_nodes[0]->block_device; |
| 31 | klog::Info("fatfs_test: virtio-blk device: {}", blk->GetName()); |
| 32 | EXPECT_GT(blk->GetSectorCount(), static_cast<uint64_t>(0), |
| 33 | "fatfs_test: virtio-blk has zero sectors"); |
| 34 | |
| 35 | // T2: Mount FatFS at /mnt/fat |
| 36 | // vfs::Init() and ramfs mount at "/" should already have been done by |
| 37 | // ramfs_test, but call Init() again (it's idempotent). |
| 38 | auto init_result = vfs::Init(); |
| 39 | EXPECT_TRUE(init_result.has_value(), "fatfs_test: vfs init failed"); |
| 40 | |
| 41 | // FileSystemInit() may have already mounted FatFS at /mnt/fat — tear it |
| 42 | // down so the test owns the full mount lifecycle. |
| 43 | if (vfs::GetMountTable().IsMountPoint("/mnt/fat")) { |
| 44 | (void)vfs::GetMountTable().Unmount("/mnt/fat"); |
| 45 | } |
| 46 | |
| 47 | // Create /mnt and /mnt/fat directories in the VFS tree (in ramfs at /) |
| 48 | // before mounting. MkDir is idempotent-ish — ignore errors if exists. |
| 49 | (void)vfs::MkDir("/mnt"); |
| 50 | (void)vfs::MkDir("/mnt/fat"); |
| 51 | |
| 52 | // MountTable::Mount calls fs->Mount() internally — do not call it manually. |
| 53 | static fatfs::FatFsFileSystem fat_fs(0); |
| 54 | auto vfs_mount = vfs::GetMountTable().Mount("/mnt/fat", &fat_fs, blk); |
| 55 | EXPECT_TRUE(vfs_mount.has_value(), |
| 56 | "fatfs_test: vfs mount at /mnt/fat failed"); |
| 57 | klog::Info("fatfs_test: vfs mount at /mnt/fat ok"); |
| 58 | |
| 59 | // T3: Write a file on the FAT volume |
| 60 | { |
| 61 | auto file_result = |
| 62 | vfs::Open("/mnt/fat/test.txt", |
| 63 | vfs::OpenFlags::kOCreate | vfs::OpenFlags::kOReadWrite); |
| 64 | EXPECT_TRUE(file_result.has_value(), |
| 65 | "fatfs_test: open /mnt/fat/test.txt failed"); |
| 66 | vfs::File* file = file_result.value(); |
| 67 | |
| 68 | const char kMsg[] = "Hello, FatFS!"; |
| 69 | auto write_result = vfs::Write(file, kMsg, sizeof(kMsg) - 1); |
| 70 | EXPECT_TRUE(write_result.has_value(), |
| 71 | "fatfs_test: write to /mnt/fat/test.txt failed"); |
| 72 | EXPECT_EQ(write_result.value(), sizeof(kMsg) - 1, |
| 73 | "fatfs_test: write byte count mismatch"); |
| 74 | klog::Info("fatfs_test: wrote {} bytes to /mnt/fat/test.txt", |
nothing calls this directly
no test coverage detected