milestone 21: abp list exceptions and a regex rule kind
This commit is contained in:
@@ -3,10 +3,10 @@
|
||||
//!
|
||||
//! The defect this module exists to fix: `import.applyToDb` deletes and
|
||||
//! reinserts every row, `blocklist_sources` included, and the compiled
|
||||
//! blocklists are named after the source row id (`<id>.list` / `<id>.wild`). A
|
||||
//! configuration re-applied on every boot would therefore hand every source a
|
||||
//! new id, orphan every compiled file, and re-download every blocklist on every
|
||||
//! restart.
|
||||
//! blocklists are named after the source row id (`<id>.list` / `<id>.wild` /
|
||||
//! `<id>.allow`). A configuration re-applied on every boot would therefore hand
|
||||
//! every source a new id, orphan every compiled file, and re-download every
|
||||
//! blocklist on every restart.
|
||||
//!
|
||||
//! So nothing is wiped. Every table has an identity; a row the file and the
|
||||
//! database agree on is **updated in place**, keeping its row id and every
|
||||
@@ -1100,6 +1100,7 @@ fn seedSourceStats(database: *db.Db, id: i64) !void {
|
||||
.last_updated = 1_700_000_000,
|
||||
.domain_count = 4321,
|
||||
.wildcard_count = 21,
|
||||
.exception_count = 9,
|
||||
.skipped_regex_count = 7,
|
||||
.checksum = "a" ** 64,
|
||||
});
|
||||
@@ -1169,6 +1170,7 @@ test "a source keeps its id, its checksum and its counters across a reconcile" {
|
||||
try testing.expectEqualStrings("advertising", row.name);
|
||||
try testing.expectEqual(@as(?i64, 1_700_000_000), row.last_updated);
|
||||
try testing.expectEqual(@as(i64, 4321), row.domain_count);
|
||||
try testing.expectEqual(@as(i64, 9), row.exception_count);
|
||||
try testing.expectEqualStrings("a" ** 64, row.checksum.?);
|
||||
}
|
||||
|
||||
@@ -1550,6 +1552,50 @@ test "rules keep created_at across a reconcile, duplicates included" {
|
||||
}
|
||||
}
|
||||
|
||||
test "a regex rule declared in the file converges into the table and back out" {
|
||||
var bench: Bench = undefined;
|
||||
try bench.init();
|
||||
defer bench.deinit();
|
||||
|
||||
// Under `.managed_file` authority the API refuses rule writes, so this is
|
||||
// the only way a regex rule reaches the table in that mode. `reconcileRules`
|
||||
// compares the whole tuple and needs no code of its own for the new kind.
|
||||
const with_regex: [:0]const u8 =
|
||||
\\.{
|
||||
\\ .groups = .{ .{ .name = "default" } },
|
||||
\\ .upstreams = .{ .{ .url = "https://dns.example/dns-query" } },
|
||||
\\ .rules = .{
|
||||
\\ .{ .group = "default", .pattern = "^ad[0-9]+-", .kind = .regex, .action = .block },
|
||||
\\ },
|
||||
\\}
|
||||
;
|
||||
const first = try bench.apply(with_regex, 1_700_000_000);
|
||||
try testing.expectEqual(@as(u32, 1), first.rules.inserted);
|
||||
|
||||
const gpa = testing.allocator;
|
||||
var rows = try rules_repo.listRuleRows(&bench.database, gpa);
|
||||
defer rows.deinit(gpa);
|
||||
defer rules_repo.freeRuleRows(gpa, rows.items);
|
||||
try testing.expectEqual(@as(usize, 1), rows.items.len);
|
||||
try testing.expectEqual(model.RuleKind.regex, rows.items[0].kind);
|
||||
try testing.expectEqualStrings("^ad[0-9]+-", rows.items[0].pattern);
|
||||
|
||||
// Idempotent: the tuple matches itself, so a second pass writes nothing.
|
||||
const second = try bench.apply(with_regex, 1_800_000_000);
|
||||
try testing.expectEqual(@as(u32, 0), second.rules.total());
|
||||
|
||||
// And a file that stops declaring it takes the row with it.
|
||||
const without: [:0]const u8 =
|
||||
\\.{
|
||||
\\ .groups = .{ .{ .name = "default" } },
|
||||
\\ .upstreams = .{ .{ .url = "https://dns.example/dns-query" } },
|
||||
\\}
|
||||
;
|
||||
const third = try bench.apply(without, 1_900_000_000);
|
||||
try testing.expectEqual(@as(u32, 1), third.rules.deleted);
|
||||
try testing.expectEqual(@as(i64, 0), try rules_repo.countRules(&bench.database));
|
||||
}
|
||||
|
||||
test "dropping one of two identical rules removes exactly one row" {
|
||||
var bench: Bench = undefined;
|
||||
try bench.init();
|
||||
|
||||
Reference in New Issue
Block a user