269 lines
9.3 KiB
Python
269 lines
9.3 KiB
Python
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:
|
|
def test_find_build_success(self, tmpdir):
|
|
# Create a mock directory structure with a build directory
|
|
build_parent = Path(tmpdir)
|
|
build_dir = build_parent / "build_2023"
|
|
build_dir.mkdir()
|
|
|
|
# Test that find_build correctly identifies the build directory
|
|
found_dir = find_build(build_parent)
|
|
assert found_dir == build_dir
|
|
|
|
def test_find_build_multiple_dirs(self, tmpdir):
|
|
# Create multiple build directories
|
|
build_parent = Path(tmpdir)
|
|
build_dir1 = build_parent / "build_2022"
|
|
build_dir2 = build_parent / "build_2023"
|
|
build_dir1.mkdir()
|
|
build_dir2.mkdir()
|
|
|
|
# Should find the alphabetically first one
|
|
found_dir = find_build(build_parent)
|
|
assert found_dir == build_dir1
|
|
|
|
def test_find_build_no_dir(self, tmpdir):
|
|
# Test the error case when no build directory exists
|
|
build_parent = Path(tmpdir)
|
|
with pytest.raises(RuntimeError):
|
|
find_build(build_parent)
|
|
|
|
|
|
class TestSPEC:
|
|
def test_init(self):
|
|
spec_dir = Path("/path/to/spec")
|
|
spec = SPEC(spec_dir)
|
|
assert spec.dir == spec_dir
|
|
|
|
def test_config_dir(self):
|
|
spec_dir = Path("/path/to/spec")
|
|
spec = SPEC(spec_dir)
|
|
assert spec.config_dir == spec_dir / "config"
|
|
|
|
def test_env(self):
|
|
spec_dir = Path("/path/to/spec")
|
|
spec = SPEC(spec_dir)
|
|
with mock.patch("speccpu.create_spec_env") as mock_create_env:
|
|
spec.env()
|
|
mock_create_env.assert_called_once_with(spec_dir)
|
|
|
|
def test_mkcmd_runcpu_default(self):
|
|
spec = SPEC(Path("/path/to/spec"))
|
|
cmd = spec.mkcmd_runcpu("myconfig", ["benchmark1", "benchmark2"])
|
|
assert cmd == [
|
|
"runcpu",
|
|
"--setprocgroup",
|
|
"-i",
|
|
"ref",
|
|
"-c",
|
|
"myconfig",
|
|
"benchmark1",
|
|
"benchmark2",
|
|
]
|
|
|
|
def test_mkcmd_runcpu_no_procgroup(self):
|
|
spec = SPEC(Path("/path/to/spec"))
|
|
cmd = spec.mkcmd_runcpu("myconfig", ["benchmark1"], setprocgroup=False)
|
|
assert "--setprocgroup" not in cmd
|
|
|
|
def test_mkcmd_runcpu_with_output_dir(self):
|
|
spec = SPEC(Path("/path/to/spec"))
|
|
output_dir = Path("/output/dir")
|
|
cmd = spec.mkcmd_runcpu("myconfig", ["benchmark1"], output_root=output_dir)
|
|
assert "--output_root" in cmd
|
|
assert str(output_dir) in cmd
|
|
|
|
def test_mkcmd_runcpu_build_type_default(self):
|
|
"""Test that mkcmd_runcpu doesn't add build flags with default build type."""
|
|
spec = SPEC(Path("/path/to/spec"))
|
|
cmd = spec.mkcmd_runcpu(
|
|
"myconfig", ["benchmark1"], build_type=SPEC.BuildType.Default
|
|
)
|
|
assert "--nobuild" not in cmd
|
|
assert "--rebuild" not in cmd
|
|
|
|
def test_mkcmd_runcpu_build_type_nobuild(self):
|
|
"""Test that mkcmd_runcpu adds --nobuild flag with Nobuild build type."""
|
|
spec = SPEC(Path("/path/to/spec"))
|
|
cmd = spec.mkcmd_runcpu(
|
|
"myconfig", ["benchmark1"], build_type=SPEC.BuildType.Nobuild
|
|
)
|
|
assert "--nobuild" in cmd
|
|
assert "--rebuild" not in cmd
|
|
|
|
def test_mkcmd_runcpu_build_type_rebuild(self):
|
|
"""Test that mkcmd_runcpu adds --rebuild flag with Rebuild build type."""
|
|
spec = SPEC(Path("/path/to/spec"))
|
|
cmd = spec.mkcmd_runcpu(
|
|
"myconfig", ["benchmark1"], build_type=SPEC.BuildType.Rebuild
|
|
)
|
|
assert "--rebuild" in cmd
|
|
assert "--nobuild" not in cmd
|
|
|
|
|
|
class TestCheckBenchDir:
|
|
def test_valid_bench_dir(self, tmpdir):
|
|
"""Test that check_bench_dir returns True for a valid benchmark directory."""
|
|
bench_dir = Path(tmpdir)
|
|
|
|
# Create the required subdirectories
|
|
(bench_dir / "build").mkdir()
|
|
(bench_dir / "exe").mkdir()
|
|
(bench_dir / "run").mkdir()
|
|
|
|
# Add some extra files/directories to make sure they don't affect the result
|
|
(bench_dir / "other_dir").mkdir()
|
|
(bench_dir / "file.txt").write_text("test")
|
|
|
|
assert check_bench_dir(bench_dir) is True
|
|
|
|
def test_invalid_bench_dir_missing_build(self, tmpdir):
|
|
"""Test that check_bench_dir returns False when 'build' directory is missing."""
|
|
bench_dir = Path(tmpdir)
|
|
|
|
# Create only exe and run directories
|
|
(bench_dir / "exe").mkdir()
|
|
(bench_dir / "run").mkdir()
|
|
|
|
assert check_bench_dir(bench_dir) is False
|
|
|
|
def test_invalid_bench_dir_missing_exe(self, tmpdir):
|
|
"""Test that check_bench_dir returns False when 'exe' directory is missing."""
|
|
bench_dir = Path(tmpdir)
|
|
|
|
# Create only build and run directories
|
|
(bench_dir / "build").mkdir()
|
|
(bench_dir / "run").mkdir()
|
|
|
|
assert check_bench_dir(bench_dir) is False
|
|
|
|
def test_invalid_bench_dir_missing_run(self, tmpdir):
|
|
"""Test that check_bench_dir returns False when 'run' directory is missing."""
|
|
bench_dir = Path(tmpdir)
|
|
|
|
# Create only build and exe directories
|
|
(bench_dir / "build").mkdir()
|
|
(bench_dir / "exe").mkdir()
|
|
|
|
assert check_bench_dir(bench_dir) is False
|
|
|
|
def test_empty_dir(self, tmpdir):
|
|
"""Test that check_bench_dir returns False for an empty directory."""
|
|
bench_dir = Path(tmpdir)
|
|
assert check_bench_dir(bench_dir) is False
|
|
|
|
def test_invalid_dir_case_sensitive(self, tmpdir):
|
|
"""Test that check_bench_dir is case-sensitive."""
|
|
bench_dir = Path(tmpdir)
|
|
|
|
# Create directories with different case
|
|
(bench_dir / "Build").mkdir()
|
|
(bench_dir / "EXE").mkdir()
|
|
(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)
|