Skip to content

Commit efe4a37

Browse files
authored
Merge pull request #191 from xylar/setup_to_custom_suite
Make `compass setup` create a custom test suite
2 parents 753b0a4 + 0df4ef7 commit efe4a37

File tree

5 files changed

+87
-72
lines changed

5 files changed

+87
-72
lines changed

compass/clean.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from compass import provenance
88

99

10-
def clean_cases(tests=None, numbers=None, work_dir=None):
10+
def clean_cases(tests=None, numbers=None, work_dir=None, suite_name='custom'):
1111
"""
1212
Set up one or more test cases
1313
@@ -21,13 +21,18 @@ def clean_cases(tests=None, numbers=None, work_dir=None):
2121
2222
work_dir : str, optional
2323
A directory that will serve as the base for creating case directories
24+
25+
suite_name : str, optional
26+
The name of the test suite if tests are being set up through a test
27+
suite or ``'custom'`` if not
2428
"""
2529

2630
if tests is None and numbers is None:
2731
raise ValueError('At least one of tests or numbers is needed.')
2832

2933
if work_dir is None:
3034
work_dir = os.getcwd()
35+
work_dir = os.path.abspath(work_dir)
3136

3237
mpas_cores = get_mpas_cores()
3338
all_test_cases = dict()
@@ -65,6 +70,14 @@ def clean_cases(tests=None, numbers=None, work_dir=None):
6570
except OSError:
6671
pass
6772

73+
# delete the pickle file for the test suite (if any)
74+
pickle_file = os.path.join(work_dir, '{}.pickle'.format(suite_name))
75+
76+
try:
77+
os.remove(pickle_file)
78+
except OSError:
79+
pass
80+
6881

6982
def main():
7083
parser = argparse.ArgumentParser(

compass/setup.py

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111

1212

1313
def setup_cases(tests=None, numbers=None, config_file=None, machine=None,
14-
work_dir=None, baseline_dir=None, mpas_model_path=None):
14+
work_dir=None, baseline_dir=None, mpas_model_path=None,
15+
suite_name='custom'):
1516
"""
1617
Set up one or more test cases
1718
@@ -41,6 +42,10 @@ def setup_cases(tests=None, numbers=None, config_file=None, machine=None,
4142
The relative or absolute path to the root of a branch where the MPAS
4243
model has been built
4344
45+
suite_name : str, optional
46+
The name of the test suite if tests are being set up through a test
47+
suite or ``'custom'`` if not
48+
4449
Returns
4550
-------
4651
test_cases : dict of compass.TestCase
@@ -58,6 +63,7 @@ def setup_cases(tests=None, numbers=None, config_file=None, machine=None,
5863

5964
if work_dir is None:
6065
work_dir = os.getcwd()
66+
work_dir = os.path.abspath(work_dir)
6167

6268
mpas_cores = get_mpas_cores()
6369

@@ -97,6 +103,26 @@ def setup_cases(tests=None, numbers=None, config_file=None, machine=None,
97103
setup_case(path, test_case, config_file, machine, work_dir,
98104
baseline_dir, mpas_model_path)
99105

106+
test_suite = {'name': suite_name,
107+
'test_cases': test_cases,
108+
'work_dir': work_dir}
109+
110+
# pickle the test or step dictionary for use at runtime
111+
pickle_file = os.path.join(test_suite['work_dir'],
112+
'{}.pickle'.format(suite_name))
113+
with open(pickle_file, 'wb') as handle:
114+
pickle.dump(test_suite, handle, protocol=pickle.HIGHEST_PROTOCOL)
115+
116+
if 'LOAD_COMPASS_ENV' in os.environ:
117+
script_filename = os.environ['LOAD_COMPASS_ENV']
118+
# make a symlink to the script for loading the compass conda env.
119+
symlink(script_filename, os.path.join(work_dir, 'load_compass_env.sh'))
120+
121+
max_cores, max_of_min_cores = _get_required_cores(test_cases)
122+
123+
print('target cores: {}'.format(max_cores))
124+
print('minimum cores: {}'.format(max_of_min_cores))
125+
100126
return test_cases
101127

102128

@@ -274,6 +300,10 @@ def main():
274300
help="The path to the build of the MPAS model for the "
275301
"core.",
276302
metavar="PATH")
303+
parser.add_argument("--suite_name", dest="suite_name", default="custom",
304+
help="The name to use for the 'custom' test suite"
305+
"containing all setup test cases.",
306+
metavar="SUITE")
277307

278308
args = parser.parse_args(sys.argv[2:])
279309
if args.test is None:
@@ -283,4 +313,18 @@ def main():
283313
setup_cases(tests=tests, numbers=args.case_num,
284314
config_file=args.config_file, machine=args.machine,
285315
work_dir=args.work_dir, baseline_dir=args.baseline_dir,
286-
mpas_model_path=args.mpas_model)
316+
mpas_model_path=args.mpas_model, suite_name=args.suite_name)
317+
318+
319+
def _get_required_cores(test_cases):
320+
""" Get the maximum number of target cores and the max of min cores """
321+
322+
max_cores = 0
323+
max_of_min_cores = 0
324+
for test_case in test_cases.values():
325+
for step_name in test_case.steps_to_run:
326+
step = test_case.steps[step_name]
327+
max_cores = max(max_cores, step.cores)
328+
max_of_min_cores = max(max_of_min_cores, step.min_cores)
329+
330+
return max_cores, max_of_min_cores

compass/suite.py

Lines changed: 4 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,8 @@
11
import argparse
22
import sys
3-
import os
43
from importlib import resources
5-
import pickle
64

75
from compass.setup import setup_cases
8-
from compass.io import symlink
96
from compass.clean import clean_cases
107

118

@@ -43,12 +40,6 @@ def setup_suite(mpas_core, suite_name, config_file=None, machine=None,
4340
The relative or absolute path to the root of a branch where the MPAS
4441
model has been built
4542
"""
46-
if machine is None and 'COMPASS_MACHINE' in os.environ:
47-
machine = os.environ['COMPASS_MACHINE']
48-
49-
if config_file is None and machine is None:
50-
raise ValueError('At least one of config_file and machine is needed.')
51-
5243
text = resources.read_text('compass.{}.suites'.format(mpas_core),
5344
'{}.txt'.format(suite_name))
5445
tests = list()
@@ -58,33 +49,9 @@ def setup_suite(mpas_core, suite_name, config_file=None, machine=None,
5849
and not test.startswith('#')):
5950
tests.append(test)
6051

