@@ -176,7 +176,7 @@ def set_mock_group_infos(
176176 }
177177
178178 monkeypatch .setattr (dragon_backend , "_group_infos" , group_infos )
179- monkeypatch .setattr (dragon_backend , "_allocated_hosts" , {hosts [0 ]: "abc123-1" })
179+ monkeypatch .setattr (dragon_backend , "_allocated_hosts" , {hosts [0 ]: { "abc123-1" } })
180180 monkeypatch .setattr (dragon_backend , "_running_steps" , ["abc123-1" ])
181181
182182 return group_infos
@@ -221,8 +221,8 @@ def test_run_request(monkeypatch: pytest.MonkeyPatch) -> None:
221221 assert dragon_backend ._running_steps == [step_id ]
222222 assert len (dragon_backend ._queued_steps ) == 0
223223 assert len (dragon_backend .free_hosts ) == 1
224- assert dragon_backend ._allocated_hosts [dragon_backend .hosts [0 ]] == step_id
225- assert dragon_backend ._allocated_hosts [dragon_backend .hosts [1 ]] == step_id
224+ assert step_id in dragon_backend ._allocated_hosts [dragon_backend .hosts [0 ]]
225+ assert step_id in dragon_backend ._allocated_hosts [dragon_backend .hosts [1 ]]
226226
227227 monkeypatch .setattr (
228228 dragon_backend ._group_infos [step_id ].process_group , "status" , "Running"
@@ -233,8 +233,8 @@ def test_run_request(monkeypatch: pytest.MonkeyPatch) -> None:
233233 assert dragon_backend ._running_steps == [step_id ]
234234 assert len (dragon_backend ._queued_steps ) == 0
235235 assert len (dragon_backend .free_hosts ) == 1
236- assert dragon_backend ._allocated_hosts [dragon_backend .hosts [0 ]] == step_id
237- assert dragon_backend ._allocated_hosts [dragon_backend .hosts [1 ]] == step_id
236+ assert step_id in dragon_backend ._allocated_hosts [dragon_backend .hosts [0 ]]
237+ assert step_id in dragon_backend ._allocated_hosts [dragon_backend .hosts [1 ]]
238238
239239 dragon_backend ._group_infos [step_id ].status = SmartSimStatus .STATUS_CANCELLED
240240
@@ -316,8 +316,8 @@ def test_run_request_with_policy(monkeypatch: pytest.MonkeyPatch) -> None:
316316 assert dragon_backend ._running_steps == [step_id ]
317317 assert len (dragon_backend ._queued_steps ) == 0
318318 assert len (dragon_backend ._prioritizer .unassigned ()) == 1
319- assert dragon_backend ._allocated_hosts [dragon_backend .hosts [0 ]] == step_id
320- assert dragon_backend ._allocated_hosts [dragon_backend .hosts [1 ]] == step_id
319+ assert step_id in dragon_backend ._allocated_hosts [dragon_backend .hosts [0 ]]
320+ assert step_id in dragon_backend ._allocated_hosts [dragon_backend .hosts [1 ]]
321321
322322 monkeypatch .setattr (
323323 dragon_backend ._group_infos [step_id ].process_group , "status" , "Running"
@@ -328,8 +328,8 @@ def test_run_request_with_policy(monkeypatch: pytest.MonkeyPatch) -> None:
328328 assert dragon_backend ._running_steps == [step_id ]
329329 assert len (dragon_backend ._queued_steps ) == 0
330330 assert len (dragon_backend ._prioritizer .unassigned ()) == 1
331- assert dragon_backend ._allocated_hosts [dragon_backend .hosts [0 ]] == step_id
332- assert dragon_backend ._allocated_hosts [dragon_backend .hosts [1 ]] == step_id
331+ assert step_id in dragon_backend ._allocated_hosts [dragon_backend .hosts [0 ]]
332+ assert step_id in dragon_backend ._allocated_hosts [dragon_backend .hosts [1 ]]
333333
334334 dragon_backend ._group_infos [step_id ].status = SmartSimStatus .STATUS_CANCELLED
335335
@@ -635,7 +635,8 @@ def test_view(monkeypatch: pytest.MonkeyPatch) -> None:
635635 hosts = dragon_backend .hosts
636636 dragon_backend ._prioritizer .increment (hosts [0 ])
637637
638- expected_msg = textwrap .dedent (f"""\
638+ expected_msg = textwrap .dedent (
639+ f"""\
639640 Dragon server backend update
640641 | Host | Status |
641642 |--------|----------|
@@ -648,7 +649,8 @@ def test_view(monkeypatch: pytest.MonkeyPatch) -> None:
648649 | del999-2 | Cancelled | { hosts [1 ]} | -9 | 1 |
649650 | c101vz-3 | Completed | { hosts [1 ]} ,{ hosts [2 ]} | 0 | 2 |
650651 | 0ghjk1-4 | Failed | { hosts [2 ]} | -1 | 1 |
651- | ljace0-5 | NeverStarted | | | 0 |""" )
652+ | ljace0-5 | NeverStarted | | | 0 |"""
653+ )
652654
653655 # get rid of white space to make the comparison easier
654656 actual_msg = dragon_backend .status_message .replace (" " , "" )
@@ -728,3 +730,36 @@ def test_can_honor_hosts_unavailable_hosts_ok(monkeypatch: pytest.MonkeyPatch) -
728730 assert can_honor , error_msg
729731 # confirm failure message indicates number of nodes requested as cause
730732 assert error_msg is None , error_msg
733+
734+
735+ def test_can_honor_hosts_1_hosts_requested (monkeypatch : pytest .MonkeyPatch ) -> None :
736+ """Verify that requesting nodes with invalid names causes number of available
737+ nodes check to be reduced but still passes if enough valid named nodes are passed"""
738+ dragon_backend = get_mock_backend (monkeypatch , num_cpus = 8 , num_gpus = 0 )
739+
740+ # let's supply 2 valid and 1 invalid hostname
741+ actual_hosts = list (dragon_backend ._hosts )
742+ actual_hosts [0 ] = f"x{ actual_hosts [0 ]} "
743+
744+ host_list = "," .join (actual_hosts )
745+
746+ run_req = DragonRunRequest (
747+ exe = "sleep" ,
748+ exe_args = ["5" ],
749+ path = "/a/fake/path" ,
750+ nodes = 1 , # <----- requesting 0 nodes - should be ignored
751+ hostlist = host_list , # <--- two valid names are available
752+ tasks = 1 ,
753+ tasks_per_node = 1 ,
754+ env = {},
755+ current_env = {},
756+ pmi_enabled = False ,
757+ policy = DragonRunPolicy (),
758+ )
759+
760+ can_honor , error_msg = dragon_backend ._can_honor (run_req )
761+
762+ # confirm the failure is indicated
763+ assert can_honor , error_msg
764+ # # confirm failure message indicates number of nodes requested as cause
765+ # assert error_msg is None, error_msg
0 commit comments