"""
Interface to the config_files.xml file. This class inherits from generic_xml.py
It supports version 2.0 of the testlist.xml file
In version 2 of the file options can be specified to further refine a test or
set of tests. They can be specified either at the top level, in which case they
apply to all machines/compilers for this test:
<test ...>
<options>
<option name="wallclock">00:20</option>
</options>
...
</test>
or at the level of a particular machine/compiler:
<test ...>
<machines>
<machine ...>
<options>
<option name="wallclock">00:20</option>
</options>
</machine>
</machines>
</test>
Currently supported options are:
- walltime: sets the wallclock limit in the queuing system
- memleak_tolerance: specifies the relative memory growth expected for this test
- comment: has no effect, but is written out when printing the test list
- workflow: adds a workflow to the test
"""
from CIME.XML.standard_module_setup import *
from CIME.XML.generic_xml import GenericXML
from CIME.XML.files import Files
logger = logging.getLogger(__name__)
[docs]class Testlist(GenericXML):
def __init__(self,infile, files=None):
"""
initialize an object
"""
schema = None
if files is None:
files = Files()
schema = files.get_schema("TESTS_SPEC_FILE")
GenericXML.__init__(self, infile, schema=schema)
expect(self.get_version() >= 2.0,
"{} is an unsupported version of the testfile format and will be ignored".format(infile))
[docs] def get_tests(self, machine=None, category=None, compiler=None, compset=None, grid=None, supported_only=False):
tests = []
attributes = {}
if compset is not None:
attributes['compset'] = compset
if grid is not None:
attributes['grid'] = grid
testnodes = self.get_children("test", attributes=attributes)
machatts = {}
if machine is not None:
machatts["name"] = machine
if category is not None:
machatts["category"] = category
if compiler is not None:
machatts["compiler"] = compiler
for tnode in testnodes:
if supported_only and self.has(tnode, "supported") and self.get(tnode, "supported") == 'false':
continue
machnode = self.get_optional_child("machines", root=tnode)
machnodes = None if machnode is None else self.get_children("machine",machatts,root=machnode)
if machnodes:
this_test_node = {}
for key, value in self.attrib(tnode).items():
if key == "name":
this_test_node["testname"] = value
else:
this_test_node[key] = value
# Get options that apply to all machines/compilers for this test
options = self.get_children("options", root=tnode)
if len(options) > 0:
optionnodes = self.get_children("option", root=options[0])
else:
optionnodes = []
for mach in machnodes:
# this_test_node can include multiple tests
this_test = dict(this_test_node)
for key, value in self.attrib(mach).items():
if key == "name":
this_test["machine"] = value
else:
this_test[key] = value
this_test["options"] = {}
for onode in optionnodes:
this_test['options'][self.get(onode, 'name')] = self.text(onode)
# Now get options specific to this machine/compiler
options = self.get_optional_child("options", root=mach)
optionnodes = [] if options is None else self.get_children("option", root=options)
for onode in optionnodes:
this_test['options'][self.get(onode, 'name')] = self.text(onode)
tests.append(this_test)
return tests