Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
a3dfca5
test: add and expand attack chain and kerberos hash extraction tests
l50 Apr 21, 2026
4f68e62
test: add comprehensive edge case tests for parsing and evaluation mo…
l50 Apr 21, 2026
03651bb
test: add comprehensive tests for evaluation, kerberos, ntlm, mitre, …
l50 Apr 21, 2026
452ade7
test: add comprehensive unit tests for gap analysis, ground truth, an…
l50 Apr 21, 2026
943e9d4
test: add comprehensive unit tests for detection, models, state, and …
l50 Apr 22, 2026
b095f4f
test: add unit tests for alert clustering, correlator, lateral graph,…
l50 Apr 22, 2026
ee86899
test: add unit tests for agent loop, context, credentials, args, and …
l50 Apr 22, 2026
6241622
test: add comprehensive unit tests for gap analysis and scoring modules
l50 Apr 22, 2026
86bfb86
test: add comprehensive tests for correlation logic and technique cov…
l50 Apr 22, 2026
b47e0eb
test: add unit tests for lateral analyzer and report markdown generation
l50 Apr 22, 2026
ea4434f
test: rename test functions for clarity and remove redundant comments
l50 Apr 22, 2026
27e4c4e
test: rename all test functions to remove "test_" prefix
l50 Apr 22, 2026
f009117
test: add test for smb connection type and simplify template lookup e…
l50 Apr 22, 2026
8f16c59
style: remove decorative and redundant comment separators from tests
l50 Apr 22, 2026
bdb74fb
style: remove test section comment banners for clarity and conciseness
l50 Apr 22, 2026
566d9a5
style: remove test_ prefix from test function names for idiomatic Rust
l50 Apr 22, 2026
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
60 changes: 25 additions & 35 deletions ares-cli/src/dedup/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ fn make_hash(domain: &str, username: &str, hash_type: &str, hash_value: &str) ->
}

