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