Tobias Deiminger | 4d412fa | 2023-06-20 00:41:07 +0200 | [diff] [blame] | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | # Copyright (c) 2023 Tobias Deiminger <tdmg@linutronix.de> |
| 3 | |
| 4 | """Test for unexpected leftovers after make clean""" |
| 5 | |
| 6 | import itertools |
| 7 | import os |
| 8 | import pathlib |
| 9 | import shutil |
| 10 | import sys |
| 11 | |
| 12 | import pytest |
| 13 | |
| 14 | # pylint: disable=redefined-outer-name |
| 15 | |
| 16 | |
| 17 | @pytest.fixture |
| 18 | def tmp_copy_of_builddir(u_boot_config, tmp_path): |
| 19 | """For each test, provide a temporary copy of the initial build directory.""" |
Tobias Deiminger | 7184a09 | 2024-01-08 22:11:00 +0100 | [diff] [blame] | 20 | if os.path.realpath(u_boot_config.source_dir) == os.path.realpath( |
| 21 | u_boot_config.build_dir |
| 22 | ): |
| 23 | pytest.skip("Leftover detection requires out of tree build.") |
| 24 | return None |
Tobias Deiminger | 4d412fa | 2023-06-20 00:41:07 +0200 | [diff] [blame] | 25 | shutil.copytree( |
| 26 | u_boot_config.build_dir, |
| 27 | tmp_path, |
| 28 | symlinks=True, |
| 29 | dirs_exist_ok=True, |
| 30 | ) |
| 31 | return tmp_path |
| 32 | |
| 33 | |
| 34 | @pytest.fixture(scope="module") |
| 35 | def run_make(u_boot_log): |
| 36 | """Provide function to run and log make without connecting to u-boot console.""" |
| 37 | runner = u_boot_log.get_runner("make", sys.stdout) |
| 38 | |
| 39 | def _run_make(build_dir, target): |
| 40 | cmd = ["make", f"O={build_dir}", target] |
| 41 | runner.run(cmd) |
| 42 | |
| 43 | yield _run_make |
| 44 | runner.close() |
| 45 | |
| 46 | |
| 47 | @pytest.fixture(scope="module") |
| 48 | def most_generated_files(): |
| 49 | """Path.glob style patterns to describe what should be removed by 'make clean'.""" |
| 50 | return ( |
| 51 | "**/*.c", |
| 52 | "**/*.dtb", |
| 53 | "**/*.dtbo", |
| 54 | "**/*.o", |
| 55 | "**/*.py", |
| 56 | "**/*.pyc", |
| 57 | "**/*.so", |
| 58 | "**/*.srec", |
| 59 | "u-boot*", |
| 60 | "[svt]pl/u-boot*", |
| 61 | ) |
| 62 | |
| 63 | |
| 64 | @pytest.fixture(scope="module") |
| 65 | def all_generated_files(most_generated_files): |
| 66 | """Path.glob style patterns to describe what should be removed by 'make mrproper'.""" |
| 67 | return most_generated_files + (".config", "**/*.h") |
| 68 | |
| 69 | |
| 70 | def find_files(search_dir, include_patterns, exclude_dirs=None): |
| 71 | """Find files matching include_patterns, unless it's in one of exclude_dirs. |
| 72 | |
| 73 | include_patterns -- Path.glob style pattern relative to search dir |
| 74 | exclude_dir -- directories to exclude, expected relative to search dir |
| 75 | """ |
| 76 | matches = [] |
| 77 | exclude_dirs = [] if exclude_dirs is None else exclude_dirs |
| 78 | for abs_path in itertools.chain.from_iterable( |
| 79 | pathlib.Path(search_dir).glob(pattern) for pattern in include_patterns |
| 80 | ): |
| 81 | if abs_path.is_dir(): |
| 82 | continue |
| 83 | rel_path = pathlib.Path(os.path.relpath(abs_path, search_dir)) |
| 84 | if not any( |
| 85 | rel_path.is_relative_to(exclude_dir) for exclude_dir in exclude_dirs |
| 86 | ): |
| 87 | matches.append(rel_path) |
| 88 | return matches |
| 89 | |
| 90 | |
| 91 | def test_clean(run_make, tmp_copy_of_builddir, most_generated_files): |
| 92 | """Test if 'make clean' deletes most generated files.""" |
| 93 | run_make(tmp_copy_of_builddir, "clean") |
| 94 | leftovers = find_files( |
| 95 | tmp_copy_of_builddir, |
| 96 | most_generated_files, |
| 97 | exclude_dirs=["scripts", "test/overlay"], |
| 98 | ) |
| 99 | assert not leftovers, f"leftovers: {', '.join(map(str, leftovers))}" |
| 100 | |
| 101 | |
| 102 | def test_mrproper(run_make, tmp_copy_of_builddir, all_generated_files): |
| 103 | """Test if 'make mrproper' deletes current configuration and all generated files.""" |
| 104 | run_make(tmp_copy_of_builddir, "mrproper") |
| 105 | leftovers = find_files( |
| 106 | tmp_copy_of_builddir, |
| 107 | all_generated_files, |
| 108 | exclude_dirs=["test/overlay"], |
| 109 | ) |
| 110 | assert not leftovers, f"leftovers: {', '.join(map(str, leftovers))}" |