Files
pristontale-eu-linux/release_tests/test_release_history.py

157 lines
4.3 KiB
Python

from __future__ import annotations
import unittest
from scripts.generate_history import load_release_statuses, release_history
from scripts.release_lib import ReleaseToolError
import json
from pathlib import Path
import tempfile
def gitea_release(tag: str, *, prerelease: bool) -> dict[str, object]:
return {
"id": 42,
"tag_name": tag,
"name": f"Release {tag}",
"draft": False,
"prerelease": prerelease,
"published_at": "2026-09-08T12:00:00Z",
"html_url": f"https://gitea.example.test/owner/project/releases/tag/{tag}",
"assets": [
{
"name": "manifest.json",
"browser_download_url": (
f"https://gitea.example.test/owner/project/releases/download/"
f"{tag}/manifest.json"
),
},
{
"name": "manifest.json.sig",
"browser_download_url": (
f"https://gitea.example.test/owner/project/releases/download/"
f"{tag}/manifest.json.sig"
),
},
],
}
class ReleaseHistoryTests(unittest.TestCase):
def test_history_uses_only_installable_immutable_releases(self) -> None:
stable = gitea_release("v1.8.0", prerelease=False)
beta = gitea_release("v1.9.0-beta.2", prerelease=True)
wrong_flag = gitea_release("v2.0.0-beta.1", prerelease=False)
draft = gitea_release("v2.0.0", prerelease=False)
draft["draft"] = True
history = release_history(
[stable, wrong_flag, draft, beta],
"2026-09-08T12:01:00Z",
)
releases = history["releases"]
assert isinstance(releases, list)
self.assertEqual(
[release["version"] for release in releases],
["1.9.0-beta.2", "1.8.0"],
)
self.assertEqual(releases[0]["channel"], "prerelease")
self.assertEqual(releases[1]["channel"], "stable")
self.assertTrue(releases[0]["manifest_url"].endswith("/manifest.json"))
def test_history_rejects_an_invalid_generation_timestamp(self) -> None:
with self.assertRaisesRegex(ReleaseToolError, "timestamp"):
release_history([], "today")
def test_history_applies_signed_release_status_overrides(self) -> None:
history = release_history(
[gitea_release("v1.9.0-beta.2", prerelease=True)],
"2026-09-08T12:01:00Z",
{"v1.9.0-beta.2": "withdrawn"},
)
releases = history["releases"]
assert isinstance(releases, list)
self.assertEqual(releases[0]["status"], "withdrawn")
self.assertEqual(
releases[0]["compatibility"],
{"config_schema": 1, "minimum_config_schema": 1},
)
def test_history_supports_explicit_config_compatibility(self) -> None:
history = release_history(
[gitea_release("v2.0.0", prerelease=False)],
"2026-09-08T12:01:00Z",
{
"v2.0.0": {
"status": "active",
"config_schema": 3,
"minimum_config_schema": 2,
}
},
)
releases = history["releases"]
assert isinstance(releases, list)
self.assertEqual(
releases[0]["compatibility"],
{"config_schema": 3, "minimum_config_schema": 2},
)
def test_status_file_rejects_unknown_fields_and_unsafe_schema_ranges(self) -> None:
with tempfile.TemporaryDirectory() as temporary:
path = Path(temporary) / "statuses.json"
path.write_text(
json.dumps(
{
"schema": 1,
"releases": {
"v2.0.0": {
"status": "active",
"config_schema": 1,
"minimum_config_schema": 2,
}
},
}
),
encoding="utf-8",
)
with self.assertRaisesRegex(ReleaseToolError, "exceeds"):
load_release_statuses(path)
path.write_text(
'{"schema":1,"releases":{"v2.0.0":{"status":"active","note":"x"}}}',
encoding="utf-8",
)
with self.assertRaisesRegex(ReleaseToolError, "unknown"):
load_release_statuses(path)
def test_history_rejects_an_unknown_status(self) -> None:
with self.assertRaisesRegex(ReleaseToolError, "invalid status"):
release_history(
[gitea_release("v1.8.0", prerelease=False)],
"2026-09-08T12:01:00Z",
{"v1.8.0": "broken"},
)
def test_history_rejects_status_override_for_a_missing_release(self) -> None:
with self.assertRaisesRegex(ReleaseToolError, "do not match"):
release_history(
[gitea_release("v1.8.0", prerelease=False)],
"2026-09-08T12:01:00Z",
{"v1.9.0-beta.1": "withdrawn"},
)
def test_history_rejects_duplicate_release_tags(self) -> None:
release = gitea_release("v1.8.0", prerelease=False)
with self.assertRaisesRegex(ReleaseToolError, "duplicate"):
release_history(
[release, dict(release)],
"2026-09-08T12:01:00Z",
)
if __name__ == "__main__":
unittest.main()