mirror of
https://github.com/d9pouces/id_configurator.git
synced 2026-11-09 01:47:21 +01:00
586f091eeb
Signed-off-by: d9pouces <github@19pouces.net>
120 lines
4.2 KiB
Python
120 lines
4.2 KiB
Python
import base64
|
|
import subprocess
|
|
from unittest.mock import MagicMock
|
|
|
|
import pytest
|
|
|
|
from id_configurator.config import Configuration
|
|
from id_configurator.context import Context
|
|
from id_configurator.modules.certificates import CertificatesModule
|
|
|
|
CERT_CONTENT = base64.b64encode(b"fake-cert-bytes").decode("ascii")
|
|
|
|
|
|
def make_config(with_certificate: bool) -> Configuration:
|
|
data = {
|
|
"uuid": "12345678-1234-5678-1234-567812345678",
|
|
"organisation": "InterDiode",
|
|
}
|
|
if with_certificate:
|
|
data["configurations"] = {
|
|
"certificates": [{"name": "new-root-ca", "content": CERT_CONTENT}]
|
|
}
|
|
return Configuration.model_validate(data)
|
|
|
|
|
|
def test_is_relevant_true_when_certificates_configured(tmp_path) -> None:
|
|
context = Context(config=make_config(True), dst=tmp_path / "dst", src=None)
|
|
assert CertificatesModule().is_relevant(context) is True
|
|
|
|
|
|
def test_is_relevant_false_when_no_certificates(tmp_path) -> None:
|
|
context = Context(config=make_config(False), dst=tmp_path / "dst", src=None)
|
|
assert CertificatesModule().is_relevant(context) is False
|
|
|
|
|
|
def _mock_success(monkeypatch, stderr: str = "") -> MagicMock:
|
|
mock_run = MagicMock(
|
|
return_value=subprocess.CompletedProcess(
|
|
args=[], returncode=0, stdout="", stderr=stderr
|
|
)
|
|
)
|
|
monkeypatch.setattr("id_configurator.modules.certificates.subprocess.run", mock_run)
|
|
return mock_run
|
|
|
|
|
|
def test_apply_writes_certificate_and_calls_update_ca_certificates(
|
|
tmp_path, monkeypatch
|
|
) -> None:
|
|
mock_run = _mock_success(monkeypatch)
|
|
dst = tmp_path / "dst"
|
|
context = Context(config=make_config(True), dst=dst, src=None)
|
|
|
|
CertificatesModule().apply(context)
|
|
|
|
written = dst / "usr/local/share/ca-certificates/new-root-ca.crt"
|
|
assert written.read_bytes() == b"fake-cert-bytes"
|
|
mock_run.assert_called_once()
|
|
args = mock_run.call_args.args[0]
|
|
assert args[0] == "update-ca-certificates"
|
|
assert "--certsconf" not in args
|
|
assert "--certsdir" not in args
|
|
|
|
|
|
def test_apply_preserves_existing_local_certificates_from_src(
|
|
tmp_path, monkeypatch
|
|
) -> None:
|
|
mock_run = _mock_success(monkeypatch, stderr="some warning")
|
|
src = tmp_path / "src"
|
|
local_certs_dir = src / "usr/local/share/ca-certificates"
|
|
local_certs_dir.mkdir(parents=True)
|
|
(local_certs_dir / "existing.crt").write_bytes(b"existing-bytes")
|
|
(local_certs_dir / "new-root-ca.crt").write_bytes(
|
|
b"stale-bytes-should-be-overwritten"
|
|
)
|
|
(src / "etc/ca-certificates.conf").parent.mkdir(parents=True)
|
|
(src / "etc/ca-certificates.conf").write_text("existing.crt\n", encoding="utf-8")
|
|
(src / "usr/share/ca-certificates").mkdir(parents=True)
|
|
|
|
dst = tmp_path / "dst"
|
|
context = Context(config=make_config(True), dst=dst, src=src)
|
|
|
|
CertificatesModule().apply(context)
|
|
|
|
local_dst = dst / "usr/local/share/ca-certificates"
|
|
assert (local_dst / "existing.crt").read_bytes() == b"existing-bytes"
|
|
assert (local_dst / "new-root-ca.crt").read_bytes() == b"fake-cert-bytes"
|
|
|
|
args = mock_run.call_args.args[0]
|
|
assert "--certsconf" in args
|
|
assert str(src / "etc/ca-certificates.conf") in args
|
|
assert "--certsdir" in args
|
|
assert str(src / "usr/share/ca-certificates") in args
|
|
|
|
|
|
def test_update_ca_certificates_raises_when_binary_missing(
|
|
tmp_path, monkeypatch
|
|
) -> None:
|
|
monkeypatch.setattr(
|
|
"id_configurator.modules.certificates.subprocess.run",
|
|
MagicMock(side_effect=FileNotFoundError()),
|
|
)
|
|
context = Context(config=make_config(True), dst=tmp_path / "dst", src=None)
|
|
|
|
with pytest.raises(RuntimeError, match="update-ca-certificates is not available"):
|
|
CertificatesModule().apply(context)
|
|
|
|
|
|
def test_update_ca_certificates_raises_on_failure(tmp_path, monkeypatch) -> None:
|
|
error = subprocess.CalledProcessError(
|
|
returncode=1, cmd=["update-ca-certificates"], stderr="boom"
|
|
)
|
|
monkeypatch.setattr(
|
|
"id_configurator.modules.certificates.subprocess.run",
|
|
MagicMock(side_effect=error),
|
|
)
|
|
context = Context(config=make_config(True), dst=tmp_path / "dst", src=None)
|
|
|
|
with pytest.raises(RuntimeError, match="update-ca-certificates failed"):
|
|
CertificatesModule().apply(context)
|