55of sleep duration limits.
66"""
77
8- import sys
98from unittest .mock import MagicMock , patch
109
1110import pytest
1211from pysquared .config .config import Config
1312from pysquared .logger import Logger
13+ from pysquared .sleep_helper import SleepHelper
1414from pysquared .watchdog import Watchdog
1515
16- # Create mock modules for alarm and alarm.time before importing SleepHelper
17- mock_alarm = MagicMock ()
18- mock_time_alarm = MagicMock ()
19- sys .modules ["alarm" ] = mock_alarm
20- sys .modules ["alarm.time" ] = MagicMock ()
21- sys .modules ["alarm.time" ].TimeAlarm = mock_time_alarm
22-
23- # Now we can import SleepHelper
24- from pysquared .sleep_helper import SleepHelper # noqa: E402
25-
2616
2717@pytest .fixture
2818def mock_logger () -> MagicMock :
@@ -88,31 +78,30 @@ def test_safe_sleep_within_limit(
8878 mock_logger: Mocked Logger instance.
8979 mock_watchdog: Mocked Watchdog instance.
9080 """
91- # Reset mocks
92- mock_alarm .reset_mock ()
93- mock_time_alarm .reset_mock ()
94-
95- # Setup mock time to simulate a time sequence
96- mock_time .monotonic = MagicMock ()
97- mock_time .monotonic .side_effect = [0.0 , 0.0 , 0.0 , 0.0 , 15.0 ]
81+ # Setup mock time to simulate the while loop behavior
82+ # The loop checks: while time.monotonic() < end_sleep_time
83+ mock_time .monotonic .side_effect = [
84+ 0.0 , # Initial call for end_sleep_time calculation
85+ 0.0 , # First while loop check (0.0 < 15.0 = True)
86+ 0.0 , # min() calculation for time_increment
87+ 15.0 , # Second while loop check (15.0 < 15.0 = False, exit loop)
88+ ]
89+ mock_time .sleep = MagicMock ()
9890
9991 sleep_helper .safe_sleep (15 )
10092
101- # Verify the watchdog was pet
93+ # Verify the watchdog was pet twice (once before loop, once after sleep)
10294 assert mock_watchdog .pet .call_count == 2
10395
96+ # Verify time.sleep was called with the correct increment
97+ mock_time .sleep .assert_called_once_with (15.0 )
98+
10499 # Verify no warning was logged
105100 mock_logger .warning .assert_not_called ()
106101
107102 # Verify debug log was called
108103 mock_logger .debug .assert_called_once_with ("Setting Safe Sleep Mode" , duration = 15 )
109104
110- # Verify TimeAlarm was created with correct parameters
111- mock_time_alarm .assert_called_once_with (monotonic_time = 15.0 )
112-
113- # Verify light_sleep was called with the alarm
114- mock_alarm .light_sleep_until_alarms .assert_called_once ()
115-
116105
117106@patch ("pysquared.sleep_helper.time" )
118107def test_safe_sleep_exceeds_limit (
@@ -131,18 +120,20 @@ def test_safe_sleep_exceeds_limit(
131120 mock_config: Mocked Config instance.
132121 mock_watchdog: Mocked Watchdog instance.
133122 """
134- # Reset mocks
135- mock_alarm .reset_mock ()
136- mock_time_alarm .reset_mock ()
137-
138- # Setup mock time to simulate a time sequence
139- mock_time .monotonic .side_effect = [0.0 , 0.0 , 0.0 , 0.0 , 115.0 ]
123+ # Setup mock time to simulate the while loop behavior with adjusted duration
124+ mock_time .monotonic .side_effect = [
125+ 0.0 , # Initial call for end_sleep_time calculation
126+ 0.0 , # First while loop check (0.0 < 100.0 = True)
127+ 0.0 , # min() calculation for time_increment
128+ 100.0 , # Second while loop check (100.0 < 100.0 = False, exit loop)
129+ ]
130+ mock_time .sleep = MagicMock ()
140131
141132 # Requested duration exceeds the longest allowable sleep time (which is 100)
142133 sleep_helper .safe_sleep (150 )
143134
144135 # Verify the watchdog was pet
145- mock_watchdog .pet .assert_called ()
136+ assert mock_watchdog .pet .call_count == 2
146137
147138 # Verify warning was logged
148139 mock_logger .warning .assert_called_once_with (
@@ -155,11 +146,8 @@ def test_safe_sleep_exceeds_limit(
155146 # Verify debug log was called with adjusted duration
156147 mock_logger .debug .assert_called_once_with ("Setting Safe Sleep Mode" , duration = 100 )
157148
158- # Verify TimeAlarm was created with correct parameters using adjusted duration
159- mock_time_alarm .assert_called_once_with (monotonic_time = 15.0 )
160-
161- # Verify light_sleep was called with the alarm
162- mock_alarm .light_sleep_until_alarms .assert_called_once ()
149+ # Verify time.sleep was called with the adjusted duration
150+ mock_time .sleep .assert_called_once_with (15 )
163151
164152
165153@patch ("pysquared.sleep_helper.time" )
@@ -175,37 +163,71 @@ def test_safe_sleep_multiple_watchdog_pets(
175163 sleep_helper: SleepHelper instance for testing.
176164 mock_watchdog: Mocked Watchdog instance.
177165 """
178- # Reset mocks
179- mock_alarm .reset_mock ()
180- mock_time_alarm .reset_mock ()
181-
182- # Setup mock time to simulate a time sequence where we need multiple increments
166+ # Setup mock time to simulate multiple sleep increments
183167 mock_time .monotonic .side_effect = [
184- 0.0 ,
185- 0.0 ,
186- 0.0 ,
187- 0.0 , # Initial
188- 15.0 ,
189- 15.0 ,
190- 15.0 , # First loop
191- 30.0 ,
192- 30.0 ,
193- 30.0 , # Second loop
194- 35.0 , # Last check and exit loop
168+ 0.0 , # Initial call for end_sleep_time calculation
169+ 0.0 , # First while loop check (0.0 < 35.0 = True)
170+ 0.0 , # First min() calculation (35.0 - 0.0, 15) = 15.0
171+ 15.0 , # Second while loop check (15.0 < 35.0 = True)
172+ 15.0 , # Second min() calculation (35.0 - 15.0, 15) = 15.0
173+ 30.0 , # Third while loop check (30.0 < 35.0 = True)
174+ 30.0 , # Third min() calculation (35.0 - 30.0, 15) = 5.0
175+ 35.0 , # Fourth while loop check (35.0 < 35.0 = False, exit loop)
195176 ]
177+ mock_time .sleep = MagicMock ()
196178
197179 # Call safe_sleep with a duration that will require multiple watchdog pets
198180 sleep_helper .safe_sleep (35 )
199181
200- # Verify watchdog was pet multiple times (once before sleeping + after each wake)
201- assert mock_watchdog .pet .call_count == 4 # Once before loop + three times in loop
182+ # Verify watchdog was pet multiple times (once before loop + after each sleep)
183+ assert (
184+ mock_watchdog .pet .call_count == 4
185+ ) # Once before loop + three times after each sleep
186+
187+ # Verify time.sleep was called multiple times with correct increments
188+ expected_calls = [
189+ ((15.0 ,),), # First increment: 15 seconds
190+ ((15.0 ,),), # Second increment: 15 seconds
191+ ((5.0 ,),), # Third increment: 5 seconds (remaining time)
192+ ]
193+ assert mock_time .sleep .call_args_list == expected_calls
194+
202195
203- # Verify TimeAlarm was created correctly for each increment
204- mock_time_alarm .assert_any_call (monotonic_time = 15.0 ) # 0.0 + 15.0 (first increment)
205- mock_time_alarm .assert_any_call (
206- monotonic_time = 30.0
207- ) # 15.0 + 15.0 (second increment)
208- mock_time_alarm .assert_any_call (monotonic_time = 35.0 ) # 30.0 + 5.0 (final increment)
196+ @patch ("pysquared.sleep_helper.time" )
197+ def test_safe_sleep_custom_watchdog_timeout (
198+ mock_time : MagicMock ,
199+ sleep_helper : SleepHelper ,
200+ mock_watchdog : MagicMock ,
201+ ) -> None :
202+ """Tests safe_sleep with custom watchdog timeout.
209203
210- # Verify light_sleep was called multiple times
211- assert mock_alarm .light_sleep_until_alarms .call_count == 3
204+ Args:
205+ mock_time: Mocked time module.
206+ sleep_helper: SleepHelper instance for testing.
207+ mock_watchdog: Mocked Watchdog instance.
208+ """
209+ # Setup mock time to simulate behavior with custom timeout
210+ mock_time .monotonic .side_effect = [
211+ 0.0 , # Initial call for end_sleep_time calculation
212+ 0.0 , # First while loop check (0.0 < 20.0 = True)
213+ 0.0 , # First min() calculation (20.0 - 0.0, 10) = 10.0
214+ 10.0 , # Second while loop check (10.0 < 20.0 = True)
215+ 10.0 , # Second min() calculation (20.0 - 10.0, 10) = 10.0
216+ 20.0 , # Third while loop check (20.0 < 20.0 = False, exit loop)
217+ ]
218+ mock_time .sleep = MagicMock ()
219+
220+ # Call safe_sleep with custom watchdog timeout
221+ sleep_helper .safe_sleep (20 , watchdog_timeout = 10 )
222+
223+ # Verify watchdog was pet correct number of times
224+ assert (
225+ mock_watchdog .pet .call_count == 3
226+ ) # Once before loop + twice after each sleep
227+
228+ # Verify time.sleep was called with custom timeout intervals
229+ expected_calls = [
230+ ((10.0 ,),), # First increment: 10 seconds (custom timeout)
231+ ((10.0 ,),), # Second increment: 10 seconds (custom timeout)
232+ ]
233+ assert mock_time .sleep .call_args_list == expected_calls
0 commit comments