diff options
Diffstat (limited to 'src/ninep/events.zig')
| -rw-r--r-- | src/ninep/events.zig | 33 |
1 files changed, 32 insertions, 1 deletions
diff --git a/src/ninep/events.zig b/src/ninep/events.zig index ffdea95b..0e489be7 100644 --- a/src/ninep/events.zig +++ b/src/ninep/events.zig @@ -565,6 +565,32 @@ const serialOf = th.serialOf; const Node = tree.Node; const Status = tree.Status; +test "a stream read at an offset inside its last answer gets the rest of it again, as bash's read seeks back" { + const p = try withFile(testing.allocator, "one\n"); + defer p.deinit(); + p.update(.tick); + while (p.nextEffect()) |_| {} + const log = @intFromEnum(tree.TopFile.log); + const f = call(p, .{ .tag = 1, .op = .open, .node = log }).reply.handle; + const frozen: u64 = call(p, .{ .tag = 2, .op = .read, .node = log, .handle = f, .size = 8192 }).bytes.len; + _ = call(p, .{ .tag = 3, .op = .write, .node = log, .handle = f, .data = "follow" }); + notePath(p, "dump", "/a"); + notePath(p, "dump", "/b"); + const Read = struct { + fn at(pp: *Pardes, h: u32, off: u64) []const u8 { + return call(pp, .{ .tag = 4, .op = .read, .node = @intFromEnum(tree.TopFile.log), .handle = h, .off = off, .size = 128 }).bytes; + } + }; + try testing.expectEqualStrings("dump /a\n", Read.at(p, f, frozen)); + // bash kept "dump" and seeked back to just past it. + try testing.expectEqualStrings(" /a\n", Read.at(p, f, frozen + 4)); + // At the end of what it was given: the next record. + try testing.expectEqualStrings("dump /b\n", Read.at(p, f, frozen + 8)); + // A client that reads every record at one offset still gets new ones. + notePath(p, "dump", "/c"); + try testing.expectEqualStrings("dump /c\n", Read.at(p, f, frozen + 8)); +} + test "event records are acme's bytes, one per read, and .again when empty" { const gpa = testing.allocator; const p = try withFile(gpa, "Msg fs-ran\n"); @@ -908,8 +934,13 @@ test "a Dump written and a Restore made are in the log, with their files" { const log = try freezeLog(core); defer core.gpa.free(log.bytes); var want: [64]u8 = undefined; - try testing.expect(std.mem.endsWith(u8, log.bytes, try std.fmt.bufPrint(&want, "{s} /tmp/pardes.dump.zon\n", .{what}))); + try testing.expect(std.mem.indexOf(u8, log.bytes, try std.fmt.bufPrint(&want, "{s} /tmp/pardes.dump.zon\n", .{what})) != null); } + // The replacement's last says which serial each pane had. + const log = try freezeLog(restored); + defer restored.gpa.free(log.bytes); + var want: [64]u8 = undefined; + try testing.expect(std.mem.endsWith(u8, log.bytes, try std.fmt.bufPrint(&want, "restore /tmp/pardes.dump.zon\nrestored {d} {d}\n", .{ p.panes[0].?.serial, restored.panes[0].?.serial }))); } test "opens of the log share the open records, and a closed one frees its record" { |
