This repository has been archived on 2026-07-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
reuse-surface/tests/test_forge_host.py
tegwick 00b7eab154
Some checks failed
ci / validate-registry (push) Has been cancelled
REUSE-WP-0019-T01: forge host abstraction + URL migration inventory
reuse_surface/forge_host.py: parse/derive/rewrite raw index URLs across
Gitea and Forgejo (handles both the legacy /raw/<branch>/... form and the
canonical /raw/branch/<branch>/... form both forges serve without a 303
redirect). migrate_source_host() verifies the new URL resolves via HTTP
HEAD before writing -- refuses to point a repo at a host it hasn't
actually migrated to.

New CLI: reuse-surface federation migrate-host --repo <slug> --to
<base-url> [--from <check>] [--dry-run] [--no-verify] [--update-hub].

Inventory: cross-referenced sources.yaml against each repo's actual git
origin. 11/61 repos already on Forgejo; found 2 with stale sources.yaml
entries (activity-core, state-hub) despite having migrated. Fixed for
real: local sources.yaml + production hub registration (hub update),
verified against GET /v1/federated post-migration. config-atlas's
WP-0017-T06 303 confirmed NOT a host-transition symptom (already diagnosed
there as something else).

Also fixed two host-agnostic gaps found while inventorying:
registry_update.py and maintain_llm.py only recognized .gitea/workflows/,
missing repos already on .forgejo/workflows/. Fixed a stale copy-paste
example (state-hub's now-wrong old URL) in docs/RegistryFederation.md, and
a pre-existing unrelated port typo (8088 vs the real llm-connect default
8080) in tools/README.md and registry/README.md.

17 new pytest cases (tests/test_forge_host.py), 106 total pass.
Recomposed federated.yaml post-migration: still 61 capabilities.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-07 18:14:30 +02:00

189 lines
7.7 KiB
Python

from __future__ import annotations
import pytest
from reuse_surface.forge_host import (
derive_raw_url,
forge_base_url,
migrate_source_host,
parse_raw_url,
rewrite_url_host,
)
def test_parse_raw_url_legacy_form():
parts = parse_raw_url("https://gitea.coulomb.social/coulomb/activity-core/raw/main/registry/indexes/capabilities.yaml")
assert parts.scheme == "https"
assert parts.host == "gitea.coulomb.social"
assert parts.org == "coulomb"
assert parts.repo == "activity-core"
assert parts.branch == "main"
assert parts.path == "registry/indexes/capabilities.yaml"
def test_parse_raw_url_branch_qualified_form():
parts = parse_raw_url("https://forgejo.coulomb.social/coulomb/core-hub/raw/branch/main/registry/indexes/capabilities.yaml")
assert parts.host == "forgejo.coulomb.social"
assert parts.repo == "core-hub"
assert parts.branch == "main"
def test_parse_raw_url_rejects_unrecognized():
with pytest.raises(ValueError):
parse_raw_url("https://example.com/not/a/raw/url")
def test_derive_raw_url_uses_branch_qualified_form():
url = derive_raw_url("https://forgejo.coulomb.social", "coulomb", "core-hub")
assert url == "https://forgejo.coulomb.social/coulomb/core-hub/raw/branch/main/registry/indexes/capabilities.yaml"
def test_derive_raw_url_strips_trailing_slash():
url = derive_raw_url("https://forgejo.coulomb.social/", "coulomb", "core-hub")
assert url.startswith("https://forgejo.coulomb.social/coulomb/")
def test_rewrite_url_host_swaps_host_and_normalizes_form():
old = "https://gitea.coulomb.social/coulomb/activity-core/raw/main/registry/indexes/capabilities.yaml"
new = rewrite_url_host(old, "https://forgejo.coulomb.social")
assert new == "https://forgejo.coulomb.social/coulomb/activity-core/raw/branch/main/registry/indexes/capabilities.yaml"
def test_forge_base_url_env_fallback(monkeypatch):
monkeypatch.setenv("REUSE_SURFACE_FORGE_BASE_URL", "https://forgejo.coulomb.social")
assert forge_base_url() == "https://forgejo.coulomb.social"
def test_forge_base_url_none_when_unset(monkeypatch):
monkeypatch.delenv("REUSE_SURFACE_FORGE_BASE_URL", raising=False)
assert forge_base_url() is None
def test_forge_base_url_explicit_wins(monkeypatch):
monkeypatch.setenv("REUSE_SURFACE_FORGE_BASE_URL", "https://env-value")
assert forge_base_url("https://explicit-value") == "https://explicit-value"
def test_migrate_source_host_mutates_matching_entry(monkeypatch):
monkeypatch.setattr("reuse_surface.forge_host.probe_url", lambda url, **k: (True, 200))
sources = [
{"repo": "activity-core", "url": "https://gitea.coulomb.social/coulomb/activity-core/raw/main/registry/indexes/capabilities.yaml"},
{"repo": "other-repo", "url": "https://gitea.coulomb.social/coulomb/other-repo/raw/main/registry/indexes/capabilities.yaml"},
]
report = migrate_source_host(sources, "activity-core", "https://forgejo.coulomb.social")
assert report["verified"] is True
assert sources[0]["url"] == "https://forgejo.coulomb.social/coulomb/activity-core/raw/branch/main/registry/indexes/capabilities.yaml"
# other entries untouched
assert sources[1]["url"] == "https://gitea.coulomb.social/coulomb/other-repo/raw/main/registry/indexes/capabilities.yaml"
def test_migrate_source_host_repo_not_found():
sources = [{"repo": "activity-core", "url": "https://gitea.coulomb.social/coulomb/activity-core/raw/main/registry/indexes/capabilities.yaml"}]
with pytest.raises(ValueError, match="not found"):
migrate_source_host(sources, "does-not-exist", "https://forgejo.coulomb.social")
def test_migrate_source_host_refuses_unverified_url(monkeypatch):
monkeypatch.setattr("reuse_surface.forge_host.probe_url", lambda url, **k: (False, 404))
sources = [{"repo": "activity-core", "url": "https://gitea.coulomb.social/coulomb/activity-core/raw/main/registry/indexes/capabilities.yaml"}]
original_url = sources[0]["url"]
with pytest.raises(ValueError, match="did not resolve"):
migrate_source_host(sources, "activity-core", "https://forgejo.coulomb.social")
# must not have mutated the entry when verification failed
assert sources[0]["url"] == original_url
def test_migrate_source_host_skips_verification_when_disabled():
sources = [{"repo": "activity-core", "url": "https://gitea.coulomb.social/coulomb/activity-core/raw/main/registry/indexes/capabilities.yaml"}]
report = migrate_source_host(sources, "activity-core", "https://forgejo.coulomb.social", verify=False)
assert report["verified"] is None
assert sources[0]["url"].startswith("https://forgejo.coulomb.social/")
def test_cmd_federation_migrate_host_dry_run(tmp_path, monkeypatch):
from reuse_surface.cli import main
sources_path = tmp_path / "sources.yaml"
sources_path.write_text(
"version: 1\n"
"domain: helix_forge\n"
"collision_policy: warn\n"
"sources:\n"
"- repo: activity-core\n"
" url: https://gitea.coulomb.social/coulomb/activity-core/raw/main/registry/indexes/capabilities.yaml\n"
" enabled: true\n"
)
monkeypatch.setattr("reuse_surface.cli.migrate_source_host", lambda sources, repo, to, verify=True: {
"repo": repo, "old_url": sources[0]["url"], "new_url": "https://forgejo.coulomb.social/x", "verified": True,
})
exit_code = main([
"federation", "migrate-host",
"--repo", "activity-core",
"--to", "https://forgejo.coulomb.social",
"--sources", str(sources_path),
"--dry-run",
])
assert exit_code == 0
# dry-run must not write
assert "gitea.coulomb.social" in sources_path.read_text()
def test_cmd_federation_migrate_host_writes_file(tmp_path, monkeypatch):
from reuse_surface.cli import main
sources_path = tmp_path / "sources.yaml"
sources_path.write_text(
"version: 1\n"
"domain: helix_forge\n"
"collision_policy: warn\n"
"sources:\n"
"- repo: activity-core\n"
" url: https://gitea.coulomb.social/coulomb/activity-core/raw/main/registry/indexes/capabilities.yaml\n"
" enabled: true\n"
)
monkeypatch.setattr("reuse_surface.forge_host.probe_url", lambda url, **k: (True, 200))
exit_code = main([
"federation", "migrate-host",
"--repo", "activity-core",
"--to", "https://forgejo.coulomb.social",
"--sources", str(sources_path),
])
assert exit_code == 0
written = sources_path.read_text()
assert "forgejo.coulomb.social" in written
assert "gitea.coulomb.social" not in written
def test_cmd_federation_migrate_host_repo_not_found_errors(tmp_path):
from reuse_surface.cli import main
sources_path = tmp_path / "sources.yaml"
sources_path.write_text("version: 1\ndomain: helix_forge\ncollision_policy: warn\nsources: []\n")
exit_code = main([
"federation", "migrate-host",
"--repo", "does-not-exist",
"--to", "https://forgejo.coulomb.social",
"--sources", str(sources_path),
"--dry-run",
])
assert exit_code == 1
def test_cmd_federation_migrate_host_from_mismatch_errors(tmp_path):
from reuse_surface.cli import main
sources_path = tmp_path / "sources.yaml"
sources_path.write_text(
"version: 1\ndomain: helix_forge\ncollision_policy: warn\n"
"sources:\n- repo: activity-core\n url: https://forgejo.coulomb.social/coulomb/activity-core/raw/branch/main/registry/indexes/capabilities.yaml\n"
)
exit_code = main([
"federation", "migrate-host",
"--repo", "activity-core",
"--to", "https://forgejo.coulomb.social",
"--from", "gitea.coulomb.social",
"--sources", str(sources_path),
"--dry-run",
])
assert exit_code == 1