Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions packages/python/openproblems/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

* Improve diagnostic print messages in `check_config` and `run_and_check_output` to be more descriptive.

* `check_config`: Skip the Nextflow resource label check for components whose script is itself a Nextflow workflow. Viash renders those as a workflow rather than a process, so the labels would have no effect.

# openproblems core Python v0.1.1

## NEW FUNCTIONALITY
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,27 +167,37 @@ def check_config(config: dict) -> None:

runners = config.get("runners", [])

print("Check that a Nextflow runner with time, mem, and cpu labels is defined", flush=True)
print("Check that a Nextflow runner is defined", flush=True)
nextflow_runner = next(
(runner for runner in runners if runner["type"] == "nextflow"),
None,
)

assert nextflow_runner, ".runners does not contain a nextflow runner"
assert nextflow_runner.get(
"directives"
), "directives not a field in nextflow runner"
nextflow_labels = nextflow_runner["directives"].get("label")
assert nextflow_labels, "label not a field in nextflow runner directives"

assert [
label for label in nextflow_labels if label in TIME_LABELS
], "time label not filled in"
assert [
label for label in nextflow_labels if label in MEM_LABELS
], "mem label not filled in"
assert [
label for label in nextflow_labels if label in CPU_LABELS
], "cpu label not filled in"

# a component whose script is itself a Nextflow workflow is rendered as a
# workflow instead of a process, so resource directives have no effect on it
is_nextflow_workflow = any(
resource.get("type") == "nextflow_script"
for resource in config.get("resources") or []
)

if not is_nextflow_workflow:
print("Check that the Nextflow runner has time, mem, and cpu labels", flush=True)
assert nextflow_runner.get(
"directives"
), "directives not a field in nextflow runner"
nextflow_labels = nextflow_runner["directives"].get("label")
assert nextflow_labels, "label not a field in nextflow runner directives"

assert [
label for label in nextflow_labels if label in TIME_LABELS
], "time label not filled in"
assert [
label for label in nextflow_labels if label in MEM_LABELS
], "mem label not filled in"
assert [
label for label in nextflow_labels if label in CPU_LABELS
], "cpu label not filled in"

print("All checks succeeded!", flush=True)
67 changes: 67 additions & 0 deletions packages/python/openproblems/tests/test_project_check_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
from typing import Any, Dict

import pytest

from openproblems.project import check_config


def _config(**kwargs: Any) -> Dict[str, Any]:
# a control method without links or references, so that check_config
# does not need network access to validate the metadata
config: Dict[str, Any] = {
"name": "foo",
"label": "Foo",
"summary": "A foo control method.",
"description": "A foo control method.",
"namespace": "control_methods",
"info": {"type": "control_method"},
"runners": [
{
"type": "nextflow",
"directives": {"label": ["lowtime", "lowmem", "lowcpu"]},
}
],
}
config.update(kwargs)
return config


def test_check_config_accepts_resource_labels():
check_config(_config())


def test_check_config_requires_a_nextflow_runner():
with pytest.raises(AssertionError, match="does not contain a nextflow runner"):
check_config(_config(runners=[{"type": "executable"}]))


def test_check_config_requires_resource_labels():
with pytest.raises(AssertionError, match="directives not a field"):
check_config(_config(runners=[{"type": "nextflow"}]))

runners = [{"type": "nextflow", "directives": {"tag": "$id"}}]
with pytest.raises(AssertionError, match="label not a field"):
check_config(_config(runners=runners))


def test_check_config_requires_a_label_of_each_kind():
for labels, message in [
(["lowmem", "lowcpu"], "time label not filled in"),
(["lowtime", "lowcpu"], "mem label not filled in"),
(["lowtime", "lowmem"], "cpu label not filled in"),
]:
runners = [{"type": "nextflow", "directives": {"label": labels}}]
with pytest.raises(AssertionError, match=message):
check_config(_config(runners=runners))


def test_check_config_skips_resource_labels_for_nextflow_workflows():
# viash renders a nextflow_script component as a workflow rather than a
# process, so it has nothing to attach resource labels to
resources = [{"type": "nextflow_script", "path": "main.nf", "entrypoint": "run_wf"}]
check_config(
_config(
resources=resources,
runners=[{"type": "nextflow"}],
)
)