Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

job platforms: Forward lookup #3459

Merged
merged 7 commits into from
Dec 13, 2019
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
5 changes: 5 additions & 0 deletions cylc/flow/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,8 @@ class CylcMissingContextPointError(CyclingError):

class CylcMissingFinalCyclePointError(CyclingError):
"""An error denoting a missing (but required) final cycle point."""


class PlatformLookupError(CylcConfigError):
"""Unable to determine the correct job platform from the information
given"""
98 changes: 98 additions & 0 deletions cylc/flow/platform_lookup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
# THIS FILE IS PART OF THE CYLC SUITE ENGINE.
# Copyright (C) 2008-2019 NIWA & British Crown (Met Office) & Contributors.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Tests for the platform lookup.

import re
from cylc.flow.exceptions import PlatformLookupError


def forward_lookup(platforms, job_platform):
"""
Find out which job platform to use given a list of possible platforms and
a task platform string.

Verifies selected platform is present in global.rc file and returns it,
raises error if platfrom is not in global.rc or returns 'localhost' if
no platform is initally selected.

Args:
job_platform (str):
platform item from config [runtime][TASK]platform
platforms (dictionary):
list of possible platforms defined by global.rc

Returns:
platform (str):
string representing a platform from the global config.

Example:
>>> platforms = {
... 'suite server platform': None,
... 'desktop[0-9][0-9]|laptop[0-9][0-9]': None,
... 'sugar': {
... 'login hosts': 'localhost',
... 'batch system': 'slurm'
... },
... 'hpc': {
... 'login hosts': ['hpc1', 'hpc2'],
... 'batch system': 'pbs'
... },
... 'hpc1-bg': {
... 'login hosts': 'hpc1',
... 'batch system': 'background'
... },
... 'hpc2-bg': {
... 'login hosts': 'hpc2',
... 'batch system': 'background'
... }
... }
>>> job_platform = 'desktop22'
>>> forward_lookup(platforms, job_platform)
'desktop22'
"""
if job_platform is None:
return 'localhost'
for platform in reversed(list(platforms)):
if re.fullmatch(platform, job_platform):
return job_platform

raise PlatformLookupError(
f"No matching platform \"{job_platform}\" found")


def reverse_lookup(task_job, task_remote, platforms):
"""
Find out which job platform to use given a list of possible platforms
and the task dictionary with cylc 7 definitions in it.

Args:
task_job (dict):
Suite config [runtime][TASK][job] section
task_remote (dict):
Suite config [runtime][TASK][remote] section
platforms (dict):
Dictionary containing platfrom definitions.

Returns:
platfrom (str):
string representing a platform from the global config.

Examples:
Tim - write some doctests here...

"""
raise NotImplementedError
87 changes: 87 additions & 0 deletions cylc/flow/tests/test_platform_lookup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# THIS FILE IS PART OF THE CYLC SUITE ENGINE.
# Copyright (C) 2008-2019 NIWA & British Crown (Met Office) & Contributors.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Tests for the platform lookup.

import pytest
from cylc.flow.platform_lookup import forward_lookup, reverse_lookup
from cylc.flow.exceptions import PlatformLookupError

PLATFORMS_STANDARD = {
'suite server platform': None,
'desktop[0-9][0-9]|laptop[0-9][0-9]': None,
'sugar': {
'login hosts': 'localhost',
'batch system': 'slurm'
},
'hpc': {
'login hosts': ['hpc1', 'hpc2'],
'batch system': 'pbs'
},
'hpc1-bg': {
'login hosts': 'hpc1',
'batch system': 'background'
},
'hpc2-bg': {
'login hosts': 'hpc2',
'batch system': 'background'
}
}

PLATFORMS_NO_UNIQUE = {
'sugar': {
'login hosts': 'localhost',
'batch system': 'slurm'
},
'pepper': {
'login hosts': ['hpc1', 'hpc2'],
'batch system': 'slurm'
},

}

PLATFORMS_WITH_RE = {
'hpc.*': {'login hosts': 'hpc1', 'batch system': 'background'},
'h.*': {'login hosts': 'hpc3'},
r'vld\d{2,3}': None,
'nu.*': {'batch system': 'slurm'}
}


@pytest.mark.parametrize(
"PLATFORMS, platform, expected",
[(PLATFORMS_WITH_RE, 'nutmeg', 'nutmeg'),
(PLATFORMS_WITH_RE, 'vld798', 'vld798'),
(PLATFORMS_WITH_RE, 'vld56', 'vld56'),
(PLATFORMS_NO_UNIQUE, 'sugar', 'sugar'),
(PLATFORMS_STANDARD, None, 'localhost'),
(PLATFORMS_STANDARD, 'laptop22', 'laptop22'),
(PLATFORMS_STANDARD, 'hpc1-bg', 'hpc1-bg'),
(PLATFORMS_WITH_RE, 'hpc2', 'hpc2')
]
)
def test_basic(PLATFORMS, platform, expected):
assert forward_lookup(PLATFORMS, platform) == expected


def test_platform_not_there():
with pytest.raises(PlatformLookupError):
forward_lookup(PLATFORMS_STANDARD, 'moooo')


def test_similar_but_not_exact_match():
with pytest.raises(PlatformLookupError):
forward_lookup(PLATFORMS_WITH_RE, 'vld1')