@@ -91,3 +91,55 @@ def test_the_runner_relays_the_infrastructure_exit_code(tmp_path, monitor_exit):
9191 timeout = 180 ,
9292 )
9393 assert result .returncode == monitor_exit
94+
95+
96+ def test_monitor_fails_a_job_slurm_marked_failed_despite_a_zero_exit_code (slurm ):
97+ """A terminal state of FAILED is a failure even when ExitCode reads 0:0.
98+
99+ SLURM reports that combination intermittently on Phoenix. Deciding purely on
100+ the exit code turned those jobs green with the test failures still in the
101+ log -- 5 of 9 "successful" gpu-acc runs on master were hiding 23 failing
102+ tests this way.
103+ """
104+ tmp_path , binz , configure = slurm
105+ out = configure ("0:0" , state = "FAILED" )
106+ assert run_script (tmp_path , binz , "monitor_slurm_job.sh" , "1234" , str (out )).returncode == 1
107+
108+
109+ def test_monitor_still_passes_a_genuinely_completed_job (slurm ):
110+ """The guard above must not turn healthy jobs red."""
111+ tmp_path , binz , configure = slurm
112+ out = configure ("0:0" , state = "COMPLETED" )
113+ assert run_script (tmp_path , binz , "monitor_slurm_job.sh" , "1234" , str (out )).returncode == 0
114+
115+
116+ # Every terminal state SLURM can report for a job that did not complete. The pairing
117+ # with 0:0 is the one the scheduler actually produces intermittently, and the one that
118+ # used to be read as success.
119+ NOT_COMPLETED = [
120+ "FAILED" ,
121+ "CANCELLED" ,
122+ "CANCELLED+" ,
123+ "TIMEOUT" ,
124+ "OUT_OF_MEMORY" ,
125+ "NODE_FAIL" ,
126+ "BOOT_FAIL" ,
127+ "DEADLINE" ,
128+ "REVOKED" ,
129+ ]
130+
131+
132+ @pytest .mark .parametrize ("state" , NOT_COMPLETED )
133+ def test_a_zero_exit_code_does_not_rescue_a_job_that_did_not_complete (slurm , state ):
134+ tmp_path , binz , configure = slurm
135+ out = configure ("0:0" , state = state )
136+ assert run_script (tmp_path , binz , "monitor_slurm_job.sh" , "1234" , str (out )).returncode == 1
137+
138+
139+ @pytest .mark .parametrize ("state" , NOT_COMPLETED )
140+ def test_an_infrastructure_fault_still_outranks_the_state (slurm , state ):
141+ """77 has to survive: the submit wrapper uses it to exclude the node and resubmit,
142+ and flattening it to a generic failure would strand the job on a bad node."""
143+ tmp_path , binz , configure = slurm
144+ out = configure ("77:0" , state = state )
145+ assert run_script (tmp_path , binz , "monitor_slurm_job.sh" , "1234" , str (out )).returncode == 77
0 commit comments