tests for passwd_all

This commit is contained in:
Motiejus Jakštys 2022-07-11 14:14:21 +03:00
parent f0777b9e94
commit 9a7447eaa1
4 changed files with 94 additions and 45 deletions

View File

@ -81,7 +81,7 @@ additional_gids_offset: u64,
pub const Entry = struct {
user: PackedUser,
next: ?[]const u8,
end: usize,
};
pub fn fromBytes(bytes: []const u8) Entry {
@ -93,37 +93,40 @@ pub fn fromBytes(bytes: []const u8) Entry {
};
const end_blob = end_strings + gids_offset.bytes_read;
const nextStart = pad.roundUp(usize, alignment_bits, end_blob);
var next: ?[]const u8 = null;
if (nextStart < bytes.len)
next = bytes[nextStart..];
return Entry{
.user = PackedUser{
.inner = inner,
.bytes = bytes[start_blob..end_blob],
.additional_gids_offset = gids_offset.value,
},
.next = next,
.end = pad.roundUp(usize, alignment_bits, end_blob),
};
}
pub const Iterator = struct {
section: ?[]const u8,
section: []const u8,
nextStart: usize = 0,
shell_reader: ShellReader,
idx: u32 = 0,
total: u32,
pub fn next(it: *Iterator) ?PackedUser {
if (it.section) |section| {
const entry = PackedUser.fromBytes(section);
it.section = entry.next;
return entry.user;
}
if (it.idx == it.total)
return null;
const entry = PackedUser.fromBytes(it.section[it.nextStart..]);
it.nextStart += entry.end;
it.idx += 1;
return entry.user;
}
};
pub fn iterator(section: []const u8, shell_reader: ShellReader) Iterator {
return Iterator{ .section = section, .shell_reader = shell_reader };
pub fn iterator(section: []const u8, total: u32, shell_reader: ShellReader) Iterator {
return Iterator{
.section = section,
.total = total,
.shell_reader = shell_reader,
};
}
// packTo packs the User record and copies it to the given arraylist.
@ -289,7 +292,7 @@ test "construct PackedUser section" {
}
var i: u29 = 0;
var it1 = PackedUser.iterator(buf.items, test_shell_reader);
var it1 = PackedUser.iterator(buf.items, users.len, test_shell_reader);
while (it1.next()) |user| : (i += 1) {
try testing.expectEqual(users[i].uid, user.uid());
try testing.expectEqual(users[i].gid, user.gid());

View File

@ -92,7 +92,7 @@ fn strlen(self: *const User) usize {
const line_fmt = "{s}:x:{d}:{d}:{s}:{s}:{s}\n";
const max_line_len = fmt.count(line_fmt, .{
pub const max_line_len = fmt.count(line_fmt, .{
max_user.name,
max_user.uid,
max_user.gid,
@ -136,7 +136,7 @@ pub fn fromReader(allocator: Allocator, err: *ErrCtx, reader: anytype) ![]User {
users.deinit();
}
var buf: [max_line_len + 1]u8 = undefined;
var buf: [max_line_len]u8 = undefined;
while (try reader.readUntilDelimiterOrEof(buf[0..], '\n')) |line| {
var user = try fromLine(allocator, err, line);
try users.append(user);

View File

@ -267,7 +267,11 @@ fn setpwent(state: *State) void {
defer state.getpwent_iterator_mu.unlock();
const db = state.file.db;
state.getpwent_iterator = PackedUser.iterator(db.users, db.shellReader());
state.getpwent_iterator = PackedUser.iterator(
db.users,
db.header.num_users,
db.shellReader(),
);
}
export fn _nss_turbo_endpwent() void {

View File

@ -9,6 +9,7 @@ const flags = @import("flags.zig");
const DB = @import("DB.zig");
const File = @import("File.zig");
const PackedUser = @import("PackedUser.zig");
const User = @import("User.zig");
const Mode = enum { group, passwd };
@ -97,13 +98,10 @@ fn execute(
}
fn passwd(stdout: anytype, db: *const DB, keys: []const [*:0]const u8) u8 {
var some_notfound = false;
if (keys.len == 0)
return passwd_all(stdout, db);
var some_notfound = false;
const shell_reader = db.shellReader();
for (keys) |key| {
const keyZ = mem.span(key);
const maybe_packed_user = if (fmt.parseUnsigned(u32, keyZ, 10)) |uid|
@ -124,7 +122,7 @@ fn passwd(stdout: anytype, db: *const DB, keys: []const [*:0]const u8) u8 {
}
fn passwd_all(stdout: anytype, db: *const DB) u8 {
var it = PackedUser.iterator(db.users, db.shellReader());
var it = PackedUser.iterator(db.users, db.header.num_users, db.shellReader());
while (it.next()) |packed_user| {
const line = packed_user.toUser(db.shellReader()).toLine();
stdout.writeAll(line.constSlice()) catch return 3;
@ -132,9 +130,23 @@ fn passwd_all(stdout: anytype, db: *const DB) u8 {
return 0;
}
fn group(stdout: anytype, db: *const DB, keys: []const [*:0]const u8) u8 {
if (keys.len == 0)
return group_all(stdout, db);
var some_notfound = false;
return if (some_notfound) 2 else 0;
}
fn group_all(stdout: anytype, db: *const DB) u8 {
_ = stdout;
_ = db;
return 0;
}
const testing = std.testing;
test "passwd and passwd_all" {
test "passwd" {
var tf = try File.TestDB.init(testing.allocator);
defer tf.deinit();
var stdout = ArrayList(u8).init(testing.allocator);
@ -142,6 +154,7 @@ test "passwd and passwd_all" {
var stderr = ArrayList(u8).init(testing.allocator);
defer stderr.deinit();
{
const args = &[_][*:0]const u8{
"--db",
tf.path,
@ -161,10 +174,39 @@ test "passwd and passwd_all" {
try testing.expectEqualStrings(stdout.items[want_root.len..offset], want_vidmantas);
try testing.expectEqualStrings(stdout.items[offset..], want_root);
}
fn group(stdout: anytype, db: *const DB, keys: []const [*:0]const u8) u8 {
_ = db;
_ = stdout;
_ = keys;
return 0;
}
test "passwd_all" {
var tf = try File.TestDB.init(testing.allocator);
defer tf.deinit();
var stdout = ArrayList(u8).init(testing.allocator);
defer stdout.deinit();
var stderr = ArrayList(u8).init(testing.allocator);
defer stderr.deinit();
const args = &[_][*:0]const u8{
"--db",
tf.path,
"passwd",
};
var buf: [User.max_line_len]u8 = undefined;
const got = execute(stdout.writer(), stderr.writer(), args);
try testing.expectEqual(got, 0);
const want_names = &[_][]const u8{
"Name" ** 8,
"nobody",
"root",
"svc-bar",
"vidmantas",
};
var i: usize = 0;
const reader = io.fixedBufferStream(stdout.items).reader();
while (try reader.readUntilDelimiterOrEof(buf[0..], '\n')) |line| {
var name = mem.split(u8, line, ":");
try testing.expectEqualStrings(want_names[i], name.next().?);
i += 1;
}
}