Files
blog/delivery/tests/test_blog_delivery.py
T

105 lines
4.5 KiB
Python

from __future__ import annotations
import hashlib
import io
import json
from pathlib import Path
import tarfile
import tempfile
import unittest
from scripts import deploy_contract
from scripts import delivery_gate
from scripts import fetch_hugo
from scripts import generic_package
DELIVERY = Path(__file__).resolve().parents[1]
REPO_ROOT = DELIVERY.parent
WORKFLOWS = REPO_ROOT / ".gitea/workflows"
REVISION = "a" * 40
class BlogSiteTests(unittest.TestCase):
def test_site_is_the_netcup_release_root_not_a_checkout(self):
site = deploy_contract.load_site(DELIVERY / "site.json")
self.assertEqual(site.target, "/srv/libretech-static/blog")
self.assertEqual(site.verify_url, "https://blog.static.librete.ch/.well-known/release.json")
url = generic_package.package_file_url(
deploy_contract.REGISTRY, "public", "blog-site", REVISION, generic_package.ARCHIVE_NAME,
)
request = deploy_contract.validate_request(
site=site,
revision=REVISION,
artifact_url=url,
artifact_digest="sha256:" + "b" * 64,
target=site.target,
verify_url=site.verify_url,
desired_commit="c" * 40,
desired_generation="1",
)
self.assertEqual(request["artifact_url"], url)
with self.assertRaisesRegex(deploy_contract.ContractError, "immutable project package"):
deploy_contract.validate_request(**{**request, "artifact_url": url.replace("public", "libretech")}, site=site)
def test_reviewed_gate_enables_publication_and_deployment(self):
config = DELIVERY / ".delivery/config.json"
for capability in delivery_gate.CAPABILITIES:
delivery_gate.check(config, capability)
def test_hugo_is_pinned_and_verified(self):
self.assertRegex(fetch_hugo.SHA256, r"^[0-9a-f]{64}$")
self.assertIn(f"/v{fetch_hugo.VERSION}/", fetch_hugo.URL)
with tempfile.TemporaryDirectory() as temp:
buffer = io.BytesIO()
with tarfile.open(fileobj=buffer, mode="w:gz") as tar:
info = tarfile.TarInfo("hugo")
info.size = 4
tar.addfile(info, io.BytesIO(b"\x7fELF"))
archive = buffer.getvalue()
binary = fetch_hugo.extract_hugo(archive, hashlib.sha256(archive).hexdigest(), Path(temp))
self.assertEqual(binary.read_bytes(), b"\x7fELF")
with self.assertRaisesRegex(fetch_hugo.FetchError, "digest mismatch"):
fetch_hugo.extract_hugo(archive, "0" * 64, Path(temp))
class BlogWorkflowTests(unittest.TestCase):
def read(self, name):
return (WORKFLOWS / name).read_text(encoding="utf-8")
def test_no_workflow_publishes_from_a_checkout(self):
for workflow in sorted(WORKFLOWS.glob("*.yml")):
text = workflow.read_text(encoding="utf-8")
with self.subTest(workflow=workflow.name):
for forbidden in ("rsync", "scp ", "publishDir", "/var/www"):
self.assertNotIn(forbidden, text)
def test_publication_is_gated_before_any_package_write(self):
workflow = self.read("publish-blog.yml")
_, _, publish = workflow.partition("\n publish:\n")
self.assertIn("vars.BLOG_PACKAGE_PUBLISH_ENABLED == 'true'", publish)
self.assertLess(publish.index("delivery_gate.py package_publish"), publish.index("generic_package.py"))
_, _, validate = workflow.partition("\n validate:\n")
self.assertNotIn("secrets.", validate.partition("\n publish:\n")[0])
def test_deployment_is_gated_ordered_and_site_scoped(self):
workflow = self.read("deploy-blog.yml")
self.assertIn("workflow_dispatch:", workflow)
self.assertNotIn("\n push:", workflow)
self.assertIn("vars.BLOG_STATIC_DEPLOY_ENABLED == 'true'", workflow)
self.assertNotIn("DONATELLA", workflow)
self.assertEqual(workflow.count("--site-config delivery/site.json"), 2)
for field in ("revision", "artifact_url", "artifact_digest", "target", "verify_url",
"desired_commit", "desired_generation"):
self.assertIn(f" {field}:\n", workflow)
self.assertIn("StrictHostKeyChecking yes", workflow)
self.assertIn("steps.receive.outputs.superseded == 'false'", workflow)
self.assertLess(
workflow.index("delivery_gate.py static_deploy"),
workflow.index("ssh static-release-target"),
)
if __name__ == "__main__":
unittest.main()