perf: 优化 Wiki 镜像增量同步 (#29)

This commit is contained in:
ila
2026-09-02 09:38:09 +08:00
parent 4bbacf4d7f
commit cbdd27d861
5 changed files with 297 additions and 26 deletions
+161
View File
@@ -5,6 +5,7 @@ import os
import sys
import tempfile
import unittest
from argparse import Namespace
from pathlib import Path
from unittest.mock import Mock, patch
@@ -17,6 +18,7 @@ from harness import ( # noqa: E402
existing_task_mirrors,
export_task_archives,
main as harness_main,
run_sync,
safe_title,
task_target,
)
@@ -122,6 +124,165 @@ class MirrorTests(unittest.TestCase):
sync_all(config, client)
client.get_page.assert_not_called()
@patch("wiki_docs.dirty_mirror_paths", return_value=[])
def test_incremental_sync_lists_once_and_skips_unchanged_body(self, _dirty) -> None:
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
target = root / "docs" / "README.md"
target.parent.mkdir(parents=True)
target.write_text(render_mirror(self.page), encoding="utf-8")
config = Config(
path=root / "wiki-docs.json",
gitea_url="http://gitea.example",
owner="o",
repository="r",
mappings=(Mapping("Home", "docs/README.md"),),
)
client = Mock()
client.list_pages.return_value = [
{
"title": "Home",
"sub_url": "Home",
"last_commit": {"sha": self.page.revision},
}
]
with patch("wiki_docs.ROOT", root):
messages = sync_all(config, client)
self.assertTrue(messages[0].startswith("无变化:"))
client.list_pages.assert_called_once_with()
client.get_page_from_metadata.assert_not_called()
@patch("wiki_docs.dirty_mirror_paths", return_value=[])
def test_incremental_sync_fetches_changed_page(self, _dirty) -> None:
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
target = root / "docs" / "README.md"
target.parent.mkdir(parents=True)
target.write_text(render_mirror(self.page), encoding="utf-8")
changed = WikiPage(
title="Home",
sub_url="Home",
text="# 新首页\n",
revision="b" * 40,
html_url=self.page.html_url,
)
metadata = {
"title": "Home",
"sub_url": "Home",
"last_commit": {"sha": changed.revision},
}
config = Config(
path=root / "wiki-docs.json",
gitea_url="http://gitea.example",
owner="o",
repository="r",
mappings=(Mapping("Home", "docs/README.md"),),
)
client = Mock()
client.list_pages.return_value = [metadata]
client.get_page_from_metadata.return_value = changed
with patch("wiki_docs.ROOT", root):
messages = sync_all(config, client)
_metadata, body = parse_mirror(target.read_text(encoding="utf-8"))
self.assertTrue(messages[0].startswith("已更新:"))
self.assertEqual(body, changed.text)
client.get_page_from_metadata.assert_called_once_with(metadata, "Home")
@patch("wiki_docs.dirty_mirror_paths", return_value=[])
def test_sync_fetches_when_remote_revision_is_missing(self, _dirty) -> None:
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
target = root / "docs" / "README.md"
target.parent.mkdir(parents=True)
target.write_text(render_mirror(self.page), encoding="utf-8")
metadata = {"title": "Home", "sub_url": "Home"}
config = Config(
path=root / "wiki-docs.json",
gitea_url="http://gitea.example",
owner="o",
repository="r",
mappings=(Mapping("Home", "docs/README.md"),),
)
client = Mock()
client.list_pages.return_value = [metadata]
client.get_page_from_metadata.return_value = self.page
with patch("wiki_docs.ROOT", root):
sync_all(config, client)
client.get_page_from_metadata.assert_called_once_with(metadata, "Home")
@patch("wiki_docs.dirty_mirror_paths", return_value=[])
def test_sync_fetches_when_local_metadata_is_invalid(self, _dirty) -> None:
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
target = root / "docs" / "README.md"
target.parent.mkdir(parents=True)
invalid = render_mirror(self.page).replace(
"wiki_page: Home", "wiki_page: Wrong"
)
target.write_text(invalid, encoding="utf-8")
metadata = {
"title": "Home",
"sub_url": "Home",
"last_commit": {"sha": self.page.revision},
}
config = Config(
path=root / "wiki-docs.json",
gitea_url="http://gitea.example",
owner="o",
repository="r",
mappings=(Mapping("Home", "docs/README.md"),),
)
client = Mock()
client.list_pages.return_value = [metadata]
client.get_page_from_metadata.return_value = self.page
with patch("wiki_docs.ROOT", root):
sync_all(config, client)
client.get_page_from_metadata.assert_called_once_with(metadata, "Home")
def test_deep_check_fetches_unchanged_page_body(self) -> None:
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
target = root / "docs" / "README.md"
target.parent.mkdir(parents=True)
target.write_text(render_mirror(self.page), encoding="utf-8")
metadata = {
"title": "Home",
"sub_url": "Home",
"last_commit": {"sha": self.page.revision},
}
config = Config(
path=root / "wiki-docs.json",
gitea_url="http://gitea.example",
owner="o",
repository="r",
mappings=(Mapping("Home", "docs/README.md"),),
)
client = Mock()
client.list_pages.return_value = [metadata]
client.get_page_from_metadata.return_value = self.page
with patch("wiki_docs.ROOT", root):
sync_all(config, client, check=True, deep_check=True)
client.list_pages.assert_called_once_with()
client.get_page_from_metadata.assert_called_once_with(metadata, "Home")
@patch("harness.run_check", return_value=0)
@patch("harness.sync_all", return_value=["已更新:docs/README.md"])
@patch("harness.WikiClient")
@patch("harness.load_config")
def test_verify_reuses_one_deep_sync(
self, load, client_class, sync, check
) -> None:
config = Mock()
load.return_value = config
result = run_sync(
Namespace(verify=True, check=False, deep_check=False, config="config.json")
)
self.assertEqual(result, 0)
sync.assert_called_once_with(
config, client_class.return_value, check=False, deep_check=True
)
check.assert_called_once()
class WikiClientTests(unittest.TestCase):
def test_encoded_unicode_sub_url_is_not_double_encoded(self) -> None: