aboutsummaryrefslogtreecommitdiff
path: root/tests/installer-steps/test_install_executable.py
blob: 6a2ecfd2d658a8ac58d96bbf464b71b0345c59bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
"""Test the guarded executable install helper.

With `set -e` off, the installer's bare `cp script /usr/local/bin/...` followed
by `chmod +x` failed silently when the source was missing or partial, leaving a
systemd service with a dead ExecStart or a pacman hook pointing at a script that
was never installed. install_executable guards the copy and the chmod, warns on
failure, and skips the chmod when the copy did not land.

Method: sed-extract install_executable from the real `archsetup` and run it
against real temp files (no fakes needed) with a fake error_warn recorder.

Run from repo root:
    python3 -m unittest tests.installer-steps.test_install_executable
"""

import os
import subprocess
import tempfile
import textwrap
import unittest

REPO_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "..", ".."))
ARCHSETUP = os.path.join(REPO_ROOT, "archsetup")


def run(src, dest):
    script = textwrap.dedent(f"""\
        logfile=/dev/null
        error_warn() {{ echo "WARN: $1"; return 1; }}
        source <(sed -n '/^install_executable() {{/,/^}}/p' "{ARCHSETUP}")
        install_executable "{src}" "{dest}"
        echo "RC=$?"
    """)
    return subprocess.run(
        ["bash", "-c", script], capture_output=True, text=True, timeout=10,
    )


class InstallExecutable(unittest.TestCase):
    def test_copies_and_makes_executable(self):
        with tempfile.TemporaryDirectory() as d:
            src = os.path.join(d, "myscript")
            dest = os.path.join(d, "bin", "myscript")
            os.mkdir(os.path.join(d, "bin"))
            with open(src, "w") as f:
                f.write("#!/bin/sh\necho hi\n")
            r = run(src, dest)
            self.assertIn("RC=0", r.stdout)
            self.assertTrue(os.path.exists(dest))
            self.assertTrue(os.access(dest, os.X_OK), "dest must be executable")
            self.assertNotIn("WARN", r.stdout)

    def test_missing_source_warns_and_skips_chmod(self):
        with tempfile.TemporaryDirectory() as d:
            src = os.path.join(d, "does-not-exist")
            dest = os.path.join(d, "bin", "myscript")
            os.mkdir(os.path.join(d, "bin"))
            r = run(src, dest)
            self.assertIn("WARN: copying", r.stdout,
                          "a failed copy must warn, not silently continue")
            self.assertNotIn("RC=0", r.stdout, "helper returns non-zero on copy failure")
            self.assertFalse(os.path.exists(dest))


if __name__ == "__main__":
    unittest.main()