forked from precice/systemtests
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommon.py
More file actions
123 lines (96 loc) · 4.86 KB
/
common.py
File metadata and controls
123 lines (96 loc) · 4.86 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import subprocess
def call(cmd, **kwargs):
""" Runs cmd in a shell, returns its return code. """
print("EXECUTING:", cmd)
cp = subprocess.run(cmd, shell=True, **kwargs)
return cp.returncode
def ccall(cmd, **kwargs):
""" Runs cmd in a shell, returns its return code. Raises exception on error """
return call(cmd, check = True, **kwargs)
def capture_output(cmd, **kwargs):
""" Runs cmd in a shell and captures output """
return subprocess.run(cmd, stdout=subprocess.PIPE, **kwargs).stdout.decode('utf-8')
import os
def determine_test_name(test):
return test.split('.')[0]
def get_tests(root = os.path.join(os.getcwd(), 'tests')):
""" List of all available system tests """
prefixes = ["Test_", "TestCompose_"]
tests = list(set([determine_test_name(s[len(prefix ):]) for prefix in prefixes for s in
os.listdir(root) if s.startswith(prefix)]))
return tests
def get_test_variants(test_name, root = os.path.join(os.getcwd(), 'tests')):
""" List of all available system tests """
prefixes = ["Test_", "TestCompose_"]
test_variants = [s[len(prefix):] for prefix in prefixes for s in os.listdir(root)
if s.startswith(prefix + test_name)]
# filter cases with same participants
if test_name and not "_" in test_name:
test_variants = [t for t in test_variants if not "_" in t]
return test_variants
def get_test_participants(test_name):
""" Returns solvers that participate in the test """
solvers_abbr = {"ccx": "calculix-adapter", "su2": "su2-adapter", "of": "openfoam-adapter",
"dealii":"dealii-adapter", "bindings": "bindings", "fe":"fenics-adapter", "nutils": "nutils",
"et1d": "elastictube1d"}
return [solvers_abbr[abbr] for abbr in test_name.lower().split('_')[0].split('-')]
from contextlib import contextmanager
@contextmanager
def chdir(path):
""" Changes and restores the current working directory. """
oldpwd = os.getcwd()
os.chdir(path)
try:
yield
finally:
os.chdir(oldpwd)
def get_diff_files(dcmp):
""" Given a filecmp.dircmp object, recursively compares files.
Returns three lists: files that differ and files that exist only in left/right directory. """
diff_files = dcmp.diff_files
left_only = dcmp.left_only
right_only = dcmp.right_only
for sub_dcmp in dcmp.subdirs.values():
ret = get_diff_files(sub_dcmp)
diff_files += ret[0]
left_only += ret[1]
right_only += ret[2]
return diff_files, left_only, right_only
def test_is_considered(test, features):
test_specializations = test.split('.')
test_specializations = test_specializations[1:] # get specialization of test (e.g. test only for Ubuntu1604)
for test_specialization in test_specializations: # check all specializations of the test whether they are met by features of the base image
if not test_specialization in features:
# test specialization does not match provided features of base image -> we will not run the test with the provided base image
return False
return True
def determine_specialization(test):
"""
The specialization degree of a test is simply determined, by counting the number of appended specializations.
Example:
test_bindings has specialization degree 1
test_bindings.Ubuntu1804 has specialization degree 2
"""
return len(test.split('.'))
def filter_for_most_specialized_tests(all_tests):
"""
We only want to consider the most specialized test, if several tests are availabe. This function removes duplicate tests and filters for the most specialized version.
"""
most_specialized_tests = {}
for test in all_tests:
test_name = determine_test_name(test)
specialization_degree = determine_specialization(test)
if not test_name in most_specialized_tests: # test has not been added to the dict so far
most_specialized_tests[test_name] = test
elif determine_specialization(most_specialized_tests[test_name]) < specialization_degree: # test has already been added to the dict, but the currently evaluated test is more specialized
most_specialized_tests[test_name] = test
return most_specialized_tests
def filter_tests(all_tests, base_dockerfile):
base_features = base_dockerfile.split('.') # put features of base Dockerfile separated by . in a list (e.g. Dockerfile.Ubuntu1604 has feature Ubuntu1604)
base_features.remove('Dockerfile') # remove Dockerfile
executed_tests = []
for test in all_tests:
if test_is_considered(test, base_features): # check all tests for compatibility with features of base image (e.g. base image with Ubuntu1604 feature cannot run tests with Ubuntu1804 specialization
executed_tests.append(test)
executed_tests = filter_for_most_specialized_tests(executed_tests)
return list(executed_tests.values())