def execute_tests(test_suites, tests_category_path): """ Routine for execution of tests from provided test_suites @param test_suites: list of test suites, from which tests are being executed @param test_category_path: path to test category being executed in tests dir @returns (dict) of results from testing in {'test_name': is_passed_boolean} key-value pairs """ results = {} for test_suite in test_suites: tests = test_suite.tests suite_name = test_suite.__class__.__name__ results[suite_name] = {} for test_name, test_case in tests: log_guest(f'Executing test {test_name}: {test_case}') os.chdir(f'{tests_category_path}/{suite_name}/{test_name}') try: test_case() results[suite_name][test_name] = (Fore.GREEN + "PASSED" + Style.RESET_ALL, None) except AssertionError as e: results[suite_name][test_name] = (Fore.RED + "FAILED", Fore.YELLOW + str(e) + Style.RESET_ALL) return results
def setup_base_authserver_configs(scripts_path, tests_path, test_categories, authserver_config): """ Creates conf for chosen authorization server for each test category passed as argument @param scripts_path: path to the MITS scripts on guest machine @param tests_path: path to tests dir on guest machine @param test_categories: list of test categories (str) @param authserver_config: (dict) configuration settings for authorization server """ authserver = authserver_config['name'] conf_extension = authserver_config['config_extension'] log_guest(f'Creating base config for {authserver}') for test_category in test_categories: test_category_path = f'{tests_path}/{test_category}' old_conf_path = f'{scripts_path}/{authserver}.{conf_extension}' new_conf_path = f'{test_category_path}/{authserver}.{conf_extension}' with open(new_conf_path, 'w') as conf_out: with open(old_conf_path, "r") as conf_file: conf_content = conf_file.read() conf_content = PathInjector.inject_paths(conf_content) conf_out.write(conf_content)
def cleanup_dirs(*args): """ Delete recursively all content in dirs specified in args @param *args: directories to be removed """ for dir_path in args: log_guest(f"Cleanup of {dir_path}") if os.path.exists(dir_path): shutil.rmtree(dir_path, ignore_errors=True)
def create_dirs(*args): """ Create dirs from *args @param *args: tuple of paths to directories, which should be created if do not exist """ for path in args: if not os.path.isdir(path): log_guest(f"Creating dir {path}") os.mkdir(path)
def get_exec_category(scripts_path, pickle_filename): """ Get exec category which is stored inside pickle file @param scripts_path: path to MITS scripts directory @param pickle_filename: name of pickle file @returns extracted exec category from pickle file as string """ pickle_tests_path = os.path.join(scripts_path, pickle_filename) exec_category = unpickle_tests(pickle_tests_path) log_guest(f"Test category to be run is {exec_category}") return exec_category
def setup_test_categories_in_test_env(test_categories, test_env_path, setup_routines, testing_options): """ Setup dirs for test categories in test environment dir @param test_categories: list of test_categories, for which dirs should be created @param test_env_path: path to test environment as str @param setup_routines: dict, where key is test category and value is callback for setup of that test category """ for test_category in test_categories: test_category_path = f'{test_env_path}/{test_category}' setup = setup_routines[test_category] setup(test_category_path, options=testing_options) log_guest(f"Set up test category {test_category}")
def register_test_suite(test_suite, execution_category): """ Registration subroutine for registering test_suite for provided exec. category @param test_suite: test suite instance to be registered @paran execution_category: execution category for test suite @Exception is raised if the test suite is registered already """ test_class = test_suite.__class__.__name__.lower() is_registered = test_class in registered_suites.keys() if is_registered is False: log_guest(f"Registering {test_class}") registered_suites.setdefault(execution_category, []) \ .append(test_suite) else: raise Exception("Guest: Test suite is already registered")
def get_required_configs(scripts_path, test_category, test_suites): """ Get config filenames for @test_suites @param scripts_path: (str) path to MITS scripts on guest machine @param test_category: test category for which the base config should be selected @param test_suites: suites for which we need to grab the configs @returns list of config filenames """ base_config = f'{scripts_path}/{test_category}.{config_extension}' config_filenames = [base_config] for test_suite in test_suites: filename = test_suite.config_filename suite_config_file = f'{scripts_path}/{filename}.{config_extension}' config_filenames.append(suite_config_file) log_guest(f"Config {filename} appended to list") return config_filenames
def setup_test_suite_dirs_in_tests(tests_path, test_env_path, suites_to_run): """ Setup environment for test suites, which should be run in tests path @param tests_path: tests path, where environment for test suites is created @param test_env_path: path to test environment @param suites_to_run: dict, where key is test category and value is tuple of test suites """ def generate_dummy_dir_name(): """ Generate random name for dir """ return uuid.uuid4().hex if not os.path.exists(tests_path): raise CleanupError("Tests dir not found") for test_category, test_suites in suites_to_run.items(): tests_category_path = f'{tests_path}/{test_category}' for test_suite in test_suites: test_suite_name = test_suite.__class__.__name__ test_suite_path = f'{tests_category_path}/{test_suite_name}' if not os.path.isdir(tests_category_path): os.mkdir(tests_category_path) os.mkdir(test_suite_path) tests = test_suite.tests for test_name, _ in tests: test_path = f'{test_suite_path}/{test_name}' os.mkdir(test_path) # the test setup is prepared from relative path, so we need to # set current test case as current dir os.chdir(test_path) dummy_dir = generate_dummy_dir_name() test_env_category_path = f'{test_env_path}/{test_category}' test_suite._test_setup(test_env_category_path, dummy_dir) log_guest(f"Set up dir for test suite {test_suite_name}")
def setup_testing_configs(scripts_path, tests_path, authserver_config, suites_to_run): config_extension = authserver_config['config_extension'] """ Creates configuration file based on chosen testing suites. @param scripts_path: (str) path to MITS scripts on guest machine @param tests_path: (str) path to tests dir @param authserver_config: configuration settings for authorization server @param suites_to_run: dict, where key is test category and value is tuple of test suites """ def get_required_configs(scripts_path, test_category, test_suites): """ Get config filenames for @test_suites @param scripts_path: (str) path to MITS scripts on guest machine @param test_category: test category for which the base config should be selected @param test_suites: suites for which we need to grab the configs @returns list of config filenames """ base_config = f'{scripts_path}/{test_category}.{config_extension}' config_filenames = [base_config] for test_suite in test_suites: filename = test_suite.config_filename suite_config_file = f'{scripts_path}/{filename}.{config_extension}' config_filenames.append(suite_config_file) log_guest(f"Config {filename} appended to list") return config_filenames for test_category, test_suites in suites_to_run.items(): log_guest(f'Creating configuration /medusa.conf for {test_category}') conf_filenames = get_required_configs(scripts_path, test_category, test_suites) tests_category_path = f'{tests_path}/{test_category}' with open(f'{tests_category_path}/medusa.conf', 'w') as conf_out: for conf_filename in conf_filenames: with open(conf_filename, "r") as conf_file: conf_content = conf_file.read() conf_content = PathInjector.inject_paths(conf_content) conf_out.write(conf_content)
def start_testing(suites_to_run, tests_path, test_env_path, authserver_start_cmd): """ Main testing function, starts Constable and executes suites one after the other. When all testing is done, results are sent to the validator module to be validated. @param suites_to_run: (dict), where key is test category and value is tuple of corresponding test suites @param tests_path: path to tests dir @param test_env_path: path to test environment dir @param authserver_start_cmd: (str) authserver start command @returns (dict) of results from testing in {'test_name': is_passed_boolean} key-value pairs """ def copy_medusa_conf_to_test_env(src, dest): shutil.copyfile(f'{src}/medusa.conf', f'{dest}/medusa.conf') all_results = {} for test_category, test_suites in suites_to_run.items(): test_category_path = f'{tests_path}/{test_category}' # it is required to copy medusa.conf file to test environment, because # this is where the authserver is going to search for the file copy_medusa_conf_to_test_env(test_category_path, test_env_path) # we need to change the dir to test_category_path because this is where # the authserver config is stored and being read os.chdir(test_category_path) log_guest('Starting authorization server') constable = Reader(authserver_start_cmd) time.sleep(1) log_guest('Starting test batch') results = execute_tests(test_suites, test_category_path) all_results[test_category] = results log_guest('Terminating authorization server') constable.terminate() return all_results
def cleanup_mount_partitions(test_env_path, testing_options): """ Make cleanup of partitions dirs @param test_env_path: str path to test environment @param testing_options: dict with special options for testing like available partitions for mounting """ if (testing_options is None or testing_options.get('mounting', None) is None): log_guest("No mounting options found") return available_partitions = testing_options['mounting'].get('partitions', None) if available_partitions is None: log_guest("No available partitions found") return if not os.path.exists(test_env_path): os.mkdir(test_env_path) tmp_mount_dir = f'{test_env_path}/tmp{uuid.uuid4().hex}' if not os.path.exists(tmp_mount_dir): log_guest(f"Creating {tmp_mount_dir} for cleanup of mount partitions") os.mkdir(tmp_mount_dir) for partition in available_partitions: # mount points can be nested and therefore we could umount all the # mounted partitions in the first iteration, we have to check each time # remaining partitions all_mounted_partitions = sh.df().stdout.decode() if not os.path.exists(partition): log_guest(f"{partition} does not exist, removing from the options") available_partitions.remove(partition) continue # if the partition is mounted somewhere in the filesystem, umount it # first and we will mount it to our specific dir if partition in all_mounted_partitions: log_guest(f"Umount of {partition}") sh.umount(partition, '-O --recursive') log_guest(f"Cleanup of device {partition}") sh.mount(partition, tmp_mount_dir, '-text4') shutil.rmtree(tmp_mount_dir, ignore_errors=True) sh.umount(partition) os.rmdir(tmp_mount_dir)