xref: /OK3568_Linux_fs/buildroot/support/testing/tests/utils/test_check_package.py (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1"""Test cases for utils/check-package.
2
3It does not inherit from infra.basetest.BRTest and therefore does not generate
4a logfile. Only when the tests fail there will be output to the console.
5
6The make target ('make check-package') is already used by the job
7'check-package' and won't be tested here.
8"""
9import os
10import subprocess
11import unittest
12
13import infra
14
15
16def call_script(args, env, cwd):
17    """Call a script and return stdout and stderr as lists."""
18    out, err = subprocess.Popen(args, cwd=cwd, stdout=subprocess.PIPE,
19                                stderr=subprocess.PIPE, env=env,
20                                universal_newlines=True).communicate()
21    return out.splitlines(), err.splitlines()
22
23
24class TestCheckPackage(unittest.TestCase):
25    """Test the various ways the script can be called.
26
27    The script can be called either using relative path, absolute path or from
28    PATH.
29
30    The files to be checked can be passed as arguments using either relative
31    path or absolute path.
32
33    When in in-tree mode (without -b) some in-tree files and also all
34    out-of-tree files are ignored.
35
36    When in out-tree mode (with -b) the script does generate warnings for these
37    but ignores external.mk.
38    """
39
40    WITH_EMPTY_PATH = {}
41    WITH_UTILS_IN_PATH = {"PATH": infra.basepath("utils") + ":" + os.environ["PATH"]}
42    relative = [
43        # base_script           base_file               rel_script               rel_file                rel_cwd
44        ["utils/check-package", "package/atop/atop.mk", "./utils/check-package", "package/atop/atop.mk", ""],
45        ["utils/check-package", "package/atop/atop.mk", "./utils/check-package", "./package/atop/atop.mk", ""],
46        ["utils/check-package", "package/atop/atop.mk", "../../utils/check-package", "atop.mk", "package/atop"],
47        ["utils/check-package", "package/atop/atop.mk", "../../utils/check-package", "./atop.mk", "package/atop"],
48        ["utils/check-package", "package/atop/atop.mk", "../utils/check-package", "atop/atop.mk", "package"],
49        ["utils/check-package", "package/atop/atop.mk", "../utils/check-package", "./atop/atop.mk", "package"],
50        ["utils/check-package", "package/atop/Config.in", "./utils/check-package", "package/atop/Config.in", ""],
51        ["utils/check-package", "package/atop/Config.in", "./utils/check-package", "./package/atop/Config.in", ""],
52        ["utils/check-package", "package/atop/Config.in", "../../utils/check-package", "Config.in", "package/atop"],
53        ["utils/check-package", "package/atop/Config.in", "../../utils/check-package", "./Config.in", "package/atop"],
54        ["utils/check-package", "package/atop/Config.in", "../utils/check-package", "atop/Config.in", "package"],
55        ["utils/check-package", "package/atop/Config.in", "../utils/check-package", "./atop/Config.in", "package"]]
56
57    def assert_file_was_processed(self, stderr):
58        """Infer from check-package stderr if at least one file was processed
59        and fail otherwise."""
60        self.assertIn("lines processed", stderr[0], stderr)
61        processed = int(stderr[0].split()[0])
62        self.assertGreater(processed, 0)
63
64    def assert_file_was_ignored(self, stderr):
65        """Infer from check-package stderr if no file was processed and fail
66        otherwise."""
67        self.assertIn("lines processed", stderr[0], stderr)
68        processed = int(stderr[0].split()[0])
69        self.assertEqual(processed, 0)
70
71    def assert_warnings_generated_for_file(self, stderr):
72        """Infer from check-package stderr if at least one warning was generated
73        and fail otherwise."""
74        self.assertIn("warnings generated", stderr[1], stderr)
75        generated = int(stderr[1].split()[0])
76        self.assertGreater(generated, 0)
77
78    def test_run(self):
79        """Test the various ways the script can be called in a simple top to
80        bottom sequence."""
81        # an intree file can be checked by the script called from relative path,
82        # absolute path and from PATH
83        for base_script, base_file, rel_script, rel_file, rel_cwd in self.relative:
84            abs_script = infra.basepath(base_script)
85            abs_file = infra.basepath(base_file)
86            cwd = infra.basepath(rel_cwd)
87
88            _, m = call_script([rel_script, rel_file],
89                               self.WITH_EMPTY_PATH, cwd)
90            self.assert_file_was_processed(m)
91
92            _, m = call_script([abs_script, rel_file],
93                               self.WITH_EMPTY_PATH, cwd)
94            self.assert_file_was_processed(m)
95
96            _, m = call_script(["check-package", rel_file],
97                               self.WITH_UTILS_IN_PATH, cwd)
98            self.assert_file_was_processed(m)
99
100            _, m = call_script([rel_script, abs_file],
101                               self.WITH_EMPTY_PATH, cwd)
102            self.assert_file_was_processed(m)
103
104            _, m = call_script([abs_script, abs_file],
105                               self.WITH_EMPTY_PATH, cwd)
106            self.assert_file_was_processed(m)
107
108            _, m = call_script(["check-package", abs_file],
109                               self.WITH_UTILS_IN_PATH, cwd)
110            self.assert_file_was_processed(m)
111
112        # some intree files are ignored
113        _, m = call_script(["./utils/check-package", "package/pkg-generic.mk"],
114                           self.WITH_EMPTY_PATH, infra.basepath())
115        self.assert_file_was_ignored(m)
116
117        _, m = call_script(["./utils/check-package", "-b", "package/pkg-generic.mk"],
118                           self.WITH_EMPTY_PATH, infra.basepath())
119        self.assert_file_was_processed(m)
120
121        # an out-of-tree file can be checked by the script called from relative
122        # path, absolute path and from PATH
123        for base_script, base_file, rel_script, rel_file, rel_cwd in self.relative:
124            abs_script = infra.basepath(base_script)
125            abs_file = infra.basepath(base_file)
126            cwd = infra.basepath(rel_cwd)
127
128            _, m = call_script([rel_script, "-b", rel_file],
129                               self.WITH_EMPTY_PATH, cwd)
130            self.assert_file_was_processed(m)
131
132            _, m = call_script([abs_script, "-b", rel_file],
133                               self.WITH_EMPTY_PATH, cwd)
134            self.assert_file_was_processed(m)
135
136            _, m = call_script(["check-package", "-b", rel_file],
137                               self.WITH_UTILS_IN_PATH, cwd)
138            self.assert_file_was_processed(m)
139
140            _, m = call_script([rel_script, "-b", abs_file],
141                               self.WITH_EMPTY_PATH, cwd)
142            self.assert_file_was_processed(m)
143
144            _, m = call_script([abs_script, "-b", abs_file],
145                               self.WITH_EMPTY_PATH, cwd)
146            self.assert_file_was_processed(m)
147
148            _, m = call_script(["check-package", "-b", abs_file],
149                               self.WITH_UTILS_IN_PATH, cwd)
150            self.assert_file_was_processed(m)
151
152        # out-of-tree files are are ignored without -b but can generate warnings
153        # with -b
154        abs_path = infra.filepath("tests/utils/br2-external")
155        rel_file = "Config.in"
156        abs_file = os.path.join(abs_path, rel_file)
157
158        _, m = call_script(["check-package", rel_file],
159                           self.WITH_UTILS_IN_PATH, abs_path)
160        self.assert_file_was_ignored(m)
161
162        _, m = call_script(["check-package", abs_file],
163                           self.WITH_UTILS_IN_PATH, infra.basepath())
164        self.assert_file_was_ignored(m)
165
166        w, m = call_script(["check-package", "-b", rel_file],
167                           self.WITH_UTILS_IN_PATH, abs_path)
168        self.assert_file_was_processed(m)
169        self.assert_warnings_generated_for_file(m)
170        self.assertIn("{}:1: empty line at end of file".format(rel_file), w)
171
172        w, m = call_script(["check-package", "-b", abs_file],
173                           self.WITH_UTILS_IN_PATH, infra.basepath())
174        self.assert_file_was_processed(m)
175        self.assert_warnings_generated_for_file(m)
176        self.assertIn("{}:1: empty line at end of file".format(abs_file), w)
177
178        # external.mk is ignored only when in the root path of a br2-external
179        rel_file = "external.mk"
180        abs_file = os.path.join(abs_path, rel_file)
181
182        _, m = call_script(["check-package", "-b", rel_file],
183                           self.WITH_UTILS_IN_PATH, abs_path)
184        self.assert_file_was_ignored(m)
185
186        _, m = call_script(["check-package", "-b", abs_file],
187                           self.WITH_UTILS_IN_PATH, infra.basepath())
188        self.assert_file_was_ignored(m)
189
190        abs_path = infra.filepath("tests/utils/br2-external/package/external")
191        abs_file = os.path.join(abs_path, rel_file)
192
193        w, m = call_script(["check-package", "-b", rel_file],
194                           self.WITH_UTILS_IN_PATH, abs_path)
195        self.assert_file_was_processed(m)
196        self.assert_warnings_generated_for_file(m)
197        self.assertIn("{}:1: should be 80 hashes (http://nightly.buildroot.org/#writing-rules-mk)".format(rel_file), w)
198
199        w, m = call_script(["check-package", "-b", abs_file],
200                           self.WITH_UTILS_IN_PATH, infra.basepath())
201        self.assert_file_was_processed(m)
202        self.assert_warnings_generated_for_file(m)
203        self.assertIn("{}:1: should be 80 hashes (http://nightly.buildroot.org/#writing-rules-mk)".format(abs_file), w)
204