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