@@ -74,6 +74,7 @@ def test_fwts_path_on_i386_with_defaults(
7474
7575
7676@patch ("suspend_trigger.fwts_test" )
77+ @patch ("suspend_trigger.subprocess.check_output" )
7778@patch ("suspend_trigger.subprocess.check_call" )
7879@patch ("suspend_trigger.platform.machine" )
7980@patch ("os.remove" )
@@ -85,12 +86,14 @@ def test_rtcwake_path_success_with_args(
8586 mock_remove ,
8687 mock_machine ,
8788 mock_check_call ,
89+ mock_check_output ,
8890 mock_fwts_test ,
8991 ):
9092 """
9193 Tests the rtcwake/systemctl path on aarch64 with custom arguments.
9294 """
9395 mock_machine .return_value = "aarch64"
96+ mock_check_output .return_value = "No jobs listed."
9497
9598 suspend_trigger .main (
9699 ["--sleep-delay" , "25" , "--rtc-device" , "/dev/my_rtc" ]
@@ -108,25 +111,34 @@ def test_rtcwake_path_success_with_args(
108111 "25" ,
109112 ]
110113 expected_suspend_cmd = ["systemctl" , "suspend" ]
114+ expected_list_cmd = ["systemctl" , "list-jobs" , "*suspend*" ]
115+ mock_check_output .assert_called_with (
116+ expected_list_cmd ,
117+ stderr = subprocess .STDOUT ,
118+ universal_newlines = True ,
119+ )
111120 subprocess_calls = [
112121 call (expected_rtcwake_cmd ),
113122 call (expected_suspend_cmd ),
114123 ]
115124 mock_check_call .assert_has_calls (subprocess_calls )
116125 self .assertEqual (mock_check_call .call_count , 2 )
126+ self .assertEqual (mock_check_output .call_count , 1 )
117127
118128 def test_rtcwake_path_with_defaults (
119129 self ,
120130 mock_exists ,
121131 mock_remove ,
122132 mock_machine ,
123133 mock_check_call ,
134+ mock_check_output ,
124135 mock_fwts_test ,
125136 ):
126137 """
127138 Tests the rtcwake/systemctl path without any argument.
128139 """
129140 mock_machine .return_value = "riscv64"
141+ mock_check_output .return_value = "No jobs listed."
130142
131143 suspend_trigger .main ([])
132144
@@ -141,24 +153,64 @@ def test_rtcwake_path_with_defaults(
141153 "30" ,
142154 ]
143155 expected_suspend_cmd = ["systemctl" , "suspend" ]
156+ expected_list_cmd = ["systemctl" , "list-jobs" , "*suspend*" ]
157+ mock_check_output .assert_called_with (
158+ expected_list_cmd ,
159+ stderr = subprocess .STDOUT ,
160+ universal_newlines = True ,
161+ )
144162 subprocess_calls = [
145163 call (expected_rtcwake_cmd ),
146164 call (expected_suspend_cmd ),
147165 ]
148166 mock_check_call .assert_has_calls (subprocess_calls )
149167
168+ def test_list_command_failure (
169+ self ,
170+ mock_exists ,
171+ mock_remove ,
172+ mock_machine ,
173+ mock_check_call ,
174+ mock_check_output ,
175+ mock_fwts_test ,
176+ ):
177+ """
178+ Tests the case where the systemctl list-jobs *suspend* fails.
179+ """
180+ mock_machine .return_value = "aarch64"
181+ mock_check_output .return_value = "Suspend jobs ongoing, waiting..."
182+ # Simulate a command failure
183+ error = subprocess .CalledProcessError (
184+ returncode = 1 ,
185+ cmd = "systemctl list-jobs *suspend*" ,
186+ output = "Timed out waiting for suspend jobs to finish"
187+ )
188+ mock_check_output .side_effect = error
189+
190+ # The script should propagate the exception
191+ with self .assertRaises (subprocess .CalledProcessError ):
192+ suspend_trigger .main ([])
193+
194+ # Verify that only the first 2 commands were attempted
195+ self .assertTrue (mock_check_output .called )
196+ called_args = mock_check_output .call_args [0 ][0 ]
197+ self .assertEqual (called_args [0 ], "systemctl" )
198+ self .assertEqual (called_args [1 ], "list-jobs" )
199+
150200 def test_rtcwake_command_failure (
151201 self ,
152202 mock_exists ,
153203 mock_remove ,
154204 mock_machine ,
155205 mock_check_call ,
206+ mock_check_output ,
156207 mock_fwts_test ,
157208 ):
158209 """
159210 Tests the case where the rtcwake command fails.
160211 """
161212 mock_machine .return_value = "aarch64"
213+ mock_check_output .return_value = "No jobs listed."
162214 # Simulate a command failure
163215 error = subprocess .CalledProcessError (
164216 returncode = 1 , cmd = "rtcwake" , output = "Error from rtcwake"
@@ -169,7 +221,8 @@ def test_rtcwake_command_failure(
169221 with self .assertRaises (subprocess .CalledProcessError ):
170222 suspend_trigger .main ([])
171223
172- # Verify that only the first command (rtcwake) was attempted
224+ # Verify that only the first 2 commands were attempted
225+ self .assertTrue (mock_check_output .called )
173226 self .assertTrue (mock_check_call .called )
174227 self .assertIn ("rtcwake" , mock_check_call .call_args [0 ][0 ])
175228
@@ -179,12 +232,14 @@ def test_suspend_command_failure(
179232 mock_remove ,
180233 mock_machine ,
181234 mock_check_call ,
235+ mock_check_output ,
182236 mock_fwts_test ,
183237 ):
184238 """
185239 Tests the case where the systemctl suspend command fails.
186240 """
187241 mock_machine .return_value = "aarch64"
242+ mock_check_output .return_value = "No jobs listed."
188243 suspend_error = subprocess .CalledProcessError (
189244 returncode = 1 , cmd = "systemctl suspend" , output = "Error from suspend"
190245 )
@@ -195,6 +250,7 @@ def test_suspend_command_failure(
195250 suspend_trigger .main ([])
196251
197252 # Verify both commands were attempted
253+ self .assertTrue (mock_check_output .called )
198254 self .assertEqual (mock_check_call .call_count , 2 )
199255 self .assertIn ("rtcwake" , mock_check_call .call_args_list [0 ][0 ][0 ])
200256 self .assertIn ("systemctl" , mock_check_call .call_args_list [1 ][0 ][0 ])
@@ -205,6 +261,7 @@ def test_log_file_removed_if_exists(
205261 mock_remove ,
206262 mock_machine ,
207263 mock_check_call ,
264+ mock_check_output ,
208265 mock_fwts_test ,
209266 ):
210267 """
@@ -214,10 +271,17 @@ def test_log_file_removed_if_exists(
214271 mock_machine .return_value = "aarch64"
215272 mock_exists .return_value = True # Simulate file exists
216273 mock_check_call .side_effect = [None , None ]
274+ mock_check_output .return_value = "No jobs listed."
217275
218276 suspend_trigger .main ([])
219277
220278 # Verify commands were called
279+ expected_list_cmd = ["systemctl" , "list-jobs" , "*suspend*" ]
280+ mock_check_output .assert_called_with (
281+ expected_list_cmd ,
282+ stderr = subprocess .STDOUT ,
283+ universal_newlines = True ,
284+ )
221285 expected_rtcwake_cmd = [
222286 "rtcwake" ,
223287 "--verbose" ,
@@ -246,6 +310,7 @@ def test_log_file_not_removed_if_missing(
246310 mock_remove ,
247311 mock_machine ,
248312 mock_check_call ,
313+ mock_check_output ,
249314 mock_fwts_test ,
250315 ):
251316 """
@@ -254,6 +319,7 @@ def test_log_file_not_removed_if_missing(
254319 mock_machine .return_value = "aarch64"
255320 mock_exists .return_value = False # Simulate file missing
256321 mock_check_call .side_effect = [None , None ]
322+ mock_check_output .return_value = "No jobs listed."
257323
258324 suspend_trigger .main ([])
259325 # Verify remove was never called
0 commit comments