From 12561d9f3aaeaa546bb1e7d44eac23fb66efc4b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Motiejus=20Jak=C5=A1tys?= Date: Tue, 7 Jun 2022 13:14:50 +0300 Subject: [PATCH] wip: full smoke test --- src/Group.zig | 13 ++++++++++ src/User.zig | 11 +++++---- src/unix2db/main.zig | 56 +++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/Group.zig b/src/Group.zig index 891d08a..59eead0 100644 --- a/src/Group.zig +++ b/src/Group.zig @@ -96,6 +96,19 @@ pub fn fromReader(allocator: Allocator, reader: anytype) FromReaderError![]Group return groups.toOwnedSlice(); } +pub fn writeTo(self: *const Group, writer: anytype) os.WriteError!void { + try writer.print("{s}:x:{d}:", .{ self.name, self.gid }); + if (self.members.len == 0) + return; + + try writer.writeAll(self.members[0]); + + for (self.members[1..]) |member| + try writer.print(",{s}", .{member}); + + try writer.writeByte('\n'); +} + // suggested buffer size in bytes if all strings were zero-terminated // (for CGroup). pub fn strlenZ(self: *const Group) usize { diff --git a/src/User.zig b/src/User.zig index c6bf370..910e236 100644 --- a/src/User.zig +++ b/src/User.zig @@ -94,16 +94,17 @@ const max_line_len = fmt.count(line_fmt, .{ max_user.shell, }); -// toPasswdLine formats the user in /etc/passwd format, including the EOL -fn toLine(self: *const User) BoundedArray(u8, max_line_len) { - var result = BoundedArray(u8, max_line_len); - fmt.bufPrint(result.slice(), line_fmt, .{ +// toLine formats the user in /etc/passwd format, including the EOL +pub fn toLine(self: *const User) BoundedArray(u8, max_line_len) { + var result = BoundedArray(u8, max_line_len).init(max_line_len) catch unreachable; + _ = fmt.bufPrint(result.slice(), line_fmt, .{ + self.name, self.uid, self.gid, self.gecos, self.home, self.shell, - }); + }) catch unreachable; return result; } diff --git a/src/unix2db/main.zig b/src/unix2db/main.zig index 829cd32..22a5fef 100644 --- a/src/unix2db/main.zig +++ b/src/unix2db/main.zig @@ -65,6 +65,7 @@ fn execute( const groupFname = result.argFlag("--group") orelse "./group"; const outFile = result.argFlag("--output") orelse "./db.turbo"; + std.debug.print("passwd file name: {s}\n", .{passwdFname}); var passwdFile = try fs.cwd().openFile(passwdFname, .{ .mode = .read_only }); defer passwdFile.close(); var groupFile = try fs.cwd().openFile(groupFname, .{ .mode = .read_only }); @@ -80,7 +81,7 @@ fn execute( var db = try DB.fromCorpus(allocator, &corpus); defer db.deinit(allocator); - const fd = try os.open(outFile, os.O.WRONLY | os.O.TRUNC, 0644); + const fd = try os.open(outFile, os.O.WRONLY | os.O.TRUNC | os.O.CREAT, 0644); errdefer os.close(fd); const len = try os.writev(fd, db.iov().constSlice()); @@ -114,8 +115,57 @@ test "invalid argument" { test "smoke test" { const allocator = testing.allocator; - const args = &[_][*:0]const u8{"--invalid-argument"}; var stderr = ArrayList(u8).init(allocator); defer stderr.deinit(); - _ = args; + + var corpus = try Corpus.testCorpus(allocator); + defer corpus.deinit(); + + var tmp = testing.tmpDir(.{}); + //errdefer tmp.cleanup(); + + const tmp_path = blk: { + const relative_path = try fs.path.join(allocator, &[_][]const u8{ + "zig-cache", + "tmp", + tmp.sub_path[0..], + }); + const real_path = try fs.realpathAlloc(allocator, relative_path); + allocator.free(relative_path); + break :blk real_path; + }; + defer allocator.free(tmp_path); + + const passwdPath = try fs.path.joinZ(allocator, &[_][]const u8{ tmp_path, "passwd" }); + defer allocator.free(passwdPath); + const groupPath = try fs.path.joinZ(allocator, &[_][]const u8{ tmp_path, "group" }); + defer allocator.free(groupPath); + const outPath = try fs.path.joinZ(allocator, &[_][]const u8{ tmp_path, "tmp.turbo" }); + defer allocator.free(outPath); + + const passwd_fd = try os.open(passwdPath, os.O.CREAT | os.O.WRONLY, 0o644); + const group_fd = try os.open(groupPath, os.O.CREAT | os.O.WRONLY, 0o644); + + var i: usize = 0; + while (i < corpus.users.len) : (i += 1) { + const user = corpus.users.get(i); + const line = user.toLine(); + _ = try os.write(passwd_fd, line.constSlice()); + } + os.close(passwd_fd); + + var group_writer = (fs.File{ .handle = group_fd }).writer(); + i = 0; + while (i < corpus.groups.len) : (i += 1) + try corpus.groups.get(i).writeTo(group_writer); + os.close(group_fd); + + const args = &[_][*:0]const u8{ + "--passwd", passwdPath, + "--group", groupPath, + "--output", outPath, + }; + const exit_code = try execute(allocator, stderr.writer(), args); + + try testing.expectEqual(@as(u8, 0), exit_code); }