diff --git a/testing.conf b/testing.conf index 2b04247e..a0435189 100644 --- a/testing.conf +++ b/testing.conf @@ -115,6 +115,14 @@ executors = auto queue_name = +# +# If a different queue is used for multi-node jobs, specify it here. If empty, +# queue_name is used for both single-node and multi-node jobs. +# + +multi_node_queue_name = + + # # If you need a project/account for billing purposes, enter it here. # diff --git a/tests/_test_tools.py b/tests/_test_tools.py index 2517bd00..a5666af9 100644 --- a/tests/_test_tools.py +++ b/tests/_test_tools.py @@ -8,7 +8,7 @@ from executor_test_params import ExecutorTestParams -from psij import JobStatus, JobState, Job, JobExecutor, JobAttributes +from psij import JobStatus, JobState, Job, JobExecutor, JobAttributes, ResourceSpecV1 _QUICK_EXECUTORS = set(['local', 'batch-test']) @@ -51,11 +51,16 @@ def _get_executor_instance(ep: ExecutorTestParams, job: Optional[Job] = None) -> if job is not None: assert job.spec is not None job.spec.launcher = ep.launcher - job.spec.attributes = JobAttributes(custom_attributes=ep.custom_attributes) + attrs = JobAttributes(custom_attributes=ep.custom_attributes) + job.spec.attributes = attrs if ep.account is not None: - job.spec.attributes.account = ep.account + attrs.account = ep.account + res = job.spec.resources if ep.queue_name is not None: - job.spec.attributes.queue_name = ep.queue_name + attrs.queue_name = ep.queue_name + if (res and isinstance(res, ResourceSpecV1) and res.computed_node_count > 1 + and ep.multi_node_queue_name is not None): + attrs.queue_name = ep.multi_node_queue_name return JobExecutor.get_instance(ep.executor, url=ep.url) diff --git a/tests/ci_runner.py b/tests/ci_runner.py index 5af69a36..b3c47553 100755 --- a/tests/ci_runner.py +++ b/tests/ci_runner.py @@ -147,11 +147,13 @@ def run_branch_tests(conf: Dict[str, str], dir: Path, run_id: str, clone: bool = args.append('--branch-name-override') args.append(fake_branch_name) for opt in ['maintainer_email', 'executors', 'server_url', 'key', 'max_age', - 'custom_attributes', 'queue_name', 'project_name', 'account']: + 'custom_attributes', 'queue_name', 'multi_node_queue_name', + 'project_name', 'account']: try: val = get_conf(conf, opt) - args.append('--' + opt.replace('_', '-')) - args.append(val) + if val != '': + args.append('--' + opt.replace('_', '-')) + args.append(val) except KeyError: # sometimes options get added; when they do, they could prevent # old test cycles from working, if their configs don't contain diff --git a/tests/executor_test_params.py b/tests/executor_test_params.py index 6c864a94..4e9487ad 100644 --- a/tests/executor_test_params.py +++ b/tests/executor_test_params.py @@ -6,6 +6,7 @@ class ExecutorTestParams: """A class holding executor, launcher, url pairs.""" def __init__(self, spec: str, queue_name: Optional[str] = None, + multi_node_queue_name: Optional[str] = None, account: Optional[str] = None, custom_attributes_raw: Optional[Dict[str, Dict[str, object]]] = None) \ -> None: @@ -19,6 +20,9 @@ def __init__(self, spec: str, queue_name: Optional[str] = None, url are specified, the string should be formatted as "::". queue_name An optional queue to submit the job to + multi_node_queue_name + An optional multi-node queue name used for multi-node jobs. If not specified, + `queue_name` is used for both single and multi-node jobs. account An optional account to use for billing purposes. custom_attributes @@ -35,6 +39,10 @@ def __init__(self, spec: str, queue_name: Optional[str] = None, self.url = None self.queue_name = queue_name + if multi_node_queue_name is None: + self.multi_node_queue_name = queue_name + else: + self.multi_node_queue_name = multi_node_queue_name self.account = account self.custom_attributes_raw = custom_attributes_raw self.custom_attributes: Dict[str, object] = {}