milestone 13 discrepancies: redact credentials from urls in logs, metrics and cli output
This commit is contained in:
@@ -1129,6 +1129,93 @@ test "W10 a rule mutation reloads the snapshot and the change is live" {
|
||||
try bounded(env.io(), default_budget, mutationReloads, .{ env.io(), env });
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// deleting a source takes its compiled files with it (m13 ruling F-f)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// The id in a `201 Created` body from `/api/blocklists`.
|
||||
fn createdId(body: []const u8) !i64 {
|
||||
const marker = "\"id\":";
|
||||
const at = std.mem.indexOf(u8, body, marker) orelse return error.TestNoId;
|
||||
const rest = body[at + marker.len ..];
|
||||
const end = std.mem.indexOfNone(u8, rest, "0123456789") orelse rest.len;
|
||||
return std.fmt.parseInt(i64, rest[0..end], 10);
|
||||
}
|
||||
|
||||
fn writeCompiled(io: std.Io, dir: std.Io.Dir, id: i64, body: []const u8) !void {
|
||||
var buf: [64]u8 = undefined;
|
||||
try dir.writeFile(io, .{
|
||||
.sub_path = try std.fmt.bufPrint(&buf, "{d}.list", .{id}),
|
||||
.data = body,
|
||||
});
|
||||
try dir.writeFile(io, .{
|
||||
.sub_path = try std.fmt.bufPrint(&buf, "{d}.wild", .{id}),
|
||||
.data = "",
|
||||
});
|
||||
}
|
||||
|
||||
fn accessCompiled(io: std.Io, dir: std.Io.Dir, id: i64) !void {
|
||||
var buf: [64]u8 = undefined;
|
||||
return dir.access(io, try std.fmt.bufPrint(&buf, "{d}.list", .{id}), .{});
|
||||
}
|
||||
|
||||
fn deleteSweepsCompiledFiles(io: std.Io, env: *Env) anyerror!void {
|
||||
var conn: Conn = undefined;
|
||||
try conn.connect(io, env.addr);
|
||||
defer conn.close(io);
|
||||
|
||||
var body_buf: [4096]u8 = undefined;
|
||||
try conn.request("POST", "/api/blocklists", null, "{\"url\":\"https://doomed.test/a.txt\",\"name\":\"doomed\"}");
|
||||
var response = try conn.receive(&body_buf);
|
||||
try testing.expectEqual(@as(u16, 201), response.status);
|
||||
const doomed = try createdId(response.body);
|
||||
|
||||
try conn.request("POST", "/api/blocklists", null, "{\"url\":\"https://kept.test/b.txt\",\"name\":\"kept\"}");
|
||||
response = try conn.receive(&body_buf);
|
||||
try testing.expectEqual(@as(u16, 201), response.status);
|
||||
const kept = try createdId(response.body);
|
||||
|
||||
// The files a refresh would have produced for each row. Neither row carries
|
||||
// a checksum, so the reload the delete runs treats both as never fetched
|
||||
// and reads neither — this case is about the directory, not the snapshot.
|
||||
_ = try env.tmp.dir.createDirPathStatus(io, "blocklists", .fromMode(0o700));
|
||||
var dir = try env.tmp.dir.openDir(io, "blocklists", .{ .iterate = true });
|
||||
defer dir.close(io);
|
||||
try writeCompiled(io, dir, doomed, "doomed.example\n");
|
||||
try writeCompiled(io, dir, kept, "kept.example\n");
|
||||
|
||||
var target_buf: [64]u8 = undefined;
|
||||
const target = try std.fmt.bufPrint(&target_buf, "/api/blocklists/{d}", .{doomed});
|
||||
try conn.request("DELETE", target, null, null);
|
||||
response = try conn.receive(&body_buf);
|
||||
try testing.expectEqual(@as(u16, 204), response.status);
|
||||
|
||||
// The row is gone, so its files are orphans; without a sweep on this path
|
||||
// they would sit here until a restart or the scheduler's next pass.
|
||||
var name_buf: [64]u8 = undefined;
|
||||
try testing.expectError(error.FileNotFound, dir.access(
|
||||
io,
|
||||
try std.fmt.bufPrint(&name_buf, "{d}.list", .{doomed}),
|
||||
.{},
|
||||
));
|
||||
try testing.expectError(error.FileNotFound, dir.access(
|
||||
io,
|
||||
try std.fmt.bufPrint(&name_buf, "{d}.wild", .{doomed}),
|
||||
.{},
|
||||
));
|
||||
try accessCompiled(io, dir, kept);
|
||||
}
|
||||
|
||||
test "W10 deleting a blocklist deletes its compiled files and spares the others" {
|
||||
if (!build_options.integration) return error.SkipZigTest;
|
||||
|
||||
const gpa = testing.allocator;
|
||||
var env = try Env.create(gpa, .{});
|
||||
defer env.destroy();
|
||||
|
||||
try bounded(env.io(), default_budget, deleteSweepsCompiledFiles, .{ env.io(), env });
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// pause via the API changes a real handler decision (ruling 15)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user