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