summaryrefslogtreecommitdiff
path: root/buildscripts/task_generation
diff options
context:
space:
mode:
authorRobert Guo <robert.guo@mongodb.com>2021-10-12 04:23:31 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2021-10-12 04:46:33 +0000
commit9c46c72e17e11a31089342abc9f56348aeaf4b87 (patch)
tree853197a50430b0a4a54139403e6f55405d9e61c6 /buildscripts/task_generation
parentb9e2784da82fef8e45b95b88e4ac1443649a5b0c (diff)
downloadmongo-9c46c72e17e11a31089342abc9f56348aeaf4b87.tar.gz
SERVER-55857 Use explicit task definitions for implicit multiversion tasks
Diffstat (limited to 'buildscripts/task_generation')
-rw-r--r--buildscripts/task_generation/evg_config_builder.py38
-rw-r--r--buildscripts/task_generation/gen_task_service.py55
-rw-r--r--buildscripts/task_generation/multiversion_util.py44
-rw-r--r--buildscripts/task_generation/resmoke_proxy.py29
-rw-r--r--buildscripts/task_generation/suite_split.py116
-rw-r--r--buildscripts/task_generation/task_types/fuzzer_tasks.py57
-rw-r--r--buildscripts/task_generation/task_types/multiversion_tasks.py143
-rw-r--r--buildscripts/task_generation/task_types/resmoke_tasks.py104
8 files changed, 138 insertions, 448 deletions
diff --git a/buildscripts/task_generation/evg_config_builder.py b/buildscripts/task_generation/evg_config_builder.py
index a1f9b299b98..c3fc3cb403a 100644
--- a/buildscripts/task_generation/evg_config_builder.py
+++ b/buildscripts/task_generation/evg_config_builder.py
@@ -14,7 +14,6 @@ from buildscripts.task_generation.resmoke_proxy import ResmokeProxyService
from buildscripts.task_generation.suite_split import SuiteSplitService, GeneratedSuite, \
SuiteSplitParameters
from buildscripts.task_generation.task_types.fuzzer_tasks import FuzzerTask
-from buildscripts.task_generation.task_types.multiversion_tasks import MultiversionGenTaskParams
# pylint: disable=too-many-instance-attributes
@@ -67,10 +66,8 @@ class EvgConfigBuilder:
:param generated_suite: Generated suite to create config files for.
:return: The suites files and evergreen configuration for the generated task.
"""
- test_list = generated_suite.get_test_list()
- return self.resmoke_proxy.render_suite_files(
- generated_suite.sub_suites, generated_suite.suite_name, generated_suite.filename,
- test_list, self.gen_options.create_misc_suite, generated_suite)
+ return self.resmoke_proxy.render_suite_files(generated_suite,
+ self.gen_options.create_misc_suite)
def generate_suite(self, split_params: SuiteSplitParameters,
gen_params: ResmokeGenTaskParams) -> None:
@@ -86,37 +83,6 @@ class EvgConfigBuilder:
self.evg_config_gen_service.generate_task(generated_suite, build_variant, gen_params)
self.generated_files.extend(self._generate_suites_config(generated_suite))
- def add_multiversion_suite(self, split_params: SuiteSplitParameters,
- gen_params: MultiversionGenTaskParams) -> None:
- """
- Add a multiversion suite to the builder.
-
- :param split_params: Parameters for how suite should be split.
- :param gen_params: Parameters for how subtasks should be generated.
- """
- generated_suite = self.suite_split_service.split_suite(split_params)
- with self.lock:
- build_variant = self.get_build_variant(generated_suite.build_variant)
- self.evg_config_gen_service.generate_multiversion_task(generated_suite, build_variant,
- gen_params)
- self.generated_files.extend(self._generate_suites_config(generated_suite))
-
- def add_multiversion_burn_in_test(self, split_params: SuiteSplitParameters,
- gen_params: MultiversionGenTaskParams) -> Set[Task]:
- """
- Add a multiversion burn_in suite to the builder.
-
- :param split_params: Parameters for how suite should be split.
- :param gen_params: Parameters for how subtasks should be generated.
- """
- generated_suite = self.suite_split_service.split_suite(split_params)
- with self.lock:
- build_variant = self.get_build_variant(generated_suite.build_variant)
- tasks = self.evg_config_gen_service.generate_multiversion_burnin_task(
- generated_suite, gen_params, build_variant)
- self.generated_files.extend(self._generate_suites_config(generated_suite))
- return tasks
-
def generate_fuzzer(self, fuzzer_params: FuzzerGenTaskParams) -> FuzzerTask:
"""
Add configuration to generate the specified fuzzer task.
diff --git a/buildscripts/task_generation/gen_task_service.py b/buildscripts/task_generation/gen_task_service.py
index b6231f825a9..349ec0ebae0 100644
--- a/buildscripts/task_generation/gen_task_service.py
+++ b/buildscripts/task_generation/gen_task_service.py
@@ -13,8 +13,6 @@ if __name__ == "__main__" and __package__ is None:
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
# pylint: disable=wrong-import-position
-from buildscripts.task_generation.task_types.multiversion_tasks import MultiversionGenTaskParams, \
- MultiversionGenTaskService
from buildscripts.task_generation.task_types.fuzzer_tasks import FuzzerGenTaskParams, FuzzerTask, \
FuzzerGenTaskService
from buildscripts.task_generation.task_types.gentask_options import GenTaskOptions
@@ -50,7 +48,6 @@ class GenTaskService:
def __init__(self, evg_api: EvergreenApi, gen_task_options: GenTaskOptions,
gen_config: GenerationConfiguration,
resmoke_gen_task_service: ResmokeGenTaskService,
- multiversion_gen_task_service: MultiversionGenTaskService,
fuzzer_gen_task_service: FuzzerGenTaskService) -> None:
"""
Initialize the service.
@@ -59,14 +56,12 @@ class GenTaskService:
:param gen_task_options: Options for how tasks should be generated.
:param gen_config:
:param resmoke_gen_task_service: Service for generating standard resmoke tasks.
- :param multiversion_gen_task_service: Service for generating multiversion resmoke tasks.
:param fuzzer_gen_task_service: Service for generating fuzzer tasks.
"""
self.evg_api = evg_api
self.gen_task_options = gen_task_options
self.gen_config = gen_config
self.resmoke_gen_task_service = resmoke_gen_task_service
- self.multiversion_gen_task_service = multiversion_gen_task_service
self.fuzzer_gen_task_service = fuzzer_gen_task_service
def generate_fuzzer_task(self, params: FuzzerGenTaskParams,
@@ -80,15 +75,12 @@ class GenTaskService:
fuzzer_task = self.fuzzer_gen_task_service.generate_tasks(params)
distros = self._get_distro(build_variant.name, params.use_large_distro,
params.large_distro_name)
- if params.add_to_display_task:
- build_variant.display_task(fuzzer_task.task_name, fuzzer_task.sub_tasks,
- distros=distros, activate=False)
- else:
- build_variant.add_tasks(fuzzer_task.sub_tasks, distros=distros, activate=False)
+ build_variant.display_task(fuzzer_task.task_name, fuzzer_task.sub_tasks, distros=distros,
+ activate=False)
return fuzzer_task
def generate_task(self, generated_suite: GeneratedSuite, build_variant: BuildVariant,
- gen_params: ResmokeGenTaskParams) -> None:
+ gen_params: ResmokeGenTaskParams) -> List[Task]:
"""
Generate evergreen configuration for the given suite and add it to the build_variant.
@@ -99,45 +91,10 @@ class GenTaskService:
execution_tasks = self.resmoke_gen_task_service.generate_tasks(generated_suite, gen_params)
distros = self._get_distro(build_variant.name, gen_params.use_large_distro,
gen_params.large_distro_name)
- build_variant.display_task(generated_suite.display_task_name(),
- execution_tasks=execution_tasks, distros=distros, activate=False)
+ build_variant.display_task(generated_suite.task_name, execution_tasks=execution_tasks,
+ distros=distros, activate=False)
- def generate_multiversion_task(self, generated_suite: GeneratedSuite,
- build_variant: BuildVariant,
- gen_params: MultiversionGenTaskParams) -> None:
- """
- Generate evergreen configuration for the given suite and add it to the build_variant.
-
- :param generated_suite: Suite to add.
- :param build_variant: Build variant to add generated configuration to.
- :param gen_params: Parameters to configuration how tasks are generated.
- """
- execution_tasks = self.multiversion_gen_task_service.generate_tasks(
- generated_suite, gen_params)
- distros = self._get_distro(build_variant.name, gen_params.use_large_distro,
- gen_params.large_distro_name)
- build_variant.display_task(generated_suite.display_task_name(),
- execution_tasks=execution_tasks, distros=distros, activate=False)
-
- def generate_multiversion_burnin_task(self, generated_suite: GeneratedSuite,
- gen_params: MultiversionGenTaskParams,
- build_variant: BuildVariant) -> Set[Task]:
- """
- Generate burn_in configuration for the given suite and add it to the build_variant.
-
- :param generated_suite: Suite to add.
- :param build_variant: Build variant to add generated configuration to.
- :param gen_params: Parameters to configuration how tasks are generated.
- :return: Set of tasks that were generated.
- """
- tasks = self.multiversion_gen_task_service.generate_tasks(generated_suite, gen_params)
- distros = self._get_distro(build_variant.name, gen_params.use_large_distro,
- gen_params.large_distro_name)
- if gen_params.add_to_display_task:
- build_variant.display_task(generated_suite.task_name, tasks, distros=distros)
- else:
- build_variant.add_tasks(tasks, distros=distros)
- return tasks
+ return execution_tasks
def _get_distro(self, build_variant: str, use_large_distro: bool,
large_distro_name: Optional[str]) -> Optional[List[str]]:
diff --git a/buildscripts/task_generation/multiversion_util.py b/buildscripts/task_generation/multiversion_util.py
deleted file mode 100644
index f690d7247d1..00000000000
--- a/buildscripts/task_generation/multiversion_util.py
+++ /dev/null
@@ -1,44 +0,0 @@
-"""Utilities for generating with multiversion tests."""
-from typing import List
-
-import inject
-
-from buildscripts.task_generation.resmoke_proxy import ResmokeProxyService
-
-REPL_MIXED_VERSION_CONFIGS = ["new-old-new", "new-new-old", "old-new-new"]
-SHARDED_MIXED_VERSION_CONFIGS = ["new-old-old-new"]
-
-
-class MultiversionUtilService:
- """Utilities to working with multiversion tests."""
-
- @inject.autoparams()
- def __init__(self, resmoke_proxy: ResmokeProxyService) -> None:
- """
- Initialize the service.
-
- :param resmoke_proxy: Resmoke proxy service.
- """
- self.resmoke_proxy = resmoke_proxy
-
- def is_suite_sharded(self, suite_name: str) -> bool:
- """Return true if a suite uses ShardedClusterFixture."""
- source_config = self.resmoke_proxy.read_suite_config(suite_name)
- return source_config["executor"]["fixture"]["class"] == "ShardedClusterFixture"
-
- def get_version_configs_for_suite(self, suite_name: str) -> List[str]:
- """
- Get the version configs that apply for the given suite.
-
- :param suite_name: Suite to get version configs for.
- :return: List of version configs.
- """
- is_sharded = self.is_suite_sharded(suite_name)
- return self.get_version_configs(is_sharded)
-
- @staticmethod
- def get_version_configs(is_sharded: bool) -> List[str]:
- """Get the version configurations to use."""
- if is_sharded:
- return SHARDED_MIXED_VERSION_CONFIGS
- return REPL_MIXED_VERSION_CONFIGS
diff --git a/buildscripts/task_generation/resmoke_proxy.py b/buildscripts/task_generation/resmoke_proxy.py
index 820e63fb284..34a30c0ae02 100644
--- a/buildscripts/task_generation/resmoke_proxy.py
+++ b/buildscripts/task_generation/resmoke_proxy.py
@@ -58,38 +58,37 @@ class ResmokeProxyService:
"""
return self._suite_config.SuiteFinder.get_config_obj(suite_name)
- def render_suite_files(self, suites: List["SubSuite"], suite_name: str,
- generated_suite_filename: str, test_list: List[str],
- create_misc_suite: bool, suite: "GeneratedSuite") -> List[GeneratedFile]:
+ def render_suite_files(self, suite: "GeneratedSuite",
+ create_misc_suite: bool) -> List[GeneratedFile]:
"""
Render the given list of suites.
This will create a dictionary of all the resmoke config files to create with the
filename of each file as the key and the contents as the value.
- :param suites: List of suites to render.
- :param suite_name: Base name of suites.
- :param generated_suite_filename: The name to use as the file name for generated suite file.
- :param test_list: List of tests used in suites.
- :param create_misc_suite: Whether or not a _misc suite file should be created.
:param suite: Generated suite files belong to.
+ :param create_misc_suite: Whether to create the file for the _misc task.
:return: Dictionary of rendered resmoke config files.
"""
# pylint: disable=too-many-arguments
- source_config = self._suite_config.SuiteFinder.get_config_obj(suite_name)
+ original_suite_name = suite.suite_name
+ test_list = suite.get_test_list()
+
+ source_config = self._suite_config.SuiteFinder.get_config_obj(original_suite_name)
suite_configs = [
- GeneratedFile(file_name=f"{suite.sub_suite_config_file(i)}.yml",
- content=sub_suite.generate_resmoke_config(source_config))
- for i, sub_suite in enumerate(suites)
+ GeneratedFile(
+ file_name=suite.sub_suite_config_file(i),
+ content=sub_suite.generate_resmoke_config(source_config))
+ for i, sub_suite in enumerate(suite.sub_suites)
]
if create_misc_suite:
suite_configs.append(
GeneratedFile(
- file_name=f"{suite.sub_suite_config_file(None)}.yml",
- content=generate_resmoke_suite_config(source_config, generated_suite_filename,
+ file_name=suite.sub_suite_config_file(None),
+ content=generate_resmoke_suite_config(source_config, original_suite_name,
excludes=test_list)))
- LOGGER.debug("Generated files for suite", suite=suite_name,
+ LOGGER.debug("Generated files for suite", suite=original_suite_name,
files=[f.file_name for f in suite_configs])
return suite_configs
diff --git a/buildscripts/task_generation/suite_split.py b/buildscripts/task_generation/suite_split.py
index 78a2e0c0486..75f24ba74e9 100644
--- a/buildscripts/task_generation/suite_split.py
+++ b/buildscripts/task_generation/suite_split.py
@@ -24,8 +24,7 @@ LOGGER = structlog.getLogger(__name__)
CLEAN_EVERY_N_HOOK = "CleanEveryN"
HEADER_TEMPLATE = """# DO NOT EDIT THIS FILE. All manual edits will be lost.
-# This file was generated by {file} from
-# {suite_file}.
+# This file was generated by {file}.
"""
# pylint: disable=too-many-arguments
@@ -62,48 +61,14 @@ def update_suite_config(suite_config, roots=None, excludes=None):
class SubSuite(object):
"""A suite of tests that can be run by evergreen."""
- def __init__(
- self,
- index: int,
- suite_name: str,
- test_list: List[str],
- tests_with_runtime_info: int,
- max_test_runtime: float,
- historic_runtime: float,
- task_overhead: float,
- ) -> None:
+ def __init__(self, test_list: List[str], task_overhead: float,
+ runtime_list: Optional[List[TestRuntime]] = None) -> None:
"""
Initialize the object.
- :param index: Sub-suite index.
- :param suite_name: Name of suite.
:param test_list: List of tests to include in this sub-suite.
- :param tests_with_runtime_info: Number of tests that that historic runtime info.
- :param max_test_runtime: Runtime of the longest running test.
- :param historic_runtime: Sum of the average runtime of all tests.
- :param task_overhead: Runtime overhead to expect from task level hooks.
- """
- self.index = index
- self.suite_name = suite_name
- self.test_list = test_list
- self.tests_with_runtime_info = tests_with_runtime_info
- self.max_test_runtime = max_test_runtime
- self.historic_runtime = historic_runtime
- self.task_overhead = task_overhead
-
- @classmethod
- def from_test_list(cls, index: int, suite_name: str, test_list: List[str],
- task_overhead: Optional[float],
- runtime_list: Optional[List[TestRuntime]] = None) -> SubSuite:
- """
- Create a sub-suite from the given test list.
-
- :param index: Index of sub-suite being created.
- :param suite_name: Name of suite.
- :param test_list: List of tests to include.
:param task_overhead: Runtime overhead to expect from task level hooks.
:param runtime_list: List of historic runtimes for tests in test_list.
- :return: Sub-suite for the given tests.
"""
runtime_count = 0
total_runtime = 0.0
@@ -116,8 +81,10 @@ class SubSuite(object):
total_runtime += runtime_map[test]
max_runtime = max(max_runtime, runtime_map[test])
- return cls(index, suite_name, test_list, runtime_count, max_runtime, total_runtime,
- task_overhead or 0.0)
+ self.test_list = test_list
+ self.tests_with_runtime_info = runtime_count
+ self.max_test_runtime = max_runtime
+ self.expected_runtime = total_runtime + task_overhead
def should_overwrite_timeout(self) -> bool:
"""
@@ -131,26 +98,12 @@ class SubSuite(object):
"""Get the estimated runtime of this task to for timeouts."""
if self.should_overwrite_timeout():
return TimeoutEstimate(max_test_runtime=self.max_test_runtime,
- expected_task_runtime=self.historic_runtime + self.task_overhead)
+ expected_task_runtime=self.expected_runtime)
return TimeoutEstimate.no_timeouts()
- def get_runtime(self):
- """Get the current average runtime of all the tests currently in this suite."""
- return self.historic_runtime
-
- def get_test_count(self) -> int:
- """Get the number of tests currently in this suite."""
- return len(self)
-
def __len__(self) -> int:
return len(self.test_list)
- def name(self, total_suites: int, suite_name: Optional[str] = None) -> str:
- """Get the name of this suite."""
- if suite_name is None:
- suite_name = self.suite_name
- return taskname.name_generated_task(suite_name, self.index, total_suites)
-
def generate_resmoke_config(self, source_config: Dict) -> str:
"""
Generate the contents of resmoke config for this suite.
@@ -159,7 +112,7 @@ class SubSuite(object):
:return: Resmoke config to run this suite.
"""
suite_config = update_suite_config(deepcopy(source_config), roots=self.test_list)
- contents = HEADER_TEMPLATE.format(file=__file__, suite_file=self.suite_name)
+ contents = HEADER_TEMPLATE.format(file=__file__)
contents += yaml.safe_dump(suite_config, default_flow_style=False)
return contents
@@ -181,14 +134,6 @@ class GeneratedSuite(NamedTuple):
task_name: str
suite_name: str
filename: str
- include_build_variant_in_name: bool = False
-
- def display_task_name(self) -> str:
- """Get the display name to use for this task."""
- base_name = remove_gen_suffix(self.task_name)
- if self.include_build_variant_in_name:
- return f"{base_name}_{self.build_variant}"
- return base_name
def get_test_list(self) -> List[str]:
"""Get the list of tests that will be run by this suite."""
@@ -203,12 +148,20 @@ class GeneratedSuite(NamedTuple):
Get the name of the file to store the resmoke configuration.
:param index: Index of suite or None for '_misc' suite.
- :return: Name resmoke configuration for subtask should stored.
+ :return: Name of generated resmoke.py configuration file.
"""
- if index is not None:
- return taskname.name_generated_task(self.display_task_name(), index,
- len(self.sub_suites))
- return f"{self.display_task_name()}_misc"
+ # Use self.task_name here instead of self.suite_name since multiple tasks can have the same resmoke.py suite.
+ return f"{taskname.name_generated_task(self.task_name, index, len(self.sub_suites))}.yml"
+
+ def sub_suite_task_name(self, index: Optional[int] = None) -> str:
+ """
+ Get the name of the task that runs one of the generated sub-suites.
+
+ :param index: Index of suite or None for '_misc' suite.
+ :return: Name of generated Evergreen task.
+ """
+ return taskname.name_generated_task(self.task_name, index, len(self.sub_suites),
+ self.build_variant)
class SuiteSplitParameters(NamedTuple):
@@ -354,24 +307,23 @@ class SuiteSplitService:
:param test_stats: Other historic task data.
:return: Generated suite for the sub-suites specified.
"""
- suites = [
- SubSuite.from_test_list(
- index,
- params.suite_name,
- test_list,
- self.get_task_hook_overhead(params.suite_name, params.is_asan, len(test_list),
- test_stats),
- tests_runtimes,
- ) for index, test_list in enumerate(test_lists)
- ]
+
+ sub_suites = []
+ for _, test_list in enumerate(test_lists):
+ task_overhead = self.get_task_hook_overhead(params.suite_name, params.is_asan,
+ len(test_list), test_stats)
+ sub_suites.append(SubSuite(test_list, task_overhead, tests_runtimes))
+
+ task_name = params.task_name
+ if self.config.include_build_variant_in_name:
+ task_name = f"{params.task_name}_{params.build_variant}"
return GeneratedSuite(
- sub_suites=suites,
+ sub_suites=sub_suites,
build_variant=params.build_variant,
- task_name=params.task_name,
+ task_name=task_name,
suite_name=params.suite_name,
filename=params.filename,
- include_build_variant_in_name=self.config.include_build_variant_in_name,
)
def filter_tests(self, tests_runtimes: List[TestRuntime],
diff --git a/buildscripts/task_generation/task_types/fuzzer_tasks.py b/buildscripts/task_generation/task_types/fuzzer_tasks.py
index 313e21275ac..df096f97191 100644
--- a/buildscripts/task_generation/task_types/fuzzer_tasks.py
+++ b/buildscripts/task_generation/task_types/fuzzer_tasks.py
@@ -1,5 +1,5 @@
"""Task generation for fuzzer tasks."""
-from typing import NamedTuple, Set, Optional, Dict, List
+from typing import NamedTuple, Set, Optional, Dict
from shrub.v2 import Task, FunctionCall, TaskDependency
@@ -8,13 +8,6 @@ from buildscripts.task_generation.constants import ARCHIVE_DIST_TEST_DEBUG_TASK
from buildscripts.util import taskname
-def get_multiversion_resmoke_args(is_sharded: bool) -> str:
- """Return resmoke args used to configure a cluster for multiversion testing."""
- if is_sharded:
- return "--numShards=2 --numReplSetNodes=2 "
- return "--numReplSetNodes=3 --linearChain=on "
-
-
class FuzzerTask(NamedTuple):
"""
Evergreen configuration for a generated fuzzer command.
@@ -43,9 +36,8 @@ class FuzzerGenTaskParams(NamedTuple):
resmoke_jobs_max: Maximum number of jobs resmoke should execute in parallel.
should_shuffle: Should tests be executed out of order.
timeout_secs: Timeout before test execution is considered hung.
- require_multiversion: Requires downloading Multiversion binaries.
+ require_multiversion_setup: Requires downloading Multiversion binaries.
use_large_distro: Should tests be generated on a large distro.
- add_to_display_task: Should generated tasks be grouped in a display task.
"""
task_name: str
@@ -60,13 +52,10 @@ class FuzzerGenTaskParams(NamedTuple):
resmoke_jobs_max: int
should_shuffle: bool
timeout_secs: int
- require_multiversion: Optional[bool]
+ require_multiversion_setup: Optional[bool]
use_large_distro: Optional[bool]
large_distro_name: Optional[str]
config_location: str
- add_to_display_task: bool = True
- version_config: Optional[List[str]] = None
- is_sharded: Optional[bool] = None
def jstestfuzz_params(self) -> Dict[str, str]:
"""Build a dictionary of parameters to pass to jstestfuzz."""
@@ -75,17 +64,8 @@ class FuzzerGenTaskParams(NamedTuple):
"npm_command": self.npm_command,
}
- def get_task_name(self, version: str) -> str:
- """Get the name to use for generated tasks."""
- if version:
- return f"{self.suite}_multiversion_{version}"
- return self.task_name
-
def get_resmoke_args(self) -> str:
"""Get the resmoke arguments to use for generated tasks."""
- if self.is_sharded is not None:
- mv_args = get_multiversion_resmoke_args(self.is_sharded)
- return f"{self.resmoke_args or ''} --mixedBinVersions={self.version_config} {mv_args}"
return self.resmoke_args
@@ -99,31 +79,24 @@ class FuzzerGenTaskService:
:param params: Parameters for how task should be generated.
:return: Set of shrub tasks.
"""
- version_list = params.version_config
- if version_list is None:
- version_list = [""]
-
sub_tasks = set()
- for version in version_list:
- sub_tasks = sub_tasks.union({
- self.build_fuzzer_sub_task(index, params, version)
- for index in range(params.num_tasks)
- })
+ sub_tasks = sub_tasks.union(
+ {self.build_fuzzer_sub_task(index, params)
+ for index in range(params.num_tasks)})
- return FuzzerTask(task_name=params.get_task_name(""), sub_tasks=sub_tasks)
+ return FuzzerTask(task_name=params.task_name, sub_tasks=sub_tasks)
@staticmethod
- def build_fuzzer_sub_task(task_index: int, params: FuzzerGenTaskParams, version: str) -> Task:
+ def build_fuzzer_sub_task(task_index: int, params: FuzzerGenTaskParams) -> Task:
"""
Build a shrub task to run the fuzzer.
:param task_index: Index of sub task being generated.
:param params: Parameters describing how tasks should be generated.
- :param version: Multiversion version to generate against.
:return: Shrub task to run the fuzzer.
"""
- sub_task_name = taskname.name_generated_task(
- params.get_task_name(version), task_index, params.num_tasks, params.variant)
+ sub_task_name = taskname.name_generated_task(params.task_name, task_index, params.num_tasks,
+ params.variant)
suite_arg = f"--suites={params.suite}"
run_tests_vars = {
@@ -131,9 +104,9 @@ class FuzzerGenTaskService:
"resmoke_args": f"{suite_arg} {params.get_resmoke_args()}",
"resmoke_jobs_max": params.resmoke_jobs_max,
"should_shuffle": params.should_shuffle,
- "require_multiversion": params.require_multiversion,
+ "require_multiversion_setup": params.require_multiversion_setup,
"timeout_secs": params.timeout_secs,
- "task": params.get_task_name(version),
+ "task": params.task_name,
"gen_task_config_location": params.config_location,
} # yapf: disable
@@ -141,7 +114,7 @@ class FuzzerGenTaskService:
commands = []
- if params.require_multiversion:
+ if params.require_multiversion_setup:
commands += [FunctionCall("git get project no modules")]
commands += [FunctionCall("add git tag")]
@@ -149,8 +122,8 @@ class FuzzerGenTaskService:
timeout_info.cmd,
FunctionCall("do setup"),
FunctionCall("configure evergreen api credentials")
- if params.require_multiversion else None,
- FunctionCall("do multiversion setup") if params.require_multiversion else None,
+ if params.require_multiversion_setup else None,
+ FunctionCall("do multiversion setup") if params.require_multiversion_setup else None,
FunctionCall("setup jstestfuzz"),
FunctionCall("run jstestfuzz", params.jstestfuzz_params()),
FunctionCall("run generated tests", run_tests_vars)
diff --git a/buildscripts/task_generation/task_types/multiversion_tasks.py b/buildscripts/task_generation/task_types/multiversion_tasks.py
deleted file mode 100644
index 0cb0fd17742..00000000000
--- a/buildscripts/task_generation/task_types/multiversion_tasks.py
+++ /dev/null
@@ -1,143 +0,0 @@
-"""Task generation for multiversion resmoke tasks."""
-from typing import NamedTuple, Set, List, Optional
-
-import inject
-from shrub.v2 import Task, FunctionCall, TaskDependency
-
-from buildscripts.resmokelib.multiversionconstants import REQUIRES_FCV_TAG
-from buildscripts.task_generation.constants import ARCHIVE_DIST_TEST_DEBUG_TASK
-from buildscripts.task_generation.suite_split import GeneratedSuite
-from buildscripts.task_generation.task_types.gentask_options import GenTaskOptions
-
-BACKPORT_REQUIRED_TAG = "backport_required_multiversion"
-EXCLUDE_TAGS = f"{REQUIRES_FCV_TAG},multiversion_incompatible,{BACKPORT_REQUIRED_TAG}"
-EXCLUDE_TAGS_FILE = "multiversion_exclude_tags.yml"
-
-
-class MultiversionGenTaskParams(NamedTuple):
- """
- Parameters for how multiversion tests should be generated.
-
- mixed_version_configs: List of version configuration to generate.
- is_sharded: Whether sharded tests are being generated.
- resmoke_args: Arguments to pass to resmoke.
- parent_task_name: Name of parent task containing all sub tasks.
- origin_suite: Resmoke suite generated tests are based off.
- """
-
- mixed_version_configs: List[str]
- is_sharded: bool
- resmoke_args: str
- parent_task_name: str
- origin_suite: str
- use_large_distro: bool
- large_distro_name: Optional[str]
- config_location: str
- name_prefix: Optional[str] = None
- test_list: Optional[str] = None
- create_misc_suite: bool = True
- add_to_display_task: bool = True
-
- def get_multiversion_resmoke_args(self) -> str:
- """Return resmoke args used to configure a cluster for multiversion testing."""
- if self.is_sharded:
- return "--numShards=2 --numReplSetNodes=2 "
- return "--numReplSetNodes=3 --linearChain=on "
-
-
-class MultiversionGenTaskService:
- """A service for generating multiversion tests."""
-
- @inject.autoparams()
- def __init__(self, gen_task_options: GenTaskOptions) -> None:
- """
- Initialize the service.
-
- :param gen_task_options: Options for how tasks should be generated.
- """
- self.gen_task_options = gen_task_options
-
- def generate_tasks(self, suite: GeneratedSuite, params: MultiversionGenTaskParams) -> Set[Task]:
- """
- Generate multiversion tasks for the given suite.
-
- :param suite: Suite to generate multiversion tasks for.
- :param params: Parameters for how tasks should be generated.
- :return: Evergreen configuration to generate the specified tasks.
- """
- sub_tasks = set()
- for version_config in params.mixed_version_configs:
- for index, sub_suite in enumerate(suite.sub_suites):
- # Generate the newly divided test suites
- sub_suite_name = sub_suite.name(len(suite))
- sub_task_name = f"{sub_suite_name}_{version_config}_{suite.build_variant}"
- if params.name_prefix is not None:
- sub_task_name = f"{params.name_prefix}:{sub_task_name}"
-
- sub_tasks.add(
- self._generate_task(sub_task_name, version_config, params, suite, index))
-
- if params.create_misc_suite:
- # Also generate the misc task.
- misc_suite_name = f"{params.origin_suite}_misc"
- misc_task_name = f"{misc_suite_name}_{version_config}_{suite.build_variant}"
- sub_tasks.add(
- self._generate_task(misc_task_name, version_config, params, suite, None))
-
- return sub_tasks
-
- # pylint: disable=too-many-arguments
- def _generate_task(self, sub_task_name: str, mixed_version_config: str,
- params: MultiversionGenTaskParams, suite: GeneratedSuite,
- index: Optional[int]) -> Task:
- """
- Generate a sub task to be run with the provided suite and mixed version config.
-
- :param sub_task_name: Name of task being generated.
- :param mixed_version_config: Versions task is being generated for.
- :param params: Parameters for how tasks should be generated.
- :return: Shrub configuration for task specified.
- """
- suite_file = self.gen_task_options.suite_location(suite.sub_suite_config_file(index))
-
- run_tests_vars = {
- "resmoke_args": self._build_resmoke_args(suite_file, mixed_version_config, params),
- "task": params.parent_task_name,
- "gen_task_config_location": params.config_location,
- "require_multiversion": True,
- }
-
- commands = [
- FunctionCall("git get project no modules"),
- FunctionCall("add git tag"),
- FunctionCall("do setup"),
- # Fetch and download the proper mongod binaries before running multiversion tests.
- FunctionCall("configure evergreen api credentials"),
- FunctionCall("do multiversion setup"),
- FunctionCall("run generated tests", run_tests_vars),
- ]
-
- return Task(sub_task_name, commands, {TaskDependency(ARCHIVE_DIST_TEST_DEBUG_TASK)})
-
- def _build_resmoke_args(self, suite_file: str, mixed_version_config: str,
- params: MultiversionGenTaskParams) -> str:
- """
- Get the resmoke args needed to run the specified task.
-
- :param suite_file: Path to resmoke suite configuration to run.
- :param mixed_version_config: Versions task is being generated for.
- :param params: Parameters for how tasks should be generated.
- :return: Arguments to pass to resmoke to run the generated task.
- """
-
- tag_file_location = self.gen_task_options.generated_file_location(EXCLUDE_TAGS_FILE)
-
- return (
- f"{params.resmoke_args} "
- f" --suite={suite_file}.yml "
- f" --mixedBinVersions={mixed_version_config}"
- f" --excludeWithAnyTags={EXCLUDE_TAGS},{params.parent_task_name}_{BACKPORT_REQUIRED_TAG} "
- f" --tagFile={tag_file_location} "
- f" --originSuite={params.origin_suite} "
- f" {params.get_multiversion_resmoke_args()} "
- f" {params.test_list if params.test_list else ''} ")
diff --git a/buildscripts/task_generation/task_types/resmoke_tasks.py b/buildscripts/task_generation/task_types/resmoke_tasks.py
index 7df492be8d4..cdc7576872d 100644
--- a/buildscripts/task_generation/task_types/resmoke_tasks.py
+++ b/buildscripts/task_generation/task_types/resmoke_tasks.py
@@ -7,14 +7,18 @@ import structlog
from shrub.v2 import Task, TaskDependency
from buildscripts.patch_builds.task_generation import resmoke_commands
+from buildscripts.resmokelib.multiversionconstants import REQUIRES_FCV_TAG
from buildscripts.task_generation.constants import ARCHIVE_DIST_TEST_DEBUG_TASK
-from buildscripts.task_generation.suite_split import GeneratedSuite, SubSuite
+from buildscripts.task_generation.suite_split import GeneratedSuite
from buildscripts.task_generation.task_types.gentask_options import GenTaskOptions
from buildscripts.task_generation.timeout import TimeoutEstimate
-from buildscripts.util import taskname
LOGGER = structlog.getLogger(__name__)
+BACKPORT_REQUIRED_TAG = "backport_required_multiversion"
+EXCLUDE_TAGS = f"{REQUIRES_FCV_TAG},multiversion_incompatible,{BACKPORT_REQUIRED_TAG}"
+EXCLUDE_TAGS_FILE = "multiversion_exclude_tags.yml"
+
def string_contains_any_of_args(string: str, args: List[str]) -> bool:
"""
@@ -32,7 +36,7 @@ class ResmokeGenTaskParams(NamedTuple):
Parameters describing how a specific resmoke suite should be generated.
use_large_distro: Whether generated tasks should be run on a "large" distro.
- require_multiversion: Requires downloading Multiversion binaries.
+ require_multiversion_setup: Requires downloading Multiversion binaries.
repeat_suites: How many times generated suites should be repeated.
resmoke_args: Arguments to pass to resmoke in generated tasks.
resmoke_jobs_max: Max number of jobs that resmoke should execute in parallel.
@@ -41,7 +45,7 @@ class ResmokeGenTaskParams(NamedTuple):
use_large_distro: bool
large_distro_name: Optional[str]
- require_multiversion: Optional[bool]
+ require_multiversion_setup: Optional[bool]
repeat_suites: int
resmoke_args: str
resmoke_jobs_max: Optional[int]
@@ -86,41 +90,38 @@ class ResmokeGenTaskService:
:return: Set of shrub tasks to generate the given suite.
"""
tasks = {
- self._create_sub_task(suite, generated_suite, params)
- for suite in generated_suite.sub_suites
+ self._create_sub_task(index, suite.get_timeout_estimate(), generated_suite, params)
+ for index, suite in enumerate(generated_suite.sub_suites)
}
if self.gen_task_options.create_misc_suite:
- # Add the misc suite
- misc_task_name = f"{generated_suite.task_name}_misc_{generated_suite.build_variant}"
tasks.add(
- self._generate_task(None, misc_task_name, TimeoutEstimate.no_timeouts(), params,
- generated_suite))
+ self._create_sub_task(None, est_timeout=TimeoutEstimate.no_timeouts(),
+ suite=generated_suite, params=params))
return tasks
- def _create_sub_task(self, sub_suite: SubSuite, suite: GeneratedSuite,
- params: ResmokeGenTaskParams) -> Task:
+ def _create_sub_task(self, index: Optional[int], est_timeout: TimeoutEstimate,
+ suite: GeneratedSuite, params: ResmokeGenTaskParams) -> Task:
"""
Create the sub task for the given suite.
- :param sub_suite: Sub-Suite to generate.
+ :param index: index of sub_suite.
+ :param est_timeout: timeout estimate.
:param suite: Parent suite being created.
:param params: Parameters describing how tasks should be generated.
:return: Shrub configuration for the sub-suite.
"""
- sub_task_name = taskname.name_generated_task(suite.task_name, sub_suite.index, len(suite),
- suite.build_variant)
- return self._generate_task(sub_suite.index, sub_task_name, sub_suite.get_timeout_estimate(),
- params, suite)
-
- def _generate_task(self, sub_suite_index: Optional[int], sub_task_name: str,
- timeout_est: TimeoutEstimate, params: ResmokeGenTaskParams,
- suite: GeneratedSuite) -> Task:
+ return self._generate_task(
+ suite.sub_suite_config_file(index), suite.sub_suite_task_name(index), est_timeout,
+ params, suite)
+
+ def _generate_task(self, sub_suite_file, sub_task_name: str, timeout_est: TimeoutEstimate,
+ params: ResmokeGenTaskParams, suite: GeneratedSuite) -> Task:
"""
Generate a shrub evergreen config for a resmoke task.
- :param sub_suite_index: Index of suite being generated.
+ :param sub_suite_file: Name of the suite file to run in the generated task.
:param sub_task_name: Name of task to generate.
:param timeout_est: Estimated runtime to use for calculating timeouts.
:param params: Parameters describing how tasks should be generated.
@@ -128,46 +129,75 @@ class ResmokeGenTaskService:
:return: Shrub configuration for the described task.
"""
# pylint: disable=too-many-arguments
- LOGGER.debug("Generating task", suite=suite.display_task_name(), index=sub_suite_index)
+ LOGGER.debug("Generating task running suite", sub_task_name=sub_task_name,
+ sub_suite_file=sub_suite_file)
- target_suite_file = self.gen_task_options.suite_location(
- suite.sub_suite_config_file(sub_suite_index))
- run_tests_vars = self._get_run_tests_vars(target_suite_file, suite.suite_name, params)
+ sub_suite_file_path = self.gen_task_options.suite_location(sub_suite_file)
+ run_tests_vars = self._get_run_tests_vars(sub_suite_file_path=sub_suite_file_path,
+ suite_file=suite.suite_name,
+ task_name=suite.task_name, params=params)
- require_multiversion = params.require_multiversion
+ require_multiversion_setup = params.require_multiversion_setup
timeout_cmd = timeout_est.generate_timeout_cmd(self.gen_task_options.is_patch,
params.repeat_suites,
self.gen_task_options.use_default_timeouts)
commands = resmoke_commands("run generated tests", run_tests_vars, timeout_cmd,
- require_multiversion)
+ require_multiversion_setup)
return Task(sub_task_name, commands, self._get_dependencies())
- @staticmethod
+ def generate_resmoke_args(self, sub_suite_file: str, original_suite: str, task_name: str,
+ params: ResmokeGenTaskParams) -> str:
+ """
+ Generate the resmoke args for the given suite.
+
+ :param sub_suite_file: File containing configuration for test suite.
+ :param original_suite: Name of source suite of the generated suite files.
+ :param task_name: Name of the task.
+ :param params: task generation parameters.
+
+ :return: arguments to pass to resmoke.
+ """
+ resmoke_args = f"--suite={sub_suite_file} --originSuite={original_suite} {params.resmoke_args}"
+ if params.repeat_suites and not string_contains_any_of_args(resmoke_args,
+ ["repeatSuites", "repeat"]):
+ resmoke_args += f" --repeatSuites={params.repeat_suites} "
+
+ if params.require_multiversion_setup:
+ tag_file = self.gen_task_options.generated_file_location(EXCLUDE_TAGS_FILE)
+ resmoke_args += f" --tagFile={tag_file}"
+ resmoke_args += f" --excludeWithAnyTags={EXCLUDE_TAGS},{task_name}_{BACKPORT_REQUIRED_TAG} "
+
+ return resmoke_args
+
def _get_run_tests_vars(
+ self,
+ sub_suite_file_path: str,
suite_file: str,
- suite_name: str,
+ task_name: str,
params: ResmokeGenTaskParams,
) -> Dict[str, Any]:
"""
Generate a dictionary of the variables to pass to the task.
- :param suite_file: Suite being generated.
- :param suite_name: Name of suite being generated
+ :param sub_suite_file_path: path to the generated suite file.
+ :param suite_file: name of the original suite file.
+ :param task_name: Name of the task.
:param params: Parameters describing how tasks should be generated.
:return: Dictionary containing variables and value to pass to generated task.
"""
variables = {
- "resmoke_args": params.generate_resmoke_args(suite_file, suite_name),
- "gen_task_config_location": params.config_location,
+ "resmoke_args":
+ self.generate_resmoke_args(sub_suite_file=sub_suite_file_path,
+ original_suite=suite_file, task_name=task_name,
+ params=params), "gen_task_config_location":
+ params.config_location, "require_multiversion_setup":
+ params.require_multiversion_setup
}
if params.resmoke_jobs_max:
variables["resmoke_jobs_max"] = params.resmoke_jobs_max
- if params.require_multiversion:
- variables["require_multiversion"] = params.require_multiversion
-
return variables
@staticmethod