0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00
mongodb/buildscripts/evergreen_run_tests.py
2019-04-10 11:42:47 -04:00

150 lines
6.5 KiB
Python
Executable File

#!/usr/bin/env python3
"""Command line utility for executing MongoDB tests in Evergreen."""
import collections
import os.path
import sys
# Get relative imports to work when the package is not installed on the PYTHONPATH.
if __name__ == "__main__" and __package__ is None:
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from buildscripts import resmoke # pylint: disable=wrong-import-position
from buildscripts import resmokelib # pylint: disable=wrong-import-position
_TagInfo = collections.namedtuple("_TagInfo", ["tag_name", "evergreen_aware", "suite_options"])
class Main(resmoke.Resmoke):
"""Execute Main class.
A class for executing potentially multiple resmoke.py test suites in a way that handles
additional options for running unreliable tests in Evergreen.
"""
UNRELIABLE_TAG = _TagInfo(
tag_name="unreliable",
evergreen_aware=True,
suite_options=resmokelib.config.SuiteOptions.ALL_INHERITED._replace( # type: ignore
report_failure_status="silentfail"))
RESOURCE_INTENSIVE_TAG = _TagInfo(
tag_name="resource_intensive",
evergreen_aware=False,
suite_options=resmokelib.config.SuiteOptions.ALL_INHERITED._replace( # type: ignore
num_jobs=1))
RETRY_ON_FAILURE_TAG = _TagInfo(
tag_name="retry_on_failure",
evergreen_aware=True,
suite_options=resmokelib.config.SuiteOptions.ALL_INHERITED._replace( # type: ignore
fail_fast=False, num_repeat_suites=2, num_repeat_tests=1,
report_failure_status="silentfail"))
@staticmethod
def _make_evergreen_aware_tags(tag_name):
"""Return a list of resmoke.py tags.
This list is for task, variant, and distro combinations in Evergreen.
"""
tags_format = ["{tag_name}"]
if resmokelib.config.EVERGREEN_TASK_NAME is not None:
tags_format.append("{tag_name}|{task_name}")
if resmokelib.config.EVERGREEN_VARIANT_NAME is not None:
tags_format.append("{tag_name}|{task_name}|{variant_name}")
if resmokelib.config.EVERGREEN_DISTRO_ID is not None:
tags_format.append("{tag_name}|{task_name}|{variant_name}|{distro_id}")
return [
tag.format(tag_name=tag_name, task_name=resmokelib.config.EVERGREEN_TASK_NAME,
variant_name=resmokelib.config.EVERGREEN_VARIANT_NAME,
distro_id=resmokelib.config.EVERGREEN_DISTRO_ID) for tag in tags_format
]
@classmethod
def _make_tag_combinations(cls):
"""Return a list of (tag, enabled) pairs.
These pairs represent all possible combinations of all possible pairings
of whether the tags are enabled or disabled together.
"""
combinations = []
if resmokelib.config.EVERGREEN_PATCH_BUILD:
combinations.append(("unreliable and resource intensive",
((cls.UNRELIABLE_TAG, True), (cls.RESOURCE_INTENSIVE_TAG, True))))
combinations.append(("unreliable and not resource intensive",
((cls.UNRELIABLE_TAG, True), (cls.RESOURCE_INTENSIVE_TAG, False))))
combinations.append(("reliable and resource intensive",
((cls.UNRELIABLE_TAG, False), (cls.RESOURCE_INTENSIVE_TAG, True))))
combinations.append(("reliable and not resource intensive",
((cls.UNRELIABLE_TAG, False), (cls.RESOURCE_INTENSIVE_TAG,
False))))
else:
combinations.append(("retry on failure and resource intensive",
((cls.RETRY_ON_FAILURE_TAG, True), (cls.RESOURCE_INTENSIVE_TAG,
True))))
combinations.append(("retry on failure and not resource intensive",
((cls.RETRY_ON_FAILURE_TAG, True), (cls.RESOURCE_INTENSIVE_TAG,
False))))
combinations.append(("run once and resource intensive",
((cls.RETRY_ON_FAILURE_TAG, False), (cls.RESOURCE_INTENSIVE_TAG,
True))))
combinations.append(("run once and not resource intensive",
((cls.RETRY_ON_FAILURE_TAG, False), (cls.RESOURCE_INTENSIVE_TAG,
False))))
return combinations
def _get_suites(self):
"""Return a list of resmokelib.testing.suite.Suite instances to execute.
For every resmokelib.testing.suite.Suite instance returned by resmoke.Main._get_suites(),
multiple copies of that test suite are run using different resmokelib.config.SuiteOptions()
depending on whether each tag in the combination is enabled or not.
"""
suites = []
for suite in resmoke.Resmoke._get_suites(self):
if suite.test_kind != "js_test":
# Tags are only support for JavaScript tests, so we leave the test suite alone when
# running any other kind of test.
suites.append(suite)
continue
for (tag_desc, tag_combo) in self._make_tag_combinations():
suite_options_list = []
for (tag_info, enabled) in tag_combo:
if tag_info.evergreen_aware:
tags = self._make_evergreen_aware_tags(tag_info.tag_name)
include_tags = {"$anyOf": tags}
else:
include_tags = tag_info.tag_name
if enabled:
suite_options = tag_info.suite_options._replace(include_tags=include_tags)
else:
suite_options = resmokelib.config.SuiteOptions.ALL_INHERITED._replace(
include_tags={"$not": include_tags})
suite_options_list.append(suite_options)
suite_options = resmokelib.config.SuiteOptions.combine(*suite_options_list)
suite_options = suite_options._replace(description=tag_desc)
suites.append(suite.with_options(suite_options))
return suites
if __name__ == "__main__":
main = Main() # pylint: disable=invalid-name
main.configure_from_command_line()
main.run()