@@ -200,9 +200,10 @@ def test_build_kernel_success(self, mock_run):
200200 config = mock .Mock ()
201201 config .get .return_value = None
202202
203- result = build_kernel (config , '/tmp/tree' )
203+ with tempfile .TemporaryDirectory () as tmpdir :
204+ result = build_kernel (config , tmpdir )
204205
205- # Should call make mrproper, defconfig, main build, and kernelversion
206+ # Should call make mrproper, defconfig, main build, and kernelrelease
206207 make_calls = [c for c in mock_run .call_args_list
207208 if 'make' in str (c )]
208209 self .assertTrue (len (make_calls ) >= 4 )
@@ -455,13 +456,13 @@ def test_self_reboot_skips_power_cycle(self, _mock_sleep,
455456 """Full flow: crash detected, then self-reboot seen in SOL,
456457 verify power_cycle is NOT called."""
457458 mock_run .return_value = mock .Mock (returncode = 0 , stdout = b'' , stderr = b'' )
458- mock_monotonic . side_effect = [
459- 0 , # start_time
460- 10 , # elapsed check (poll 1)
461- 10 , # crash_detected_at set
462- 20 , # elapsed check (poll 2)
463- 30 , # elapsed check (poll 3)
464- ]
459+ _clock = { 't' : 0 }
460+
461+ def monotonic ():
462+ _clock [ 't' ] += 10
463+ return _clock [ 't' ]
464+
465+ mock_monotonic . side_effect = monotonic
465466
466467 from lib .deployer import wait_for_results
467468
@@ -474,10 +475,12 @@ def test_self_reboot_skips_power_cycle(self, _mock_sleep,
474475 }.get (key , fallback )
475476
476477 mc = mock .Mock ()
478+ # Seed: initial SOL cursor position
477479 # Poll 1: SOL shows crash
478480 # Poll 2: SOL shows reboot (early boot line) -> triggers recovery
479481 # Poll 3: clean (after recovery, hw-worker completes)
480482 mc .get_sol_logs .side_effect = [
483+ {'last_id' : 50 , 'lines' : []}, # seed
481484 {
482485 'last_id' : 100 ,
483486 'lines' : [{'line' : '] RIP: 0010:bad_func+0x10' }],
@@ -492,20 +495,19 @@ def test_self_reboot_skips_power_cycle(self, _mock_sleep,
492495 },
493496 ]
494497
495- # hw-worker: active on polls 1-2, completed on poll 3
498+ # hw-worker: activating on polls 1-2 (crash + reboot), results on poll 3
496499 poll_num = {'n' : 0 }
497500
498501 def ssh_retcode_side_effect (ip , cmd , timeout = 30 ):
499502 if 'test -f' in cmd :
500- return 0 # results exist
503+ # No results until after recovery (poll 3)
504+ return 1 if poll_num ['n' ] < 3 else 0
501505 return 0
502506
503507 def ssh_side_effect (ip , cmd , check = True , timeout = 30 ):
504508 if 'systemctl show' in cmd :
505509 poll_num ['n' ] += 1
506- if poll_num ['n' ] <= 2 :
507- return 'activating\n '
508- return 'active\n '
510+ return 'activating\n '
509511 return ''
510512
511513 with mock .patch ('lib.deployer._ssh_retcode' ,
@@ -515,10 +517,10 @@ def ssh_side_effect(ip, cmd, check=True, timeout=30):
515517 with mock .patch ('lib.deployer._crash_recover' ) as mock_recover :
516518 wait_for_results (config , mc , 42 , [1 ], ['10.0.0.1' ])
517519
518- # Should have been called with skip_power_cycle=True
519- mock_recover .assert_called_once ()
520- _ , kwargs = mock_recover .call_args
521- self .assertTrue (kwargs .get ('skip_power_cycle' , False ))
520+ # Should have been called with skip_power_cycle=True
521+ mock_recover .assert_called_once ()
522+ _ , kwargs = mock_recover .call_args
523+ self .assertTrue (kwargs .get ('skip_power_cycle' , False ))
522524
523525 @mock .patch ('subprocess.run' )
524526 @mock .patch ('time.monotonic' )
0 commit comments