144 lines
4.8 KiB
Python
144 lines
4.8 KiB
Python
"""
|
|
Holder for a set of TestGroup instances.
|
|
"""
|
|
|
|
from __future__ import absolute_import
|
|
|
|
import time
|
|
|
|
from . import summary as _summary
|
|
from . import testgroup
|
|
from .. import config as _config
|
|
from .. import selector as _selector
|
|
|
|
|
|
class Suite(object):
|
|
"""
|
|
A suite of tests.
|
|
"""
|
|
|
|
TESTS_ORDER = ("cpp_unit_test", "cpp_integration_test", "db_test", "js_test", "mongos_test")
|
|
|
|
def __init__(self, suite_name, suite_config):
|
|
"""
|
|
Initializes the suite with the specified name and configuration.
|
|
"""
|
|
|
|
self._suite_name = suite_name
|
|
self._suite_config = suite_config
|
|
|
|
self.test_groups = []
|
|
for test_kind in Suite.TESTS_ORDER:
|
|
if test_kind not in suite_config["selector"]:
|
|
continue
|
|
tests = self._get_tests_for_group(test_kind)
|
|
test_group = testgroup.TestGroup(test_kind, tests)
|
|
self.test_groups.append(test_group)
|
|
|
|
self.return_code = None
|
|
|
|
self._start_time = None
|
|
self._end_time = None
|
|
|
|
def _get_tests_for_group(self, test_kind):
|
|
"""
|
|
Returns the tests to run based on the 'test_kind'-specific
|
|
filtering policy.
|
|
"""
|
|
|
|
test_info = self.get_selector_config()[test_kind]
|
|
|
|
# The mongos_test doesn't have to filter anything, the test_info is just the arguments to
|
|
# the mongos program to be used as the test case.
|
|
if test_kind == "mongos_test":
|
|
mongos_options = test_info # Just for easier reading.
|
|
if not isinstance(mongos_options, dict):
|
|
raise TypeError("Expected dictionary of arguments to mongos")
|
|
return [mongos_options]
|
|
elif test_kind == "cpp_integration_test":
|
|
tests = _selector.filter_cpp_integration_tests(**test_info)
|
|
elif test_kind == "cpp_unit_test":
|
|
tests = _selector.filter_cpp_unit_tests(**test_info)
|
|
elif test_kind == "db_test":
|
|
tests = _selector.filter_dbtests(**test_info)
|
|
else: # test_kind == "js_test":
|
|
tests = _selector.filter_jstests(**test_info)
|
|
|
|
if _config.ORDER_TESTS_BY_NAME:
|
|
return sorted(tests, key=str.lower)
|
|
return tests
|
|
|
|
def get_name(self):
|
|
"""
|
|
Returns the name of the test suite.
|
|
"""
|
|
return self._suite_name
|
|
|
|
def get_selector_config(self):
|
|
"""
|
|
Returns the "selector" section of the YAML configuration.
|
|
"""
|
|
return self._suite_config["selector"]
|
|
|
|
def get_executor_config(self):
|
|
"""
|
|
Returns the "executor" section of the YAML configuration.
|
|
"""
|
|
return self._suite_config["executor"]
|
|
|
|
def record_start(self):
|
|
"""
|
|
Records the start time of the suite.
|
|
"""
|
|
self._start_time = time.time()
|
|
|
|
def record_end(self):
|
|
"""
|
|
Records the end time of the suite.
|
|
|
|
Sets the 'return_code' of the suite based on the record codes of
|
|
each of the individual test groups.
|
|
"""
|
|
|
|
self._end_time = time.time()
|
|
|
|
# Only set 'return_code' if it hasn't been set already. It may have been set if there was
|
|
# an exception that happened during the execution of the suite.
|
|
if self.return_code is None:
|
|
# The return code of the suite should be 2 if any test group has a return code of 2.
|
|
# The return code of the suite should be 1 if any test group has a return code of 1,
|
|
# and none have a return code of 2. Otherwise, the return code should be 0.
|
|
self.return_code = max(test_group.return_code for test_group in self.test_groups)
|
|
|
|
def summarize(self, sb):
|
|
"""
|
|
Appends a summary of each individual test group onto the string
|
|
builder 'sb'.
|
|
"""
|
|
|
|
combined_summary = _summary.Summary(0, 0.0, 0, 0, 0, 0)
|
|
|
|
summarized_groups = []
|
|
for group in self.test_groups:
|
|
group_sb = []
|
|
summary = group.summarize(group_sb)
|
|
summarized_groups.append(" %ss: %s" % (group.test_kind, "\n ".join(group_sb)))
|
|
|
|
combined_summary = _summary.combine(combined_summary, summary)
|
|
|
|
if combined_summary.num_run == 0:
|
|
sb.append("Suite did not run any tests.")
|
|
return
|
|
|
|
# Override the 'time_taken' attribute of the summary if we have more accurate timing
|
|
# information available.
|
|
if self._start_time is not None and self._end_time is not None:
|
|
time_taken = self._end_time - self._start_time
|
|
combined_summary = combined_summary._replace(time_taken=time_taken)
|
|
|
|
sb.append("%d test(s) ran in %0.2f seconds"
|
|
" (%d succeeded, %d were skipped, %d failed, %d errored)" % combined_summary)
|
|
|
|
for summary_text in summarized_groups:
|
|
sb.append(summary_text)
|