GRM-111: feat: unified --become-password-file, --verbose, --no-status, labels fix
Post-merge / detect-type (push) Successful in 51s
Post-merge / release (push) Successful in 1m14s
Post-merge / validate-commit-msg (push) Successful in 1m14s
Post-merge / vikunja (push) Successful in 1m14s
Post-merge / badges (push) Successful in 1m25s
Post-merge / sync-wiki (push) Successful in 1m53s
Post-merge / configure-repo (push) Successful in 1m20s
Post-merge / publish (push) Successful in 1m21s

This commit was merged in pull request #178.
This commit is contained in:
2026-06-28 11:21:11 +00:00
parent 763f7640af
commit f67dff8458
16 changed files with 865 additions and 73 deletions
+82 -1
View File
@@ -137,6 +137,16 @@ class TestRunnerManager:
manager.install("host1", "root", token="tok", gitea_url="https://git.example.com")
assert "runner_labels" not in manager._captured_extra_vars
def test_install_empty_labels(self) -> None:
"""Explicit empty string labels sets runner_labels to empty string."""
mock_registry = MagicMock()
manager = RunnerManager(registry=mock_registry)
mock_executor = MagicMock()
manager._executor = mock_executor
manager.install("host1", "root", token="tok", gitea_url="https://git.example.com", labels="")
assert manager._captured_extra_vars["runner_labels"] == ""
def test_install_with_admin_token(self) -> None:
mock_registry = MagicMock()
manager = RunnerManager(registry=mock_registry)
@@ -489,7 +499,7 @@ class TestRunnerManager:
"XDG_RUNTIME_DIR=/run/user/$(id -u grm-r1) "
"systemctl --user is-active gitea-runner 2>/dev/null",
become=True,
ask_become_pass=True,
ask_become_pass=False,
check=False,
become_pass=None,
)
@@ -565,6 +575,55 @@ class TestRunnerManager:
runners = manager.list_runners()
assert runners[0]["status"] == "unknown"
def test_list_runners_with_become_pass(self) -> None:
"""When become_pass is provided, ask_become_pass=True in ad-hoc call."""
mock_registry = MagicMock()
mock_registry.list.return_value = {
"r1": {"host": "10.0.0.1", "user": "ubuntu", "key": None},
}
manager = RunnerManager(registry=mock_registry)
mock_executor = MagicMock()
mock_executor.run_ad_hoc.return_value = "active"
manager._executor = mock_executor
runners = manager.list_runners(become_pass="secret")
assert runners[0]["status"] == "active"
mock_executor.run_ad_hoc.assert_called_once_with(
"10.0.0.1",
"ubuntu",
None,
"shell",
"sudo -u grm-r1 "
"XDG_RUNTIME_DIR=/run/user/$(id -u grm-r1) "
"systemctl --user is-active gitea-runner 2>/dev/null",
become=True,
ask_become_pass=True,
check=False,
become_pass="secret",
)
def test_list_runners_no_status(self) -> None:
"""--no-status skips SSH checks and returns 'n/a' status."""
mock_registry = MagicMock()
mock_registry.list.return_value = {
"r1": {"host": "10.0.0.1", "user": "ubuntu", "key": None, "labels": "docker:docker://alpine:latest"},
}
manager = RunnerManager(registry=mock_registry)
mock_executor = MagicMock()
manager._executor = mock_executor
runners = manager.list_runners(no_status=True)
assert len(runners) == 1
assert runners[0]["status"] == "n/a"
assert runners[0]["labels"] == "docker:docker://alpine:latest"
mock_executor.run_ad_hoc.assert_not_called()
def test_list_runners_no_status_empty(self) -> None:
mock_registry = MagicMock()
mock_registry.list.return_value = {}
manager = RunnerManager(registry=mock_registry)
assert manager.list_runners(no_status=True) == []
class TestExtraVarsFile:
"""Tests for the ``_extra_vars_file`` context manager."""
@@ -624,6 +683,28 @@ class TestBuildCmd:
cmd = manager._build_cmd("test.yml", "host1", "user1", "/tmp/vars.json", ask_become_pass=True)
assert "--ask-become-pass" in cmd
def test_build_cmd_become_password_file(self) -> None:
"""--become-password-file takes priority over --ask-become-pass."""
manager = RunnerManager()
with patch.object(Path, "exists", return_value=True):
cmd = manager._build_cmd(
"test.yml",
"host1",
"user1",
"/tmp/vars.json",
ask_become_pass=True,
become_password_file="/tmp/pw.txt",
)
assert "--become-password-file" in cmd
assert "/tmp/pw.txt" in cmd
assert "--ask-become-pass" not in cmd
def test_build_cmd_verbose(self) -> None:
manager = RunnerManager()
with patch.object(Path, "exists", return_value=True):
cmd = manager._build_cmd("test.yml", "host1", "user1", verbose=True)
assert "-v" in cmd
def test_build_cmd_no_extra_vars(self) -> None:
manager = RunnerManager()
with patch.object(Path, "exists", return_value=True):