def test_verify_container_mountpoints_failure(config_files, monkeypatch): with mocked_executable('lxc', '/here/is/no/lxc'): with mocked_lxd_version_check(): with open(config_files, "r") as main_file: def fake_lxc_exec_command(*popenargs, **kwargs): if get_command(popenargs).endswith( 'lxc') and get_sub_command(popenargs) == 'exec': if get_command_parameter(popenargs, '--') == 'test': return subprocess.CompletedProcess( "failure", 1, 'failure') else: return subprocess.CompletedProcess( "fakerun", 0, '') else: return subprocess.run(*popenargs, **kwargs) monkeypatch.setattr(mockablerun, 'run_mockable', fake_lxc_exec_command) parser = ConfigurationParser(main_file) coordinator = SharedFolderCoordinator(parser) with pytest.raises(FatalError) as error: coordinator.verify_container_mountpoints('fake-container') assert 'fake-container' in error.value.message assert '/foo/bar/target_mountpoint' in error.value.message
def test_verify_container_mountpoints_connection_failure( config_files, monkeypatch): with open(config_files, "r") as main_file: def fake_lxc_exec_command(*popenargs, **kwargs): command = popenargs[0] if command[0] == 'lxc' and command[1] == 'exec': if command[command.index('--') + 1] == 'true': cmd = [ 'bash', '-c', '>&2 echo -e "lxc command failed" ; exit 1' ] return subprocess.run(cmd, **kwargs) else: return subprocess.CompletedProcess("fakerun", 0, '') else: return subprocess.run(*popenargs, **kwargs) monkeypatch.setattr(mockablerun, 'run_mockable', fake_lxc_exec_command) parser = ConfigurationParser(main_file) coordinator = SharedFolderCoordinator(parser) with pytest.raises(FatalError) as error: coordinator.verify_container_mountpoints('fake-container') assert 'fake-container' in error.value.message assert 'lxc command failed' in error.value.message
def test_create_host_folders_successful_create(config_files, monkeypatch): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) coordinator = SharedFolderCoordinator(parser) def fake_os_path_isdir(*_): return False monkeypatch.setattr(os.path, 'isdir', fake_os_path_isdir) def fake_os_path_exists(*_): return False monkeypatch.setattr(os.path, 'exists', fake_os_path_exists) def fake_mkdir_command(*popenargs, **kwargs): if get_command(popenargs) == 'mkdir' and get_sub_command( popenargs) == '-p': folder = popenargs[0][-1] assert 'valid_folder' in folder or 'work' in folder return subprocess.CompletedProcess("fakerun", 0, '') else: return subprocess.run(*popenargs, **kwargs) monkeypatch.setattr(mockablerun, 'run_mockable', fake_mkdir_command) coordinator.create_host_folders() # successful mkdir
def test_general_parameters(config_files): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) parameters = parser.get_general_parameters() assert parameters.get("param1") == "keep" assert parameters.get("param2") == "overwritten" assert parameters.get("param3") == "new"
def test_create_host_folders_failed_create(config_files, monkeypatch): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) coordinator = SharedFolderCoordinator(parser) def fake_os_path_isdir(*_): return False monkeypatch.setattr(os.path, 'isdir', fake_os_path_isdir) def fake_os_path_exists(*_): return False monkeypatch.setattr(os.path, 'exists', fake_os_path_exists) def fake_mkdir_command(*popenargs, **kwargs): if get_command(popenargs) == 'mkdir' and get_sub_command( popenargs) == '-p': cmd = ['bash', '-c', '>&2 echo -e "no permission" ; exit 1'] return subprocess.run(cmd, **kwargs) else: return subprocess.run(*popenargs, **kwargs) monkeypatch.setattr(mockablerun, 'run_mockable', fake_mkdir_command) with pytest.raises(FatalError) as error: coordinator.create_host_folders() # failed mkdir assert 'valid_folder' in error.value.message assert 'no permission' in error.value.message
def test_lxd_connection(config_files, monkeypatch): def fake_ansible_playbook_run(*popenargs, **kwargs): if get_command(popenargs) == 'ansible-playbook': assert 'lxd' == get_command_parameter(popenargs, '--connection') verify_inventory(get_command_parameter(popenargs, '--inventory')) verify_extra_vars( get_command_parameter(popenargs, '--extra-vars').lstrip('@')) # TODO: verify --user for ssh connection return subprocess.CompletedProcess("fakerun", 0, '') else: return subprocess.run(*popenargs, **kwargs) monkeypatch.setattr(mockablerun, 'run_mockable', fake_ansible_playbook_run) def fakechown(*_): pass monkeypatch.setattr(shutil, 'chown', fakechown) with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) runner = PlaybookRunner(parser, "fake-container", "lxd") playbooks = runner.run_all() expected_playbooks = ['10_base_system', '20_networking', '30_foo'] assert playbooks == expected_playbooks
def test_configuration_rendering(tmpdir): source = os.path.join(get_edi_plugin_directory(), 'config_templates', 'project_tree') assert os.path.isdir(source) assert not os.listdir(str(tmpdir)) # target should be empty copy_tree(source, str(tmpdir)) template_link = os.path.join(str(tmpdir), 'PROJECTNAME-develop.yml.edilink') assert os.path.isfile(template_link) template = ConfigurationTemplate(str(tmpdir)) result = template.render({'edi_project_name': 'test-project'}) assert 'PROJECTNAME' not in ''.join(result) assert 'plugins/playbooks/sample_playbook/roles/sample_role/tasks/main.yml' in ''.join( result) assert not os.path.isfile(template_link) test_project_dev = os.path.join(str(tmpdir), 'test-project-develop.yml') assert os.path.isfile(test_project_dev) assert os.path.islink(test_project_dev) gitignore = os.path.join(str(tmpdir), '.gitignore') assert os.path.isfile(gitignore) with open(test_project_dev, mode='r', encoding='UTF-8') as config_file: cp = ConfigurationParser(config_file) assert cp.get_bootstrap_architecture() == 'amd64'
def test_no_shared_folders_for_distributable_image(config_files, monkeypatch): with mocked_executable('lxc'): with mocked_lxd_version_check(): with open(config_files, "r") as main_file: with command_context({'edi_create_distributable_image': True}): parser = ConfigurationParser(main_file) coordinator = SharedFolderCoordinator(parser) def fake_os_path_exists(*_): return False monkeypatch.setattr(os.path, 'exists', fake_os_path_exists) def fake_run(*popenargs, **kwargs): # We should not run anything! assert False monkeypatch.setattr(mockablerun, 'run_mockable', fake_run) coordinator.create_host_folders() coordinator.verify_container_mountpoints('does-not-exist') assert coordinator.get_mountpoints() == [] assert coordinator.get_pre_config_profiles() == [] assert coordinator.get_post_config_profiles() == []
def test_get_mountpoints(config_files): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) coordinator = SharedFolderCoordinator(parser) mountpoints = coordinator.get_mountpoints() assert mountpoints[0] == '/foo/bar/target_mountpoint' assert len(mountpoints) == 2
def test_create_host_folders_folder_exists(config_files, monkeypatch): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) coordinator = SharedFolderCoordinator(parser) patch_os_path(monkeypatch, True, True) coordinator.create_host_folders() # nothing to do
def test_require_root(config_files): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) input_file = os.path.join(os.sep, 'fake_folder', 'input.txt') runner = CommandRunner(parser, 'postprocessing_commands', input_file) assert not runner.require_root() assert not runner.require_root_for_clean()
def test_run_and_clean(config_files, monkeypatch): def intercept_command_run(*popenargs, **kwargs): if "command" in get_command(popenargs): print(popenargs) with open(get_command(popenargs), encoding='utf-8') as f: print(f.read()) return subprocess.run(*popenargs, **kwargs) else: print("passthrough") return subprocess.run(*popenargs, **kwargs) monkeypatch.setattr(mockablerun, 'run_mockable', intercept_command_run) suppress_chown_during_debuild(monkeypatch) with workspace() as workdir: with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) input_file = os.path.join(workdir, 'input.txt') with open(input_file, mode='w', encoding='utf-8') as i: i.write("*input file*\n") runner = CommandRunner(parser, 'postprocessing_commands', input_file) artifacts = runner.run() assert os.path.isfile(os.path.join('artifacts', 'first.txt')) assert os.path.isfile(os.path.join('artifacts', 'last.txt')) def verify_last_artifact(artifact): assert str(workdir) in str(artifact) assert 'artifacts/last.txt' in str(artifact) assert 'last.txt' in str(artifact) with open(artifact, mode='r') as result_file: content = result_file.read() assert "*input file*" in content assert "*first step*" in content assert "*second step*" in content assert "*last step*" in content verify_last_artifact(artifacts[-1]) first_file = os.path.join('artifacts', 'first.txt') first_folder = os.path.join('artifacts', 'first_folder') os.remove(first_file) os.rmdir(first_folder) runner.run() assert os.path.isfile(first_file) assert os.path.isdir(first_folder) runner.clean() assert not os.path.isfile(os.path.join('artifacts', 'last.txt')) assert not os.path.isfile(first_file) assert not os.path.isdir(first_folder)
def test_config_nodes_absence(empty_config_file): with open(empty_config_file, "r") as main_file: parser = ConfigurationParser(main_file) assert not parser.has_bootstrap_node() with pytest.raises(FatalError) as error: parser.get_bootstrap_repository() assert "repository" in error.value.message with pytest.raises(FatalError) as error: parser.get_bootstrap_architecture() assert "architecture" in error.value.message
def test_create_host_folders_not_a_folder(config_files, monkeypatch): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) coordinator = SharedFolderCoordinator(parser) patch_os_path(monkeypatch, False, True) with pytest.raises(FatalError) as error: coordinator.create_host_folders() # exists but not a folder assert 'edi_marker_valid_folder' in error.value.message
def test_pre_config_profiles(config_files): expected_profiles = render_expected_profiles() with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) coordinator = SharedFolderCoordinator(parser) profiles = coordinator.get_pre_config_profiles() assert len(profiles) == 1 assert profiles[0][0] == expected_profiles[0]
def test_bootstrap_overlay(config_files): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) # the host file shall win boostrap_source = SourceEntry(parser.get_bootstrap_repository()) assert parser.get_bootstrap_architecture() == "i386" assert "main" in boostrap_source.comps assert boostrap_source.uri == "http://deb.debian.org/debian/" # the all file shall provide this key expected_key = "https://ftp-master.debian.org/keys/archive-key-8.asc" assert parser.get_bootstrap_repository_key() == expected_key assert boostrap_source.dist == "jessie" assert parser.get_bootstrap_tool() == "debootstrap"
def test_without_shared_folders(empty_config_file): with open(empty_config_file, "r") as main_file: parser = ConfigurationParser(main_file) coordinator = SharedFolderCoordinator(parser) mountpoints = coordinator.get_mountpoints() assert isinstance(mountpoints, list) assert len(mountpoints) == 0 pre = coordinator.get_pre_config_profiles() assert isinstance(pre, list) assert len(pre) == 0 post = coordinator.get_post_config_profiles() assert isinstance(post, list) assert len(post) == 0
def test_documentation_steps_overlay(config_files, monkeypatch): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) documentation_steps = parser.get_ordered_path_items( "documentation_steps") assert len(documentation_steps) == 2 expected_steps = ["10_first_step", "20_second_step"] for step, expected in zip(documentation_steps, expected_steps): name, path, parameters, raw_node = step assert name == expected if name == "20_second_step": value = parameters.get("edi_doc_include_packages") assert value == ['x', 'y', 'z'] assert raw_node.get('output', {}).get('file') == 'foo.rst'
def test_plugin_report(config_files): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) input_file = os.path.join(os.sep, 'fake_folder', 'input.txt') runner = CommandRunner(parser, 'postprocessing_commands', input_file) output = runner.get_plugin_report() commands = output.get('postprocessing_commands', []) assert len(commands) == 3 assert next(iter(commands[0].keys())) == '10_first_command' assert next(iter(commands[1].keys())) == '20_second_command' assert next(iter(commands[2].keys())) == '40_last_command'
def test_verify_container_mountpoints(config_files, monkeypatch): with mocked_executable('lxc', '/here/is/no/lxc'): with mocked_lxd_version_check(): with open(config_files, "r") as main_file: def fake_lxc_exec_command(*popenargs, **kwargs): if get_command(popenargs).endswith('lxc') and get_sub_command(popenargs) == 'exec': return subprocess.CompletedProcess("fakerun", 0, '') else: return subprocess.run(*popenargs, **kwargs) monkeypatch.setattr(mockablerun, 'run_mockable', fake_lxc_exec_command) parser = ConfigurationParser(main_file) coordinator = SharedFolderCoordinator(parser) coordinator.verify_container_mountpoints('fake-container')
def test_verify_container_mountpoints(config_files, monkeypatch): with open(config_files, "r") as main_file: def fake_lxc_exec_command(*popenargs, **kwargs): command = popenargs[0] if command[0] == 'lxc' and command[1] == 'exec': return subprocess.CompletedProcess("fakerun", 0, '') else: return subprocess.run(*popenargs, **kwargs) monkeypatch.setattr(mockablerun, 'run_mockable', fake_lxc_exec_command) parser = ConfigurationParser(main_file) coordinator = SharedFolderCoordinator(parser) coordinator.verify_container_mountpoints('fake-container')
def test_playbooks_overlay(config_files, monkeypatch): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) playbooks = parser.get_ordered_path_items("playbooks") assert len(playbooks) == 3 expected_playbooks = ["10_base_system", "20_networking", "30_foo"] for playbook, expected in zip(playbooks, expected_playbooks): name, path, extra_vars, _ = playbook assert name == expected if name == "10_base_system": value = extra_vars.get("kernel_package") assert value == "linux-image-amd64-rt" value = extra_vars.get("message") assert value == "some message" if name == "20_networking": assert path.endswith("playbooks/foo.yml")
def test_create_host_folders_folder_exists(config_files, monkeypatch): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) coordinator = SharedFolderCoordinator(parser) def fake_os_path_isdir(*_): return True monkeypatch.setattr(os.path, 'isdir', fake_os_path_isdir) def fake_os_path_exists(*_): return True monkeypatch.setattr(os.path, 'exists', fake_os_path_exists) coordinator.create_host_folders() # nothing to do
def test_shared_folders(config_files): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) shared_folders = parser.get_ordered_raw_items('shared_folders') # first element name, content, dict = shared_folders[0] assert name == 'other_folder' assert content.get('mountpoint') == 'target_mountpoint' assert content.get('folder') == 'valid_folder' # merge result assert dict.get('edi_current_user_host_home_directory') assert dict.get('edi_current_user_target_home_directory') == '/foo/bar' # second element name, content, dict = shared_folders[1] assert name == 'workspace' assert content.get('mountpoint') == 'mywork' assert content.get('folder') == 'work' assert dict.get('edi_current_user_target_home_directory').startswith('/home/')
def test_create_host_folders_not_a_folder(config_files, monkeypatch): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) coordinator = SharedFolderCoordinator(parser) def fake_os_path_isdir(*_): return False monkeypatch.setattr(os.path, 'isdir', fake_os_path_isdir) def fake_os_path_exists(*_): return True monkeypatch.setattr(os.path, 'exists', fake_os_path_exists) with pytest.raises(FatalError) as error: coordinator.create_host_folders() # exists but not a folder assert 'valid_folder' in error.value.message
def test_empty_overlay_file(empty_overlay_config_file): with open(empty_overlay_config_file, "r") as main_file: parser = ConfigurationParser(main_file) assert parser.get_compression() == 'gz'
def test_config_nodes_presence(config_files): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) assert parser.has_bootstrap_node() assert parser.get_bootstrap_repository() assert parser.get_bootstrap_architecture()
def test_global_configuration_overlay(config_files): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) assert parser.get_compression() == "gz" assert parser.get_lxc_stop_timeout() == 130
def test_project_name(config_files, config_name): with open(config_files, "r") as main_file: parser = ConfigurationParser(main_file) assert parser.get_configuration_name() == config_name
def _setup_parser(self, config_file): self.config = ConfigurationParser(config_file)