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

Test config version #268

Merged
merged 55 commits into from
Jul 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
835ac00
Started implemented version variables in test config.
Jun 10, 2020
8b2efc4
Pavilion will now output current version in results.
kjeverson Jun 11, 2020
8281649
Set default test version to be 1.0.
kjeverson Jun 11, 2020
50e5240
Removed trailing new line from pav version variable.
kjeverson Jun 12, 2020
f6d765d
Implemented new version subsection in test config. Currently only out…
kjeverson Jun 12, 2020
4254277
Implemented default value for min_pav_version.
kjeverson Jun 12, 2020
7f987aa
Test incapatibility will cause the whole suite to stop running.
kjeverson Jun 12, 2020
3600d18
Initial unit test for version test config.
kjeverson Jun 12, 2020
a145110
Put min_pav_version in the results
kjeverson Jun 12, 2020
1189fa4
Implemented version info as fields in test_run object, updated accord…
kjeverson Jun 15, 2020
5dc856e
Fixed how I get the version info.
kjeverson Jun 15, 2020
05cd04b
Changed to a RegexElem to ensure we get a range in the expected format.
kjeverson Jun 15, 2020
456550f
Fixed a typ.
kjeverson Jun 15, 2020
6c70c71
Moved compatibility check to resolver.py
kjeverson Jun 16, 2020
1c78019
Removed unit test on run command, as version check is done elsewhere.
kjeverson Jun 16, 2020
c2ff1e8
Fixed some whitespace issues,I created accidently.
kjeverson Jun 16, 2020
14f1057
Removed trailing new line in pav version variable.
kjeverson Jun 16, 2020
2833428
Replaces a null value with a 'None' string, for result purposes.
kjeverson Jun 16, 2020
3f85f76
Initial unit tests for version compatibility checks.
kjeverson Jun 16, 2020
38d63e2
Removed unnecessary imports in unit test
kjeverson Jun 16, 2020
703c073
Added comment for clarification.
kjeverson Jun 17, 2020
4be39a8
merged master.
kjeverson Jun 17, 2020
de07f58
Merge branch 'master' into TestConfigVersion
Paul-Ferrell Jun 18, 2020
530c93e
Merge branch 'master' into TestConfigVersion
Paul-Ferrell Jun 18, 2020
8eca915
Removed version keyed elem and made min_pav_version and test_verion t…
kjeverson Jun 19, 2020
0dc2640
Updated the unit tests to reflect changed made to config format.
kjeverson Jun 19, 2020
53efd28
Updated unit tests to reflect change in config format.
kjeverson Jun 19, 2020
e2148e4
Changed min_pav_version to compatible_pav_versions.
kjeverson Jun 19, 2020
3cd5417
Updated help text for compatible_pav_versions.
kjeverson Jun 19, 2020
60d5470
Merge branch 'master' of https://github.com/hpc/pavilion2 into TestCo…
kjeverson Jun 22, 2020
d837fcc
Merge branch 'TestConfigVersion' of https://github.com/hpc/pavilion2 …
kjeverson Jun 22, 2020
5733331
yaml_config changes.
kjeverson Jun 22, 2020
3b05bd2
Updated compatible_pav_versions update null object as a string for re…
kjeverson Jun 22, 2020
f0c8bce
Updated unit tests.
kjeverson Jun 22, 2020
4fc3cd9
Changed default test_version to 0.0
kjeverson Jun 24, 2020
1b23fde
Fixed a spelling issue.
kjeverson Jun 24, 2020
033571b
Updated unit test to include silence() method.
kjeverson Jun 24, 2020
b3e8e17
Compatible versions can be single version, range, or wildcard.
kjeverson Jun 24, 2020
0514a70
Changed the help text to reflect changes made.
kjeverson Jun 24, 2020
d745f94
Made compatible_pav_version a StrElem instead of RegexElem.
kjeverson Jun 25, 2020
94ed20e
Removed compatible_pav_versions from test results, and updated unit t…
kjeverson Jun 29, 2020
0616300
Reworked the version check by breaking it into different methods.
kjeverson Jun 29, 2020
a26e538
White space fixes.
kjeverson Jun 29, 2020
c71dece
Made a check_version_compatibility method that calls the other method…
kjeverson Jun 29, 2020
2581253
Renamed some methods.
kjeverson Jul 7, 2020
f27ece6
Merge branch 'master' into TestConfigVersion
Paul-Ferrell Jul 9, 2020
b452473
Removed get_min_str, get_max_str methods. Removed calc_max, calc_min …
kjeverson Jul 9, 2020
ee02870
Removed a variable that doesn't get reused.
kjeverson Jul 9, 2020
faaf8b8
Reworked how compatible_pav_versions is verified, and broken up.
kjeverson Jul 9, 2020
336af5f
No longer allow * in the compatible_pav_version.
kjeverson Jul 9, 2020
f5cdf89
Changed how pav version is obtained.
kjeverson Jul 9, 2020
a1a158f
Reworked where compatibility check occurs, updated error handling, fi…
kjeverson Jul 9, 2020
c9a8eed
Merge branch 'master' into TestConfigVersion
Paul-Ferrell Jul 15, 2020
c6fca04
Update file_format.py
Paul-Ferrell Jul 15, 2020
c8a5d09
Merge branch 'master' into TestConfigVersion
Paul-Ferrell Jul 15, 2020
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: 1 addition & 1 deletion lib/pavilion/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ def get_version():
lines = file.readlines()
for line in lines:
if line.startswith('RELEASE='):
return line.split('=')[1]
return line.split('=')[1].strip()

