113 lines
4.8 KiB
Python
113 lines
4.8 KiB
Python
import subprocess
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
import tools.sync.wiki_git as wiki_git
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"value", ["", "../master", "-main", "a..b", "a b", "a.lock", "a/@{x", "a//b"]
|
|
)
|
|
def test_invalid_branch_configuration_is_rejected(monkeypatch, value):
|
|
monkeypatch.setenv("EXPECTED_GITEA_BRANCH", value)
|
|
with pytest.raises(RuntimeError, match="EXPECTED_GITEA_BRANCH"):
|
|
wiki_git.expected_branch()
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
"url",
|
|
[
|
|
"git@git.kemt.fei.tuke.sk:jp170na/zpwiki.git",
|
|
"ssh://git@git.kemt.fei.tuke.sk/jp170na/zpwiki.git",
|
|
"https://git.kemt.fei.tuke.sk/jp170na/zpwiki",
|
|
],
|
|
)
|
|
def test_repository_identity_from_transport_url(url):
|
|
assert wiki_git.repository_from_url(url) == "jp170na/zpwiki"
|
|
|
|
|
|
def test_real_git_fetch_fast_forward_and_local_change_protection(tmp_path, monkeypatch):
|
|
run = subprocess.run
|
|
|
|
def git(root, *args):
|
|
return run(
|
|
["git", "-C", str(root), *args], capture_output=True, text=True, check=True
|
|
).stdout.strip()
|
|
|
|
bare, author, checkout = (tmp_path / name for name in ("remote.git", "author", "checkout"))
|
|
run(["git", "init", "--bare", str(bare)], check=True, capture_output=True)
|
|
run(["git", "clone", str(bare), str(author)], check=True, capture_output=True)
|
|
git(author, "checkout", "-b", "master")
|
|
git(author, "config", "user.name", "Sync test")
|
|
git(author, "config", "user.email", "sync@example.test")
|
|
(author / "README.md").write_text("old")
|
|
git(author, "add", ".")
|
|
git(author, "commit", "-m", "initial")
|
|
git(author, "push", "origin", "master")
|
|
run(["git", "clone", str(bare), str(checkout)], check=True, capture_output=True)
|
|
git(checkout, "remote", "set-url", "origin", "git@example.test:KEMT/zpwiki.git")
|
|
(author / "README.md").write_text("new")
|
|
git(author, "commit", "-am", "update")
|
|
git(author, "push", "origin", "master")
|
|
wanted = git(author, "rev-parse", "HEAD")
|
|
|
|
# Exercise real Git fetch/merge against a local bare remote. Only transport
|
|
# is redirected, so the production origin/branch validation still runs.
|
|
def local_transport(args, **kw):
|
|
if args[:2] == ["git", "fetch"]:
|
|
args = [str(bare) if arg == "origin" else arg for arg in args]
|
|
return run(args, **kw)
|
|
|
|
monkeypatch.setattr(wiki_git.subprocess, "run", local_transport)
|
|
wiki_git.update_wiki(checkout)
|
|
assert git(checkout, "rev-parse", "HEAD") == wanted
|
|
assert (checkout / "README.md").read_text() == "new"
|
|
(checkout / "untracked.md").write_text("local notes")
|
|
with pytest.raises(RuntimeError, match="lokálne zmeny"):
|
|
wiki_git.update_wiki(checkout)
|
|
(checkout / "untracked.md").unlink()
|
|
(checkout / "README.md").write_text("local modification")
|
|
with pytest.raises(RuntimeError, match="lokálne zmeny"):
|
|
wiki_git.update_wiki(checkout)
|
|
assert (checkout / "README.md").read_text() == "local modification"
|
|
git(checkout, "restore", "README.md")
|
|
monkeypatch.setenv("EXPECTED_GITEA_BRANCH", "other")
|
|
with pytest.raises(RuntimeError, match="Aktívna Git vetva"):
|
|
wiki_git.update_wiki(checkout)
|
|
monkeypatch.setenv("EXPECTED_GITEA_BRANCH", "master")
|
|
monkeypatch.setenv("EXPECTED_GITEA_REPOSITORY", "OTHER/zpwiki")
|
|
with pytest.raises(RuntimeError, match="origin nezodpovedá"):
|
|
wiki_git.update_wiki(checkout)
|
|
monkeypatch.setenv("EXPECTED_GITEA_REPOSITORY", "KEMT/zpwiki")
|
|
git(checkout, "config", "user.name", "Local author")
|
|
git(checkout, "config", "user.email", "local@example.test")
|
|
(checkout / "local.md").write_text("local commit")
|
|
git(checkout, "add", "local.md")
|
|
git(checkout, "commit", "-m", "local")
|
|
local_head = git(checkout, "rev-parse", "HEAD")
|
|
(author / "README.md").write_text("remote update")
|
|
git(author, "commit", "-am", "remote")
|
|
git(author, "push", "origin", "master")
|
|
with pytest.raises(RuntimeError, match="Git operácia merge zlyhala"):
|
|
wiki_git.update_wiki(checkout)
|
|
assert git(checkout, "rev-parse", "HEAD") == local_head
|
|
assert (checkout / "local.md").read_text() == "local commit"
|
|
|
|
|
|
def test_upstream_sync_rejects_wrong_destination_before_any_write(tmp_path, monkeypatch):
|
|
root = tmp_path / "wiki"
|
|
(root / ".git").mkdir(parents=True)
|
|
monkeypatch.setenv("SYNC_UPSTREAM_FORK", "1")
|
|
seen = []
|
|
def run(args, **kwargs):
|
|
seen.append(args)
|
|
output = {"remote": "git@git.kemt.fei.tuke.sk:KEMT/zpwiki.git",
|
|
"branch": "master", "status": ""}.get(args[1], "")
|
|
return subprocess.CompletedProcess(args, 0, stdout=output, stderr="")
|
|
monkeypatch.setattr(wiki_git.subprocess, "run", run)
|
|
with pytest.raises(RuntimeError, match="restricted"):
|
|
wiki_git.update_wiki(root)
|
|
assert len(seen) == 3
|
|
assert all(args[0] == "git" for args in seen)
|