Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/report-artifacts.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ The report contracts are backed by generated fixture artifacts:
| Fixture case | Golden artifacts |
| --- | --- |
| [`syslog_legacy`](../tests/fixtures/report_contracts/syslog_legacy) | `report.md`, `report.json`, `findings.csv`, `warnings.csv` |
| [`journalctl_short_full`](../tests/fixtures/report_contracts/journalctl_short_full) | `report.md`, `report.json` |
| [`journalctl_short_full`](../tests/fixtures/report_contracts/journalctl_short_full) | `report.md`, `report.json`, `findings.csv`, `warnings.csv` |
| [`multi_host_syslog_legacy`](../tests/fixtures/report_contracts/multi_host_syslog_legacy) | `report.md`, `report.json`, `findings.csv`, `warnings.csv` |
| [`multi_host_journalctl_short_full`](../tests/fixtures/report_contracts/multi_host_journalctl_short_full) | `report.md`, `report.json` |
| [`multi_host_journalctl_short_full`](../tests/fixtures/report_contracts/multi_host_journalctl_short_full) | `report.md`, `report.json`, `findings.csv`, `warnings.csv` |

The enforcement lives in [`tests/test_report_contracts.cpp`](../tests/test_report_contracts.cpp). The focused report writer tests live in [`tests/test_report.cpp`](../tests/test_report.cpp).
The enforcement lives in [`tests/test_report_contracts.cpp`](../tests/test_report_contracts.cpp). Parser or rule changes that alter report artifacts must update these snapshots explicitly. The focused report writer tests live in [`tests/test_report.cpp`](../tests/test_report.cpp).

## Boundaries

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
rule,subject_kind,subject,event_count,window_start,window_end,usernames,summary
brute_force,source_ip,203.0.113.10,5,2026-03-10 08:11:22,2026-03-10 08:18:05,,5 failed SSH attempts from 203.0.113.10 within 10 minutes.
multi_user_probing,source_ip,203.0.113.10,5,2026-03-10 08:11:22,2026-03-10 08:18:05,admin;deploy;guest;root;test,203.0.113.10 targeted 5 usernames within 15 minutes.
sudo_burst,username,alice,3,2026-03-10 08:21:00,2026-03-10 08:24:15,,alice ran 3 sudo commands within 5 minutes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
kind,line_number,message
parse_warning,15,unrecognized auth pattern: sshd_connection_closed_preauth
parse_warning,16,unrecognized auth pattern: sshd_timeout_or_disconnection
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
rule,subject_kind,subject,event_count,window_start,window_end,usernames,summary
brute_force,source_ip,203.0.113.10,5,2026-03-11 09:00:00,2026-03-11 09:04:05,,5 failed SSH attempts from 203.0.113.10 within 10 minutes.
multi_user_probing,source_ip,203.0.113.10,5,2026-03-11 09:00:00,2026-03-11 09:04:05,admin;deploy;guest;root;test,203.0.113.10 targeted 5 usernames within 15 minutes.
sudo_burst,username,alice,3,2026-03-11 09:11:00,2026-03-11 09:14:15,,alice ran 3 sudo commands within 5 minutes.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind,line_number,message
parse_warning,12,unrecognized auth pattern: pam_sss_unknown_user
parse_warning,14,unrecognized auth pattern: sshd_connection_closed_preauth
parse_warning,15,unrecognized auth pattern: sshd_timeout_or_disconnection
parse_warning,16,unrecognized auth pattern: pam_unix_session_closed
parse_warning,17,unrecognized auth pattern: sshd_negotiation_failure
22 changes: 22 additions & 0 deletions tests/test_report_contracts.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,14 @@ void run_report_contract_case(const std::filesystem::path& loglens_exe,
const auto golden_markdown = read_file(fixture_directory / "report.md");
const auto golden_json = read_file(fixture_directory / "report.json");

expect_equal_lines(
split_lines(actual_markdown),
split_lines(golden_markdown),
"markdown snapshot mismatch for " + fixture_directory.filename().string());
expect_equal_lines(
split_lines(actual_json),
split_lines(golden_json),
"json snapshot mismatch for " + fixture_directory.filename().string());
expect_equal_lines(
extract_markdown_contract_lines(actual_markdown),
extract_markdown_contract_lines(golden_markdown),
Expand Down Expand Up @@ -326,13 +334,27 @@ int main(int argc, char* argv[]) {
"syslog",
"--year 2026 --csv",
true);
run_report_contract_case(
loglens_exe,
fixture_root / "journalctl_short_full",
output_root,
"journalctl-short-full",
"--csv",
true);
run_report_contract_case(
loglens_exe,
fixture_root / "multi_host_syslog_legacy",
output_root,
"syslog",
"--year 2026 --csv",
true);
run_report_contract_case(
loglens_exe,
fixture_root / "multi_host_journalctl_short_full",
output_root,
"journalctl-short-full",
"--csv",
true);
} catch (...) {
std::filesystem::current_path(original_cwd);
throw;
Expand Down
Loading