return '<unknown>'

Expand Down
4 changes: 4 additions & 0 deletions lib/pavilion/result/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ def get_sched_keys(test):
"The test run name"),
'id': (lambda test: test.id,
"The test run id"),
'test_version': (lambda test: test.test_version,
"The test config version."),
'pav_version': (lambda test: test.var_man['pav.version'],
"The version of Pavilion used to run this test."),
'created': (lambda test: datetime.datetime.fromtimestamp(
test.path.stat().st_mtime).isoformat(" "),
"When the test was created."),
Expand Down
11 changes: 11 additions & 0 deletions lib/pavilion/test_config/file_format.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,17 @@ class TestConfigLoader(yc.YamlConfigLoader):
"the Pavilion variable matches one or more of the "
" values."
),
yc.StrElem(
'compatible_pav_versions', default='',
help_text="Specify compatibile pavilion versions for this "
"specific test. Can be represented as a single "
"version, ex: 1, 1.2, 1.2.3, or a range, "
"ex: 1.2-1.3.4, etc."
),
yc.StrElem(
'test_version', default='0.0',
help_text="Documented test version."
),
yc.KeyedElem(
'build', elements=[
yc.ListElem(
Expand Down
65 changes: 65 additions & 0 deletions lib/pavilion/test_config/resolver.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import io
import logging
import os
import re
from collections import defaultdict
from typing import List, IO, Tuple

Expand All @@ -19,6 +20,7 @@
from pavilion import pavilion_variables
from pavilion import schedulers
from pavilion import system_variables
from pavilion.pavilion_variables import PavVars
from pavilion.test_config import parsers
from pavilion.test_config import variables
from pavilion.test_config.file_format import (TestConfigError, TEST_NAME_RE,
Expand All @@ -33,6 +35,8 @@

LOGGER = logging.getLogger('pav.' + __name__)

TEST_VERS_RE = re.compile(r'^\d+(\.\d+){0,2}$')


class TestConfigResolver:
"""Converts raw test configurations into their final, fully resolved
Expand Down Expand Up @@ -469,6 +473,61 @@ def load_raw_configs(self, tests, host, modes):

return picked_tests

def verify_version_range(comp_versions):

if comp_versions.count('-') > 1:
raise TestConfigError(
"Invalid compatible_pav_versions value ('{}'). Not a valid "
"range.".format(comp_versions))

min_str = comp_versions.split('-')[0]
max_str = comp_versions.split('-')[-1]

min_version = TestConfigResolver.verify_version(min_str, comp_versions)
max_version = TestConfigResolver.verify_version(max_str, comp_versions)

return min_version, max_version

def verify_version(version_str, comp_versions):
"""Ensures version was provided in the correct format, and returns the
version as a list of digits."""

if TEST_VERS_RE.match(version_str) is not None:
version = version_str.split(".")
return [int(i) for i in version]
else:
raise TestConfigError(
"Invalid compatible_pav_versions value '{}' in '{}'. "
"Compatible versions must be of form X, X.X, or X.X.X ."
.format(version_str, comp_versions))

def check_version_compatibility(test_cfg):
"""Returns a bool on if the test is compatible with the current version
of pavilion."""

version = PavVars()['version']
version = [int(i) for i in version.split(".")]
comp_versions = test_cfg.get('compatible_pav_versions')

# If no version is provided we assume compatibility
if not comp_versions:
return True

min_version, max_version = TestConfigResolver.verify_version_range(comp_versions)

# Trim pavilion version to the degree dictated by min and max version.
# This only matters if they are equal, and only occurs when a specific
# version is provided.
if min_version == max_version and len(min_version) < len(version):
offset = len(version) - len(min_version)
version = version[:-offset]
if min_version <= version <= max_version:
return True
else:
raise TestConfigError(
"Incompatible with pavilion version '{}', compatible versions "
"'{}'.".format(PavVars()['version'], comp_versions))

def apply_host(self, test_cfg, host):
"""Apply the host configuration to the given config."""

Expand Down Expand Up @@ -675,6 +734,12 @@ def resolve_inheritance(base_config, suite_cfg, suite_path):
"Loaded test '{}' in suite '{}' raised a type error, "
"but that should never happen. {}"
.format(test_name, suite_path, err))
try:
TestConfigResolver.check_version_compatibility(test_config)
except TestConfigError as err:
raise TestConfigError(
"Test '{}' in suite '{}' has incompatibility issues:\n{}"
.format(test_name, suite_path, err))

return suite_tests

Expand Down
4 changes: 4 additions & 0 deletions lib/pavilion/test_run.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,10 @@ def __init__(self, pav_cfg, config,

self.id = None # pylint: disable=invalid-name

# Get the test version information
self.test_version = config.get('test_version')
self.compatible_pav_versions = config.get('compatible_pav_versions')

self._attrs = {}

# Mark the run to build locally.
Expand Down
16 changes: 16 additions & 0 deletions test/data/pav_config_dir/tests/version_compatible.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
one:
test_version: 1.2.3
run:
cmds:
- 'sleep 1'
two:
test_version: beta
compatible_pav_versions: 1.2.3-5.4.9
run:
cmds:
- 'sleep 1'

three:
run:
cmds:
- 'sleep 1'
6 changes: 6 additions & 0 deletions test/data/pav_config_dir/tests/version_incompatible.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
one:
test_version: 1.4
compatible_pav_versions: 1.2.4-1.2.8
run:
cmd:
- 'sleep 1'
62 changes: 62 additions & 0 deletions test/tests/resolver_tests.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
"""Test the various components of the test resolver."""

import copy
import io
import json

from pavilion import arguments
from pavilion import commands
from pavilion import plugins
from pavilion import system_variables
from pavilion.pavilion_variables import PavVars
from pavilion.test_config import TestConfigError, resolver
from pavilion.test_config import variables
from pavilion.unittest import PavTestCase
Expand Down Expand Up @@ -466,3 +471,60 @@ def test_env_order(self):
"Got the following instead: \n{}"
.format(''.join(["{}: {}\n".format(*v) for v in
exports])))

def test_version_compatibility(self):
"""Make sure version compatibility checks are working and populate the
results.json file correctly."""

pav_version = PavVars.version(self)

arg_parser = arguments.get_parser()
args = arg_parser.parse_args([
'run',
'-w',
'5',
'version_compatible'
])

expected_results = {
'version_compatible.one': {
'test_version': '1.2.3',
'pav_version': pav_version
},
'version_compatible.two': {
'test_version': 'beta',
'pav_version': pav_version
},
'version_compatible.three': {
'test_version': '0.0',
'pav_version': pav_version
}
}

# Ensures Version information gets populated correclty even with empty
# version section in test config
run_cmd = commands.get_command(args.command_name)
kjeverson marked this conversation as resolved.
Show resolved Hide resolved
run_cmd.silence()
run_cmd.run(self.pav_cfg, args)

for test in run_cmd.last_tests:
results = test.load_results()
name = results['name']
for key in expected_results[name].keys():
self.assertEqual(expected_results[name][key],
results[key])

def test_version_incompatibility(self):
"""Make sure incompatible versions exit gracefully when attempting to
run."""

arg_parser = arguments.get_parser()
args = arg_parser.parse_args([
'run',
'version_incompatible'
])

run_cmd = commands.get_command(args.command_name)
run_cmd.outfile = io.StringIO()
run_cmd.errfile = run_cmd.outfile
self.assertEqual(run_cmd.run(self.pav_cfg, args), 22)