| """Test cases for utils/get-developers. |
| |
| It does not inherit from infra.basetest.BRTest and therefore does not generate |
| a logfile. Only when the tests fail there will be output to the console. |
| |
| The file syntax is already tested by the GitLab-CI job check-DEVELOPERS. |
| """ |
| import os |
| import subprocess |
| import tempfile |
| import unittest |
| |
| import infra |
| |
| |
| def call_script(args, env, cwd, stdin_data=None): |
| """Call a script and return stdout and stderr as lists and the exit code.""" |
| if stdin_data is None: |
| # We need stdin to be a tty, not just a pipe or whatever |
| m_tty, s_tty = os.openpty() |
| com_opts = dict() |
| else: |
| s_tty = subprocess.PIPE |
| com_opts = dict([("input", stdin_data)]) |
| proc = subprocess.Popen(args, cwd=cwd, |
| stdin=s_tty, |
| stdout=subprocess.PIPE, |
| stderr=subprocess.PIPE, env=env, |
| universal_newlines=True) |
| out, err = proc.communicate(**com_opts) |
| if stdin_data is None: |
| os.close(s_tty) |
| os.close(m_tty) |
| return out.splitlines(), err.splitlines(), proc.returncode |
| |
| |
| def call_get_developers(cmd, args, env, cwd, developers_content, stdin_data=None): |
| """Call get-developers overrinding the default DEVELOPERS file.""" |
| with tempfile.NamedTemporaryFile(buffering=0) as developers_file: |
| developers_file.write(developers_content) |
| return call_script([cmd, "-d", developers_file.name] + args, env, cwd, stdin_data) |
| |
| |
| class TestGetDevelopers(unittest.TestCase): |
| """Test the various ways the script can be called in a simple top to bottom sequence.""" |
| |
| WITH_EMPTY_PATH = {} |
| WITH_UTILS_IN_PATH = {"PATH": infra.basepath("utils") + ":" + os.environ["PATH"]} |
| |
| def test_run(self): |
| topdir = infra.basepath() |
| |
| # no args, with syntax error in the file |
| developers = b'text3\n' |
| out, err, rc = call_get_developers("./utils/get-developers", [], self.WITH_EMPTY_PATH, topdir, developers) |
| self.assertIn("No action specified", "\n".join(err)) |
| self.assertEqual(rc, 2) |
| self.assertEqual(len(out), 0) |
| |
| # -v generating error, called from the main dir |
| developers = b'text1\n' |
| out, err, rc = call_get_developers("./utils/get-developers", ["-v"], self.WITH_EMPTY_PATH, topdir, developers) |
| self.assertIn("Syntax error in DEVELOPERS file, line 1: 'text1'", err) |
| self.assertEqual(rc, 1) |
| self.assertEqual(len(out), 0) |
| self.assertEqual(len(err), 1) |
| |
| # -v generating error, called from path |
| developers = b'text2\n' |
| out, err, rc = call_get_developers("get-developers", ["-v"], self.WITH_UTILS_IN_PATH, topdir, developers) |
| self.assertIn("Syntax error in DEVELOPERS file, line 1: 'text2'", err) |
| self.assertEqual(rc, 1) |
| self.assertEqual(len(out), 0) |
| self.assertEqual(len(err), 1) |
| |
| # -v generating error for file entry with no developer entry |
| developers = b'# comment\n' \ |
| b'\n' \ |
| b'F:\tutils/get-developers\n' \ |
| b'\n' \ |
| b'N:\tAuthor2 <email>\n' \ |
| b'F:\tutils/get-developers\n' |
| out, err, rc = call_get_developers("get-developers", ["-v"], self.WITH_UTILS_IN_PATH, topdir, developers) |
| self.assertIn("Syntax error in DEVELOPERS file, line 4", err) |
| self.assertEqual(rc, 1) |
| self.assertEqual(len(out), 0) |
| self.assertEqual(len(err), 1) |
| |
| # -v generating error for developer entry with no file entries, stopping on first error |
| developers = b'# comment\n' \ |
| b'# comment\n' \ |
| b'\n' \ |
| b'N:\tAuthor1 <email>\n' \ |
| b'N:\tAuthor2 <email>\n' \ |
| b'N:\tAuthor3 <email>\n' \ |
| b'F:\tutils/get-developers\n' |
| out, err, rc = call_get_developers("get-developers", ["-v"], self.WITH_UTILS_IN_PATH, topdir, developers) |
| self.assertIn("Syntax error in DEVELOPERS file, line 4", err) |
| self.assertEqual(rc, 1) |
| self.assertEqual(len(out), 0) |
| self.assertEqual(len(err), 1) |
| |
| # -v not generating error for developer entry with empty list of file entries |
| developers = b'# comment\n' \ |
| b'# comment\n' \ |
| b'\n' \ |
| b'N:\tAuthor1 <email>\n' \ |
| b'\n' \ |
| b'N:\tAuthor2 <email>\n' \ |
| b'\n' \ |
| b'N:\tAuthor3 <email>\n' \ |
| b'F:\tutils/get-developers\n' |
| out, err, rc = call_get_developers("get-developers", ["-v"], self.WITH_UTILS_IN_PATH, topdir, developers) |
| self.assertEqual(rc, 0) |
| self.assertEqual(len(out), 0) |
| self.assertEqual(len(err), 0) |
| |
| # -v generating warning for old file entry |
| developers = b'N:\tAuthor <email>\n' \ |
| b'F:\tpath/that/does/not/exists/1\n' \ |
| b'F:\tpath/that/does/not/exists/2\n' |
| out, err, rc = call_get_developers("get-developers", ["-v"], self.WITH_UTILS_IN_PATH, topdir, developers) |
| self.assertIn("WARNING: 'path/that/does/not/exists/1' doesn't match any file, line 2", err) |
| self.assertIn("WARNING: 'path/that/does/not/exists/2' doesn't match any file, line 3", err) |
| self.assertEqual(rc, 0) |
| self.assertEqual(len(out), 0) |
| self.assertEqual(len(err), 2) |
| |
| # -c generating warning and printing lots of files with no developer |
| developers = b'N:\tAuthor <email>\n' \ |
| b'F:\tpath/that/does/not/exists/1\n' \ |
| b'F:\tpath/that/does/not/exists/2\n' |
| out, err, rc = call_get_developers("./utils/get-developers", ["-c"], self.WITH_EMPTY_PATH, topdir, developers) |
| self.assertIn("WARNING: 'path/that/does/not/exists/1' doesn't match any file, line 2", err) |
| self.assertIn("WARNING: 'path/that/does/not/exists/2' doesn't match any file, line 3", err) |
| self.assertEqual(rc, 0) |
| self.assertGreater(len(out), 1000) |
| self.assertEqual(len(err), 2) |
| |
| # -c printing lots of files with no developer |
| developers = b'# comment\n' \ |
| b'\n' \ |
| b'N:\tAuthor <email>\n' \ |
| b'F:\tutils/get-developers\n' |
| out, err, rc = call_get_developers("./utils/get-developers", ["-c"], self.WITH_EMPTY_PATH, topdir, developers) |
| self.assertEqual(rc, 0) |
| self.assertGreater(len(out), 1000) |
| self.assertEqual(len(err), 0) |
| |
| # -p lists more than one developer |
| developers = b'N:\tdev1\n' \ |
| b'F:\ttoolchain/\n' \ |
| b'\n' \ |
| b'N:\tdev2\n' \ |
| b'F:\ttoolchain/\n' |
| out, err, rc = call_get_developers("./utils/get-developers", ["-p", "toolchain"], self.WITH_EMPTY_PATH, topdir, developers) |
| self.assertIn("dev1", out) |
| self.assertIn("dev2", out) |
| self.assertEqual(rc, 0) |
| self.assertEqual(len(err), 0) |
| |
| # no args, with syntax error in the file |
| developers = b'text3\n' |
| out, err, rc = call_get_developers("./utils/get-developers", [], self.WITH_EMPTY_PATH, topdir, developers) |
| self.assertIn("No action specified", "\n".join(err)) |
| self.assertEqual(rc, 2) |
| self.assertEqual(len(out), 0) |
| |
| # patchfile from topdir and from elsewhere |
| abs_path = infra.filepath("tests/utils/test_get_developers/") |
| rel_file = "0001-package-binutils-change-.mk.patch" |
| abs_file = os.path.join(abs_path, rel_file) |
| developers = b'N:\tdev1\n' \ |
| b'F:\tpackage/binutils/\n' |
| out, err, rc = call_get_developers("./utils/get-developers", [abs_file], self.WITH_EMPTY_PATH, topdir, developers) |
| self.assertIn('git send-email --to buildroot@buildroot.org --cc "dev1"', out) |
| self.assertEqual(rc, 0) |
| self.assertEqual(len(err), 0) |
| out, err, rc = call_get_developers("get-developers", [rel_file], self.WITH_UTILS_IN_PATH, abs_path, developers) |
| self.assertIn('git send-email --to buildroot@buildroot.org --cc "dev1"', out) |
| self.assertEqual(rc, 0) |
| self.assertEqual(len(err), 0) |
| with open(abs_file, "r") as fd: |
| patch_data = fd.read() |
| out, err, rc = call_get_developers("./utils/get-developers", [], self.WITH_EMPTY_PATH, topdir, developers, patch_data) |
| self.assertIn('git send-email --to buildroot@buildroot.org --cc "dev1"', out) |
| self.assertEqual(rc, 0) |
| self.assertEqual(len(err), 0) |