Skip to content

Commit 689733a

Browse files
committed
Add basic unit tests for AuthMonitor
1 parent 8852b12 commit 689733a

File tree

2 files changed

+126
-0
lines changed

2 files changed

+126
-0
lines changed

src/auth_monitor.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,7 @@ impl AuthMonitor {
7070
}
7171
}
7272
}
73+
74+
#[cfg(test)]
75+
#[path = "./auth_monitor.test.rs"]
76+
mod test;

src/auth_monitor.test.rs

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
use std::thread::sleep;
2+
use std::time::Duration;
3+
4+
use crate::auth_monitor::AuthMonitor;
5+
use crate::auth_monitor_options::AuthMonitorOptions;
6+
use crate::auth_monitor_params::AuthMonitorParams;
7+
use crate::test_utils::test_file::{create_log_line, TestFile};
8+
9+
const AUTH_FAILED_TEST_MESSAGES: [&str; 2] = [
10+
"workstation sudo: pam_unix(sudo:auth): authentication failure; logname=john uid=1000 euid=0 tty=/dev/pts/7 ruser=john rhost= user=john",
11+
"workstation kscreenlocker_greet: pam_unix(kde:auth): authentication failure; logname= uid=1000 euid=1000 tty= ruser= rhost= user=john",
12+
];
13+
14+
const OTHER_TEST_MESSAGES: [&str; 4] = [
15+
"workstation dbus-daemon[1988]: [system] Failed to activate service 'org.bluez': timed out (service_start_timeout=25000ms)",
16+
"workstation CRON[9419]: pam_unix(cron:session): session opened for user root(uid=0) by (uid=0)",
17+
"workstation CRON[9419]: pam_unix(cron:session): session closed for user root",
18+
"workstation PackageKit: uid 1000 is trying to obtain org.freedesktop.packagekit.system-sources-refresh auth (only_trusted:0)",
19+
];
20+
21+
#[test]
22+
pub fn when_max_failed_attempts_limit_is_reached_then_update_callback_is_called() {
23+
for max_failed_attempts in 2..10 {
24+
let mut file = TestFile::new("auth-monitor");
25+
let mut auth_monitor = AuthMonitor::new(AuthMonitorParams {
26+
filepath: file.filepath.clone(),
27+
options: AuthMonitorOptions {
28+
max_failed_attempts,
29+
..AuthMonitorOptions::default()
30+
},
31+
})
32+
.expect("Error creating AuthMonitor");
33+
auth_monitor.update(|| panic!("Callback call was not expected"));
34+
35+
expect_update_callback_is_not_called_after_writing_auth_failed_messages(
36+
&mut auth_monitor,
37+
&mut file,
38+
(max_failed_attempts - 1) as usize,
39+
);
40+
41+
expect_update_callback_is_not_called_after_writing_other_messages(
42+
&mut auth_monitor,
43+
&mut file,
44+
);
45+
46+
expect_update_callback_is_called_after_writing_auth_failed_message(
47+
&mut auth_monitor,
48+
&mut file,
49+
);
50+
}
51+
}
52+
53+
fn expect_update_callback_is_not_called_after_writing_auth_failed_messages(
54+
auth_monitor: &mut AuthMonitor,
55+
file: &mut TestFile,
56+
message_count: usize,
57+
) {
58+
for i in 0usize..message_count {
59+
let message_index = i % AUTH_FAILED_TEST_MESSAGES.len();
60+
let message = create_log_line(AUTH_FAILED_TEST_MESSAGES[message_index]);
61+
file.write(&message);
62+
auth_monitor.update(|| panic!("Callback call was not expected"));
63+
}
64+
}
65+
66+
fn expect_update_callback_is_not_called_after_writing_other_messages(
67+
auth_monitor: &mut AuthMonitor,
68+
file: &mut TestFile,
69+
) {
70+
for other_message in OTHER_TEST_MESSAGES {
71+
let message = create_log_line(other_message);
72+
file.write(&message);
73+
auth_monitor.update(|| panic!("Callback call was not expected"));
74+
}
75+
}
76+
77+
fn expect_update_callback_is_called_after_writing_auth_failed_message(
78+
auth_monitor: &mut AuthMonitor,
79+
file: &mut TestFile,
80+
) {
81+
let message = create_log_line(AUTH_FAILED_TEST_MESSAGES[0]);
82+
file.write(&message);
83+
let mut call_count = 0;
84+
auth_monitor.update(|| call_count += 1);
85+
assert_eq!(call_count, 1, "One callback call was expected")
86+
}
87+
88+
#[test]
89+
pub fn when_reset_after_seconds_passed_then_failed_attempts_count_is_reset() {
90+
let options = AuthMonitorOptions {
91+
max_failed_attempts: 3,
92+
reset_after_seconds: 5,
93+
};
94+
let mut file = TestFile::new("auth-monitor");
95+
let mut auth_monitor = AuthMonitor::new(AuthMonitorParams {
96+
filepath: file.filepath.clone(),
97+
options,
98+
})
99+
.expect("Error creating AuthMonitor");
100+
auth_monitor.update(|| panic!("Callback call was not expected"));
101+
102+
expect_update_callback_is_not_called_after_writing_auth_failed_messages(
103+
&mut auth_monitor,
104+
&mut file,
105+
(options.max_failed_attempts - 1) as usize,
106+
);
107+
108+
let sleep_duration = Duration::from_secs((options.reset_after_seconds + 1) as u64);
109+
println!("Sleeping for {} sec", sleep_duration.as_secs());
110+
sleep(sleep_duration);
111+
112+
expect_update_callback_is_not_called_after_writing_auth_failed_messages(
113+
&mut auth_monitor,
114+
&mut file,
115+
(options.max_failed_attempts - 1) as usize,
116+
);
117+
118+
expect_update_callback_is_called_after_writing_auth_failed_message(
119+
&mut auth_monitor,
120+
&mut file,
121+
);
122+
}

0 commit comments

Comments
 (0)