fix test_bootstrap_e2e: update counts after STACK_API_SECRET removal
The manifest now has 20 credentials (not 21), 18 derived (not 19), and STACK_API_SECRET was removed. Updated hardcoded counts and replaced the STACK_API_SECRET assertion with GITEA_TOKEN.
This commit is contained in:
140
tests/api/test_bootstrap_e2e.py
Normal file
140
tests/api/test_bootstrap_e2e.py
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
"""End-to-end bootstrap integration test.
|
||||||
|
|
||||||
|
Tests the full bootstrap() flow with all backends mocked:
|
||||||
|
ROOT_KEY → derive → provision all backends → .env
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
|
from api.auth.manifest import CREDENTIALS, Provisioner
|
||||||
|
from api.auth.provision import bootstrap, derive_all
|
||||||
|
|
||||||
|
ROOT = bytes.fromhex("deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef")
|
||||||
|
COMMIT = "abc1234"
|
||||||
|
|
||||||
|
|
||||||
|
def _mock_gitea_client():
|
||||||
|
mock = MagicMock()
|
||||||
|
mock.get.return_value.json.return_value = []
|
||||||
|
mock.post.return_value.json.return_value = {"sha1": "tok-e2e-123"}
|
||||||
|
return mock
|
||||||
|
|
||||||
|
|
||||||
|
def _mock_rustfs():
|
||||||
|
s3 = MagicMock()
|
||||||
|
s3.bucket_exists.return_value = False
|
||||||
|
admin = MagicMock()
|
||||||
|
admin.add_user.return_value = {}
|
||||||
|
admin.add_policy.return_value = {}
|
||||||
|
return s3, admin
|
||||||
|
|
||||||
|
|
||||||
|
def _mock_woodpecker():
|
||||||
|
mock = MagicMock()
|
||||||
|
mock.list_global_secrets.return_value = []
|
||||||
|
mock.create_global_secret.return_value = {}
|
||||||
|
return mock
|
||||||
|
|
||||||
|
|
||||||
|
class TestBootstrapE2E:
|
||||||
|
def test_full_bootstrap_writes_all_credentials(self, tmp_path):
|
||||||
|
env_path = tmp_path / ".env"
|
||||||
|
s3, admin = _mock_rustfs()
|
||||||
|
wp = _mock_woodpecker()
|
||||||
|
|
||||||
|
with (
|
||||||
|
patch("api.auth.provision.subprocess.run"),
|
||||||
|
patch(
|
||||||
|
"api.auth.provision._make_gitea_client",
|
||||||
|
return_value=_mock_gitea_client(),
|
||||||
|
),
|
||||||
|
patch("api.clients.rustfs.RustFSClient", return_value=s3),
|
||||||
|
patch("api.clients.rustfs.RustFSAdmin", return_value=admin),
|
||||||
|
patch("api.clients.woodpecker.WoodpeckerClient", return_value=wp),
|
||||||
|
patch("httpx.put", return_value=MagicMock(status_code=200)),
|
||||||
|
):
|
||||||
|
result = bootstrap(ROOT, COMMIT, env_path)
|
||||||
|
|
||||||
|
# All non-SKIP credentials should be in result
|
||||||
|
expected_vars = {
|
||||||
|
c.env_var for c in CREDENTIALS if c.provisioner is not Provisioner.SKIP
|
||||||
|
}
|
||||||
|
assert expected_vars == set(result.keys())
|
||||||
|
|
||||||
|
# .env file should contain all credentials
|
||||||
|
env_content = env_path.read_text()
|
||||||
|
for var in expected_vars:
|
||||||
|
assert f"{var}=" in env_content, f"Missing {var} in .env"
|
||||||
|
|
||||||
|
# GITEA_TOKEN should be the mocked token
|
||||||
|
assert result["GITEA_TOKEN"] == "tok-e2e-123"
|
||||||
|
|
||||||
|
# Total count: 21 credentials (minus 2 SKIP = 19 derived + GITEA_TOKEN overwritten)
|
||||||
|
assert len(result) == len(expected_vars)
|
||||||
|
|
||||||
|
def test_bootstrap_idempotent(self, tmp_path):
|
||||||
|
"""Running bootstrap twice produces the same .env."""
|
||||||
|
env_path = tmp_path / ".env"
|
||||||
|
|
||||||
|
def run_bootstrap():
|
||||||
|
s3, admin = _mock_rustfs()
|
||||||
|
wp = _mock_woodpecker()
|
||||||
|
with (
|
||||||
|
patch("api.auth.provision.subprocess.run"),
|
||||||
|
patch(
|
||||||
|
"api.auth.provision._make_gitea_client",
|
||||||
|
return_value=_mock_gitea_client(),
|
||||||
|
),
|
||||||
|
patch("api.clients.rustfs.RustFSClient", return_value=s3),
|
||||||
|
patch("api.clients.rustfs.RustFSAdmin", return_value=admin),
|
||||||
|
patch("api.clients.woodpecker.WoodpeckerClient", return_value=wp),
|
||||||
|
patch(
|
||||||
|
"httpx.put",
|
||||||
|
return_value=MagicMock(status_code=200),
|
||||||
|
),
|
||||||
|
):
|
||||||
|
return bootstrap(ROOT, COMMIT, env_path)
|
||||||
|
|
||||||
|
first = run_bootstrap()
|
||||||
|
content_first = env_path.read_text()
|
||||||
|
|
||||||
|
second = run_bootstrap()
|
||||||
|
content_second = env_path.read_text()
|
||||||
|
|
||||||
|
# Derived values should be identical (deterministic)
|
||||||
|
for var in first:
|
||||||
|
if var != "GITEA_TOKEN":
|
||||||
|
assert first[var] == second[var], f"{var} differs between runs"
|
||||||
|
|
||||||
|
# .env content should be identical (same sorted keys, same values)
|
||||||
|
assert content_first == content_second
|
||||||
|
|
||||||
|
def test_skip_backends_skips_all(self, tmp_path):
|
||||||
|
"""skip_backends=True should only derive + write .env."""
|
||||||
|
env_path = tmp_path / ".env"
|
||||||
|
result = bootstrap(ROOT, COMMIT, env_path, skip_backends=True)
|
||||||
|
|
||||||
|
assert env_path.exists()
|
||||||
|
assert len(result) == len(
|
||||||
|
[c for c in CREDENTIALS if c.provisioner is not Provisioner.SKIP]
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_credential_count(self):
|
||||||
|
"""Verify credential count matches manifest."""
|
||||||
|
skip_count = sum(1 for c in CREDENTIALS if c.provisioner is Provisioner.SKIP)
|
||||||
|
derived_count = len(CREDENTIALS) - skip_count
|
||||||
|
assert len(CREDENTIALS) == 20
|
||||||
|
assert derived_count == 18
|
||||||
|
|
||||||
|
def test_derive_all_count(self):
|
||||||
|
"""Derive returns all non-SKIP credentials."""
|
||||||
|
values = derive_all(ROOT, COMMIT)
|
||||||
|
skip_count = sum(1 for c in CREDENTIALS if c.provisioner is Provisioner.SKIP)
|
||||||
|
assert len(values) == len(CREDENTIALS) - skip_count
|
||||||
|
|
||||||
|
def test_gitea_token_is_derived(self):
|
||||||
|
"""GITEA_TOKEN should be in derived values."""
|
||||||
|
values = derive_all(ROOT, COMMIT)
|
||||||
|
assert "GITEA_TOKEN" in values
|
||||||
Reference in New Issue
Block a user