AI Implementation feature(1089): Scheduled Execution with Cron and Retry Handling (#9)

This commit was merged in pull request #9.
This commit is contained in:
2026-08-04 20:48:16 +00:00
parent 3545b81546
commit 5f6ddf76a4
27 changed files with 644 additions and 272 deletions
+8 -7
View File
@@ -10,6 +10,7 @@ from git import GitCommandError, InvalidGitRepositoryError, Repo
from tenbackward.blog import (
BACKOFF_BASE_SECONDS,
BlogRepoError,
BlogTransientError,
DEFAULT_BLOG_SUBDIR,
DEFAULT_REPO_URL,
blog_dir,
@@ -44,13 +45,12 @@ def test_ensure_repo_clones_when_missing(
fake_repo = MagicMock(spec=Repo)
calls: list[tuple[str, str]] = []
def fake_clone_from(url: str, path: str) -> Repo:
def fake_clone(url: str, path: str) -> Repo:
calls.append((url, path))
target.mkdir(parents=True)
(target / ".git").mkdir()
return fake_repo
monkeypatch.setattr("tenbackward.blog.Repo.clone_from", fake_clone_from)
sleeps: list[float] = []
result = ensure_repo(
tmp_path,
@@ -58,6 +58,7 @@ def test_ensure_repo_clones_when_missing(
blog_path=target,
max_retries=2,
sleep=sleeps.append,
clone_impl=fake_clone,
)
assert result is fake_repo
assert calls == [("https://example.com/repo.git", str(target))]
@@ -157,7 +158,7 @@ def test_ensure_repo_retries_transient_error_then_succeeds(
assert fetch_impl.call_count == 2
pull_impl.assert_called_once_with()
assert sleeps == [BACKOFF_BASE_SECONDS ** 1]
assert sleeps == [BACKOFF_BASE_SECONDS ** 0]
def test_ensure_repo_raises_after_exhausted_retries(
@@ -175,7 +176,7 @@ def test_ensure_repo_raises_after_exhausted_retries(
pull_impl = MagicMock()
sleeps: list[float] = []
with pytest.raises(BlogRepoError, match="blog fetch/pull failed"):
with pytest.raises(BlogTransientError, match="git pull failed"):
ensure_repo(
tmp_path,
repo_url="https://example.com/repo.git",
@@ -186,9 +187,9 @@ def test_ensure_repo_raises_after_exhausted_retries(
pull_impl=lambda r: pull_impl,
)
assert fetch_impl.call_count == 3
assert fetch_impl.call_count == 2
pull_impl.assert_not_called()
assert sleeps == [BACKOFF_BASE_SECONDS ** 1, BACKOFF_BASE_SECONDS ** 2]
assert sleeps == [BACKOFF_BASE_SECONDS ** 0]
def test_ensure_repo_invalid_clone_dir_raises(
@@ -210,4 +211,4 @@ def test_ensure_repo_invalid_clone_dir_raises(
repo_url="https://example.com/repo.git",
blog_path=target,
max_retries=0,
)
)