1 // Copyright 2021, The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 //! Watchdog tests.
16
17 use super::*;
18 use std::sync::atomic;
19 use std::thread;
20 use std::time::Duration;
21
22 /// Count the number of times `Debug::fmt` is invoked.
23 #[derive(Default, Clone)]
24 struct DebugCounter(Arc<atomic::AtomicU8>);
25 impl DebugCounter {
value(&self) -> u826 fn value(&self) -> u8 {
27 self.0.load(atomic::Ordering::Relaxed)
28 }
29 }
30 impl std::fmt::Debug for DebugCounter {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error>31 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
32 let count = self.0.fetch_add(1, atomic::Ordering::Relaxed);
33 write!(f, "hit_count: {count}")
34 }
35 }
36
37 #[test]
test_watchdog()38 fn test_watchdog() {
39 android_logger::init_once(
40 android_logger::Config::default()
41 .with_tag("keystore2_watchdog_tests")
42 .with_max_level(log::LevelFilter::Debug),
43 );
44
45 let wd = Watchdog::new(Duration::from_secs(3));
46 let hit_counter = DebugCounter::default();
47 let wp =
48 Watchdog::watch_with(&wd, "test_watchdog", Duration::from_millis(100), hit_counter.clone());
49 assert_eq!(0, hit_counter.value());
50 thread::sleep(Duration::from_millis(500));
51 assert_eq!(1, hit_counter.value());
52 thread::sleep(Duration::from_secs(1));
53 assert_eq!(1, hit_counter.value());
54
55 drop(wp);
56 thread::sleep(Duration::from_secs(10));
57 assert_eq!(1, hit_counter.value());
58 let (_, ref state) = *wd.state;
59 let state = state.lock().unwrap();
60 assert_eq!(state.state, State::NotRunning);
61 }
62
63 #[test]
test_watchdog_backoff()64 fn test_watchdog_backoff() {
65 android_logger::init_once(
66 android_logger::Config::default()
67 .with_tag("keystore2_watchdog_tests")
68 .with_max_level(log::LevelFilter::Debug),
69 );
70
71 let wd = Watchdog::new(Duration::from_secs(3));
72 let hit_counter = DebugCounter::default();
73 let wp =
74 Watchdog::watch_with(&wd, "test_watchdog", Duration::from_millis(100), hit_counter.clone());
75 assert_eq!(0, hit_counter.value());
76 thread::sleep(Duration::from_millis(500));
77 assert_eq!(1, hit_counter.value());
78 thread::sleep(Duration::from_secs(6));
79 assert_eq!(2, hit_counter.value());
80 thread::sleep(Duration::from_secs(11));
81 assert_eq!(3, hit_counter.value());
82
83 drop(wp);
84 thread::sleep(Duration::from_secs(4));
85 assert_eq!(3, hit_counter.value());
86 }
87