Files

93 lines
3.7 KiB
Python

"""Tests for the removal of apps and everything they left on their servers."""
import os
import sys
import click
import pytest
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
import alakazam
from alakazam import purge_app_secrets, purge_apps
INSTANCE_APPS = {"a.org": [["authentik", "login.a.org"]]}
CONFIG = {"a.org": {"authentik": {"app_domain": "login.a.org", "server": "a.org"}}}
@pytest.fixture
def env_file(tmp_path, monkeypatch):
"""Places a local app configuration where purge_apps looks for it."""
path = tmp_path / "login.a.org.env"
path.write_text("")
monkeypatch.setattr(alakazam, "get_env_path", lambda server, domain: path)
monkeypatch.setattr(alakazam, "INSTANCE_CONFIGS", CONFIG)
return path
class TestPurgeApps:
def test_a_failing_removal_aborts(self, env_file, monkeypatch):
"""Reporting a purge that did not happen would make a later setup build on leftovers."""
def failing(*args, **kwargs):
raise RuntimeError("FATA login.a.org is still deployed")
monkeypatch.setattr(alakazam, "abra", failing)
with pytest.raises(click.ClickException) as excinfo:
purge_apps(INSTANCE_APPS)
assert "could not purge login.a.org" in excinfo.value.message
assert excinfo.value.exit_code != 0
def test_a_successful_removal_reports_it(self, env_file, monkeypatch, capsys):
monkeypatch.setattr(alakazam, "abra", lambda *a, **k: "removed")
purge_apps(INSTANCE_APPS)
assert "login.a.org purged" in capsys.readouterr().out
def test_an_app_without_a_local_config_is_skipped(self, tmp_path, monkeypatch):
"""abra addresses secrets and volumes through the .env, without it there is nothing to remove."""
calls = []
monkeypatch.setattr(alakazam, "INSTANCE_CONFIGS", CONFIG)
monkeypatch.setattr(alakazam, "get_env_path", lambda server, domain: tmp_path / "absent.env")
monkeypatch.setattr(alakazam, "abra", lambda *a, **k: calls.append(a) or "")
purge_apps(INSTANCE_APPS)
assert calls == []
class TestPurgeAppSecrets:
@pytest.fixture
def config(self, monkeypatch):
monkeypatch.setattr(alakazam, "INSTANCE_CONFIGS", CONFIG)
def install(self, monkeypatch, error=None):
calls = []
def abra(*args, **kwargs):
calls.append(args)
if error:
raise RuntimeError(error)
return ""
monkeypatch.setattr(alakazam, "abra", abra)
return calls
def test_all_secrets_of_a_recipe_are_removed(self, config, monkeypatch, capsys):
calls = self.install(monkeypatch)
purge_app_secrets({"authentik": []})
assert calls == [("app", "secret", "rm", "-a", "login.a.org")]
assert "purged" in capsys.readouterr().out
def test_an_app_without_secrets_is_not_a_failure(self, config, monkeypatch, capsys):
"""abra exits non-zero when it found nothing to remove, which says the job is already done."""
self.install(monkeypatch, error="FATA no secrets to remove?")
purge_app_secrets({"authentik": []})
assert "has no secrets on its server" in capsys.readouterr().out
def test_a_real_failure_still_propagates(self, config, monkeypatch):
self.install(monkeypatch, error="FATA error during connect: no route to host")
with pytest.raises(RuntimeError):
purge_app_secrets({"authentik": []})
def test_a_named_secret_that_is_absent_is_skipped(self, config, monkeypatch, capsys):
self.install(monkeypatch, error="FATA email_pass doesn't exist on server?")
purge_app_secrets({"authentik": ["email_pass"]})
assert "is not stored on the server" in capsys.readouterr().out