def create_multiversion_generate_tasks_config(evg_config: Configuration, tests_by_task: Dict, evg_api: EvergreenApi, generate_config: GenerateConfig) -> Configuration: """ Create the multiversion 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 evg_api: Evergreen API. :param generate_config: Configuration of what to generate. :return: Shrub configuration with added tasks. """ dt = DisplayTaskDefinition(BURN_IN_MULTIVERSION_TASK) if tests_by_task: # Get the multiversion suites that will run in as part of burn_in_multiversion. multiversion_suites = get_named_suites_with_root_level_key(MULTIVERSION_CONFIG_KEY) for suite in multiversion_suites: idx = 0 if suite["origin"] not in tests_by_task.keys(): # Only generate burn in multiversion tasks for suites that would run the detected # changed tests. continue LOGGER.debug("Generating multiversion suite", suite=suite["multiversion_name"]) # We hardcode the number of fallback sub suites and the target resmoke time here # since burn_in_tests cares about individual tests and not entire suites. The config # options here are purely used to generate the proper multiversion suites to run # tests against. config_options = { "suite": suite["origin"], "fallback_num_sub_suites": 1, "project": generate_config.project, "build_variant": generate_config.build_variant, "task_id": generate_config.task_id, "task_name": suite["multiversion_name"], "target_resmoke_time": 60, } config_options.update(gen_resmoke.DEFAULT_CONFIG_VALUES) config_generator = gen_multiversion.EvergreenConfigGenerator( evg_api, evg_config, gen_resmoke.ConfigOptions(config_options)) test_list = tests_by_task[suite["origin"]]["tests"] for test in test_list: # Exclude files that should be blacklisted from multiversion testing. files_to_exclude = gen_multiversion.get_exclude_files(suite["multiversion_name"], TASK_PATH_SUFFIX) LOGGER.debug("Files to exclude", files_to_exclude=files_to_exclude, test=test, suite=suite["multiversion_name"]) if test not in files_to_exclude: # Generate the multiversion tasks for each test. config_generator.generate_evg_tasks(test, idx) idx += 1 dt.execution_tasks(config_generator.task_names) evg_config.variant(generate_config.build_variant).tasks(config_generator.task_specs) dt.execution_task(f"{BURN_IN_MULTIVERSION_TASK}_gen") evg_config.variant(generate_config.build_variant).display_task(dt) return evg_config
def test_items_added_to_display_task(self): dt = DisplayTaskDefinition("display task name") dt.execution_task("comp0").execution_tasks(["comp1", "comp2"]) obj = dt.to_map() assert "display task name" == obj["name"] assert "comp0" in obj["execution_tasks"] assert "comp1" in obj["execution_tasks"] assert "comp2" in obj["execution_tasks"]
def _generate_fuzzer_tasks(self, version_configs, is_sharded): dt = DisplayTaskDefinition(self.task) for version_config in version_configs: fuzzer_config = generate_resmoke.ConfigOptions(self.options.config) fuzzer_config = self._get_fuzzer_options(version_config, is_sharded) gen_fuzzer.generate_evg_tasks(fuzzer_config, self.evg_config, task_name_suffix=version_config, display_task=dt) dt.execution_task(f"{fuzzer_config.name}_gen") self.evg_config.variant(self.options.variant).display_task(dt) return self.evg_config
def _generate_fuzzer_tasks(self, config): suite_file = self.options.suite + ".yml" # Update the jstestfuzz yml suite with the proper multiversion configurations. source_config = generate_resmoke.read_yaml(TEST_SUITE_DIR, suite_file) config.update_yaml(source_config) updated_yml = generate_resmoke.generate_resmoke_suite_config(source_config, suite_file) file_dict = {f"{self.options.suite}.yml": updated_yml} dt = DisplayTaskDefinition(self.task) for version_config in config.version_configs: fuzzer_config = self._get_fuzzer_options(version_config, suite_file) gen_fuzzer.generate_evg_tasks(fuzzer_config, self.evg_config, task_name_suffix=version_config, display_task=dt) generate_resmoke.write_file_dict(CONFIG_DIR, file_dict) dt.execution_task(f"{fuzzer_config.name}_gen") self.evg_config.variant(self.options.variant).display_task(dt) return self.evg_config
def test_invalid_component(self): dt = DisplayTaskDefinition("display task") with pytest.raises(TypeError): dt.execution_task(42)
def generate_evg_tasks(options, evg_config, task_name_suffix=None, display_task=None): """ Generate an evergreen configuration for fuzzers based on the options given. :param options: task options. :param evg_config: evergreen configuration. :param task_name_suffix: suffix to be appended to each task name. :param display_task: an existing display task definition to append to. :return: An evergreen configuration. """ task_names = [] task_specs = [] for task_index in range(options.num_tasks): task_name = options.name if not task_name_suffix else f"{options.name}_{task_name_suffix}" name = taskname.name_generated_task(task_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("setup jstestfuzz")) commands.append(CommandDefinition().function("run jstestfuzz").vars({ "jstestfuzz_vars": "--numGeneratedFiles {0} {1}".format(options.num_files, options.jstestfuzz_vars), "npm_command": options.npm_command })) # Unix path separators are used because Evergreen only runs this script in unix shells, # even on Windows. suite_arg = f"--suites={CONFIG_DIRECTORY}/{options.suite}.yml" 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.append(CommandDefinition().function( "run generated tests").vars(run_tests_vars)) task.dependency(TaskDependency("compile")).commands(commands) # Create a new DisplayTaskDefinition or append to the one passed in. dt = DisplayTaskDefinition(task_name) if not display_task else display_task dt.execution_tasks(task_names) evg_config.variant(options.variant).tasks(task_specs) if not display_task: dt.execution_task("{0}_gen".format(options.name)) evg_config.variant(options.variant).display_task(dt) return evg_config