diff --git a/src/speccpu/x264.py b/src/speccpu/x264.py index 1360e5c..2e95504 100644 --- a/src/speccpu/x264.py +++ b/src/speccpu/x264.py @@ -203,3 +203,18 @@ def perf_ref(x264_run, perf_output): ], cwd=x264_run, ) + + +def recompile_mc_src(mc_src: str, x264_build: Path, spec_env: Mapping[str, str]): + mc_path = get_mc_path(x264_build) + assert mc_path.exists() + + # Write mc_src to mc_path, recompile it, and replace resulting exe + with open(mc_path, "w") as f: + f.write(mc_src) + + # Recompile + recompiled_x264_path = recompile_mc(mc_path, x264_build, spec_env) + assert recompiled_x264_path.exists() + assert recompiled_x264_path.is_file() + return recompiled_x264_path diff --git a/test/test_spec.py b/test/test_spec.py index d9d044b..b3c8e65 100644 --- a/test/test_spec.py +++ b/test/test_spec.py @@ -1,9 +1,11 @@ from pathlib import Path from unittest import mock +from unittest.mock import mock_open, patch import pytest from speccpu import SPEC, check_bench_dir, find_build +from speccpu.x264 import recompile_mc_src class TestFindBuild: @@ -169,3 +171,98 @@ class TestCheckBenchDir: (bench_dir / "RUN").mkdir() assert check_bench_dir(bench_dir) is False + + +@pytest.fixture +def mock_build_path(): + return Path("/mock/build/path") + + +@pytest.fixture +def mock_spec_env(): + return {"CC": "gcc", "CFLAGS": "-O2"} + + +@pytest.fixture +def mock_mc_path(mock_build_path): + return Path("/mock/build/path/x264_src/common/mc.c") + + +def test_recompile_mc_src(mock_build_path, mock_spec_env, mock_mc_path): + test_mc_src = "test source code" + + with ( + patch("speccpu.x264.get_mc_path", return_value=mock_mc_path) as mock_get_path, + patch("builtins.open", mock_open()) as mock_file, + patch("speccpu.x264.recompile_mc") as mock_recompile, + patch.object(Path, "exists", return_value=True), + patch.object(Path, "is_file", return_value=True), + ): + + # Configure recompile_mc mock to return a path + mock_exe_path = Path("/mock/build/path/x264_s") + mock_recompile.return_value = mock_exe_path + + # Call the function under test + result = recompile_mc_src(test_mc_src, mock_build_path, mock_spec_env) + + # Verify the function behavior + mock_get_path.assert_called_once_with(mock_build_path) + mock_file.assert_called_once_with(mock_mc_path, "w") + mock_file().write.assert_called_once_with(test_mc_src) + mock_recompile.assert_called_once_with( + mock_mc_path, mock_build_path, mock_spec_env + ) + + +def test_recompile_mc_src_file_not_exists(mock_build_path, mock_spec_env, mock_mc_path): + test_mc_src = "test source code" + + with ( + patch("speccpu.x264.get_mc_path", return_value=mock_mc_path), + patch.object(Path, "exists", return_value=False), + ): + + # Test that the function raises an assertion error when file doesn't exist + with pytest.raises(AssertionError): + recompile_mc_src(test_mc_src, mock_build_path, mock_spec_env) + + +def test_recompile_mc_src_exe_not_exists(mock_build_path, mock_spec_env, mock_mc_path): + test_mc_src = "test source code" + + with ( + patch("speccpu.x264.get_mc_path", return_value=mock_mc_path) as mock_get_path, + patch("builtins.open", mock_open()) as mock_file, + patch("speccpu.x264.recompile_mc") as mock_recompile, + patch.object(Path, "exists", side_effect=[True, False]), + patch.object(Path, "is_file", return_value=True), + ): + + # Configure recompile_mc mock to return a path + mock_exe_path = Path("/mock/build/path/x264_s") + mock_recompile.return_value = mock_exe_path + + # Test that the function raises an assertion error when exe doesn't exist + with pytest.raises(AssertionError): + recompile_mc_src(test_mc_src, mock_build_path, mock_spec_env) + + +def test_recompile_mc_src_exe_not_file(mock_build_path, mock_spec_env, mock_mc_path): + test_mc_src = "test source code" + + with ( + patch("speccpu.x264.get_mc_path", return_value=mock_mc_path) as mock_get_path, + patch("builtins.open", mock_open()) as mock_file, + patch("speccpu.x264.recompile_mc") as mock_recompile, + patch.object(Path, "exists", return_value=True), + patch.object(Path, "is_file", return_value=False), + ): + + # Configure recompile_mc mock to return a path + mock_exe_path = Path("/mock/build/path/x264_s") + mock_recompile.return_value = mock_exe_path + + # Test that the function raises an assertion error when exe is not a file + with pytest.raises(AssertionError): + recompile_mc_src(test_mc_src, mock_build_path, mock_spec_env) diff --git a/tools/x264_disable_mc_mul.py b/tools/x264_disable_mc_mul.py index 01e83ca..bfd8115 100644 --- a/tools/x264_disable_mc_mul.py +++ b/tools/x264_disable_mc_mul.py @@ -22,19 +22,9 @@ def x264_disable_mc_mul( assert x264_build.exists() assert "x264_src" in os.listdir(x264_build) - mc_path = x264.get_mc_path(x264_build) - assert mc_path.exists() - mc_src = x264.MCBuilder().with_disabled_iscale_mul().build() - # Write mc_src to mc_path, recompile it, and replace resulting exe - with open(mc_path, "w") as f: - f.write(mc_src) - - # Recompile - recompiled_x264_path = x264.recompile_mc(mc_path, x264_build, spec_env) - assert recompiled_x264_path.exists() - assert recompiled_x264_path.is_file() + recompiled_x264_path = x264.recompile_mc_src(mc_src, x264_build, spec_env) # Execute that new binary x264.update_exe(recompiled_x264_path, x264_dir / "exe")