diff options
-rw-r--r-- | test/py/tests/test_cleanup_build.py | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/test/py/tests/test_cleanup_build.py b/test/py/tests/test_cleanup_build.py new file mode 100644 index 00000000000..5206ff73ec7 --- /dev/null +++ b/test/py/tests/test_cleanup_build.py @@ -0,0 +1,105 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2023 Tobias Deiminger <tdmg@linutronix.de> + +"""Test for unexpected leftovers after make clean""" + +import itertools +import os +import pathlib +import shutil +import sys + +import pytest + +# pylint: disable=redefined-outer-name + + +@pytest.fixture +def tmp_copy_of_builddir(u_boot_config, tmp_path): + """For each test, provide a temporary copy of the initial build directory.""" + shutil.copytree( + u_boot_config.build_dir, + tmp_path, + symlinks=True, + dirs_exist_ok=True, + ) + return tmp_path + + +@pytest.fixture(scope="module") +def run_make(u_boot_log): + """Provide function to run and log make without connecting to u-boot console.""" + runner = u_boot_log.get_runner("make", sys.stdout) + + def _run_make(build_dir, target): + cmd = ["make", f"O={build_dir}", target] + runner.run(cmd) + + yield _run_make + runner.close() + + +@pytest.fixture(scope="module") +def most_generated_files(): + """Path.glob style patterns to describe what should be removed by 'make clean'.""" + return ( + "**/*.c", + "**/*.dtb", + "**/*.dtbo", + "**/*.o", + "**/*.py", + "**/*.pyc", + "**/*.so", + "**/*.srec", + "u-boot*", + "[svt]pl/u-boot*", + ) + + +@pytest.fixture(scope="module") +def all_generated_files(most_generated_files): + """Path.glob style patterns to describe what should be removed by 'make mrproper'.""" + return most_generated_files + (".config", "**/*.h") + + +def find_files(search_dir, include_patterns, exclude_dirs=None): + """Find files matching include_patterns, unless it's in one of exclude_dirs. + + include_patterns -- Path.glob style pattern relative to search dir + exclude_dir -- directories to exclude, expected relative to search dir + """ + matches = [] + exclude_dirs = [] if exclude_dirs is None else exclude_dirs + for abs_path in itertools.chain.from_iterable( + pathlib.Path(search_dir).glob(pattern) for pattern in include_patterns + ): + if abs_path.is_dir(): + continue + rel_path = pathlib.Path(os.path.relpath(abs_path, search_dir)) + if not any( + rel_path.is_relative_to(exclude_dir) for exclude_dir in exclude_dirs + ): + matches.append(rel_path) + return matches + + +def test_clean(run_make, tmp_copy_of_builddir, most_generated_files): + """Test if 'make clean' deletes most generated files.""" + run_make(tmp_copy_of_builddir, "clean") + leftovers = find_files( + tmp_copy_of_builddir, + most_generated_files, + exclude_dirs=["scripts", "test/overlay"], + ) + assert not leftovers, f"leftovers: {', '.join(map(str, leftovers))}" + + +def test_mrproper(run_make, tmp_copy_of_builddir, all_generated_files): + """Test if 'make mrproper' deletes current configuration and all generated files.""" + run_make(tmp_copy_of_builddir, "mrproper") + leftovers = find_files( + tmp_copy_of_builddir, + all_generated_files, + exclude_dirs=["test/overlay"], + ) + assert not leftovers, f"leftovers: {', '.join(map(str, leftovers))}" |