def __init__(self, evg_api, evg_config, options): """Create new EvergreenConfigGenerator object.""" self.evg_api = evg_api self.evg_config = evg_config self.options = options self.task_names = [] self.task_specs = [] # Strip the "_gen" suffix appended to the name of tasks generated by evergreen. self.task = generate_resmoke.remove_gen_suffix(self.options.task)
def generate_exclude_yaml(suite: str, task_path_suffix: str, is_generated_suite: bool) -> None: # pylint: disable=too-many-locals """ Update the given multiversion suite configuration yaml to exclude tests. Compares the BACKPORTS_REQUIRED_FILE on the current branch with the same file on the last-stable branch to determine which tests should be blacklisted. """ enable_logging() suite_name = generate_resmoke.remove_gen_suffix(suite) files_to_exclude = get_exclude_files(suite_name, task_path_suffix) if not files_to_exclude: LOGGER.info(f"No tests need to be excluded from suite '{suite_name}'.") return suite_yaml_dict = {} if not is_generated_suite: # Populate the config values to get the resmoke config directory. buildscripts.resmokelib.parser.set_options() suites_dir = os.path.join(_config.CONFIG_DIR, "suites") # Update the static suite config with the excluded files and write to disk. file_name = f"{suite_name}.yml" suite_config = generate_resmoke.read_yaml(suites_dir, file_name) suite_yaml_dict[file_name] = generate_resmoke.generate_resmoke_suite_config( suite_config, file_name, excludes=list(files_to_exclude)) else: # We expect the generated suites to already have been generated in the generated config # directory. suites_dir = CONFIG_DIR for file_name in os.listdir(suites_dir): # Update the 'exclude_files' for each of the appropriate generated suites. if file_name.endswith('misc.yml'): # New tests will be run as part of misc.yml. We want to make sure to properly # exclude these tests if they have been blacklisted. suite_config = generate_resmoke.read_yaml(CONFIG_DIR, file_name) exclude_files = suite_config["selector"]["exclude_files"] add_to_excludes = [test for test in files_to_exclude if test not in exclude_files] exclude_files += add_to_excludes suite_yaml_dict[file_name] = generate_resmoke.generate_resmoke_suite_config( suite_config, file_name, excludes=list(exclude_files)) elif file_name.endswith('.yml'): suite_config = generate_resmoke.read_yaml(CONFIG_DIR, file_name) selected_files = suite_config["selector"]["roots"] # Only exclude the files that we want to exclude in the first place and have been # selected to run as part of the generated suite yml. intersection = [test for test in selected_files if test in files_to_exclude] if not intersection: continue suite_yaml_dict[file_name] = generate_resmoke.generate_resmoke_suite_config( suite_config, file_name, excludes=list(intersection)) generate_resmoke.write_file_dict(suites_dir, suite_yaml_dict)
def create_generate_tasks_config( evg_config: Configuration, tests_by_task: Dict, generate_config: GenerateConfig, repeat_config: RepeatConfig, evg_api: Optional[EvergreenApi], evg_project_config: EvergreenProjectConfig, 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): if task in evg_project_config.get_task_names_by_tag(RANDOM_MULTIVERSION_REPLSETS_TAG): # Exclude files that should be blacklisted from multiversion testing. task_name = gen_resmoke.remove_gen_suffix(task) files_to_exclude = gen_multiversion.get_exclude_files(task_name, TASK_PATH_SUFFIX) if test in files_to_exclude: LOGGER.debug("Files to exclude", files_to_exclude=files_to_exclude, test=test, suite=task) continue 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 run_tests_task(self): """Return name of task name for s3 folder containing generated tasks config.""" return remove_gen_suffix(self.name_of_generating_task)
def test_doesnt_remove_non_gen_suffix(self): input_task_name = "sharded_multi_stmt_txn_jscore_passthroug" self.assertEqual("sharded_multi_stmt_txn_jscore_passthroug", under_test.remove_gen_suffix(input_task_name))
def test_removes_gen_suffix(self): input_task_name = "sharding_auth_auditg_gen" self.assertEqual("sharding_auth_auditg", under_test.remove_gen_suffix(input_task_name))
def __init__(self, evg_api: EvergreenApi, options): """Create new EvergreenMultiversionConfigGenerator object.""" self.evg_api = evg_api self.options = options # Strip the "_gen" suffix appended to the name of tasks generated by evergreen. self.task = generate_resmoke.remove_gen_suffix(self.options.task)
def generate_exclude_yaml(suite, task_path_suffix, is_generated_suite): """ Update the given multiversion suite configuration yaml to exclude tests. Compares the BACKPORTS_REQUIRED_FILE on the current branch with the same file on the last-stable branch to determine which tests should be blacklisted. """ enable_logging() suite_name = generate_resmoke.remove_gen_suffix(suite) # Get the backports_required_for_multiversion_tests.yml on the current version branch. backports_required_latest = generate_resmoke.read_yaml( ETC_DIR, BACKPORTS_REQUIRED_FILE) if suite_name not in backports_required_latest: LOGGER.info( f"Generating exclude files not supported for '{suite_name}''.") return latest_suite_yaml = backports_required_latest[suite_name] if not latest_suite_yaml: LOGGER.info(f"No tests need to be excluded from suite '{suite_name}'.") return # Get the state of the backports_required_for_multiversion_tests.yml file for the last-stable # binary we are running tests against. We do this by using the commit hash from the last-stable # mongo shell executable. last_stable_commit_hash = get_backports_required_last_stable_hash( task_path_suffix) # Get the yaml contents under the 'suite_name' key from the last-stable commit. last_stable_suite_yaml = get_last_stable_yaml(last_stable_commit_hash, suite_name) if last_stable_suite_yaml is None: files_to_exclude = set(elem["test_file"] for elem in latest_suite_yaml) else: files_to_exclude = set(elem["test_file"] for elem in latest_suite_yaml if elem not in last_stable_suite_yaml) if not files_to_exclude: LOGGER.info(f"No tests need to be excluded from suite '{suite_name}'.") return suite_yaml_dict = {} if not is_generated_suite: # Populate the config values to get the resmoke config directory. buildscripts.resmokelib.parser.set_options() suites_dir = os.path.join(_config.CONFIG_DIR, "suites") # Update the static suite config with the excluded files and write to disk. file_name = f"{suite_name}.yml" suite_config = generate_resmoke.read_yaml(suites_dir, file_name) suite_yaml_dict[ file_name] = generate_resmoke.generate_resmoke_suite_config( suite_config, file_name, excludes=list(files_to_exclude)) else: # We expect the generated suites to already have been generated in the generated config # directory. for file_name in os.listdir(CONFIG_DIR): suites_dir = CONFIG_DIR # Update the 'exclude_files' for each of the appropriate generated suites. if suite_name in file_name and file_name.endswith('.yml'): suite_config = generate_resmoke.read_yaml( CONFIG_DIR, file_name) selected_files = suite_config["selector"]["roots"] # Only exclude the files that we want to exclude in the first place and have been # selected to run as part of the generated suite yml. intersection = [ test for test in selected_files if test in files_to_exclude ] if not intersection: continue suite_yaml_dict[ file_name] = generate_resmoke.generate_resmoke_suite_config( suite_config, file_name, excludes=list(intersection)) generate_resmoke.write_file_dict(suites_dir, suite_yaml_dict)
def test_doesnt_remove_non_gen_suffix(self): input_task_name = "sharded_multi_stmt_txn_jscore_passthroug" self.assertEqual("sharded_multi_stmt_txn_jscore_passthroug", remove_gen_suffix(input_task_name))
def test_removes_gen_suffix(self): input_task_name = "sharding_auth_auditg_gen" self.assertEqual("sharding_auth_auditg", remove_gen_suffix(input_task_name))