forked from toolshed/alakazam
93 lines
3.7 KiB
Python
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
|