#[test]
fn test_dedup_users_basic() {
fn dedup_users_basic() {
let nb = HashMap::new();
let users = vec![
make_user("contoso.local", "admin"),
Expand All @@ -61,7 +61,7 @@ fn test_dedup_users_basic() {
}

#[test]
fn test_dedup_users_case_insensitive() {
fn dedup_users_case_insensitive() {
let nb = HashMap::new();
let users = vec![
make_user("CONTOSO.LOCAL", "Admin"),
Expand All @@ -72,7 +72,7 @@ fn test_dedup_users_case_insensitive() {
}

#[test]
fn test_dedup_users_different_domains() {
fn dedup_users_different_domains() {
let nb = HashMap::new();
let users = vec![
make_user("contoso.local", "admin"),
Expand All @@ -83,7 +83,7 @@ fn test_dedup_users_different_domains() {
}

#[test]
fn test_dedup_credentials_basic() {
fn dedup_credentials_basic() {
let creds = vec![
make_cred("contoso.local", "admin", "P@ss1"),
make_cred("contoso.local", "admin", "P@ss1"), // dup
Expand All @@ -94,7 +94,7 @@ fn test_dedup_credentials_basic() {
}

#[test]
fn test_dedup_credentials_case_insensitive_username() {
fn dedup_credentials_case_insensitive_username() {
let creds = vec![
make_cred("contoso.local", "Admin", "P@ss1"),
make_cred("CONTOSO.LOCAL", "admin", "P@ss1"),
Expand All @@ -104,7 +104,7 @@ fn test_dedup_credentials_case_insensitive_username() {
}

#[test]
fn test_dedup_hashes_basic() {
fn dedup_hashes_basic() {
let hashes = vec![
make_hash("contoso.local", "admin", "ntlm", "aabbccdd"),
make_hash("contoso.local", "admin", "ntlm", "aabbccdd"), // dup
Expand All @@ -115,7 +115,7 @@ fn test_dedup_hashes_basic() {
}

#[test]
fn test_dedup_hashes_case_insensitive() {
fn dedup_hashes_case_insensitive() {
let hashes = vec![
make_hash("contoso.local", "Admin", "NTLM", "AABBCCDD"),
make_hash("CONTOSO.LOCAL", "admin", "ntlm", "aabbccdd"),
Expand All @@ -125,31 +125,31 @@ fn test_dedup_hashes_case_insensitive() {
}

#[test]
fn test_normalize_source_label_empty() {
fn normalize_source_label_empty() {
assert_eq!(normalize_source_label(""), "Unknown");
}

#[test]
fn test_normalize_source_label_exact_match() {
fn normalize_source_label_exact_match() {
assert_eq!(normalize_source_label("recon"), "Reconnaissance");
assert_eq!(normalize_source_label("privesc"), "Privilege Escalation");
assert_eq!(normalize_source_label("bloodhound"), "BloodHound");
assert_eq!(normalize_source_label("secretsdump"), "Secretsdump");
}

#[test]
fn test_normalize_source_label_case_insensitive() {
fn normalize_source_label_case_insensitive() {
assert_eq!(normalize_source_label("RECON"), "Reconnaissance");
assert_eq!(normalize_source_label("BloodHound"), "BloodHound");
}

#[test]
fn test_normalize_source_label_dedup_colon() {
fn normalize_source_label_dedup_colon() {
assert_eq!(normalize_source_label("recon:recon"), "Reconnaissance");
}

#[test]
fn test_normalize_source_label_prefix_match() {
fn normalize_source_label_prefix_match() {
assert_eq!(
normalize_source_label("privesc_enumeration"),
"Privesc Enumeration"
Expand All @@ -161,23 +161,23 @@ fn test_normalize_source_label_prefix_match() {
}

#[test]
fn test_normalize_source_label_task_suffix() {
fn normalize_source_label_task_suffix() {
assert_eq!(
normalize_source_label("recon_abc12345678"),
"Reconnaissance"
);
}

#[test]
fn test_normalize_source_label_fallback() {
fn normalize_source_label_fallback() {
assert_eq!(
normalize_source_label("some_custom_source"),
"Some Custom Source"
);
}

#[test]
fn test_normalize_state_domains_corrects_cred_domain() {
fn normalize_state_domains_corrects_cred_domain() {
let users = vec![make_user("contoso.local", "admin")];
let mut creds = vec![make_cred("WRONG.local", "admin", "P@ss1")];
let mut hashes = vec![];
Expand All @@ -193,7 +193,7 @@ fn test_normalize_state_domains_corrects_cred_domain() {
}

#[test]
fn test_normalize_state_domains_dedupes_cross_domain_creds() {
fn normalize_state_domains_dedupes_cross_domain_creds() {
let users = vec![make_user("contoso.local", "admin")];
let mut creds = vec![
make_cred("contoso.local", "admin", "P@ss1"),
Expand All @@ -210,7 +210,7 @@ fn test_normalize_state_domains_dedupes_cross_domain_creds() {
}

#[test]
fn test_normalize_state_domains_preserves_well_known() {
fn normalize_state_domains_preserves_well_known() {
let users = vec![
make_user("contoso.local", "administrator"),
make_user("child.contoso.local", "administrator"),
Expand All @@ -233,7 +233,7 @@ fn test_normalize_state_domains_preserves_well_known() {
}

#[test]
fn test_sanitize_strips_password_prefix() {
fn sanitize_strips_password_prefix() {
let mut creds = vec![
make_cred("contoso.local", "jdoe", "Password: jdoe"),
make_cred("contoso.local", "admin", "password:secret"),
Expand All @@ -250,7 +250,7 @@ fn test_sanitize_strips_password_prefix() {
}

#[test]
fn test_sanitize_removes_password_only() {
fn sanitize_removes_password_only() {
let mut creds = vec![
make_cred("contoso.local", "jdoe", "Password"),
make_cred("contoso.local", "admin", "password"),
Expand All @@ -264,7 +264,7 @@ fn test_sanitize_removes_password_only() {
}

#[test]
fn test_sanitize_strips_trailing_paren_metadata() {
fn sanitize_strips_trailing_paren_metadata() {
let mut creds = vec![
make_cred("contoso.local", "svc_test", "svc_test (Guest)"),
make_cred("contoso.local", "admin", "P@ss1 (Pwn3d!)"),
Expand All @@ -278,7 +278,7 @@ fn test_sanitize_strips_trailing_paren_metadata() {
}

#[test]
fn test_sanitize_normalizes_username_with_at_domain() {
fn sanitize_normalizes_username_with_at_domain() {
let mut creds = vec![
make_cred(
"fabrikam.local",
Expand All @@ -300,7 +300,7 @@ fn test_sanitize_normalizes_username_with_at_domain() {
}

#[test]
fn test_sanitize_preserves_clean_credentials() {
fn sanitize_preserves_clean_credentials() {
let mut creds = vec![
make_cred("contoso.local", "admin", "P@ss1"),
make_cred("contoso.local", "user1", "Secret123!"),
Expand All @@ -313,7 +313,7 @@ fn test_sanitize_preserves_clean_credentials() {
}

#[test]
fn test_sanitize_removes_empty_password_after_strip() {
fn sanitize_removes_empty_password_after_strip() {
let mut creds = vec![
make_cred("contoso.local", "jdoe", "Password: "),
make_cred("contoso.local", "admin", ""),
Expand All @@ -323,7 +323,7 @@ fn test_sanitize_removes_empty_password_after_strip() {
}

#[test]
fn test_sanitize_then_dedup_collapses_variants() {
fn sanitize_then_dedup_collapses_variants() {
// jdoe:jdoe is a valid credential; "Password: jdoe" strips to "jdoe" (dup);
// "Password" is filtered as noise
let mut creds = vec![
Expand All @@ -338,7 +338,7 @@ fn test_sanitize_then_dedup_collapses_variants() {
}

#[test]
fn test_sanitize_keeps_password_equals_username() {
fn sanitize_keeps_password_equals_username() {
// password == username is valid (e.g. jdoe:jdoe)
let mut creds = vec![
make_cred("contoso.local", "admin", "admin"),
Expand Down Expand Up @@ -400,8 +400,6 @@ fn make_host(ip: &str, hostname: &str) -> Host {
}
}

// ==================== normalize_state_domains edge cases ====================

#[test]
fn normalize_state_domains_empty_inputs() {
let users: Vec<User> = vec![];
Expand Down Expand Up @@ -696,8 +694,6 @@ fn normalize_state_domains_cred_one_domain_no_matching_corrects_best() {
assert_eq!(creds[0].domain, "contoso.local");
}

// ==================== dedup_hashes edge cases ====================

#[test]
fn dedup_hashes_normalizes_hash_type() {
let hashes = vec![
Expand Down Expand Up @@ -814,8 +810,6 @@ fn dedup_hashes_unknown_hash_type_preserved() {
assert_eq!(deduped[0].hash_type, "des-cbc-md5");
}

// ==================== normalize_source_label edge cases ====================

#[test]
fn normalize_source_label_task_input_pattern() {
assert_eq!(
Expand Down Expand Up @@ -880,8 +874,6 @@ fn normalize_source_label_mixed_case_prefix_match() {
assert_eq!(normalize_source_label("Exploit_something"), "Exploitation");
}

// ==================== dedup_users edge cases ====================

#[test]
fn dedup_users_filters_noise_usernames() {
let nb = HashMap::new();
Expand Down Expand Up @@ -1025,8 +1017,6 @@ fn dedup_users_empty_source_accepted() {
assert_eq!(deduped.len(), 1);
}

// ==================== dedup_credentials additional edge cases ====================

#[test]
fn dedup_credentials_strips_trailing_dot_domains() {
let creds = vec![
Expand Down
14 changes: 7 additions & 7 deletions ares-cli/src/detection/markdown.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,19 +202,19 @@ mod tests {
}

#[test]
fn test_generate_markdown_has_header() {
fn generate_markdown_has_header() {
let md = generate_detection_markdown(&make_playbook());
assert!(md.starts_with("# Detection Playbook"));
}

#[test]
fn test_generate_markdown_has_operation_id() {
fn generate_markdown_has_operation_id() {
let md = generate_detection_markdown(&make_playbook());
assert!(md.contains("test-op"));
}

#[test]
fn test_generate_markdown_has_sections() {
fn generate_markdown_has_sections() {
let md = generate_detection_markdown(&make_playbook());
assert!(md.contains("## Executive Summary"));
assert!(md.contains("## Attack Statistics"));
Expand All @@ -224,26 +224,26 @@ mod tests {
}

#[test]
fn test_generate_markdown_has_ioc_table() {
fn generate_markdown_has_ioc_table() {
let md = generate_detection_markdown(&make_playbook());
assert!(md.contains("| Type | Value |"));
assert!(md.contains("192.168.58.10"));
}

#[test]
fn test_generate_markdown_has_footer() {
fn generate_markdown_has_footer() {
let md = generate_detection_markdown(&make_playbook());
assert!(md.contains("Generated by Ares Detection Playbook Export"));
}

#[test]
fn test_generate_markdown_has_logql() {
fn generate_markdown_has_logql() {
let md = generate_detection_markdown(&make_playbook());
assert!(md.contains("```logql"));
}

#[test]
fn test_generate_markdown_domain_admin_no() {
fn generate_markdown_domain_admin_no() {
let md = generate_detection_markdown(&make_playbook());
assert!(md.contains("**Domain Admin Achieved:** No"));
}
Expand Down
12 changes: 6 additions & 6 deletions ares-cli/src/detection/playbook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ mod tests {
}

#[test]
fn test_generate_playbook_minimal() {
fn generate_playbook_minimal() {
let state = make_state();
let playbook = generate_detection_playbook(&state, &[]);
assert_eq!(playbook.operation_id, "test-op-001");
Expand All @@ -205,7 +205,7 @@ mod tests {
}

#[test]
fn test_generate_playbook_with_hosts() {
fn generate_playbook_with_hosts() {
let mut state = make_state();
state.all_hosts = vec![Host {
ip: "192.168.58.10".to_string(),
Expand Down Expand Up @@ -235,7 +235,7 @@ mod tests {
}

#[test]
fn test_generate_playbook_with_credentials() {
fn generate_playbook_with_credentials() {
let mut state = make_state();
state.all_credentials = vec![Credential {
id: String::new(),
Expand All @@ -259,7 +259,7 @@ mod tests {
}

#[test]
fn test_generate_playbook_with_hashes() {
fn generate_playbook_with_hashes() {
let mut state = make_state();
state.all_hashes = vec![Hash {
id: String::new(),
Expand All @@ -285,7 +285,7 @@ mod tests {
}

#[test]
fn test_generate_playbook_domain_admin_summary() {
fn generate_playbook_domain_admin_summary() {
let mut state = make_state();
state.has_domain_admin = true;
state.domain_admin_path = Some("admin -> DA".to_string());
Expand All @@ -299,7 +299,7 @@ mod tests {
}

#[test]
fn test_generate_playbook_technique_detections() {
fn generate_playbook_technique_detections() {
let state = make_state();
let techniques = vec!["T1003".to_string(), "T1558.003".to_string()];
let playbook = generate_detection_playbook(&state, &techniques);
Expand Down
Loading
Loading