perf: 优化 Wiki 镜像增量同步 (#29)
This commit is contained in:
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user