git commit -m "feat(update): add --silent mode with continue-on-failure and unified summary
Some checks failed
Mark stable commit / test-unit (push) Has been cancelled
Mark stable commit / test-integration (push) Has been cancelled
Mark stable commit / test-env-virtual (push) Has been cancelled
Mark stable commit / test-env-nix (push) Has been cancelled
Mark stable commit / test-e2e (push) Has been cancelled
Mark stable commit / test-virgin-user (push) Has been cancelled
Mark stable commit / test-virgin-root (push) Has been cancelled
Mark stable commit / lint-shell (push) Has been cancelled
Mark stable commit / lint-python (push) Has been cancelled
Mark stable commit / mark-stable (push) Has been cancelled
Some checks failed
Mark stable commit / test-unit (push) Has been cancelled
Mark stable commit / test-integration (push) Has been cancelled
Mark stable commit / test-env-virtual (push) Has been cancelled
Mark stable commit / test-env-nix (push) Has been cancelled
Mark stable commit / test-e2e (push) Has been cancelled
Mark stable commit / test-virgin-user (push) Has been cancelled
Mark stable commit / test-virgin-root (push) Has been cancelled
Mark stable commit / lint-shell (push) Has been cancelled
Mark stable commit / lint-python (push) Has been cancelled
Mark stable commit / mark-stable (push) Has been cancelled
- Introduce --silent flag for install/update to downgrade per-repo errors to warnings - Continue processing remaining repositories on pull/install failures - Emit a single summary at the end (suppress per-repo summaries during update) - Preserve interactive verification behavior when not silent - Add integration test covering silent vs non-silent update behavior - Update e2e tests to use --silent for stability" https://chatgpt.com/share/693ffcca-f680-800f-9f95-9d8c52a9a678
This commit is contained in:
110
tests/integration/test_update_silent_continues.py
Normal file
110
tests/integration/test_update_silent_continues.py
Normal file
@@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
from unittest.mock import patch
|
||||
|
||||
from pkgmgr.actions.update.manager import UpdateManager
|
||||
|
||||
|
||||
class TestUpdateSilentContinues(unittest.TestCase):
|
||||
def test_update_continues_on_failures_and_silent_controls_exit_code(self) -> None:
|
||||
"""
|
||||
Integration test for UpdateManager:
|
||||
- pull failure on repo A should not stop repo B/C
|
||||
- install failure on repo B should not stop repo C
|
||||
- without silent -> SystemExit(1) at end if any failures
|
||||
- with silent -> no SystemExit even if there are failures
|
||||
"""
|
||||
|
||||
repos = [
|
||||
{"provider": "github", "account": "example", "repository": "repo-a"},
|
||||
{"provider": "github", "account": "example", "repository": "repo-b"},
|
||||
{"provider": "github", "account": "example", "repository": "repo-c"},
|
||||
]
|
||||
|
||||
# We patch the internal calls used by UpdateManager:
|
||||
# - pull_with_verification is called once per repo
|
||||
# - install_repos is called once per repo that successfully pulled
|
||||
#
|
||||
# We simulate:
|
||||
# repo-a: pull fails
|
||||
# repo-b: pull ok, install fails
|
||||
# repo-c: pull ok, install ok
|
||||
pull_calls = []
|
||||
install_calls = []
|
||||
|
||||
def pull_side_effect(selected_repos, *_args, **_kwargs):
|
||||
# selected_repos is a list with exactly one repo in our implementation.
|
||||
repo = selected_repos[0]
|
||||
pull_calls.append(repo["repository"])
|
||||
if repo["repository"] == "repo-a":
|
||||
raise SystemExit(2)
|
||||
return None
|
||||
|
||||
def install_side_effect(selected_repos, *_args, **kwargs):
|
||||
repo = selected_repos[0]
|
||||
install_calls.append((repo["repository"], kwargs.get("silent"), kwargs.get("emit_summary")))
|
||||
if repo["repository"] == "repo-b":
|
||||
raise SystemExit(3)
|
||||
return None
|
||||
|
||||
# Patch at the exact import locations used inside UpdateManager.run()
|
||||
with patch("pkgmgr.actions.repository.pull.pull_with_verification", side_effect=pull_side_effect), patch(
|
||||
"pkgmgr.actions.install.install_repos", side_effect=install_side_effect
|
||||
):
|
||||
# 1) silent=True: should NOT raise (even though failures happened)
|
||||
UpdateManager().run(
|
||||
selected_repos=repos,
|
||||
repositories_base_dir="/tmp/repos",
|
||||
bin_dir="/tmp/bin",
|
||||
all_repos=repos,
|
||||
no_verification=True,
|
||||
system_update=False,
|
||||
preview=True,
|
||||
quiet=True,
|
||||
update_dependencies=False,
|
||||
clone_mode="shallow",
|
||||
silent=True,
|
||||
force_update=True,
|
||||
)
|
||||
|
||||
# Ensure it tried all pulls, and installs happened for B and C only.
|
||||
self.assertEqual(pull_calls, ["repo-a", "repo-b", "repo-c"])
|
||||
self.assertEqual([r for r, _silent, _emit in install_calls], ["repo-b", "repo-c"])
|
||||
|
||||
# Ensure UpdateManager suppressed install summary spam by passing emit_summary=False.
|
||||
for _repo_name, _silent, emit_summary in install_calls:
|
||||
self.assertFalse(emit_summary)
|
||||
|
||||
# Reset tracking for the non-silent run
|
||||
pull_calls.clear()
|
||||
install_calls.clear()
|
||||
|
||||
# 2) silent=False: should raise SystemExit(1) at end due to failures
|
||||
with self.assertRaises(SystemExit) as cm:
|
||||
UpdateManager().run(
|
||||
selected_repos=repos,
|
||||
repositories_base_dir="/tmp/repos",
|
||||
bin_dir="/tmp/bin",
|
||||
all_repos=repos,
|
||||
no_verification=True,
|
||||
system_update=False,
|
||||
preview=True,
|
||||
quiet=True,
|
||||
update_dependencies=False,
|
||||
clone_mode="shallow",
|
||||
silent=False,
|
||||
force_update=True,
|
||||
)
|
||||
self.assertEqual(cm.exception.code, 1)
|
||||
|
||||
# Still must have processed all repos (continue-on-failure behavior).
|
||||
self.assertEqual(pull_calls, ["repo-a", "repo-b", "repo-c"])
|
||||
self.assertEqual([r for r, _silent, _emit in install_calls], ["repo-b", "repo-c"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user