summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYves Duhem <yves.duhem@mongodb.com>2018-02-23 18:22:33 -0500
committerYves Duhem <yves.duhem@mongodb.com>2018-02-23 18:23:48 -0500
commit649502fd5942d5a572c6a55cfbca61ce1c9611d0 (patch)
tree4428c847c6c2b4a97d11e0bea2d7fe0cd7c2cb87
parenta430d6886290129605dde5ed86589dffb84345e1 (diff)
downloadmongo-649502fd5942d5a572c6a55cfbca61ce1c9611d0.tar.gz
SERVER-33397 New suitesconfig module
-rw-r--r--buildscripts/burn_in_tests.py8
-rwxr-xr-xbuildscripts/resmoke.py8
-rw-r--r--buildscripts/resmokelib/__init__.py2
-rw-r--r--buildscripts/resmokelib/parser.py106
-rw-r--r--buildscripts/resmokelib/suitesconfig.py114
-rwxr-xr-xbuildscripts/update_test_lifecycle.py2
6 files changed, 131 insertions, 109 deletions
diff --git a/buildscripts/burn_in_tests.py b/buildscripts/burn_in_tests.py
index 69cf37e0f38..fa37a810190 100644
--- a/buildscripts/burn_in_tests.py
+++ b/buildscripts/burn_in_tests.py
@@ -243,7 +243,7 @@ def find_tests_by_executor(suites):
"""
memberships = {}
- test_membership = resmokelib.parser.create_test_membership_map()
+ test_membership = resmokelib.suitesconfig.create_test_membership_map()
for suite in suites:
for test in suite.tests:
memberships[test] = test_membership[test]
@@ -258,7 +258,7 @@ def create_executor_list(suites, exclude_suites):
"""
memberships = collections.defaultdict(list)
- test_membership = resmokelib.parser.create_test_membership_map()
+ test_membership = resmokelib.suitesconfig.create_test_membership_map()
for suite in suites:
for test in suite.tests:
for executor in set(test_membership[test]) - set(exclude_suites):
@@ -384,7 +384,9 @@ def main():
if values.test_list_outfile is not None:
_write_report_file({}, values.test_list_outfile)
sys.exit(0)
- suites = resmokelib.parser.get_suites(values, changed_tests)
+ suites = resmokelib.suitesconfig.get_suites(
+ suite_files=values.suite_files.split(","),
+ test_files=changed_tests)
tests_by_executor = create_executor_list(suites, exclude_suites)
tests_by_task = create_task_list(evergreen_conf,
values.buildvariant,
diff --git a/buildscripts/resmoke.py b/buildscripts/resmoke.py
index fcf067ae7f1..4e59bc183a0 100755
--- a/buildscripts/resmoke.py
+++ b/buildscripts/resmoke.py
@@ -134,7 +134,7 @@ def find_suites_by_test(suites):
"""
memberships = {}
- test_membership = resmokelib.parser.create_test_membership_map()
+ test_membership = resmokelib.suitesconfig.create_test_membership_map()
for suite in suites:
for test in suite.tests:
memberships[test] = test_membership[test]
@@ -142,7 +142,7 @@ def find_suites_by_test(suites):
def _list_suites_and_exit(logger, exit_code=0):
- suite_names = resmokelib.parser.get_named_suites()
+ suite_names = resmokelib.suitesconfig.get_named_suites()
logger.info("Suites available to execute:\n%s", "\n".join(suite_names))
sys.exit(exit_code)
@@ -168,7 +168,9 @@ class Main(object):
Returns a list of resmokelib.testing.suite.Suite instances to execute.
"""
- return resmokelib.parser.get_suites(self.__values, self.__args)
+ return resmokelib.suitesconfig.get_suites(
+ suite_files=self.__values.suite_files.split(","),
+ test_files=self.__args)
def run(self):
"""
diff --git a/buildscripts/resmokelib/__init__.py b/buildscripts/resmokelib/__init__.py
index d8019dcf404..abebdc3c665 100644
--- a/buildscripts/resmokelib/__init__.py
+++ b/buildscripts/resmokelib/__init__.py
@@ -1,9 +1,11 @@
from __future__ import absolute_import
+from . import config
from . import errors
from . import logging
from . import parser
from . import reportfile
from . import sighandler
+from . import suitesconfig
from . import testing
from . import utils
diff --git a/buildscripts/resmokelib/parser.py b/buildscripts/resmokelib/parser.py
index b300d573daf..b51dc239f35 100644
--- a/buildscripts/resmokelib/parser.py
+++ b/buildscripts/resmokelib/parser.py
@@ -4,14 +4,11 @@ Parser for command line arguments.
from __future__ import absolute_import
-import collections
import os
import os.path
import optparse
from . import config as _config
-from . import errors
-from . import testing
from . import utils
from .. import resmokeconfig
@@ -141,7 +138,7 @@ def parse_command_line():
" run."))
parser.add_option("-n", action="store_const", const="tests", dest="dry_run",
- help=("Outputs the tests that would be run."))
+ help="Outputs the tests that would be run.")
# TODO: add support for --dryRun=commands
parser.add_option("--dryRun", type="choice", action="store", dest="dry_run",
@@ -336,7 +333,7 @@ def validate_options(parser, options, args):
if options.executor_file:
parser.error("--executor is superseded by --suites; specify --suites={} {} to run the"
- "test(s) under those suite configuration(s)"
+ " test(s) under those suite configuration(s)"
.format(options.executor_file, " ".join(args)))
@@ -424,75 +421,6 @@ def update_config_vars(values):
raise optparse.OptionValueError("Unknown option(s): %s" % (config.keys()))
-def create_test_membership_map(fail_on_missing_selector=False, test_kind=None):
- """
- Returns a dict keyed by test name containing all of the suites that will run that test.
-
- If 'test_kind' is specified then only the mappings for that kind are returned.
- Since this iterates through every available suite, it should only be run once.
- """
-
- test_membership = collections.defaultdict(list)
- suite_names = get_named_suites()
- for suite_name in suite_names:
- try:
- suite_config = _get_suite_config(suite_name)
- if test_kind and suite_config.get("test_kind") != test_kind:
- continue
- suite = testing.suite.Suite(suite_name, suite_config)
- except IOError as err:
- # We ignore errors from missing files referenced in the test suite's "selector"
- # section. Certain test suites (e.g. unittests.yml) have a dedicated text file to
- # capture the list of tests they run; the text file may not be available if the
- # associated SCons target hasn't been built yet.
- if err.filename in _config.EXTERNAL_SUITE_SELECTORS:
- if not fail_on_missing_selector:
- continue
- raise
-
- for testfile in suite.tests:
- if isinstance(testfile, dict):
- continue
- test_membership[testfile].append(suite_name)
- return test_membership
-
-
-def get_suites(values, args):
- suite_roots = None
- if args:
- # Do not change the execution order of the tests passed as args, unless a tag option is
- # specified. If an option is specified, then sort the tests for consistent execution order.
- _config.ORDER_TESTS_BY_NAME = any(tag_filter is not None for
- tag_filter in (_config.EXCLUDE_WITH_ANY_TAGS,
- _config.INCLUDE_WITH_ANY_TAGS))
- # Build configuration for list of files to run.
- suite_roots = _get_suite_roots(args)
-
- suite_files = values.suite_files.split(",")
-
- suites = []
- for suite_filename in suite_files:
- suite_config = _get_suite_config(suite_filename)
- if suite_roots:
- # Override the suite's default test files with those passed in from the command line.
- suite_config.update(suite_roots)
- suite = testing.suite.Suite(suite_filename, suite_config)
- suites.append(suite)
- return suites
-
-
-def get_named_suites():
- """
- Returns the list of suites available to execute.
- """
-
- # Skip "with_*server" and "no_server" because they do not define any test files to run.
- executor_only = set(["with_server", "with_external_server", "no_server"])
- suite_names = [suite for suite in resmokeconfig.NAMED_SUITES if suite not in executor_only]
- suite_names.sort()
- return suite_names
-
-
def _get_logging_config(pathname):
"""
Attempts to read a YAML configuration from 'pathname' that describes
@@ -502,11 +430,11 @@ def _get_logging_config(pathname):
# Named loggers are specified as the basename of the file, without the .yml extension.
if not utils.is_yaml_file(pathname) and not os.path.dirname(pathname):
if pathname not in resmokeconfig.NAMED_LOGGERS:
- raise optparse.OptionValueError("Unknown logger '%s'" % (pathname))
+ raise optparse.OptionValueError("Unknown logger '%s'" % pathname)
pathname = resmokeconfig.NAMED_LOGGERS[pathname] # Expand 'pathname' to full path.
if not utils.is_yaml_file(pathname) or not os.path.isfile(pathname):
- raise optparse.OptionValueError("Expected a logger YAML config, but got '%s'" % (pathname))
+ raise optparse.OptionValueError("Expected a logger YAML config, but got '%s'" % pathname)
return utils.load_yaml_file(pathname).pop("logging")
@@ -523,32 +451,6 @@ def _get_options_config(pathname):
return utils.load_yaml_file(pathname).pop("options")
-def _get_suite_config(pathname):
- """
- Attempts to read a YAML configuration from 'pathname' that describes
- what tests to run and how to run them.
- """
- return _get_yaml_config("suite", pathname)
-
-
-def _get_suite_roots(files):
- return {"selector": {"roots": files}}
-
-
-def _get_yaml_config(kind, pathname):
- # Named executors or suites are specified as the basename of the file, without the .yml
- # extension.
- if not utils.is_yaml_file(pathname) and not os.path.dirname(pathname):
- if pathname not in resmokeconfig.NAMED_SUITES:
- raise errors.SuiteNotFound("Unknown %s '%s'" % (kind, pathname))
- pathname = resmokeconfig.NAMED_SUITES[pathname] # Expand 'pathname' to full path.
-
- if not utils.is_yaml_file(pathname) or not os.path.isfile(pathname):
- raise optparse.OptionValueError("Expected a %s YAML config, but got '%s'"
- % (kind, pathname))
- return utils.load_yaml_file(pathname)
-
-
def _expand_user(pathname):
"""
Wrapper around os.path.expanduser() to do nothing when given None.
diff --git a/buildscripts/resmokelib/suitesconfig.py b/buildscripts/resmokelib/suitesconfig.py
new file mode 100644
index 00000000000..dc668035c90
--- /dev/null
+++ b/buildscripts/resmokelib/suitesconfig.py
@@ -0,0 +1,114 @@
+"""Module for retrieving the configuration of resmoke.py test suites."""
+
+from __future__ import absolute_import
+
+import collections
+import optparse
+import os
+
+from . import config as _config
+from . import errors
+from . import utils
+from .testing import suite as _suite
+from .. import resmokeconfig
+
+
+def get_named_suites():
+ """
+ Returns the list of suites available to execute.
+ """
+
+ # Skip "with_*server" and "no_server" because they do not define any test files to run.
+ executor_only = {"with_server", "with_external_server", "no_server"}
+ suite_names = [suite for suite in resmokeconfig.NAMED_SUITES if suite not in executor_only]
+ suite_names.sort()
+ return suite_names
+
+
+def create_test_membership_map(fail_on_missing_selector=False, test_kind=None):
+ """
+ Returns a dict keyed by test name containing all of the suites that will run that test.
+
+ If 'test_kind' is specified then only the mappings for that kind are returned.
+ Since this iterates through every available suite, it should only be run once.
+ """
+
+ test_membership = collections.defaultdict(list)
+ suite_names = get_named_suites()
+ for suite_name in suite_names:
+ try:
+ suite_config = _get_suite_config(suite_name)
+ if test_kind and suite_config.get("test_kind") != test_kind:
+ continue
+ suite = _suite.Suite(suite_name, suite_config)
+ except IOError as err:
+ # We ignore errors from missing files referenced in the test suite's "selector"
+ # section. Certain test suites (e.g. unittests.yml) have a dedicated text file to
+ # capture the list of tests they run; the text file may not be available if the
+ # associated SCons target hasn't been built yet.
+ if err.filename in _config.EXTERNAL_SUITE_SELECTORS:
+ if not fail_on_missing_selector:
+ continue
+ raise
+
+ for testfile in suite.tests:
+ if isinstance(testfile, dict):
+ continue
+ test_membership[testfile].append(suite_name)
+ return test_membership
+
+
+def get_suites(suite_files, test_files):
+ """Retrieves the Suite instances based on suite configuration files and override parameters.
+
+ Args:
+ suite_files: A list of file paths pointing to suite YAML configuration files. For the suites
+ defined in 'buildscripts/resmokeconfig/suites/', a shorthand name consisting of the
+ filename without the extension can be used.
+ test_files: A list of file paths pointing to test files overriding the roots for the suites.
+ """
+ suite_roots = None
+ if test_files:
+ # Do not change the execution order of the tests passed as args, unless a tag option is
+ # specified. If an option is specified, then sort the tests for consistent execution order.
+ _config.ORDER_TESTS_BY_NAME = any(tag_filter is not None for
+ tag_filter in (_config.EXCLUDE_WITH_ANY_TAGS,
+ _config.INCLUDE_WITH_ANY_TAGS))
+ # Build configuration for list of files to run.
+ suite_roots = _make_suite_roots(test_files)
+
+ suites = []
+ for suite_filename in suite_files:
+ suite_config = _get_suite_config(suite_filename)
+ if suite_roots:
+ # Override the suite's default test files with those passed in from the command line.
+ suite_config.update(suite_roots)
+ suite = _suite.Suite(suite_filename, suite_config)
+ suites.append(suite)
+ return suites
+
+
+def _make_suite_roots(files):
+ return {"selector": {"roots": files}}
+
+
+def _get_suite_config(pathname):
+ """
+ Attempts to read a YAML configuration from 'pathname' that describes
+ what tests to run and how to run them.
+ """
+ return _get_yaml_config("suite", pathname)
+
+
+def _get_yaml_config(kind, pathname):
+ # Named executors or suites are specified as the basename of the file, without the .yml
+ # extension.
+ if not utils.is_yaml_file(pathname) and not os.path.dirname(pathname):
+ if pathname not in resmokeconfig.NAMED_SUITES:
+ raise errors.SuiteNotFound("Unknown %s '%s'" % (kind, pathname))
+ pathname = resmokeconfig.NAMED_SUITES[pathname] # Expand 'pathname' to full path.
+
+ if not utils.is_yaml_file(pathname) or not os.path.isfile(pathname):
+ raise optparse.OptionValueError("Expected a %s YAML config, but got '%s'"
+ % (kind, pathname))
+ return utils.load_yaml_file(pathname)
diff --git a/buildscripts/update_test_lifecycle.py b/buildscripts/update_test_lifecycle.py
index fe854bdf70c..a86c7719fc0 100755
--- a/buildscripts/update_test_lifecycle.py
+++ b/buildscripts/update_test_lifecycle.py
@@ -88,7 +88,7 @@ def get_suite_tasks_membership(evg_conf):
def get_test_tasks_membership(evg_conf):
"""Return a dictionary with keys of all tests and list of associated tasks."""
- test_suites_membership = resmokelib.parser.create_test_membership_map(test_kind="js_test")
+ test_suites_membership = resmokelib.suitesconfig.create_test_membership_map(test_kind="js_test")
suite_tasks_membership = get_suite_tasks_membership(evg_conf)
test_tasks_membership = collections.defaultdict(list)
for test in test_suites_membership.keys():