3
3
import configparser
4
4
import os
5
5
import pickle
6
+ import warnings
6
7
7
8
from compass .mpas_cores import get_mpas_cores
8
9
from compass .config import add_config , ensure_absolute_paths
11
12
12
13
13
14
def setup_cases (tests = None , numbers = None , config_file = None , machine = None ,
14
- work_dir = None , baseline_dir = None , mpas_model_path = None ):
15
+ work_dir = None , baseline_dir = None , mpas_model_path = None ,
16
+ cached = None ):
15
17
"""
16
18
Set up one or more test cases
17
19
@@ -20,8 +22,10 @@ def setup_cases(tests=None, numbers=None, config_file=None, machine=None,
20
22
tests : list of str, optional
21
23
Relative paths for a test cases to set up
22
24
23
- numbers : list of int, optional
24
- Case numbers to setup, as listed from ``compass list``
25
+ numbers : list of str, optional
26
+ Case numbers to setup, as listed from ``compass list``, optionally with
27
+ a suffix ``c`` to indicate that all steps in that test case should be
28
+ cached
25
29
26
30
config_file : str, optional
27
31
Configuration file with custom options for setting up and running test
@@ -41,6 +45,10 @@ def setup_cases(tests=None, numbers=None, config_file=None, machine=None,
41
45
The relative or absolute path to the root of a branch where the MPAS
42
46
model has been built
43
47
48
+ cached : list of list of str, optional
49
+ For each test in ``tests``, which steps (if any) should be cached,
50
+ or "_all" if all steps should be cached
51
+
44
52
Returns
45
53
-------
46
54
test_cases : dict of compass.TestCase
@@ -56,6 +64,14 @@ def setup_cases(tests=None, numbers=None, config_file=None, machine=None,
56
64
if tests is None and numbers is None :
57
65
raise ValueError ('At least one of tests or numbers is needed.' )
58
66
67
+ if cached is not None :
68
+ if tests is None :
69
+ warnings .warn ('Ignoring "cached" argument becasue "tests" was '
70
+ 'not provided' )
71
+ elif len (cached ) != len (tests ):
72
+ raise ValueError ('A list of cached steps must be provided for '
73
+ 'each test in "tests"' )
74
+
59
75
if work_dir is None :
60
76
work_dir = os .getcwd ()
61
77
@@ -71,18 +87,36 @@ def setup_cases(tests=None, numbers=None, config_file=None, machine=None,
71
87
if numbers is not None :
72
88
keys = list (all_test_cases )
73
89
for number in numbers :
90
+ cache_all = False
91
+ if number .endswith ('c' ):
92
+ cache_all = True
93
+ number = int (number [:- 1 ])
94
+ else :
95
+ number = int (number )
96
+
74
97
if number >= len (keys ):
75
98
raise ValueError ('test number {} is out of range. There are '
76
99
'only {} tests.' .format (number , len (keys )))
77
100
path = keys [number ]
78
- test_cases [path ] = all_test_cases [path ]
101
+ test_case = all_test_cases [path ]
102
+ if cache_all :
103
+ for step in test_case .steps .values ():
104
+ step .cached = True
105
+ test_cases [path ] = test_case
79
106
80
107
if tests is not None :
81
- for path in tests :
108
+ for index , path in enumerate ( tests ) :
82
109
if path not in all_test_cases :
83
110
raise ValueError ('Test case with path {} is not in '
84
111
'test_cases' .format (path ))
85
- test_cases [path ] = all_test_cases [path ]
112
+ test_case = all_test_cases [path ]
113
+ if cached is not None :
114
+ step_names = cached [index ]
115
+ if len (step_names ) > 0 and step_names [0 ] == '_all' :
116
+ step_names = list (test_case .steps .keys ())
117
+ for step_name in step_names :
118
+ test_case .steps [step_name ].cached = True
119
+ test_cases [path ] = test_case
86
120
87
121
# get the MPAS core of the first test case. We'll assume all tests are
88
122
# for this core
@@ -133,6 +167,10 @@ def setup_case(path, test_case, config_file, machine, work_dir, baseline_dir,
133
167
"""
134
168
135
169
print (' {}' .format (path ))
170
+ cached_steps = [step .name for step in test_case .steps .values () if step .cached ]
171
+ if len (cached_steps ) > 0 :
172
+ cached_steps = ' ' .join (cached_steps )
173
+ print (f' steps with cached outputs: { cached_steps } ' )
136
174
137
175
config = configparser .ConfigParser (
138
176
interpolation = configparser .ExtendedInterpolation ())
@@ -253,10 +291,12 @@ def main():
253
291
help = "Relative path for a test case to set up" ,
254
292
metavar = "PATH" )
255
293
parser .add_argument ("-n" , "--case_number" , nargs = '+' , dest = "case_num" ,
256
- type = int ,
294
+ type = str ,
257
295
help = "Case number(s) to setup, as listed from "
258
296
"'compass list'. Can be a space-separated"
259
- "list of case numbers." , metavar = "NUM" )
297
+ "list of case numbers. A suffix 'c' indicates"
298
+ "that all steps in the test should use cached"
299
+ "outputs." , metavar = "NUM" )
260
300
parser .add_argument ("-f" , "--config_file" , dest = "config_file" ,
261
301
help = "Configuration file for test case setup" ,
262
302
metavar = "FILE" )
@@ -274,13 +314,21 @@ def main():
274
314
help = "The path to the build of the MPAS model for the "
275
315
"core." ,
276
316
metavar = "PATH" )
317
+ parser .add_argument ("--cached" , dest = "cached" , nargs = '+' ,
318
+ help = "A list of steps in the test case supplied with"
319
+ "--test that should use cached outputs, or "
320
+ "'_all' if all steps should be cached" ,
321
+ metavar = "STEP" )
277
322
278
323
args = parser .parse_args (sys .argv [2 :])
324
+ cached = None
279
325
if args .test is None :
280
326
tests = None
281
327
else :
282
328
tests = [args .test ]
329
+ if args .cached is not None :
330
+ cached = [args .cached ]
283
331
setup_cases (tests = tests , numbers = args .case_num ,
284
332
config_file = args .config_file , machine = args .machine ,
285
333
work_dir = args .work_dir , baseline_dir = args .baseline_dir ,
286
- mpas_model_path = args .mpas_model )
334
+ mpas_model_path = args .mpas_model , cached = cached )
0 commit comments