Skip to content

Commit

Permalink
Changed the rose stem functional tests to a more pytest-integration s…
Browse files Browse the repository at this point in the history
…tyle.
  • Loading branch information
wxtim committed Oct 3, 2022
1 parent f4398ef commit a7ca960
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 73 deletions.
11 changes: 9 additions & 2 deletions cylc/rose/stem.py
Original file line number Diff line number Diff line change
Expand Up @@ -524,7 +524,7 @@ def get_source_opt_from_args(opts, args):
return opts


def main():
def _get_rose_stem_opts():
"""Implement rose stem."""
# use the cylc install option parser
parser = get_option_parser()
Expand Down Expand Up @@ -565,7 +565,6 @@ def main():
parser.add_option_group(rose_stem_options)

parser.usage = __doc__

opts, args = parser.parse_args(sys.argv[1:])
# sliced sys.argv to drop 'rose-stem'
opts = get_source_opt_from_args(opts, args)
Expand All @@ -574,7 +573,15 @@ def main():
# verbosity as part of the parser, but rose needs opts.quietness too, so
# hard set it.
opts.quietness = 0
return parser, opts


def main():
parser, opts = _get_rose_stem_opts()
rose_stem(parser, opts)


def rose_stem(parser, opts):
try:
# modify the CLI options to add whatever rose stem would like to add
opts = StemRunner(opts).process()
Expand Down
146 changes: 75 additions & 71 deletions tests/functional/test_rose_stem.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,23 @@
"""
import os
import pytest
import re
import shutil
import subprocess

from pathlib import Path
from shlex import split
from types import SimpleNamespace
from uuid import uuid4

from cylc.flow.pathutil import get_workflow_run_dir
from cylc.flow.hostuserutil import get_host

from cylc.rose.stem import rose_stem, _get_rose_stem_opts

from metomi.rose.resource import ResourceLocator


HOST = get_host().split('.')[0]


Expand All @@ -98,7 +105,7 @@ def monkeymodule():
mpatch.undo()


@pytest.fixture(scope='module')
@pytest.fixture(scope='class')
def setup_stem_repo(tmp_path_factory, monkeymodule, request):
"""Setup a Rose Stem Repository for the tests.
Expand Down Expand Up @@ -135,7 +142,8 @@ def setup_stem_repo(tmp_path_factory, monkeymodule, request):
"""
# Set up required folders:
basetemp = tmp_path_factory.getbasetemp()
testname = re.findall(r'Function\s(.*?)[\[>]', str(request))[0]
basetemp = tmp_path_factory.getbasetemp() / testname
baseinstall = basetemp / 'baseinstall'
rose_stem_dir = baseinstall / 'trunk/rose-stem'
repo = basetemp / 'rose-test-battery-stemtest-repo'
Expand Down Expand Up @@ -180,19 +188,16 @@ def setup_stem_repo(tmp_path_factory, monkeymodule, request):
and Path(suite_install_dir).exists()
):
shutil.rmtree(suite_install_dir)
ResourceLocator.default(reset=True)


@pytest.fixture(scope='class')
def rose_stem_run_template(setup_stem_repo, pytestconfig):
"""Runs rose-stem and Cylc Play.
def rose_stem_run_template(setup_stem_repo, pytestconfig, monkeymodule):
"""Runs rose-stem
Uses an inner function to allow inheriting fixtures to run different
cylc-run commands.
n.b. Subprocesses are run with capture_output so that running
``pytest --pdb`` allows one to inspect the stderr and stdout
if a test fails.
Args:
setup_stem_repo (function):
Pytest fixture function setting up the structure of a rose-stem
Expand All @@ -211,57 +216,42 @@ def rose_stem_run_template(setup_stem_repo, pytestconfig):
verbosity = pytestconfig.getoption('verbose')

def _inner_fn(rose_stem_cmd, verbosity=verbosity):
# Run rose-stem
run_stem = subprocess.run(
split(rose_stem_cmd), capture_output=True,
cwd=setup_stem_repo['workingcopy']
)

# To assist with debugging fail horribly if the subproc'd rose-stem
# command returns non-zero:
if run_stem.returncode != 0:
if verbosity > 1:
# If -v print error details
print('\n\t'.join(
[x.decode() for x in run_stem.stderr.split(b'\n')]
))
if verbosity > 2:
# If -vv print replication instructions.
msg = (
'To reproduce failure outside test environment:'
f'\n\tcd {setup_stem_repo["workingcopy"]}'
f'\n\texport FCM_CONF_PATH={os.environ["FCM_CONF_PATH"]}'
f'\n\t{rose_stem_cmd}'
)
print(msg)
# If you want to debug add a breakpoint here:
msg = (
f'rose-stem command:\n {rose_stem_cmd} failed with'
f':\n{run_stem.stderr.decode()}'
)
raise SubprocessesError(msg)
outputpath = (
Path(setup_stem_repo['suite_install_dir']) /
'runN/opt/rose-suite-cylc-install.conf'
)
output = outputpath.read_text()
monkeymodule.setattr('sys.argv', ['stem'])
monkeymodule.chdir(setup_stem_repo['workingcopy'])
parser, opts = _get_rose_stem_opts()
[setattr(opts, key, val) for key, val in rose_stem_cmd.items()]

run_stem = SimpleNamespace()
run_stem.stdout = ''
try:
rose_stem(parser, opts)
run_stem.returncode = 0
run_stem.stderr = ''
except Exception as exc:
run_stem.returncode = 0
run_stem.stderr = exc

return {
'run_stem': run_stem,
'jobout_content': output,
'jobout_content': (
Path(setup_stem_repo['suite_install_dir']) /
'runN/opt/rose-suite-cylc-install.conf'
).read_text(),
**setup_stem_repo
}

yield _inner_fn


@pytest.fixture(scope='class')
def rose_stem_run_basic(rose_stem_run_template, setup_stem_repo):
rose_stem_cmd = (
"rose stem --group=earl_grey --task=milk,sugar --group=spoon,cup,milk "
f"--source={setup_stem_repo['workingcopy']} "
"--source=\"fcm:foo.x_tr\"@head "
f"--workflow-name {setup_stem_repo['suitename']}"
)
rose_stem_cmd = {
'stem_groups': ['earl_grey', 'milk,sugar', 'spoon,cup,milk'],
'stem_sources': [
str(setup_stem_repo['workingcopy']), "fcm:foo.x_tr@head"
],
'workflow_name': setup_stem_repo['suitename']
}
yield rose_stem_run_template(rose_stem_cmd)


Expand Down Expand Up @@ -296,12 +286,13 @@ def test_basic(self, rose_stem_run_basic, expected):
def project_override(
rose_stem_run_template, setup_stem_repo
):
rose_stem_cmd = (
"rose stem --group=earl_grey --task=milk,sugar --group=spoon,cup,milk "
f"--source=bar={setup_stem_repo['workingcopy']} "
"--source=fcm:foo.x_tr@head "
f"--workflow-name {setup_stem_repo['suitename']}"
)
rose_stem_cmd = {
'stem_groups': ['earl_grey', 'milk,sugar', 'spoon,cup,milk'],
'stem_sources': [
f'bar={str(setup_stem_repo["workingcopy"])}', "fcm:foo.x_tr@head"
],
'workflow_name': setup_stem_repo['suitename']
}
yield rose_stem_run_template(rose_stem_cmd)


Expand Down Expand Up @@ -344,12 +335,12 @@ def test_project_override(self, project_override, expected):
def suite_redirection(
rose_stem_run_template, setup_stem_repo
):
rose_stem_cmd = (
f"rose stem {setup_stem_repo['workingcopy']}/rose-stem "
"--group=lapsang "
"--source=\"fcm:foo.x_tr\"@head "
f"--workflow-name {setup_stem_repo['suitename']}"
)
rose_stem_cmd = {
'source': f'{setup_stem_repo["workingcopy"]}/rose-stem',
'stem_groups': ['lapsang'],
'stem_sources': ["fcm:foo.x_tr@head"],
'workflow_name': setup_stem_repo['suitename']
}
yield rose_stem_run_template(rose_stem_cmd)


Expand Down Expand Up @@ -381,11 +372,11 @@ def test_suite_redirection(self, suite_redirection, expected):
def subdirectory(
rose_stem_run_template, setup_stem_repo
):
rose_stem_cmd = (
"rose stem --group=assam "
f"--source={setup_stem_repo['workingcopy']}/rose-stem "
f"--workflow-name {setup_stem_repo['suitename']}"
)
rose_stem_cmd = {
'stem_groups': ['assam'],
'stem_sources': [f'{setup_stem_repo["workingcopy"]}/rose-stem'],
'workflow_name': setup_stem_repo['suitename']
}
yield rose_stem_run_template(rose_stem_cmd)


Expand Down Expand Up @@ -420,10 +411,11 @@ def test_subdirectory(self, subdirectory, expected):
def relative_path(
rose_stem_run_template, setup_stem_repo
):
rose_stem_cmd = (
f"rose stem rose-stem --group=ceylon "
f"--workflow-name {setup_stem_repo['suitename']}"
)
rose_stem_cmd = {
'source': './rose-stem',
'stem_groups': ['ceylon'],
'workflow_name': setup_stem_repo['suitename']
}
yield rose_stem_run_template(rose_stem_cmd)


Expand Down Expand Up @@ -467,6 +459,12 @@ def with_config(
"--source=fcm:foo.x_tr@head "
f"--workflow-name {setup_stem_repo['suitename']}"
)
rose_stem_cmd = {
'stem_groups': ['earl_grey', 'milk,sugar', 'spoon,cup,milk'],
'stem_sources': [
f'{setup_stem_repo["workingcopy"]}', 'fcm:foo.x_tr@head'],
'workflow_name': setup_stem_repo['suitename']
}
(setup_stem_repo['basetemp'] / 'rose.conf').write_text(
'[rose-stem]\n'
'automatic-options=MILK=true\n'
Expand Down Expand Up @@ -495,7 +493,7 @@ class TestWithConfig:
"MILK=\"true\"",
]
)
def test_with_config(self, with_config, expected):
def test_with_config(self, with_config, expected, monkeypatch):
"""test for successful execution with site/user configuration
"""
if expected == 'run_ok':
Expand All @@ -519,6 +517,12 @@ def with_config2(
f"--source={setup_stem_repo['workingcopy']}/rose-stem "
f"--workflow-name {setup_stem_repo['suitename']}"
)
rose_stem_cmd = {
'stem_groups': ['assam'],
'stem_sources': [
f'{setup_stem_repo["workingcopy"]}'],
'workflow_name': setup_stem_repo['suitename']
}
(setup_stem_repo['basetemp'] / 'rose.conf').write_text(
'[rose-stem]\n'
'automatic-options=MILK=true TEA=darjeeling\n'
Expand Down

0 comments on commit a7ca960

Please sign in to comment.