def test_rootbuilddir_for_all_platforms_copy(build_dir, mock_source): root = RootBuildDir(build_dir) root.init_build_dirs(["x86_64", "s390x"], mock_source) results = root.for_all_platforms_copy(create_dockerfile) build_dir_s390x = build_dir.joinpath("s390x") build_dir_x86_64 = build_dir.joinpath("x86_64") # created files/dirs by action method expected_created = sorted([ build_dir_s390x / DOCKERFILE_FILENAME, build_dir_s390x / "data" / "data.json", build_dir_s390x / "cachito-1", ]) assert expected_created == sorted(results) # action method creates files for s390x (platforms are sorted) # and copies it to x86_64 expected_all_copied = expected_created + [ build_dir_s390x / "cachito-1" / "app", build_dir_s390x / "cachito-1" / "app" / "main.py", build_dir_x86_64 / "cachito-1" / "app", build_dir_x86_64 / "cachito-1" / "app" / "main.py", build_dir_x86_64 / DOCKERFILE_FILENAME, build_dir_x86_64 / "data" / "data.json", build_dir_x86_64 / "cachito-1", ] for f in expected_all_copied: assert f.is_absolute() assert f.exists()
def test_rootbuilddir_get_any_platform(build_dir, mock_source): root = RootBuildDir(build_dir) root.init_build_dirs(["x86_64", "s390x"], mock_source) build_dir_1 = root.any_platform build_dir_2 = root.any_platform assert build_dir_1.path == build_dir_2.path assert build_dir_1.platform == build_dir_2.platform
def test_rootbuilddir_for_each_platform(build_dir, mock_source): root = RootBuildDir(build_dir) root.init_build_dirs(["x86_64", "s390x"], mock_source) results = root.for_each_platform(handle_platform) expected = { "x86_64": "handled x86_64", "s390x": {"reserved_build_id": 1000}, } assert expected == results
def task_with_mocked_deps(self, monkeypatch, context_dir, build_dir, dummy_source, tmpdir): """Create a PluginBasedTask instance with mocked task parameters. Mock DockerBuildWorkflow accordingly. Return the mocked workflow instance for further customization in individual tests. """ task_params = TaskParams(build_dir=build_dir, config_file="config.yaml", context_dir=str(context_dir), namespace="test-namespace", pipeline_run_name='test-pipeline-run', user_params={"a": "b"}) expect_source = dummy_source (flexmock(task_params) .should_receive("source") .and_return(expect_source)) expect_plugins = [] monkeypatch.setattr(plugin_based.PluginBasedTask, "plugins_conf", expect_plugins) root_build_dir = RootBuildDir(build_dir) # Help to verify the RootBuildDir object is passed to the workflow object. (flexmock(plugin_based.PluginBasedTask) .should_receive("get_build_dir") .and_return(root_build_dir)) # The test methods inside this test case do not involve the workflow # data. Thanks the dataclass, flexmock is able to assert the workflow # data object, which is created during task execution, is the same as # this one, that is they are all workflow data objects and the data # included are same. wf_data = ImageBuildWorkflowData() mocked_workflow = flexmock(inner.DockerBuildWorkflow) ( mocked_workflow .should_call("__init__") .once() .with_args( context_dir=ContextDir, build_dir=root_build_dir, data=wf_data, namespace="test-namespace", pipeline_run_name='test-pipeline-run', source=expect_source, plugins_conf=expect_plugins, user_params={"a": "b"}, reactor_config_path="config.yaml", keep_plugins_running=False, ) ) mocked_workflow.should_receive("build_docker_image").and_raise( AssertionError("you must mock the build_docker_image() workflow method") ) task = plugin_based.PluginBasedTask(task_params) return task, mocked_workflow
def test_rootbuilddir_copy_sources(build_dir, mock_source): root_path = build_dir / "root_builddir" root_path.mkdir() platforms = ["x86_64", "ppc64le"] root = RootBuildDir(root_path) root.platforms = platforms root._copy_sources(mock_source) dockerfile = os.path.join(mock_source.path, DOCKERFILE_FILENAME) with open(dockerfile, "r") as f: original_content = f.read() for platform in platforms: copied_dockerfile = root.path / platform / DOCKERFILE_FILENAME assert copied_dockerfile.exists() assert copied_dockerfile.read_text("utf-8") == original_content
def workflow(context_dir, build_dir, dummy_source, user_params): return DockerBuildWorkflow( ContextDir(context_dir), RootBuildDir(build_dir), source=dummy_source, namespace='test-namespace', pipeline_run_name='test-pipeline-run', )
def test_rootbuilddir_for_all_platforms_copy_invalid_file_path( creation_func: FileCreationFunc, expected_err, build_dir, mock_source ): root = RootBuildDir(build_dir) root.init_build_dirs(["x86_64"], mock_source) with expected_err: root.for_all_platforms_copy(creation_func)
def test_rootbuilddir_for_all_platforms_copy_preserve_permissions( build_dir, mock_source): root = RootBuildDir(build_dir) root.init_build_dirs(["aarch64", "x86_64"], mock_source) def create_files(d: BuildDir): f1 = d.path / "400.txt" f1.write_text("Preserve permissions for a single file") f1.chmod(0o400) subdir = d.path / "some-dir" subdir.mkdir() f2 = subdir / "666.txt" f2.write_text("Preserve permissions for files in a directory") f2.chmod(0o666) return [f1, subdir] root.for_all_platforms_copy(create_files) def check_rwx_perms(filepath: Path, expected_perms: int): # Check the 3 rwx bytes (owner, group and others) of file permissions actual_perms = filepath.stat().st_mode & 0o777 assert actual_perms == expected_perms, ( f"{filepath.relative_to(root.path)}: expected permissions {oct(expected_perms)}, " f"actual {oct(actual_perms)}") for platform in ["aarch64", "x86_64"]: check_rwx_perms(root.path / platform / "400.txt", 0o400) check_rwx_perms(root.path / platform / "some-dir" / "666.txt", 0o666)
def test_rootbuilddir_for_all_platforms_copy_reflink(caplog, build_dir, mock_source, reflink_support): root = RootBuildDir(build_dir) # one time in copy_sources, another in for_all_platforms_copy flexmock(reflink).should_receive('supported_at').and_return( reflink_support).times(2) # 2 times in copy_source, it has to copy Dockerfile to both platform dirs # 3 times in for_all_platforms, method itself creates all for the first platform s390x # and then copies for x86_64 3 files flexmock(reflink).should_receive('reflink').and_return(True).times( 5 if reflink_support else 0) flexmock(shutil).should_receive('copy2').and_return(True).times( 0 if reflink_support else 5) root.init_build_dirs(["x86_64", "s390x"], mock_source) root.for_all_platforms_copy(create_dockerfile) method_name = shutil.copy2.__name__ if reflink_support: method_name = 'reflink_copy' log_msg1 = f"copy method used for copy sources: {method_name}" log_msg2 = f"copy method used for all platforms copy: {method_name}" assert log_msg1 in caplog.text assert log_msg2 in caplog.text
def test_rootbuilddir_for_all_platforms_copy(build_dir, mock_source): root = RootBuildDir(build_dir) root.init_build_dirs(["x86_64", "s390x"], mock_source) results = root.for_all_platforms_copy(create_dockerfile) build_dir_s390x = build_dir.joinpath("s390x") expected_created_files = sorted([ build_dir_s390x / DOCKERFILE_FILENAME, build_dir_s390x / "data" / "data.json", build_dir_s390x / "cachito-1", ]) assert expected_created_files == sorted(results) expected_all_copied_files = expected_created_files + [ build_dir_s390x / "cachito-1" / "app", build_dir_s390x / "cachito-1" / "app" / "main.py", ] for f in expected_all_copied_files: assert f.is_absolute() assert f.exists()
def test_rootbuilddir_copy_sources_reflink(caplog, build_dir, mock_source, reflink_support): root_path = build_dir / "root_builddir" root_path.mkdir() platforms = ["x86_64"] root = RootBuildDir(root_path) root.platforms = platforms flexmock(reflink).should_receive('supported_at').and_return( reflink_support).once() flexmock(reflink).should_receive('reflink').and_return(True).times( int(reflink_support)) flexmock(shutil).should_receive('copy2').and_return(True).times( int(not reflink_support)) method_name = shutil.copy2.__name__ if reflink_support: method_name = 'reflink_copy' root._copy_sources(mock_source) log_msg = f"copy method used for copy sources: {method_name}" assert log_msg in caplog.text
def test_rootbuilddir_has_sources(build_dir): build_dir.joinpath("x86_64").mkdir() build_dir.joinpath("s390x").mkdir() root = RootBuildDir(build_dir) root.platforms = ["x86_64", "s390x"] assert root.has_sources
def test_rootbuilddir_for_all_platforms_copy_fails_if_build_dirs_not_inited( build_dir): with pytest.raises(BuildDirIsNotInitialized, match="not initialized yet"): RootBuildDir(build_dir).for_all_platforms_copy(lambda path: [])
def test_rootbuilddir_for_each_platform_failure_from_action( build_dir, mock_source): root = RootBuildDir(build_dir) root.init_build_dirs(["x86_64", "s390x"], mock_source) with pytest.raises(ValueError, match="Error is raised"): root.for_each_platform(failure_action)
def test_rootbuilddir_for_each_fails_if_build_dirs_not_inited( build_dir, mock_source): with pytest.raises(BuildDirIsNotInitialized, match="not initialized yet"): RootBuildDir(build_dir).for_each_platform(lambda path: None)
def test_rootbuilddir_get_any_platform_fails_if_build_dirs_not_inited( build_dir): with pytest.raises(BuildDirIsNotInitialized, match="not initialized yet"): print(RootBuildDir(build_dir).any_platform)
def test_rootbuilddir_has_sources_if_build_dirs_not_inited(build_dir): assert not RootBuildDir(build_dir).has_sources
def test_rootbuilddir_has_sources_no_builddir_created(build_dir): root = RootBuildDir(build_dir) root.platforms = ["x86_64"] assert not root.has_sources