authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-05-07 15:24:37+02:00
committergravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2021-05-11 12:33:48+02:00
logc065e12dbefcde1a48926405bd4f401eadecaca2
tree6b09232db1a05c86350f864d991963b38df10309
parent31f1cc9a0d80e87efb1f414352ff9d6abf2067ca

std: Add more tests, fix broken code

It turns out that nothing in the test suite was exercising preadv/pwritev and so the previous commits silently broke them. Adding tests revealed readvAll and preadvAll were also broken and not covered by any test.

3 files changed, 90 insertions(+), 5 deletions(-)

lib/std/fs/file.zig+3-3
...@@ -482,7 +482,7 @@ pub const File = struct {...@@ -482,7 +482,7 @@ pub const File = struct {
482 /// order to handle partial reads from the underlying OS layer.482 /// order to handle partial reads from the underlying OS layer.
483 /// See https://github.com/ziglang/zig/issues/7699483 /// See https://github.com/ziglang/zig/issues/7699
484 pub fn readvAll(self: File, iovecs: []os.iovec) ReadError!usize {484 pub fn readvAll(self: File, iovecs: []os.iovec) ReadError!usize {
485 if (iovecs.len == 0) return;485 if (iovecs.len == 0) return 0;
486486
487 var i: usize = 0;487 var i: usize = 0;
488 var off: usize = 0;488 var off: usize = 0;
...@@ -524,8 +524,8 @@ pub const File = struct {...@@ -524,8 +524,8 @@ pub const File = struct {
524 /// The `iovecs` parameter is mutable because this function needs to mutate the fields in524 /// The `iovecs` parameter is mutable because this function needs to mutate the fields in
525 /// order to handle partial reads from the underlying OS layer.525 /// order to handle partial reads from the underlying OS layer.
526 /// See https://github.com/ziglang/zig/issues/7699526 /// See https://github.com/ziglang/zig/issues/7699
527 pub fn preadvAll(self: File, iovecs: []const os.iovec, offset: u64) PReadError!void {527 pub fn preadvAll(self: File, iovecs: []os.iovec, offset: u64) PReadError!usize {
528 if (iovecs.len == 0) return;528 if (iovecs.len == 0) return 0;
529529
530 var i: usize = 0;530 var i: usize = 0;
531 var off: usize = 0;531 var off: usize = 0;
lib/std/fs/test.zig+83
...@@ -520,6 +520,89 @@ test "makePath, put some files in it, deleteTree" {...@@ -520,6 +520,89 @@ test "makePath, put some files in it, deleteTree" {
520 }520 }
521}521}
522522
523test "writev, readv" {
524 var tmp = tmpDir(.{});
525 defer tmp.cleanup();
526
527 const line1 = "line1\n";
528 const line2 = "line2\n";
529
530 var buf1: [line1.len]u8 = undefined;
531 var buf2: [line2.len]u8 = undefined;
532 var write_vecs = [_]std.os.iovec_const{
533 .{
534 .iov_base = line1,
535 .iov_len = line1.len,
536 },
537 .{
538 .iov_base = line2,
539 .iov_len = line2.len,
540 },
541 };
542 var read_vecs = [_]std.os.iovec{
543 .{
544 .iov_base = &buf2,
545 .iov_len = buf2.len,
546 },
547 .{
548 .iov_base = &buf1,
549 .iov_len = buf1.len,
550 },
551 };
552
553 var src_file = try tmp.dir.createFile("test.txt", .{ .read = true });
554 defer src_file.close();
555
556 try src_file.writevAll(&write_vecs);
557 try testing.expectEqual(@as(u64, line1.len + line2.len), try src_file.getEndPos());
558 try src_file.seekTo(0);
559 const read = try src_file.readvAll(&read_vecs);
560 try testing.expectEqual(@as(usize, line1.len + line2.len), read);
561 try testing.expectEqualStrings(&buf1, "line2\n");
562 try testing.expectEqualStrings(&buf2, "line1\n");
563}
564
565test "pwritev, preadv" {
566 var tmp = tmpDir(.{});
567 defer tmp.cleanup();
568
569 const line1 = "line1\n";
570 const line2 = "line2\n";
571
572 var buf1: [line1.len]u8 = undefined;
573 var buf2: [line2.len]u8 = undefined;
574 var write_vecs = [_]std.os.iovec_const{
575 .{
576 .iov_base = line1,
577 .iov_len = line1.len,
578 },
579 .{
580 .iov_base = line2,
581 .iov_len = line2.len,
582 },
583 };
584 var read_vecs = [_]std.os.iovec{
585 .{
586 .iov_base = &buf2,
587 .iov_len = buf2.len,
588 },
589 .{
590 .iov_base = &buf1,
591 .iov_len = buf1.len,
592 },
593 };
594
595 var src_file = try tmp.dir.createFile("test.txt", .{ .read = true });
596 defer src_file.close();
597
598 try src_file.pwritevAll(&write_vecs, 16);
599 try testing.expectEqual(@as(u64, 16 + line1.len + line2.len), try src_file.getEndPos());
600 const read = try src_file.preadvAll(&read_vecs, 16);
601 try testing.expectEqual(@as(usize, line1.len + line2.len), read);
602 try testing.expectEqualStrings(&buf1, "line2\n");
603 try testing.expectEqualStrings(&buf2, "line1\n");
604}
605
523test "access file" {606test "access file" {
524 if (builtin.os.tag == .wasi) return error.SkipZigTest;607 if (builtin.os.tag == .wasi) return error.SkipZigTest;
525608
lib/std/os.zig+4-2
...@@ -646,8 +646,9 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {...@@ -646,8 +646,9 @@ pub fn preadv(fd: fd_t, iov: []const iovec, offset: u64) PReadError!usize {
646 else646 else
647 system.preadv;647 system.preadv;
648648
649 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
649 while (true) {650 while (true) {
650 const rc = preadv_sym(fd, iov.ptr, iov_count, offset);651 const rc = preadv_sym(fd, iov.ptr, iov_count, ioffset);
651 switch (errno(rc)) {652 switch (errno(rc)) {
652 0 => return @bitCast(usize, rc),653 0 => return @bitCast(usize, rc),
653 EINTR => continue,654 EINTR => continue,
...@@ -998,8 +999,9 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz...@@ -998,8 +999,9 @@ pub fn pwritev(fd: fd_t, iov: []const iovec_const, offset: u64) PWriteError!usiz
998 system.pwritev;999 system.pwritev;
9991000
1000 const iov_count = math.cast(u31, iov.len) catch math.maxInt(u31);1001 const iov_count = math.cast(u31, iov.len) catch math.maxInt(u31);
1002 const ioffset = @bitCast(i64, offset); // the OS treats this as unsigned
1001 while (true) {1003 while (true) {
1002 const rc = pwritev_sym(fd, iov.ptr, iov_count, offset);1004 const rc = pwritev_sym(fd, iov.ptr, iov_count, ioffset);
1003 switch (errno(rc)) {1005 switch (errno(rc)) {
1004 0 => return @intCast(usize, rc),1006 0 => return @intCast(usize, rc),
1005 EINTR => continue,1007 EINTR => continue,