-
Notifications
You must be signed in to change notification settings - Fork 687
/
test_securedrop_deb_package.py
104 lines (86 loc) · 3.56 KB
/
test_securedrop_deb_package.py
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
import os
import subprocess
import tempfile
from pathlib import Path
import pytest
SECUREDROP_ROOT = Path(
subprocess.check_output(["git", "rev-parse", "--show-toplevel"]).decode().strip()
)
DEB_PATHS = list((SECUREDROP_ROOT / "build/focal").glob("*.deb"))
SITE_PACKAGES = "/opt/venvs/securedrop-app-code/lib/python3.8/site-packages"
@pytest.fixture(scope="module")
def securedrop_app_code_contents() -> str:
"""
Returns the content listing of the securedrop-app-code Debian package.
"""
try:
path = [pkg for pkg in DEB_PATHS if pkg.name.startswith("securedrop-app-code")][0]
except IndexError:
raise RuntimeError("Unable to find securedrop-app-code package in build/ folder")
return subprocess.check_output(["dpkg-deb", "--contents", path]).decode()
@pytest.mark.parametrize("deb", DEB_PATHS)
def test_deb_packages_appear_installable(deb: Path) -> None:
"""
Confirms that a dry-run of installation reports no errors.
Simple check for valid Debian package structure, but not thorough.
When run on a malformed package, `dpkg` will report:
dpkg-deb: error: `foo.deb' is not a debian format archive
Testing application behavior is left to the functional tests.
"""
# Normally this is called as root, but we can get away with simply
# adding sbin to the path
path = os.getenv("PATH") + ":/usr/sbin:/sbin"
subprocess.check_call(["dpkg", "--install", "--dry-run", deb], env={"PATH": path})
@pytest.mark.parametrize("deb", DEB_PATHS)
def test_deb_package_contains_expected_conffiles(deb: Path):
"""
Ensures the `securedrop-app-code` package declares only allow-listed
`conffiles`. Several files in `/etc/` would automatically be marked
conffiles, which would break unattended updates to critical package
functionality such as AppArmor profiles. This test validates overrides
in the build logic to unset those conffiles.
The same applies to `securedrop-config` too.
"""
if not deb.name.startswith(("securedrop-app-code", "securedrop-config")):
return
with tempfile.TemporaryDirectory() as tmpdir:
subprocess.check_call(["dpkg-deb", "--control", deb, tmpdir])
conffiles_path = Path(tmpdir) / "conffiles"
assert conffiles_path.exists()
# No files are currently allow-listed to be conffiles
assert conffiles_path.read_text().rstrip() == ""
@pytest.mark.parametrize(
"path",
[
"/var/www/securedrop/.well-known/pki-validation/",
"/var/www/securedrop/translations/messages.pot",
"/var/www/securedrop/translations/de_DE/LC_MESSAGES/messages.mo",
f"{SITE_PACKAGES}/redwood/redwood.cpython-38-x86_64-linux-gnu.so",
],
)
def test_app_code_paths(securedrop_app_code_contents: str, path: str):
"""
Ensures the `securedrop-app-code` package contains the specified paths
"""
for line in securedrop_app_code_contents.splitlines():
if line.endswith(path):
assert True
return
pytest.fail("not found")
@pytest.mark.parametrize(
"path",
[
"/var/www/securedrop/static/.webassets-cache/",
"/var/www/securedrop/static/gen/",
"/var/www/securedrop/config.py",
"/var/www/securedrop/static/i/custom_logo.png",
".j2",
],
)
def test_app_code_paths_missing(securedrop_app_code_contents: str, path: str):
"""
Ensures the `securedrop-app-code` package do *NOT* contain the specified paths
"""
for line in securedrop_app_code_contents.splitlines():
if line.endswith(path):
pytest.fail(f"found {line}")