@@ -176,7 +176,7 @@ def set_mock_group_infos(
176
176
}
177
177
178
178
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" } })
180
180
monkeypatch .setattr (dragon_backend , "_running_steps" , ["abc123-1" ])
181
181
182
182
return group_infos
@@ -221,8 +221,8 @@ def test_run_request(monkeypatch: pytest.MonkeyPatch) -> None:
221
221
assert dragon_backend ._running_steps == [step_id ]
222
222
assert len (dragon_backend ._queued_steps ) == 0
223
223
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 ]]
226
226
227
227
monkeypatch .setattr (
228
228
dragon_backend ._group_infos [step_id ].process_group , "status" , "Running"
@@ -233,8 +233,8 @@ def test_run_request(monkeypatch: pytest.MonkeyPatch) -> None:
233
233
assert dragon_backend ._running_steps == [step_id ]
234
234
assert len (dragon_backend ._queued_steps ) == 0
235
235
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 ]]
238
238
239
239
dragon_backend ._group_infos [step_id ].status = SmartSimStatus .STATUS_CANCELLED
240
240
@@ -316,8 +316,8 @@ def test_run_request_with_policy(monkeypatch: pytest.MonkeyPatch) -> None:
316
316
assert dragon_backend ._running_steps == [step_id ]
317
317
assert len (dragon_backend ._queued_steps ) == 0
318
318
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 ]]
321
321
322
322
monkeypatch .setattr (
323
323
dragon_backend ._group_infos [step_id ].process_group , "status" , "Running"
@@ -328,8 +328,8 @@ def test_run_request_with_policy(monkeypatch: pytest.MonkeyPatch) -> None:
328
328
assert dragon_backend ._running_steps == [step_id ]
329
329
assert len (dragon_backend ._queued_steps ) == 0
330
330
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 ]]
333
333
334
334
dragon_backend ._group_infos [step_id ].status = SmartSimStatus .STATUS_CANCELLED
335
335
@@ -635,7 +635,8 @@ def test_view(monkeypatch: pytest.MonkeyPatch) -> None:
635
635
hosts = dragon_backend .hosts
636
636
dragon_backend ._prioritizer .increment (hosts [0 ])
637
637
638
- expected_msg = textwrap .dedent (f"""\
638
+ expected_msg = textwrap .dedent (
639
+ f"""\
639
640
Dragon server backend update
640
641
| Host | Status |
641
642
|--------|----------|
@@ -648,7 +649,8 @@ def test_view(monkeypatch: pytest.MonkeyPatch) -> None:
648
649
| del999-2 | Cancelled | { hosts [1 ]} | -9 | 1 |
649
650
| c101vz-3 | Completed | { hosts [1 ]} ,{ hosts [2 ]} | 0 | 2 |
650
651
| 0ghjk1-4 | Failed | { hosts [2 ]} | -1 | 1 |
651
- | ljace0-5 | NeverStarted | | | 0 |""" )
652
+ | ljace0-5 | NeverStarted | | | 0 |"""
653
+ )
652
654
653
655
# get rid of white space to make the comparison easier
654
656
actual_msg = dragon_backend .status_message .replace (" " , "" )
@@ -728,3 +730,36 @@ def test_can_honor_hosts_unavailable_hosts_ok(monkeypatch: pytest.MonkeyPatch) -
728
730
assert can_honor , error_msg
729
731
# confirm failure message indicates number of nodes requested as cause
730
732
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