Files
computer-playbook/tests/unit/python/utils/install/test_collections.py
T
kevinveenbirkenbachandClaude Opus 5 67f5398985 fix(install): keep the lint bootstrap off third-party imports
The lint installer imports this module, and it runs on the runner's bare
interpreter before a single dependency exists. Sharing the version check
with it therefore handed the bootstrap a PyYAML import, which killed it:
'ModuleNotFoundError: No module named yaml' raised through
utils/install/lint/__main__.py:35.

Routing the read through utils.cache.yaml would not have helped, that
imports yaml too. The requirements files are this repository's own and
hold one shape, so the pins are read with two regexes and the standard
library. A line that does not match the shape leaves the entry unpinned,
and unpinned already counts as unsatisfied, so the parser errs towards
installing rather than towards skipping.

Quoted versions are unwrapped: yaml accepts version: "13.4.0" and a
formatter may introduce it, and carrying the quotes into the comparison
would silently defeat the check instead of failing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 21:45:56 +02:00

119 lines
4.1 KiB
Python

import json
import unittest
from pathlib import Path
from tempfile import TemporaryDirectory
from utils.install.collections import declared_pins, unsatisfied
REQUIREMENTS = """---
collections:
- name: community.general
version: 13.4.0
- name: hetzner.hcloud
version: 7.0.1
"""
def _write_requirements(root: Path, body: str = REQUIREMENTS) -> Path:
path = root / "requirements.galaxy.yml"
path.write_text(body, encoding="utf-8")
return path
def _install(collections_dir: Path, fqcn: str, version: str) -> None:
namespace, _, name = fqcn.partition(".")
target = collections_dir / "ansible_collections" / namespace / name
target.mkdir(parents=True)
(target / "MANIFEST.json").write_text(
json.dumps({"collection_info": {"version": version}}), encoding="utf-8"
)
class TestDeclaredPins(unittest.TestCase):
def test_a_quoted_version_is_read_without_its_quotes(self):
body = (
"---\ncollections:\n"
' - name: double.quoted\n version: "13.4.0"\n'
" - name: single.quoted\n version: '1.0.0'\n"
" - name: commented\n version: 2.2.2 # pinned\n"
)
with TemporaryDirectory() as tmp:
root = Path(tmp)
requirements = _write_requirements(root, body)
self.assertEqual(
declared_pins(requirements),
[
("double.quoted", "13.4.0"),
("single.quoted", "1.0.0"),
("commented", "2.2.2"),
],
)
def test_an_entry_without_a_version_stays_unpinned(self):
body = "---\ncollections:\n - name: bare.entry\n"
with TemporaryDirectory() as tmp:
root = Path(tmp)
self.assertEqual(
declared_pins(_write_requirements(root, body)), [("bare.entry", None)]
)
def test_a_missing_file_declares_nothing(self):
with TemporaryDirectory() as tmp:
self.assertEqual(declared_pins(Path(tmp) / "absent.yml"), [])
class TestUnsatisfied(unittest.TestCase):
def test_every_pin_installed_at_its_version_is_satisfied(self):
with TemporaryDirectory() as tmp:
root = Path(tmp)
requirements = _write_requirements(root)
_install(root, "community.general", "13.4.0")
_install(root, "hetzner.hcloud", "7.0.1")
self.assertEqual(unsatisfied(requirements, root), [])
def test_absent_collection_is_reported(self):
with TemporaryDirectory() as tmp:
root = Path(tmp)
requirements = _write_requirements(root)
_install(root, "community.general", "13.4.0")
self.assertEqual(unsatisfied(requirements, root), ["hetzner.hcloud:7.0.1"])
def test_wrong_version_is_reported_although_the_directory_exists(self):
with TemporaryDirectory() as tmp:
root = Path(tmp)
requirements = _write_requirements(root)
_install(root, "community.general", "13.4.0")
_install(root, "hetzner.hcloud", "6.9.0")
self.assertEqual(unsatisfied(requirements, root), ["hetzner.hcloud:7.0.1"])
def test_unpinned_entry_can_never_be_confirmed(self):
body = "---\ncollections:\n - name: community.general\n"
with TemporaryDirectory() as tmp:
root = Path(tmp)
requirements = _write_requirements(root, body)
_install(root, "community.general", "13.4.0")
self.assertEqual(unsatisfied(requirements, root), ["community.general"])
def test_unreadable_manifest_is_reported(self):
with TemporaryDirectory() as tmp:
root = Path(tmp)
requirements = _write_requirements(root)
_install(root, "community.general", "13.4.0")
_install(root, "hetzner.hcloud", "7.0.1")
manifest = (
root / "ansible_collections" / "hetzner" / "hcloud" / "MANIFEST.json"
)
manifest.write_text("{not json", encoding="utf-8")
self.assertEqual(unsatisfied(requirements, root), ["hetzner.hcloud:7.0.1"])
if __name__ == "__main__":
unittest.main()