Each engine now refuses the other's volume at mount(): the exFAT engine rejects a FAT boot sector (a non-zero byte where exFAT keeps MustBeZero), and the FAT engine rejects an exFAT one (MustBeZero reads as a zero bytes-per-sector), each mounting its own as a control. The two engines can never claim the same medium. exfat-test is the mount round-trip client, cloned from fat-test: it waits for /volumes/exfat-e0fa0001, reads the seeded HELLO.TXT, then exercises mkdir + write + rename + read-back + remove through the VFS and reports "exfat-test: ok". It ships as a lazy fixture in test builds (the exfat-volume QEMU case, step 8, drives it). build + zig build test + bounds green.
89 lines
3.5 KiB
Zig
89 lines
3.5 KiB
Zig
//! test/system/services/exfat-test — a client that proves the exFAT mount end to
|
|
//! end: it waits for the exfat server to mount the volume at /volumes/exfat-
|
|
//! e0fa0001, reads the seeded HELLO.TXT off it, and exercises mkdir / write /
|
|
//! read / rename / remove through the VFS (which routes the id-path to the exfat
|
|
//! backend). Shipped in the initial_ramdisk; the `exfat-volume` QEMU case spawns
|
|
//! it alongside init with an exFAT data device attached beside the FAT boot volume.
|
|
|
|
const std = @import("std");
|
|
const fs = @import("file-system");
|
|
const process = @import("process");
|
|
const time = @import("time");
|
|
const logging = @import("logging");
|
|
|
|
// The exFAT data device's content id-path — its VolumeSerialNumber is 0xE0FA0001
|
|
// (the `exfat-volume` case passes --serial E0FA0001 to make-exfat-image.py).
|
|
const mount = "/volumes/exfat-e0fa0001";
|
|
|
|
fn writeLine(comptime fmt: []const u8, arguments: anytype) void {
|
|
var line: [128]u8 = undefined;
|
|
_ = logging.write(std.fmt.bufPrint(&line, fmt, arguments) catch return);
|
|
}
|
|
|
|
pub fn main(init: process.Init) void {
|
|
_ = init;
|
|
|
|
// Wait for the exfat server to bring up the USB storage chain and mount.
|
|
var opened: ?fs.Directory = null;
|
|
var tries: u32 = 0;
|
|
while (opened == null and tries < 1400) : (tries += 1) {
|
|
opened = fs.openDirectory(mount);
|
|
if (opened == null) time.sleepMillis(50);
|
|
}
|
|
var dir = opened orelse {
|
|
_ = logging.write("exfat-test: " ++ mount ++ " never became available\n");
|
|
return;
|
|
};
|
|
var count: u32 = 0;
|
|
var entry: fs.Entry = .{};
|
|
while (dir.next(&entry)) {
|
|
writeLine("exfat-test: entry '{s}' size={d}\n", .{ entry.name(), entry.size });
|
|
count += 1;
|
|
if (count > 32) break;
|
|
}
|
|
dir.close();
|
|
|
|
// Read the seeded HELLO.TXT (make-exfat-image.py writes "exfat hello danos\n").
|
|
var read_ok = false;
|
|
if (fs.open(mount ++ "/HELLO.TXT", .{})) |opened_file| {
|
|
var file = opened_file;
|
|
var buf: [32]u8 = undefined;
|
|
const n = file.read(&buf) orelse 0;
|
|
file.close();
|
|
read_ok = std.mem.startsWith(u8, buf[0..n], "exfat hello danos");
|
|
}
|
|
if (read_ok) _ = logging.write("exfat-test: read HELLO.TXT ok\n");
|
|
|
|
// Mutation through the mount: mkdir, create + write, rename, read back, remove
|
|
// — proof the write path reaches the engine over a real device.
|
|
var mut_ok = false;
|
|
if (fs.makeDirectory(mount ++ "/TESTDIR")) {
|
|
var wrote = false;
|
|
if (fs.open(mount ++ "/TESTDIR/W.TXT", .{ .create = true, .truncate = true })) |created| {
|
|
var f = created;
|
|
wrote = (f.writeAll("exfat-mutation-ok") orelse 0) == "exfat-mutation-ok".len;
|
|
f.close();
|
|
}
|
|
const renamed = fs.rename(mount ++ "/TESTDIR/W.TXT", mount ++ "/TESTDIR/R.TXT");
|
|
var readback = false;
|
|
if (fs.open(mount ++ "/TESTDIR/R.TXT", .{})) |reopened| {
|
|
var f = reopened;
|
|
var buf: [32]u8 = undefined;
|
|
const got = f.read(&buf) orelse 0;
|
|
f.close();
|
|
readback = std.mem.eql(u8, buf[0..got], "exfat-mutation-ok");
|
|
}
|
|
const removed = fs.remove(mount ++ "/TESTDIR/R.TXT");
|
|
mut_ok = wrote and renamed and readback and removed;
|
|
}
|
|
if (mut_ok) _ = logging.write("exfat-test: mutations ok\n");
|
|
|
|
if (read_ok and mut_ok) {
|
|
while (true) {
|
|
_ = logging.write("exfat-test: ok\n");
|
|
time.sleepMillis(1000);
|
|
}
|
|
}
|
|
writeLine("exfat-test: FAILED (read={} mutations={})\n", .{ read_ok, mut_ok });
|
|
}
|