61-
if work_dir is None:
62-
work_dir = os.getcwd()
63-
work_dir = os.path.abspath(work_dir)
64-
65-
test_cases = setup_cases(tests, config_file=config_file, machine=machine,
66-
work_dir=work_dir, baseline_dir=baseline_dir,
67-
mpas_model_path=mpas_model_path)
68-
69-
test_suite = {'name': suite_name,
70-
'test_cases': test_cases,
71-
'work_dir': work_dir}
72-
73-
# pickle the test or step dictionary for use at runtime
74-
pickle_file = os.path.join(test_suite['work_dir'],
75-
'{}.pickle'.format(suite_name))
76-
with open(pickle_file, 'wb') as handle:
77-
pickle.dump(test_suite, handle, protocol=pickle.HIGHEST_PROTOCOL)
78-
79-
if 'LOAD_COMPASS_ENV' in os.environ:
80-
script_filename = os.environ['LOAD_COMPASS_ENV']
81-
# make a symlink to the script for loading the compass conda env.
82-
symlink(script_filename, os.path.join(work_dir, 'load_compass_env.sh'))
83-
84-
max_cores, max_of_min_cores = _get_required_cores(test_cases)
85-
86-
print('target cores: {}'.format(max_cores))
87-
print('minimum cores: {}'.format(max_of_min_cores))
52+
setup_cases(tests, config_file=config_file, machine=machine,
53+
work_dir=work_dir, baseline_dir=baseline_dir,
54+
mpas_model_path=mpas_model_path, suite_name=suite_name)
8855

8956

9057
def clean_suite(mpas_core, suite_name, work_dir=None):
@@ -111,19 +78,7 @@ def clean_suite(mpas_core, suite_name, work_dir=None):
11178
tests = [test.strip() for test in text.split('\n') if
11279
len(test.strip()) > 0 and not test.startswith('#')]
11380

