def decorate_tasks_with_explicit_files( self, sub_tasks: List[ResmokeTask], params: MultiversionDecoratorParams) -> List[ResmokeTask]: """ Make multiversion subtasks based on generated subtasks for explicit tasks. Explicit tasks need to have new resmoke.py suite files created for each one with a unique list of test roots. """ fixture_type = self._get_suite_fixture_type(params.base_suite) versions_combinations = self._get_versions_combinations(fixture_type) decorated_tasks = [] for old_version in self.old_versions: for mixed_bin_versions in versions_combinations: for index, sub_task in enumerate(sub_tasks): shrub_task = sub_task.shrub_task commands = list(shrub_task.commands) # Decorate the task name. base_task_name = self._build_name(params.task, old_version, mixed_bin_versions) sub_task_name = taskname.name_generated_task( base_task_name, index, params.num_tasks, params.variant) # Decorate the suite name resmoke_suite_name = self._build_name( sub_task.resmoke_suite_name, old_version, mixed_bin_versions) execution_task_suite_name = taskname.name_generated_task( resmoke_suite_name, index, params.num_tasks) execution_task_suite_yaml_dir = os.path.dirname( sub_task.execution_task_suite_yaml_path) execution_task_suite_yaml_file = f"{execution_task_suite_name}.yml" execution_task_suite_yaml_path = os.path.join( execution_task_suite_yaml_dir, execution_task_suite_yaml_file) # Decorate the command invocation options. self._update_execution_task_suite_info( commands, execution_task_suite_yaml_path, old_version) commands = self._add_multiversion_commands(commands) # Store the result. shrub_task = Task(name=sub_task_name, commands=commands, dependencies=shrub_task.dependencies) decorated_tasks.append( ResmokeTask(shrub_task=shrub_task, resmoke_suite_name=resmoke_suite_name, execution_task_suite_yaml_name= execution_task_suite_yaml_file, execution_task_suite_yaml_path= execution_task_suite_yaml_path, test_list=sub_task.test_list, excludes=sub_task.excludes)) return decorated_tasks
def _generate_sub_task(self, mixed_version_config, task, task_index, suite, num_suites, burn_in_test=None): # pylint: disable=too-many-arguments """Generate a sub task to be run with the provided suite and mixed version config.""" # Create a sub task name appended with the task_index and build variant name. task_name = "{0}_{1}".format(task, mixed_version_config) sub_task_name = taskname.name_generated_task(task_name, task_index, num_suites, self.options.variant) self.task_names.append(sub_task_name) self.task_specs.append(TaskSpec(sub_task_name)) task = self.evg_config.task(sub_task_name) gen_task_name = BURN_IN_TASK if burn_in_test is not None else self.task commands = [ CommandDefinition().function("do setup"), # Fetch and download the proper mongod binaries before running multiversion tests. CommandDefinition().function("do multiversion setup") ] # TODO(SERVER-43306): Remove --dryRun command line option once we start turning on # multiversion tests. run_tests_vars = { "resmoke_args": "{0} --suite={1} --mixedBinVersions={2} --excludeWithAnyTags={3} ".format( self.options.resmoke_args, suite, mixed_version_config, EXCLUDE_TAGS), "task": gen_task_name, } if burn_in_test is not None: run_tests_vars["resmoke_args"] += burn_in_test commands.append(CommandDefinition().function("run generated tests").vars(run_tests_vars)) task.dependency(TaskDependency("compile")).commands(commands)
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. :return: Shrub task to run the fuzzer. """ sub_task_name = taskname.name_generated_task(params.task_name, task_index, params.num_tasks, params.variant) run_tests_vars = { "continue_on_failure": params.continue_on_failure, "resmoke_args": params.get_resmoke_args(), "resmoke_jobs_max": params.resmoke_jobs_max, "should_shuffle": params.should_shuffle, "require_multiversion_setup": params.require_multiversion_setup, "timeout_secs": params.timeout_secs, "task": params.task_name, "gen_task_config_location": params.config_location, "suite": params.suite, } # yapf: disable timeout_info = TimeoutInfo.overridden(timeout=params.timeout_secs) commands = [ timeout_info.cmd, FunctionCall("do setup"), FunctionCall(CONFIGURE_EVG_CREDENTIALS), FunctionCall("setup jstestfuzz"), FunctionCall("run jstestfuzz", params.jstestfuzz_params()), FunctionCall(RUN_GENERATED_TESTS, run_tests_vars) ] return Task(sub_task_name, commands, {TaskDependency(ARCHIVE_DIST_TEST_DEBUG_TASK)})
def _generate_sub_task(self, mixed_version_config, task_index, suite, num_suites): """Generate a sub task to be run with the provided suite and mixed version config.""" # Create a sub task name appended with the task_index and build variant name. task = "{0}_{1}".format(self.task, mixed_version_config) sub_task_name = taskname.name_generated_task(task, task_index, num_suites, self.options.variant) self.task_names.append(sub_task_name) self.task_specs.append(TaskSpec(sub_task_name)) task = self.evg_config.task(sub_task_name) commands = [CommandDefinition().function("do setup")] # Fetch and download the proper mongod binaries before running multiversion tests. commands.append(CommandDefinition().function("do multiversion setup")) exclude_tags = "requires_fcv_44" # TODO(SERVER-43306): Remove --dryRun command line option once we start turning on multiversion tests. run_tests_vars = { "resmoke_args": "{0} --suite={1} --mixedBinVersions={2} --excludeWithAnyTags={3} --dryRun=tests". format(self.options.resmoke_args, suite, mixed_version_config, exclude_tags), "task": self.task, } commands.append(CommandDefinition().function("run generated tests").vars(run_tests_vars)) task.dependency(TaskDependency("compile")).commands(commands)
def decorate_tasks(self, sub_tasks: Set[Task], params) -> Set[Task]: """Make multiversion subtasks based on generated subtasks.""" fixture_type = self._get_suite_fixture_type(params.suite) versions_combinations = self._get_versions_combinations(fixture_type) decorated_tasks = set() for old_version in self.old_versions: for mixed_bin_versions in versions_combinations: for index, sub_task in enumerate(sub_tasks): commands = list(sub_task.commands) base_task_name = self._build_name( params.task_name, old_version, mixed_bin_versions.replace("-", "_")) sub_task_name = taskname.name_generated_task( base_task_name, index, params.num_tasks, params.variant) suite_name = self._build_name( params.suite, old_version, mixed_bin_versions.replace("-", "_")) self._update_suite_name(commands, suite_name) commands = self._add_multiversion_commands(commands) decorated_tasks.add( Task(name=sub_task_name, commands=commands, dependencies=sub_task.dependencies)) return decorated_tasks
def create_generate_tasks_config( evg_config: Configuration, tests_by_task: Dict, generate_config: GenerateConfig, repeat_config: RepeatConfig, evg_api: Optional[EvergreenApi], include_gen_task: bool = True, task_prefix: str = "burn_in") -> Configuration: # pylint: disable=too-many-arguments,too-many-locals """ Create the config for the Evergreen generate.tasks file. :param evg_config: Shrub configuration to add to. :param tests_by_task: Dictionary of tests to generate tasks for. :param generate_config: Configuration of what to generate. :param repeat_config: Configuration of how to repeat tests. :param evg_api: Evergreen API. :param include_gen_task: Should generating task be include in display task. :param task_prefix: Prefix all task names with this. :return: Shrub configuration with added tasks. """ task_list = TaskList(evg_config) resmoke_options = repeat_config.generate_resmoke_options() for task in sorted(tests_by_task): test_list = tests_by_task[task]["tests"] for index, test in enumerate(test_list): # TODO: Extract multiversion related code into separate tooling - SERVER-47137 multiversion_path = tests_by_task[task].get("use_multiversion") display_task_name = tests_by_task[task]["display_task_name"] task_runtime_stats = _get_task_runtime_history( evg_api, generate_config.project, display_task_name, generate_config.build_variant) resmoke_args = tests_by_task[task]["resmoke_args"] distro = tests_by_task[task].get("distro", generate_config.distro) # Evergreen always uses a unix shell, even on Windows, so instead of using os.path.join # here, just use the forward slash; otherwise the path separator will be treated as # the escape character on Windows. sub_task_name = name_generated_task( f"{task_prefix}:{display_task_name}", index, len(test_list), generate_config.run_build_variant) LOGGER.debug("Generating sub-task", sub_task=sub_task_name) test_unix_style = test.replace('\\', '/') run_tests_vars = { "resmoke_args": f"{resmoke_args} {resmoke_options} {test_unix_style}" } if multiversion_path: run_tests_vars["task_path_suffix"] = multiversion_path timeout = _generate_timeouts(repeat_config, test, task_runtime_stats) commands = resmoke_commands("run tests", run_tests_vars, timeout, multiversion_path) task_list.add_task(sub_task_name, commands, ["compile"], distro) existing_tasks = [BURN_IN_TESTS_GEN_TASK] if include_gen_task else None task_list.add_to_variant(generate_config.run_build_variant, BURN_IN_TESTS_TASK, existing_tasks) return evg_config
def decorate_tasks_with_dynamically_generated_files( self, sub_tasks: Set[Task], params: MultiversionDecoratorParams) -> Set[Task]: """ Make multiversion subtasks based on generated subtasks, for tasks with generated files. E.g. fuzzers. @param sub_tasks: set of existing sub-tasks to be converted to multiversion. @param params: decoration parameters. @return: Set of multiversion tasks. """ fixture_type = self._get_suite_fixture_type(params.base_suite) versions_combinations = self._get_versions_combinations(fixture_type) decorated_tasks = set() for old_version in self.old_versions: for mixed_bin_versions in versions_combinations: for index, sub_task in enumerate(sub_tasks): commands = list(sub_task.commands) base_task_name = self._build_name(params.task, old_version, mixed_bin_versions) sub_task_name = taskname.name_generated_task( base_task_name, index, params.num_tasks, params.variant) suite_name = self._build_name(params.base_suite, old_version, mixed_bin_versions) self._update_execution_task_suite_info( commands, suite_name, old_version) commands = self._add_multiversion_commands(commands) decorated_tasks.add( Task(name=sub_task_name, commands=commands, dependencies=sub_task.dependencies)) return decorated_tasks
def main(expansions_file: str = "expansions.yml", output_file: str = "powercycle_tasks.json") -> None: """Generate multiple powercycle tasks to run in evergreen.""" config = make_config(expansions_file) build_variant = BuildVariant(config.build_variant) for task_name in config.task_names: if "skip_compile" in task_name: commands, task_dependency = get_skip_compile_setup_commands() else: commands, task_dependency = get_setup_commands() commands.extend([ FunctionCall("set up remote credentials", config.remote_credentials_vars), BuiltInCommand("timeout.update", config.timeout_params), FunctionCall("set up EC2 instance", config.set_up_ec2_instance_vars), FunctionCall("run powercycle test", config.run_powercycle_vars), ]) build_variant.display_task( task_name, { Task( name_generated_task(task_name, index, config.num_tasks, config.build_variant), commands, task_dependency) for index in range(config.num_tasks) }, distros=[config.distro]) shrub_project = ShrubProject.empty() shrub_project.add_build_variant(build_variant) write_file(output_file, shrub_project.json())
def generate_evg_config(suites, options): """Generate evergreen configuration for the given suites.""" evg_config = Configuration() task_names = [] task_specs = [] def generate_task(sub_suite_name, sub_task_name, max_test_runtime=None, expected_suite_runtime=None): """Generate evergreen config for a resmoke task.""" task_names.append(sub_task_name) spec = TaskSpec(sub_task_name) if options.use_large_distro: spec.distro(options.large_distro_name) task_specs.append(spec) task = evg_config.task(sub_task_name) target_suite_file = os.path.join(CONFIG_DIR, sub_suite_name) run_tests_vars = { "resmoke_args": "--suites={0}.yml {1}".format(target_suite_file, options.resmoke_args), "run_multiple_jobs": options.run_multiple_jobs, "task": options.task, } if options.resmoke_jobs_max: run_tests_vars["resmoke_jobs_max"] = options.resmoke_jobs_max commands = [] if max_test_runtime or expected_suite_runtime: cmd_timeout = CmdTimeoutUpdate() if max_test_runtime: cmd_timeout.timeout(int(math.ceil(max_test_runtime * 3))) if expected_suite_runtime: cmd_timeout.exec_timeout(int(math.ceil(expected_suite_runtime * 3))) commands.append(cmd_timeout.validate().resolve()) commands += [ CommandDefinition().function("do setup"), CommandDefinition().function("run generated tests").vars(run_tests_vars) ] task.dependency(TaskDependency("compile")).commands(commands) for idx, suite in enumerate(suites): sub_task_name = taskname.name_generated_task(options.task, idx, len(suites), options.variant) generate_task(suite.name, sub_task_name, suite.max_runtime, suite.get_runtime()) # Add the misc suite misc_suite_name = "{0}_misc".format(options.suite) generate_task(misc_suite_name, "{0}_misc_{1}".format(options.task, options.variant)) dt = DisplayTaskDefinition(options.task).execution_tasks(task_names) \ .execution_task("{0}_gen".format(options.task)) evg_config.variant(options.variant).tasks(task_specs).display_task(dt) return evg_config
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)
def _generate_all_tasks(self): for idx, suite in enumerate(self.suites): sub_task_name = taskname.name_generated_task(self.options.task, idx, len(self.suites), self.options.variant) self._generate_task(suite.name, sub_task_name, suite.max_runtime, suite.get_runtime()) # Add the misc suite misc_suite_name = "{0}_misc".format(self.options.suite) self._generate_task(misc_suite_name, "{0}_misc_{1}".format(self.options.task, self.options.variant))
def generate_name(self, index: int) -> str: """ Generate a subtask name. :param index: Index of subtask. :return: Name to use for generated sub-task. """ prefix = self.generate_config.task_prefix task_name = self.task_info.display_task_name return name_generated_task(f"{prefix}:{task_name}", index, len(self.task_info.tests), self.generate_config.run_build_variant)
def _create_sub_task(self, idx: int, suite: Suite) -> Task: """ Create the sub task for the given suite. :param idx: Index of suite to created. :param suite: Suite to create. :return: Shrub configuration for the suite. """ sub_task_name = taskname.name_generated_task(self.options.task, idx, len(self.suites), self.options.variant) return self._generate_task(suite.name, sub_task_name, self.options.generated_config_dir, suite.get_timeout_estimate())
def create_generate_tasks_config( evg_config: Configuration, tests_by_task: Dict, generate_config: GenerateConfig, repeat_config: RepeatConfig, evg_api: Optional[EvergreenApi], include_gen_task: bool = True, task_prefix: str = "burn_in") -> Configuration: # pylint: disable=too-many-arguments,too-many-locals """ Create the config for the Evergreen generate.tasks file. :param evg_config: Shrub configuration to add to. :param tests_by_task: Dictionary of tests to generate tasks for. :param generate_config: Configuration of what to generate. :param repeat_config: Configuration of how to repeat tests. :param evg_api: Evergreen API. :param include_gen_task: Should generating task be include in display task. :param task_prefix: Prefix all task names with this. :return: Shrub configuration with added tasks. """ task_list = TaskList(evg_config) resmoke_options = repeat_config.generate_resmoke_options() for task in sorted(tests_by_task): multiversion_path = tests_by_task[task].get("use_multiversion") task_runtime_stats = _get_task_runtime_history( evg_api, generate_config.project, task, generate_config.build_variant) resmoke_args = tests_by_task[task]["resmoke_args"] test_list = tests_by_task[task]["tests"] distro = tests_by_task[task].get("distro", generate_config.distro) for index, test in enumerate(test_list): sub_task_name = name_generated_task( f"{task_prefix}:{task}", index, len(test_list), generate_config.run_build_variant) LOGGER.debug("Generating sub-task", sub_task=sub_task_name) run_tests_vars = { "resmoke_args": f"{resmoke_args} {resmoke_options} {test}" } if multiversion_path: run_tests_vars["task_path_suffix"] = multiversion_path timeout = _generate_timeouts(repeat_config.repeat_tests_secs, test, task_runtime_stats) commands = resmoke_commands("run tests", run_tests_vars, timeout, multiversion_path) task_list.add_task(sub_task_name, commands, ["compile"], distro) existing_tasks = [BURN_IN_TESTS_GEN_TASK] if include_gen_task else None task_list.add_to_variant(generate_config.run_build_variant, BURN_IN_TESTS_TASK, existing_tasks) return evg_config
def _generate_task_name(self, gen_suite: GeneratedSuite, index: int) -> str: """ Generate a subtask name. :param gen_suite: GeneratedSuite object. :param index: Index of subtask. :return: Name to use for generated sub-task. """ prefix = self.generate_config.task_prefix task_name = gen_suite.task_name return name_generated_task(f"{prefix}:{task_name}", index, len(gen_suite), self.generate_config.run_build_variant)
def _generate_evg_tasks(options): """ Generate an evergreen configuration for fuzzers based on the options given. :param options: task options. :return: An evergreen configuration. """ evg_config = Configuration() task_names = [] task_specs = [] for task_index in range(options.num_tasks): name = taskname.name_generated_task(options.name, task_index, options.num_tasks, options.variant) task_names.append(name) task_specs.append(TaskSpec(name)) task = evg_config.task(name) commands = [CommandDefinition().function("do setup")] if options.use_multiversion: commands.append( CommandDefinition().function("do multiversion setup")) commands.append(CommandDefinition().function("run jstestfuzz").vars({ "jstestfuzz_vars": "--numGeneratedFiles {0} {1}".format(options.num_files, options.jstestfuzz_vars), "npm_command": options.npm_command })) run_tests_vars = { "continue_on_failure": options.continue_on_failure, "resmoke_args": options.resmoke_args, "resmoke_jobs_max": options.resmoke_jobs_max, "should_shuffle": options.should_shuffle, "task_path_suffix": options.use_multiversion, "timeout_secs": options.timeout_secs, } commands.append( CommandDefinition().function("run tests").vars(run_tests_vars)) task.dependency(TaskDependency("compile")).commands(commands) dt = DisplayTaskDefinition(options.name).execution_tasks(task_names)\ .execution_task("{0}_gen".format(options.name)) evg_config.variant(options.variant).tasks(task_specs).display_task(dt) return evg_config
def _generate_all_tasks(self): for idx, suite in enumerate(self.suites): sub_task_name = taskname.name_generated_task(self.options.task, idx, len(self.suites), self.options.variant) max_runtime = None total_runtime = None if suite.should_overwrite_timeout(): max_runtime = suite.max_runtime total_runtime = suite.get_runtime() self._generate_task(suite.name, sub_task_name, max_runtime, total_runtime) # Add the misc suite misc_suite_name = "{0}_misc".format(self.options.suite) self._generate_task(misc_suite_name, "{0}_misc_{1}".format(self.options.task, self.options.variant))
def build_fuzzer_sub_task(task_index: int, params: FuzzerGenTaskParams, version: str) -> 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) suite_arg = f"--suites={params.suite}" run_tests_vars = { "continue_on_failure": params.continue_on_failure, "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, "timeout_secs": params.timeout_secs, "task": params.get_task_name(version), "gen_task_config_location": params.config_location, } # yapf: disable timeout_info = TimeoutInfo.overridden(timeout=params.timeout_secs) commands = [] if params.require_multiversion: commands += [FunctionCall("git get project no modules")] commands += [ 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, FunctionCall("setup jstestfuzz"), FunctionCall("run jstestfuzz", params.jstestfuzz_params()), FunctionCall("run generated tests", run_tests_vars) ] commands = [command for command in commands if command is not None] return Task(sub_task_name, commands, {TaskDependency(ARCHIVE_DIST_TEST_DEBUG_TASK)})
def _generate_all_tasks(self): for idx, suite in enumerate(self.suites): sub_task_name = taskname.name_generated_task(self.options.task, idx, len(self.suites), self.options.variant) max_runtime = None total_runtime = None if suite.should_overwrite_timeout(): max_runtime = suite.max_runtime total_runtime = suite.get_runtime() self._generate_task(suite.name, sub_task_name, self.options.generated_config_dir, max_runtime, total_runtime) # Add the misc suite misc_suite_name = f"{os.path.basename(self.options.suite)}_misc" misc_task_name = f"{self.options.task}_misc_{self.options.variant}" self._generate_task(misc_suite_name, misc_task_name, self.options.generated_config_dir)
def generate_evg_config(suites, options): """Generate evergreen configuration for the given suites.""" evg_config = Configuration() task_names = [] task_specs = [] def generate_task(sub_suite_name, sub_task_name): """Generate evergreen config for a resmoke task.""" task_names.append(sub_task_name) task_specs.append(TaskSpec(sub_task_name)) task = evg_config.task(sub_task_name) target_suite_file = os.path.join(CONFIG_DIR, sub_suite_name) run_tests_vars = { "resmoke_args": "--suites={0} {1}".format(target_suite_file, options.resmoke_args), "run_multiple_jobs": options.run_multiple_jobs, } if options.resmoke_jobs_max: run_tests_vars["resmoke_jobs_max"] = options.resmoke_jobs_max commands = [ CommandDefinition().function("do setup"), CommandDefinition().function("run tests").vars(run_tests_vars) ] task.dependency(TaskDependency("compile")).commands(commands) for idx, suite in enumerate(suites): sub_task_name = taskname.name_generated_task(options.task, idx, len(suites), options.variant) generate_task(suite.name, sub_task_name) # Add the misc suite misc_suite_name = "{0}_misc".format(options.suite) generate_task(misc_suite_name, "{0}_misc_{1}".format(options.task, options.variant)) dt = DisplayTaskDefinition(options.task).execution_tasks(task_names) \ .execution_task("{0}_gen".format(options.task)) evg_config.variant(options.variant).tasks(task_specs).display_task(dt) return evg_config
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. :return: Shrub task to run the fuzzer. """ sub_task_name = taskname.name_generated_task(params.task_name, task_index, params.num_tasks, params.variant) run_tests_vars = { "continue_on_failure": params.continue_on_failure, "resmoke_args": params.get_resmoke_args(), "resmoke_jobs_max": params.resmoke_jobs_max, "should_shuffle": params.should_shuffle, "require_multiversion_setup": params.require_multiversion_setup, "timeout_secs": params.timeout_secs, "task": params.task_name, # This expansion's name was shortened to reduce the overall size of # the generated configuration file # gtcl = gen_task_config_location "gtcl": params.config_location, "suite": params.suite, } # yapf: disable timeout_info = TimeoutInfo.overridden(timeout=params.timeout_secs) commands = [ timeout_info.cmd, FunctionCall("do setup"), FunctionCall(CONFIGURE_EVG_CREDENTIALS), FunctionCall("setup jstestfuzz"), FunctionCall("run jstestfuzz", params.jstestfuzz_params()), FunctionCall(RUN_GENERATED_TESTS, run_tests_vars), FunctionCall("minimize jstestfuzz") ] dependencies = { TaskDependency(dependency) for dependency in params.dependencies } return Task(sub_task_name, commands, dependencies)
def _generate_evg_tasks(options): """ Generate an evergreen configuration for fuzzers based on the options given. :param options: task options. :return: An evergreen configuration. """ evg_config = Configuration() task_names = [] task_specs = [] for task_index in range(options.num_tasks): name = taskname.name_generated_task(options.name, task_index, options.num_tasks, options.variant) task_names.append(name) task_specs.append(TaskSpec(name)) task = evg_config.task(name) commands = [CommandDefinition().function("do setup")] if options.use_multiversion: commands.append(CommandDefinition().function("do multiversion setup")) commands.append(CommandDefinition().function("run jstestfuzz").vars({ "jstestfuzz_vars": "--numGeneratedFiles {0} {1}".format(options.num_files, options.jstestfuzz_vars), "npm_command": options.npm_command })) run_tests_vars = { "continue_on_failure": options.continue_on_failure, "resmoke_args": options.resmoke_args, "resmoke_jobs_max": options.resmoke_jobs_max, "should_shuffle": options.should_shuffle, "task_path_suffix": options.use_multiversion, "timeout_secs": options.timeout_secs, } commands.append(CommandDefinition().function("run tests").vars(run_tests_vars)) task.dependency(TaskDependency("compile")).commands(commands) dt = DisplayTaskDefinition(options.name).execution_tasks(task_names)\ .execution_task("{0}_gen".format(options.name)) evg_config.variant(options.variant).tasks(task_specs).display_task(dt) return evg_config
def _generate_sub_task(self, mixed_version_config: str, task: str, task_index: int, suite: str, num_suites: int, is_sharded: bool, burn_in_test: Optional[str] = None) -> Task: # pylint: disable=too-many-arguments """ Generate a sub task to be run with the provided suite and mixed version config. :param mixed_version_config: mixed version configuration. :param task: Name of task. :param task_index: Index of task to generate. :param suite: Name of suite being generated. :param num_suites: Number os suites being generated. :param is_sharded: If this is being generated for a sharded configuration. :param burn_in_test: If generation is for burn_in, burn_in options to use. :return: Shrub configuration for task specified. """ # Create a sub task name appended with the task_index and build variant name. task_name = f"{task}_{mixed_version_config}" sub_task_name = taskname.name_generated_task(task_name, task_index, num_suites, self.options.variant) gen_task_name = BURN_IN_TASK if burn_in_test is not None else self.task run_tests_vars = { "resmoke_args": _generate_resmoke_args(suite, mixed_version_config, is_sharded, self.options, burn_in_test), "task": gen_task_name, } commands = [ 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")})
def _create_sub_task(self, idx: int, suite: Suite) -> Task: """ Create the sub task for the given suite. :param idx: Index of suite to created. :param suite: Suite to create. :return: Shrub configuration for the suite. """ sub_task_name = taskname.name_generated_task(self.options.task, idx, len(self.suites), self.options.variant) max_runtime = None total_runtime = None if suite.should_overwrite_timeout(): max_runtime = suite.max_runtime total_runtime = suite.get_runtime() return self._generate_task(suite.name, sub_task_name, self.options.generated_config_dir, max_runtime, total_runtime)
def _create_sub_task(self, sub_suite: SubSuite, suite: GeneratedSuite, params: ResmokeGenTaskParams) -> Task: """ Create the sub task for the given suite. :param sub_suite: Sub-Suite to generate. :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.name(len(suite)), sub_task_name, sub_suite.get_timeout_estimate(), params, suite)
def build_fuzzer_sub_task(task_name: str, task_index: int, options: ConfigOptions) -> Task: """ Build a shrub task to run the fuzzer. :param task_name: Parent name of task. :param task_index: Index of sub task being generated. :param options: Options to use for task. :return: Shrub task to run the fuzzer. """ sub_task_name = taskname.name_generated_task(task_name, task_index, options.num_tasks, options.variant) run_jstestfuzz_vars = { "jstestfuzz_vars": "--numGeneratedFiles {0} {1}".format(options.num_files, options.jstestfuzz_vars), "npm_command": options.npm_command, } suite_arg = f"--suites={options.suite}" run_tests_vars = { "continue_on_failure": options.continue_on_failure, "resmoke_args": f"{suite_arg} {options.resmoke_args}", "resmoke_jobs_max": options.resmoke_jobs_max, "should_shuffle": options.should_shuffle, "task_path_suffix": options.use_multiversion, "timeout_secs": options.timeout_secs, "task": options.name } # yapf: disable commands = [ FunctionCall("do setup"), FunctionCall("configure evergreen api credentials") if options.use_multiversion else None, FunctionCall("do multiversion setup") if options.use_multiversion else None, FunctionCall("setup jstestfuzz"), FunctionCall("run jstestfuzz", run_jstestfuzz_vars), FunctionCall("run generated tests", run_tests_vars) ] commands = [command for command in commands if command is not None] return Task(sub_task_name, commands, {TaskDependency("archive_dist_test_debug")})
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. :return: Shrub task to run the fuzzer. """ 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 = { "continue_on_failure": params.continue_on_failure, "resmoke_args": f"{suite_arg} {params.resmoke_args}", "resmoke_jobs_max": params.resmoke_jobs_max, "should_shuffle": params.should_shuffle, "require_multiversion": params.require_multiversion, "timeout_secs": params.timeout_secs, "task": params.task_name, "gen_task_config_location": params.config_location, } # yapf: disable commands = [ FunctionCall("do setup"), FunctionCall("configure evergreen api credentials") if params.require_multiversion else None, FunctionCall("do multiversion setup") if params.require_multiversion else None, FunctionCall("setup jstestfuzz"), FunctionCall("run jstestfuzz", params.jstestfuzz_params()), FunctionCall("run generated tests", run_tests_vars) ] commands = [command for command in commands if command is not None] return Task(sub_task_name, commands, {TaskDependency("archive_dist_test_debug")})
def _create_task(index: int, test_count: int, test: str, task_data: Dict, task_runtime_stats: List[TestRuntime], generate_config: GenerateConfig, repeat_config: RepeatConfig, task_prefix: str) -> Task: # pylint: disable=too-many-arguments,too-many-locals """ Create the described shrub sub task. :param index: Index of task being created. :param test_count: Total number of testing being created. :param test: Test task is being generated for. :param task_data: Data about task to create. :param task_runtime_stats: Historical runtime of test. :param generate_config: Configuration of how to generate the task. :param repeat_config: Configuration of how the task should be repeated. :param task_prefix: String to prefix generated task with. :return: Shrub task for given configuration. """ # TODO: Extract multiversion related code into separate tooling - SERVER-47137 multiversion_path = task_data.get("use_multiversion") display_task_name = task_data["display_task_name"] resmoke_args = task_data["resmoke_args"] sub_task_name = name_generated_task(f"{task_prefix}:{display_task_name}", index, test_count, generate_config.run_build_variant) LOGGER.debug("Generating sub-task", sub_task=sub_task_name) test_unix_style = test.replace('\\', '/') run_tests_vars = { "resmoke_args": f"{resmoke_args} {repeat_config.generate_resmoke_options()} {test_unix_style}" } if multiversion_path: run_tests_vars["task_path_suffix"] = multiversion_path timeout = _generate_timeouts(repeat_config, test, task_runtime_stats) commands = resmoke_commands("run tests", run_tests_vars, timeout, multiversion_path) dependencies = {TaskDependency("compile")} return Task(sub_task_name, commands, dependencies)
def test_name_task_with_width_four(self): self.assertEqual("task_3141_var", taskname.name_generated_task("task", 3141, 5000, "var"))
def test_name_task_with_width_one(self): self.assertEqual("name_3_var", taskname.name_generated_task("name", 3, 10, "var"))
def render_suite(suites, suite_name): """Render the given suites into yml files that can be used by resmoke.py.""" for idx, suite in enumerate(suites): suite.name = taskname.name_generated_task(suite_name, idx, len(suites)) generate_subsuite_file(suite_name, suite.name, roots=suite.tests)
def name(self) -> str: """Get the name of this suite.""" return taskname.name_generated_task(self.source_name, self.index, Suite._current_index)