summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvrachev <vlad.rachev@mongodb.com>2020-05-06 09:46:35 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-05-12 17:55:40 +0000
commitbc8faeeeefe9e6663598b161ced59d41be71f2b8 (patch)
tree17ffff0cb33252e5087d94af2710503edf277f8b
parent9c1ce38d7c87f625be1c2d5d7f5a6b709ebfb72e (diff)
downloadmongo-bc8faeeeefe9e6663598b161ced59d41be71f2b8.tar.gz
SERVER-47611 Re-work to_local_args function using argparse
(cherry picked from commit ece056a4cd1eba70a47f88d6d5fd2ba38e7d4df0)
-rw-r--r--buildscripts/resmokelib/commands/run.py12
-rw-r--r--buildscripts/resmokelib/parser.py304
-rw-r--r--buildscripts/tests/resmokelib/test_parser.py76
3 files changed, 231 insertions, 161 deletions
diff --git a/buildscripts/resmokelib/commands/run.py b/buildscripts/resmokelib/commands/run.py
index 4d876a0047a..0d8fe334597 100644
--- a/buildscripts/resmokelib/commands/run.py
+++ b/buildscripts/resmokelib/commands/run.py
@@ -22,6 +22,7 @@ except ImportError:
from buildscripts.resmokelib import config
from buildscripts.resmokelib import errors
from buildscripts.resmokelib import logging
+from buildscripts.resmokelib import parser
from buildscripts.resmokelib import reportfile
from buildscripts.resmokelib import sighandler
from buildscripts.resmokelib import suitesconfig
@@ -158,12 +159,11 @@ class TestRunner(interface.Subcommand): # pylint: disable=too-many-instance-att
"""Run the suite and tests specified."""
self._resmoke_logger.info("verbatim resmoke.py invocation: %s", " ".join(sys.argv))
- # TODO: SERVER-47611
- # if config.EVERGREEN_TASK_ID:
- # local_args = parser.to_local_args()
- # self._resmoke_logger.info("resmoke.py invocation for local usage: %s %s",
- # os.path.join("buildscripts", "resmoke.py"),
- # " ".join(local_args))
+ if config.EVERGREEN_TASK_ID:
+ local_args = parser.to_local_args()
+ self._resmoke_logger.info("resmoke.py invocation for local usage: %s %s",
+ os.path.join("buildscripts", "resmoke.py"),
+ " ".join(local_args))
suites = None
try:
diff --git a/buildscripts/resmokelib/parser.py b/buildscripts/resmokelib/parser.py
index 4e155e851da..b3e8dcc285a 100644
--- a/buildscripts/resmokelib/parser.py
+++ b/buildscripts/resmokelib/parser.py
@@ -10,6 +10,8 @@ from . import config as _config
from . import configure_resmoke
from . import commands
+_INTERNAL_OPTIONS_TITLE = "Internal Options"
+_BENCHMARK_ARGUMENT_TITLE = "Benchmark/Benchrun test options"
_EVERGREEN_ARGUMENT_TITLE = "Evergreen options"
@@ -59,32 +61,11 @@ def _add_run(subparsers): # pylint: disable=too-many-statements
" passed in from test files may cause an error."))
parser.add_argument(
- "--archiveFile", dest="archive_file", metavar="ARCHIVE_FILE",
- help=("Sets the archive file name for the Evergreen task running the tests."
- " The archive file is JSON format containing a list of tests that were"
- " successfully archived to S3. If unspecified, no data files from tests"
- " will be archived in S3. Tests can be designated for archival in the"
- " task suite configuration file."))
-
- parser.add_argument(
- "--archiveLimitMb", type=int, dest="archive_limit_mb", metavar="ARCHIVE_LIMIT_MB",
- help=("Sets the limit (in MB) for archived files to S3. A value of 0"
- " indicates there is no limit."))
-
- parser.add_argument(
- "--archiveLimitTests", type=int, dest="archive_limit_tests", metavar="ARCHIVE_LIMIT_TESTS",
- help=("Sets the maximum number of tests to archive to S3. A value"
- " of 0 indicates there is no limit."))
-
- parser.add_argument(
"--basePort", dest="base_port", metavar="PORT",
help=("The starting port number to use for mongod and mongos processes"
" spawned by resmoke.py or the tests themselves. Each fixture and Job"
" allocates a contiguous range of ports."))
- parser.add_argument("--buildloggerUrl", action="store", dest="buildlogger_url", metavar="URL",
- help="The root url of the buildlogger server.")
-
parser.add_argument("--continueOnFailure", action="store_true", dest="continue_on_failure",
help="Executes all tests in all suites, even if some of them fail.")
@@ -130,11 +111,6 @@ def _add_run(subparsers): # pylint: disable=too-many-statements
help=("The number of Job instances to use. Each instance will receive its"
" own MongoDB deployment to dispatch tests to."))
- parser.add_argument(
- "--log", dest="logger_file", metavar="LOGGER",
- help=("A YAML file that specifies the logging configuration. If the file is"
- " located in the resmokeconfig/suites/ directory, then the basename"
- " without the .yml extension can be specified, e.g. 'console'."))
parser.set_defaults(logger_file="console")
parser.add_argument("--mongo", dest="mongo_executable", metavar="PATH",
@@ -166,9 +142,6 @@ def _add_run(subparsers): # pylint: disable=too-many-statements
parser.add_argument("--numClientsPerFixture", type=int, dest="num_clients_per_fixture",
help="Number of clients running tests per fixture.")
- parser.add_argument("--perfReportFile", dest="perf_report_file", metavar="PERF_REPORT",
- help="Writes a JSON file with performance test results.")
-
parser.add_argument(
"--shellConnString", dest="shell_conn_string", metavar="CONN_STRING",
help="Overrides the default fixture and connects with a mongodb:// connection"
@@ -211,16 +184,6 @@ def _add_run(subparsers): # pylint: disable=too-many-statements
" command line.")
parser.add_argument(
- "--reportFailureStatus", action="store", dest="report_failure_status",
- choices=("fail", "silentfail"), metavar="STATUS",
- help="Controls if the test failure status should be reported as failed"
- " or be silently ignored (STATUS=silentfail). Dynamic test failures will"
- " never be silently ignored. Defaults to STATUS=%%default.")
-
- parser.add_argument("--reportFile", dest="report_file", metavar="REPORT",
- help="Writes a JSON file with test status and timing information.")
-
- parser.add_argument(
"--seed", type=int, dest="seed", metavar="SEED",
help=("Seed for the random number generator. Useful in combination with the"
" --shuffle option for producing a consistent test execution order."))
@@ -252,11 +215,6 @@ def _add_run(subparsers): # pylint: disable=too-many-statements
" all cases except when the number of jobs requested is 1."))
parser.add_argument(
- "--staggerJobs", action="store", dest="stagger_jobs", choices=("on", "off"),
- metavar="ON|OFF", help=("Enables or disables the stagger of launching resmoke jobs."
- " Defaults to %%default."))
-
- parser.add_argument(
"--majorityReadConcern", action="store", dest="majority_read_concern", choices=("on",
"off"),
metavar="ON|OFF", help=("Enable or disable majority read concern support."
@@ -286,9 +244,6 @@ def _add_run(subparsers): # pylint: disable=too-many-statements
parser.add_argument("--numShards", type=int, dest="num_shards", metavar="N",
help="The number of shards to use in a ShardedClusterFixture.")
- parser.add_argument("--tagFile", dest="tag_file", metavar="OPTIONS",
- help="A YAML file that associates tests and tags.")
-
parser.add_argument(
"--wiredTigerCollectionConfigString", dest="wt_coll_config", metavar="CONFIG",
help="Sets the WiredTiger collection configuration setting for all mongod's.")
@@ -316,14 +271,70 @@ def _add_run(subparsers): # pylint: disable=too-many-statements
metavar="ON|OFF", help="Enable or disable linear chaining for tests using "
"ReplicaSetFixture.")
+ internal_options = parser.add_argument_group(
+ title=_INTERNAL_OPTIONS_TITLE,
+ description=("Internal options for advanced users and resmoke developers."
+ " These are not meant to be invoked when running resmoke locally."))
+
+ internal_options.add_argument(
+ "--log", dest="logger_file", metavar="LOGGER",
+ help=("A YAML file that specifies the logging configuration. If the file is"
+ " located in the resmokeconfig/suites/ directory, then the basename"
+ " without the .yml extension can be specified, e.g. 'console'."))
+
+ # Used for testing resmoke. Do not set this.
+ internal_options.add_argument("--internalParam", action="append", dest="internal_params",
+ help=argparse.SUPPRESS)
+
+ internal_options.add_argument("--perfReportFile", dest="perf_report_file",
+ metavar="PERF_REPORT",
+ help="Writes a JSON file with performance test results.")
+
+ internal_options.add_argument(
+ "--reportFailureStatus", action="store", dest="report_failure_status",
+ choices=("fail", "silentfail"), metavar="STATUS",
+ help="Controls if the test failure status should be reported as failed"
+ " or be silently ignored (STATUS=silentfail). Dynamic test failures will"
+ " never be silently ignored. Defaults to STATUS=%%default.")
+
+ internal_options.add_argument(
+ "--reportFile", dest="report_file", metavar="REPORT",
+ help="Writes a JSON file with test status and timing information.")
+
+ internal_options.add_argument(
+ "--staggerJobs", action="store", dest="stagger_jobs", choices=("on", "off"),
+ metavar="ON|OFF", help=("Enables or disables the stagger of launching resmoke jobs."
+ " Defaults to %%default."))
+
evergreen_options = parser.add_argument_group(
title=_EVERGREEN_ARGUMENT_TITLE,
description=("Options used to propagate information about the Evergreen task running this"
" script."))
+ evergreen_options.add_argument(
+ "--archiveFile", dest="archive_file", metavar="ARCHIVE_FILE",
+ help=("Sets the archive file name for the Evergreen task running the tests."
+ " The archive file is JSON format containing a list of tests that were"
+ " successfully archived to S3. If unspecified, no data files from tests"
+ " will be archived in S3. Tests can be designated for archival in the"
+ " task suite configuration file."))
+
+ evergreen_options.add_argument(
+ "--archiveLimitMb", type=int, dest="archive_limit_mb", metavar="ARCHIVE_LIMIT_MB",
+ help=("Sets the limit (in MB) for archived files to S3. A value of 0"
+ " indicates there is no limit."))
+
+ evergreen_options.add_argument(
+ "--archiveLimitTests", type=int, dest="archive_limit_tests", metavar="ARCHIVE_LIMIT_TESTS",
+ help=("Sets the maximum number of tests to archive to S3. A value"
+ " of 0 indicates there is no limit."))
+
evergreen_options.add_argument("--buildId", dest="build_id", metavar="BUILD_ID",
help="Sets the build ID of the task.")
+ evergreen_options.add_argument("--buildloggerUrl", action="store", dest="buildlogger_url",
+ metavar="URL", help="The root url of the buildlogger server.")
+
evergreen_options.add_argument(
"--distroId", dest="distro_id", metavar="DISTRO_ID",
help=("Sets the identifier for the Evergreen distro running the"
@@ -360,6 +371,9 @@ def _add_run(subparsers): # pylint: disable=too-many-statements
metavar="REVISION_ORDER_ID",
help="Sets the chronological order number of this commit.")
+ evergreen_options.add_argument("--tagFile", dest="tag_file", metavar="OPTIONS",
+ help="A YAML file that associates tests and tags.")
+
evergreen_options.add_argument("--taskName", dest="task_name", metavar="TASK_NAME",
help="Sets the name of the Evergreen task running the tests.")
@@ -375,8 +389,7 @@ def _add_run(subparsers): # pylint: disable=too-many-statements
help="Sets the version ID of the task.")
benchmark_options = parser.add_argument_group(
- title="Benchmark/Benchrun test options",
- description="Options for running Benchmark/Benchrun tests")
+ title=_BENCHMARK_ARGUMENT_TITLE, description="Options for running Benchmark/Benchrun tests")
benchmark_options.add_argument("--benchmarkFilter", type=str, dest="benchmark_filter",
metavar="BENCHMARK_FILTER",
@@ -424,17 +437,13 @@ def _add_find_suites(subparsers):
parser = subparsers.add_parser(
"find-suites", help="Lists the names of the suites that will execute the specified tests.")
+ # find-suites shares a lot of code with 'run' (for now), and this option needs be specified,
+ # though it is not used.
parser.set_defaults(logger_file="console")
parser.add_argument("test_files", metavar="TEST_FILES", nargs="*",
help="Explicit test files to run")
- parser.add_argument(
- "--log", dest="logger_file", metavar="LOGGER",
- help=("A YAML file that specifies the logging configuration. If the file is"
- " located in the resmokeconfig/suites/ directory, then the basename"
- " without the .yml extension can be specified, e.g. 'console'."))
-
def _add_hang_analyzer(subparsers):
"""Create and add the parser for the hang analyzer subcommand."""
@@ -471,94 +480,103 @@ def _add_hang_analyzer(subparsers):
" Python process's stdout.")
-# def to_local_args(args=None): # pylint: disable=too-many-branches,too-many-locals
-# """
-# Return a command line invocation for resmoke.py suitable for being run outside of Evergreen.
-# This function parses the 'args' list of command line arguments, removes any Evergreen-centric
-# options, and returns a new list of command line arguments.
-# """
-
-# if args is None:
-# args = sys.argv[1:]
-
-# parser = _make_parser()
-
-# # We call optparse.OptionParser.parse_args() with a new instance of optparse.Values to avoid
-# # having the default values filled in. This makes it so 'options' only contains command line
-# # options that were explicitly specified.
-# options, extra_args = parser.parse_args(args=args, values=optparse.Values())
-
-# # If --originSuite was specified, then we replace the value of --suites with it. This is done to
-# # avoid needing to have engineers learn about the test suites generated by the
-# # evergreen_generate_resmoke_tasks.py script.
-# origin_suite = getattr(options, "origin_suite", None)
-# if origin_suite is not None:
-# setattr(options, "suite_files", origin_suite)
-
-# # optparse.OptionParser doesn't offer a public and/or documented method for getting all of the
-# # options. Given that the optparse module is deprecated, it is unlikely for the
-# # _get_all_options() method to ever be removed or renamed.
-# all_options = parser._get_all_options() # pylint: disable=protected-access
-
-# options_by_dest = {}
-# for option in all_options:
-# options_by_dest[option.dest] = option
-
-# suites_arg = None
-# storage_engine_arg = None
-# other_local_args = []
-
-# options_to_ignore = {
-# "--archiveLimitMb",
-# "--archiveLimitTests",
-# "--buildloggerUrl",
-# "--log",
-# "--perfReportFile",
-# "--reportFailureStatus",
-# "--reportFile",
-# "--staggerJobs",
-# "--tagFile",
-# }
-
-# def format_option(option_name, option_value):
-# """
-# Return <option_name>=<option_value>.
-# This function assumes that 'option_name' is always "--" prefix and isn't "-" prefixed.
-# """
-# return "%s=%s" % (option_name, option_value)
-
-# for option_dest in sorted(vars(options)):
-# option_value = getattr(options, option_dest)
-# option = options_by_dest[option_dest]
-# option_name = option.get_opt_string()
-
-# if option_name in options_to_ignore:
-# continue
-
-# option_group = parser.get_option_group(option_name)
-# if option_group is not None and option_group.title == _EVERGREEN_OPTIONS_TITLE:
-# continue
-
-# if option.takes_value():
-# if option.action == "append":
-# args = [format_option(option_name, elem) for elem in option_value]
-# other_local_args.extend(args)
-# else:
-# arg = format_option(option_name, option_value)
-
-# # We track the value for the --suites and --storageEngine command line options
-# # separately in order to more easily sort them to the front.
-# if option_dest == "suite_files":
-# suites_arg = arg
-# elif option_dest == "storage_engine":
-# storage_engine_arg = arg
-# else:
-# other_local_args.append(arg)
-# else:
-# other_local_args.append(option_name)
-
-# return [arg for arg in (suites_arg, storage_engine_arg) if arg is not None
-# ] + other_local_args + extra_args
+def to_local_args(input_args=None): # pylint: disable=too-many-branches,too-many-locals
+ """
+ Return a command line invocation for resmoke.py suitable for being run outside of Evergreen.
+
+ This function parses the 'args' list of command line arguments, removes any Evergreen-centric
+ options, and returns a new list of command line arguments.
+ """
+
+ if input_args is None:
+ input_args = sys.argv[1:]
+
+ if input_args[0] != 'run':
+ raise TypeError(
+ f"to_local_args can only be called for the 'run' subcommand. Instead was called on '{input_args[0]}'"
+ )
+
+ (parser, parsed_args) = _parse(input_args)
+
+ # If --originSuite was specified, then we replace the value of --suites with it. This is done to
+ # avoid needing to have engineers learn about the test suites generated by the
+ # evergreen_generate_resmoke_tasks.py script.
+ origin_suite = getattr(parsed_args, "origin_suite", None)
+ if origin_suite is not None:
+ setattr(parsed_args, "suite_files", origin_suite)
+
+ # The top-level parser has one subparser that contains all subcommand parsers.
+ command_subparser = [
+ action for action in parser._actions # pylint: disable=protected-access
+ if action.dest == "command"
+ ][0]
+
+ run_parser = command_subparser.choices.get("run")
+
+ suites_arg = None
+ storage_engine_arg = None
+ other_local_args = []
+ positional_args = []
+
+ def format_option(option_name, option_value):
+ """
+ Return <option_name>=<option_value>.
+
+ This function assumes that 'option_name' is always "--" prefix and isn't "-" prefixed.
+ """
+ return f"{option_name}={option_value}"
+
+ # Trim the argument namespace of any args we don't want to return.
+ for group in run_parser._action_groups: # pylint: disable=protected-access
+ arg_dests_visited = set()
+ for action in group._group_actions: # pylint: disable=protected-access
+ arg_dest = action.dest
+ arg_value = getattr(parsed_args, arg_dest, None)
+
+ # Some arguments, such as --shuffle and --shuffleMode, update the same dest variable.
+ # To not print out multiple arguments that will update the same dest, we will skip once
+ # one such argument has been visited.
+ if arg_dest in arg_dests_visited:
+ continue
+ else:
+ arg_dests_visited.add(arg_dest)
+
+ # If the arg doesn't exist in the parsed namespace, skip.
+ # This is mainly for "--help".
+ if not hasattr(parsed_args, arg_dest):
+ continue
+ # Skip any evergreen centric args.
+ elif group.title in [_INTERNAL_OPTIONS_TITLE, _EVERGREEN_ARGUMENT_TITLE]:
+ continue
+ # Keep these args.
+ elif group.title == 'optional arguments':
+ arg_name = action.option_strings[-1]
+
+ # If an option has the same value as the default, we don't need to specify it.
+ if getattr(parsed_args, arg_dest, None) == action.default:
+ continue
+ # These are arguments that take no value.
+ elif action.nargs == 0:
+ other_local_args.append(arg_name)
+ elif isinstance(action, argparse._AppendAction): # pylint: disable=protected-access
+ args = [format_option(arg_name, elem) for elem in arg_value]
+ other_local_args.extend(args)
+ else:
+ arg = format_option(arg_name, arg_value)
+
+ # We track the value for the --suites and --storageEngine command line options
+ # separately in order to more easily sort them to the front.
+ if arg_dest == "suite_files":
+ suites_arg = arg
+ elif arg_dest == "storage_engine":
+ storage_engine_arg = arg
+ else:
+ other_local_args.append(arg)
+ elif group.title == 'positional arguments':
+ positional_args.extend(arg_value)
+
+ return ["run"] + [arg for arg in (suites_arg, storage_engine_arg) if arg is not None
+ ] + other_local_args + positional_args
def _parse(sys_args):
diff --git a/buildscripts/tests/resmokelib/test_parser.py b/buildscripts/tests/resmokelib/test_parser.py
index faf2826edbf..281053f17df 100644
--- a/buildscripts/tests/resmokelib/test_parser.py
+++ b/buildscripts/tests/resmokelib/test_parser.py
@@ -7,21 +7,22 @@ from buildscripts.resmokelib import parser as _parser
# pylint: disable=missing-docstring
-@unittest.skip("TODO: SERVER-47611")
class TestLocalCommandLine(unittest.TestCase):
"""Unit tests for the to_local_args() function."""
def test_keeps_any_positional_arguments(self):
cmdline = _parser.to_local_args([
+ "run",
"test_file1.js",
- "--suites=my_suite",
"test_file2.js",
- "--storageEngine=my_storage_engine",
"test_file3.js",
"test_file4.js",
+ "--suites=my_suite",
+ "--storageEngine=my_storage_engine",
])
self.assertEqual(cmdline, [
+ "run",
"--suites=my_suite",
"--storageEngine=my_storage_engine",
"test_file1.js",
@@ -32,12 +33,14 @@ class TestLocalCommandLine(unittest.TestCase):
def test_keeps_continue_on_failure_option(self):
cmdline = _parser.to_local_args([
+ "run",
"--suites=my_suite",
"--continueOnFailure",
"--storageEngine=my_storage_engine",
])
self.assertEqual(cmdline, [
+ "run",
"--suites=my_suite",
"--storageEngine=my_storage_engine",
"--continueOnFailure",
@@ -45,6 +48,7 @@ class TestLocalCommandLine(unittest.TestCase):
def test_keeps_exclude_with_any_tags_option(self):
cmdline = _parser.to_local_args([
+ "run",
"--suites=my_suite",
"--excludeWithAnyTags=tag1,tag2,tag4",
"--excludeWithAnyTags=tag3,tag5",
@@ -52,6 +56,7 @@ class TestLocalCommandLine(unittest.TestCase):
])
self.assertEqual(cmdline, [
+ "run",
"--suites=my_suite",
"--storageEngine=my_storage_engine",
"--excludeWithAnyTags=tag1,tag2,tag4",
@@ -60,6 +65,7 @@ class TestLocalCommandLine(unittest.TestCase):
def test_keeps_include_with_any_tags_option(self):
cmdline = _parser.to_local_args([
+ "run",
"--suites=my_suite",
"--includeWithAnyTags=tag1,tag2,tag4",
"--includeWithAnyTags=tag3,tag5",
@@ -67,6 +73,7 @@ class TestLocalCommandLine(unittest.TestCase):
])
self.assertEqual(cmdline, [
+ "run",
"--suites=my_suite",
"--storageEngine=my_storage_engine",
"--includeWithAnyTags=tag1,tag2,tag4",
@@ -75,12 +82,14 @@ class TestLocalCommandLine(unittest.TestCase):
def test_keeps_no_journal_option(self):
cmdline = _parser.to_local_args([
+ "run",
"--suites=my_suite",
"--nojournal",
"--storageEngine=my_storage_engine",
])
self.assertEqual(cmdline, [
+ "run",
"--suites=my_suite",
"--storageEngine=my_storage_engine",
"--nojournal",
@@ -88,12 +97,14 @@ class TestLocalCommandLine(unittest.TestCase):
def test_keeps_num_clients_per_fixture_option(self):
cmdline = _parser.to_local_args([
+ "run",
"--suites=my_suite",
"--numClientsPerFixture=10",
"--storageEngine=my_storage_engine",
])
self.assertEqual(cmdline, [
+ "run",
"--suites=my_suite",
"--storageEngine=my_storage_engine",
"--numClientsPerFixture=10",
@@ -101,30 +112,35 @@ class TestLocalCommandLine(unittest.TestCase):
def test_keeps_repeat_options(self):
cmdline = _parser.to_local_args([
+ "run",
"--suites=my_suite",
"--repeatSuites=1000",
"--storageEngine=my_storage_engine",
])
self.assertEqual(cmdline, [
+ "run",
"--suites=my_suite",
"--storageEngine=my_storage_engine",
- "--repeat=1000",
+ "--repeatSuites=1000",
])
cmdline = _parser.to_local_args([
+ "run",
"--suites=my_suite",
"--repeatTests=1000",
"--storageEngine=my_storage_engine",
])
self.assertEqual(cmdline, [
+ "run",
"--suites=my_suite",
"--storageEngine=my_storage_engine",
"--repeatTests=1000",
])
cmdline = _parser.to_local_args([
+ "run",
"--suites=my_suite",
"--repeatTestsMax=1000",
"--repeatTestsMin=20",
@@ -133,6 +149,7 @@ class TestLocalCommandLine(unittest.TestCase):
])
self.assertEqual(cmdline, [
+ "run",
"--suites=my_suite",
"--storageEngine=my_storage_engine",
"--repeatTestsMax=1000",
@@ -142,25 +159,29 @@ class TestLocalCommandLine(unittest.TestCase):
def test_keeps_shuffle_option(self):
cmdline = _parser.to_local_args([
+ "run",
"--suites=my_suite",
"--shuffle",
"--storageEngine=my_storage_engine",
])
self.assertEqual(cmdline, [
+ "run",
"--suites=my_suite",
"--storageEngine=my_storage_engine",
- "--shuffleMode=on",
+ "--shuffle",
])
def test_keeps_storage_engine_cache_size_option(self):
cmdline = _parser.to_local_args([
+ "run",
"--suites=my_suite",
"--storageEngineCacheSizeGB=1",
"--storageEngine=my_storage_engine",
])
self.assertEqual(cmdline, [
+ "run",
"--suites=my_suite",
"--storageEngine=my_storage_engine",
"--storageEngineCacheSizeGB=1",
@@ -171,15 +192,18 @@ class TestLocalCommandLine(unittest.TestCase):
# We intentionally say --suite rather than --suites here to protect against this command
# line option from becoming ambiguous if more similarly named command line options are
# added in the future.
+ "run",
"--suite=part_of_my_suite",
"--originSuite=my_entire_suite",
"--storageEngine=my_storage_engine",
])
- self.assertEqual(cmdline, ["--suites=my_entire_suite", "--storageEngine=my_storage_engine"])
+ self.assertEqual(cmdline,
+ ["run", "--suites=my_entire_suite", "--storageEngine=my_storage_engine"])
def test_removes_archival_options(self):
cmdline = _parser.to_local_args([
+ "run",
"--suites=my_suite",
"--archiveFile=archive.json",
"--archiveLimitMb=100",
@@ -187,11 +211,13 @@ class TestLocalCommandLine(unittest.TestCase):
"--storageEngine=my_storage_engine",
])
- self.assertEqual(cmdline, ["--suites=my_suite", "--storageEngine=my_storage_engine"])
+ self.assertEqual(cmdline, ["run", "--suites=my_suite", "--storageEngine=my_storage_engine"])
def test_removes_evergreen_options(self):
cmdline = _parser.to_local_args([
+ "run",
"--suites=my_suite",
+ "--archiveFile=archive.json",
"--buildId=some_build_id",
"--distroId=some_distro_id",
"--executionNumber=1",
@@ -206,20 +232,22 @@ class TestLocalCommandLine(unittest.TestCase):
"--storageEngine=my_storage_engine",
])
- self.assertEqual(cmdline, ["--suites=my_suite", "--storageEngine=my_storage_engine"])
+ self.assertEqual(cmdline, ["run", "--suites=my_suite", "--storageEngine=my_storage_engine"])
def test_removes_log_option(self):
cmdline = _parser.to_local_args([
+ "run",
"--suites=my_suite",
"--log=buildlogger",
"--buildloggerUrl=some_url",
"--storageEngine=my_storage_engine",
])
- self.assertEqual(cmdline, ["--suites=my_suite", "--storageEngine=my_storage_engine"])
+ self.assertEqual(cmdline, ["run", "--suites=my_suite", "--storageEngine=my_storage_engine"])
def test_removes_report_file_options(self):
cmdline = _parser.to_local_args([
+ "run",
"--suites=my_suite",
"--reportFailureStatus=fail",
"--reportFile=report.json",
@@ -227,25 +255,49 @@ class TestLocalCommandLine(unittest.TestCase):
"--storageEngine=my_storage_engine",
])
- self.assertEqual(cmdline, ["--suites=my_suite", "--storageEngine=my_storage_engine"])
+ self.assertEqual(cmdline, ["run", "--suites=my_suite", "--storageEngine=my_storage_engine"])
def test_removes_stagger_jobs_option(self):
cmdline = _parser.to_local_args([
+ "run",
"--suites=my_suite",
"--staggerJobs=on",
"--storageEngine=my_storage_engine",
])
- self.assertEqual(cmdline, ["--suites=my_suite", "--storageEngine=my_storage_engine"])
+ self.assertEqual(cmdline, ["run", "--suites=my_suite", "--storageEngine=my_storage_engine"])
def test_removes_tag_file_option(self):
cmdline = _parser.to_local_args([
+ "run",
"--suites=my_suite",
"--tagFile=etc/test_retrial.yml",
"--storageEngine=my_storage_engine",
])
- self.assertEqual(cmdline, ["--suites=my_suite", "--storageEngine=my_storage_engine"])
+ self.assertEqual(cmdline, ["run", "--suites=my_suite", "--storageEngine=my_storage_engine"])
+
+ def test_accepts_space_delimited_args(self):
+ cmdline = _parser.to_local_args([
+ "run",
+ "--suites",
+ "my_suite",
+ "--tagFile=etc/test_retrial.yml",
+ "--storageEngine",
+ "my_storage_engine",
+ "--includeWithAnyTags",
+ "tag1,tag2,tag4",
+ "--includeWithAnyTags",
+ "tag3,tag5",
+ ])
+
+ self.assertEqual(cmdline, [
+ "run",
+ "--suites=my_suite",
+ "--storageEngine=my_storage_engine",
+ "--includeWithAnyTags=tag1,tag2,tag4",
+ "--includeWithAnyTags=tag3,tag5",
+ ])
class TestParseArgs(unittest.TestCase):