114-
if work_dir is None:
115-
work_dir = os.getcwd()
116-
work_dir = os.path.abspath(work_dir)
117-
118-
clean_cases(tests=tests, work_dir=work_dir)
119-
120-
# delete the pickle file
121-
pickle_file = os.path.join(work_dir, '{}.pickle'.format(suite_name))
122-
123-
try:
124-
os.remove(pickle_file)
125-
except OSError:
126-
pass
81+
clean_cases(tests=tests, work_dir=work_dir, suite_name=suite_name)
12782

12883

12984
def main():
@@ -173,16 +128,3 @@ def main():
173128
config_file=args.config_file, machine=args.machine,
174129
work_dir=args.work_dir, baseline_dir=args.baseline_dir,
175130
mpas_model_path=args.mpas_model)
176-
177-
178-
def _get_required_cores(test_cases):
179-
""" Get the maximum number of target cores and the max of min cores """
180-
181-
max_cores = 0
182-
max_of_min_cores = 0
183-
for test_case in test_cases.values():
184-
for step in test_case.steps.values():
185-
max_cores = max(max_cores, step.cores)
186-
max_of_min_cores = max(max_of_min_cores, step.min_cores)
187-
188-
return max_cores, max_of_min_cores

docs/developers_guide/command_line.rst

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ The command-line options are:
9595
.. code-block:: none
9696
9797
compass setup [-h] [-t PATH] [-n NUM [NUM ...]] [-f FILE] [-m MACH]
98-
[-w PATH] [-b PATH] [-p PATH]
98+
[-w PATH] [-b PATH] [-p PATH] [--suite_name SUITE]
9999
100100
The ``-h`` or ``--help`` options will display the help message describing the
101101
command-line options.
@@ -142,8 +142,18 @@ previous run. Many test cases validate variables to make sure they are
142142
identical between runs, compare timers to see how much performance has changed,
143143
or both. See :ref:`dev_validation`.
144144

145-
See :ref:`dev_setup` for more about the underlying framework.
145+
The test cases will be included in a "custom" test suite in the order they are
146+
named or numbered. You can give this suite a name with ``--suite_name`` or
147+
leave it with the default name ``custom``. You can run this test suite with
148+
``compass run [suite_name]`` as with the predefined test suites (see
149+
:ref:`dev_compass_suite`).
150+
151+
Test cases within the custom suite are run in the order they are supplied to
152+
``compass setup``, so keep this in mind when providing the list. Any test
153+
cases that depend on the output of other test cases must run afther their
154+
dependencies.
146155

156+
See :ref:`dev_setup` for more about the underlying framework.
147157

148158
.. _dev_compass_clean:
149159

@@ -228,9 +238,10 @@ Whereas other ``compass`` commands are typically run in the local clone of the
228238
compass repo, ``compass run`` needs to be run in the appropriate work
229239
directory. If you are running a test suite, you may need to provide the name
230240
of the test suite if more than one suite has been set up in the same work
231-
directory (with or without the ``.pickle`` suffix that exists on the suite's
232-
file in the working directory). If you are in the work directory for a test
233-
case or step, you do not need to provide any arguments.
241+
directory. You can provide either just the suite name or
242+
``<suite_name>.pickle`` (the latter is convenient for tab completion). If you
243+
are in the work directory for a test case or step, you do not need to provide
244+
any arguments.
234245

235246
If you want to explicitly select which steps in a test case you want to run,
236247
you have two options. You can either edit the ``steps_to_run`` config options

docs/users_guide/quick_start.rst

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ Each time you want to work with compass, you will need to run:
7979
8080
.. _setup_overview:
8181

82-
Setting up a test case
83-
----------------------
82+
Setting up test cases
83+
---------------------
8484

8585
Before you set up a test case with ``compass``, you will need to build the
8686
MPAS component you wish to test with. Since the instructions for building
@@ -213,6 +213,11 @@ in the repository.
213213
In order to run a bit-for-bit test with a previous test case, use
214214
``-b $PREVIOUS_WORKDIR`` to specify a "baseline".
215215

216+
When you set up one or more test cases, they will also be included in a custom
217+
test suite, which is called ``custom`` by default. (You can give it another
218+
name with the ``--suite_name`` flag.) You can run all the test cases in
219+
sequence with one command as described in :ref:`suite_overview` or run them
220+
one at a time as follows.
216221

217222
Running a test case
218223
-------------------

0 commit comments

Comments
 (0)