GRM-7: feat: integrate AnsibleExecutor and i18n into CLI and RunnerManager
This commit is contained in:
+18
-4
@@ -19,7 +19,7 @@ class TestCLI:
|
||||
mock_manager = MagicMock()
|
||||
mock_manager_class.return_value = mock_manager
|
||||
|
||||
runner = CliRunner(env={"GITEA_URL": "https://git.example.com"})
|
||||
runner = CliRunner(env={"GITEA_URL": "https://git.example.com", "GITEA_ADMIN_TOKEN": ""})
|
||||
result = runner.invoke(cli, ["install", "host1", "--user", "ubuntu", "--token", "tok"])
|
||||
assert result.exit_code == 0
|
||||
mock_manager.install.assert_called_once_with(
|
||||
@@ -30,6 +30,8 @@ class TestCLI:
|
||||
token="tok",
|
||||
gitea_url="https://git.example.com",
|
||||
mode="docker",
|
||||
admin_token="",
|
||||
integration_retries=3,
|
||||
ask_become_pass=False,
|
||||
)
|
||||
|
||||
@@ -43,6 +45,12 @@ class TestCLI:
|
||||
|
||||
@patch("gitea_runner_manager.cli.RunnerManager")
|
||||
def test_install_missing_token(self, mock_manager_class: MagicMock) -> None:
|
||||
mock_manager = MagicMock()
|
||||
from gitea_runner_manager.exceptions import AnsibleError
|
||||
|
||||
mock_manager.install.side_effect = AnsibleError("GITEA_REGISTRATION_TOKEN must be set (or pass --token)")
|
||||
mock_manager_class.return_value = mock_manager
|
||||
|
||||
with patch.dict("os.environ", {"GITEA_URL": "https://git.example.com"}, clear=True):
|
||||
runner = CliRunner()
|
||||
result = runner.invoke(cli, ["install", "host1", "--user", "ubuntu"])
|
||||
@@ -54,7 +62,7 @@ class TestCLI:
|
||||
mock_manager = MagicMock()
|
||||
mock_manager_class.return_value = mock_manager
|
||||
|
||||
runner = CliRunner(env={"GITEA_URL": "https://git.example.com"})
|
||||
runner = CliRunner(env={"GITEA_URL": "https://git.example.com", "GITEA_ADMIN_TOKEN": ""})
|
||||
result = runner.invoke(
|
||||
cli,
|
||||
[
|
||||
@@ -79,6 +87,8 @@ class TestCLI:
|
||||
token="tok",
|
||||
gitea_url="https://git.example.com",
|
||||
mode="docker",
|
||||
admin_token="",
|
||||
integration_retries=3,
|
||||
ask_become_pass=False,
|
||||
)
|
||||
|
||||
@@ -87,7 +97,7 @@ class TestCLI:
|
||||
mock_manager = MagicMock()
|
||||
mock_manager_class.return_value = mock_manager
|
||||
|
||||
runner = CliRunner(env={"GITEA_URL": "https://git.example.com"})
|
||||
runner = CliRunner(env={"GITEA_URL": "https://git.example.com", "GITEA_ADMIN_TOKEN": ""})
|
||||
result = runner.invoke(cli, ["install", "host1", "--user", "ubuntu", "--token", "tok", "--ask-become-pass"])
|
||||
assert result.exit_code == 0
|
||||
mock_manager.install.assert_called_once_with(
|
||||
@@ -98,6 +108,8 @@ class TestCLI:
|
||||
token="tok",
|
||||
gitea_url="https://git.example.com",
|
||||
mode="docker",
|
||||
admin_token="",
|
||||
integration_retries=3,
|
||||
ask_become_pass=True,
|
||||
)
|
||||
|
||||
@@ -106,7 +118,7 @@ class TestCLI:
|
||||
mock_manager = MagicMock()
|
||||
mock_manager_class.return_value = mock_manager
|
||||
|
||||
runner = CliRunner(env={"GITEA_URL": "https://git.example.com"})
|
||||
runner = CliRunner(env={"GITEA_URL": "https://git.example.com", "GITEA_ADMIN_TOKEN": ""})
|
||||
result = runner.invoke(cli, ["install", "host1", "--user", "ubuntu", "--token", "tok", "--mode", "binary"])
|
||||
assert result.exit_code == 0
|
||||
mock_manager.install.assert_called_once_with(
|
||||
@@ -117,6 +129,8 @@ class TestCLI:
|
||||
token="tok",
|
||||
gitea_url="https://git.example.com",
|
||||
mode="binary",
|
||||
admin_token="",
|
||||
integration_retries=3,
|
||||
ask_become_pass=False,
|
||||
)
|
||||
|
||||
|
||||
@@ -13,62 +13,64 @@ class TestRunnerManager:
|
||||
def test_init(self) -> None:
|
||||
manager = RunnerManager()
|
||||
assert manager is not None
|
||||
assert manager._executor is not None
|
||||
|
||||
def test_install_basic(self) -> None:
|
||||
manager = RunnerManager()
|
||||
mock_executor = MagicMock()
|
||||
manager._executor = mock_executor
|
||||
|
||||
with patch("subprocess.run") as mock_run:
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
manager.install("192.168.1.10", "ubuntu", token="tok", gitea_url="https://git.example.com")
|
||||
mock_run.assert_called_once()
|
||||
cmd = mock_run.call_args[0][0]
|
||||
cmd_str = " ".join(cmd)
|
||||
assert "ansible-playbook" in cmd_str
|
||||
assert "192.168.1.10," in cmd_str
|
||||
assert "-u" in cmd_str
|
||||
assert "ubuntu" in cmd_str
|
||||
assert "registration_token=tok" in cmd_str
|
||||
assert "runner_name=192.168.1.10" in cmd_str
|
||||
assert "gitea_url=https://git.example.com" in cmd_str
|
||||
assert "runner_mode=docker" in cmd_str
|
||||
manager.install("192.168.1.10", "ubuntu", token="tok", gitea_url="https://git.example.com")
|
||||
mock_executor.run.assert_called_once()
|
||||
cmd = mock_executor.run.call_args.args[0]
|
||||
cmd_str = " ".join(cmd)
|
||||
assert "ansible-playbook" in cmd_str
|
||||
assert "192.168.1.10," in cmd_str
|
||||
assert "-u" in cmd_str
|
||||
assert "ubuntu" in cmd_str
|
||||
assert "registration_token=tok" in cmd_str
|
||||
assert "runner_name=192.168.1.10" in cmd_str
|
||||
assert "gitea_url=https://git.example.com" in cmd_str
|
||||
assert "runner_mode=docker" in cmd_str
|
||||
assert "Installing Gitea Runner on 192.168.1.10" in mock_executor.run.call_args.kwargs["description"]
|
||||
|
||||
def test_install_with_name_and_key(self) -> None:
|
||||
manager = RunnerManager()
|
||||
mock_executor = MagicMock()
|
||||
manager._executor = mock_executor
|
||||
|
||||
with patch("subprocess.run") as mock_run:
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
manager.install(
|
||||
"host1", "root", key="/key", name="my-runner", token="preset", gitea_url="https://git.example.com"
|
||||
)
|
||||
cmd = mock_run.call_args[0][0]
|
||||
cmd_str = " ".join(cmd)
|
||||
assert "--private-key" in cmd_str
|
||||
assert "/key" in cmd_str
|
||||
assert "registration_token=preset" in cmd_str
|
||||
assert "runner_name=my-runner" in cmd_str
|
||||
assert "runner_mode=docker" in cmd_str
|
||||
assert "--ask-become-pass" not in cmd_str
|
||||
manager.install(
|
||||
"host1", "root", key="/key", name="my-runner", token="preset", gitea_url="https://git.example.com"
|
||||
)
|
||||
cmd = mock_executor.run.call_args.args[0]
|
||||
cmd_str = " ".join(cmd)
|
||||
assert "--private-key" in cmd_str
|
||||
assert "/key" in cmd_str
|
||||
assert "registration_token=preset" in cmd_str
|
||||
assert "runner_name=my-runner" in cmd_str
|
||||
assert "runner_mode=docker" in cmd_str
|
||||
assert "--ask-become-pass" not in cmd_str
|
||||
|
||||
def test_install_ask_become_pass(self) -> None:
|
||||
manager = RunnerManager()
|
||||
mock_executor = MagicMock()
|
||||
manager._executor = mock_executor
|
||||
|
||||
with patch("subprocess.run") as mock_run:
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
manager.install("host1", "root", token="tok", gitea_url="https://git.example.com", ask_become_pass=True)
|
||||
cmd = mock_run.call_args[0][0]
|
||||
cmd_str = " ".join(cmd)
|
||||
assert "--ask-become-pass" in cmd_str
|
||||
assert "runner_mode=docker" in cmd_str
|
||||
manager.install("host1", "root", token="tok", gitea_url="https://git.example.com", ask_become_pass=True)
|
||||
cmd = mock_executor.run.call_args.args[0]
|
||||
cmd_str = " ".join(cmd)
|
||||
assert "--ask-become-pass" in cmd_str
|
||||
assert "runner_mode=docker" in cmd_str
|
||||
|
||||
def test_install_binary_mode(self) -> None:
|
||||
manager = RunnerManager()
|
||||
mock_executor = MagicMock()
|
||||
manager._executor = mock_executor
|
||||
|
||||
with patch("subprocess.run") as mock_run:
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
manager.install("host1", "root", token="tok", gitea_url="https://git.example.com", mode="binary")
|
||||
cmd = mock_run.call_args[0][0]
|
||||
cmd_str = " ".join(cmd)
|
||||
assert "runner_mode=binary" in cmd_str
|
||||
manager.install("host1", "root", token="tok", gitea_url="https://git.example.com", mode="binary")
|
||||
cmd = mock_executor.run.call_args.args[0]
|
||||
cmd_str = " ".join(cmd)
|
||||
assert "runner_mode=binary" in cmd_str
|
||||
|
||||
def test_install_missing_token(self) -> None:
|
||||
manager = RunnerManager()
|
||||
@@ -81,45 +83,60 @@ class TestRunnerManager:
|
||||
with pytest.raises(AnsibleError, match="Playbook not found"):
|
||||
manager.install("host", "user", token="tok")
|
||||
|
||||
def test_install_with_admin_token(self) -> None:
|
||||
manager = RunnerManager()
|
||||
mock_executor = MagicMock()
|
||||
manager._executor = mock_executor
|
||||
|
||||
manager.install("host1", "root", token="tok", gitea_url="https://git.example.com", admin_token="admin-tok")
|
||||
cmd = mock_executor.run.call_args.args[0]
|
||||
cmd_str = " ".join(cmd)
|
||||
assert "gitea_admin_token=admin-tok" in cmd_str
|
||||
|
||||
def test_install_ansible_failure(self) -> None:
|
||||
manager = RunnerManager()
|
||||
with patch("subprocess.run") as mock_run:
|
||||
mock_run.return_value = MagicMock(returncode=1)
|
||||
with pytest.raises(AnsibleError, match="Ansible failed with exit code 1"):
|
||||
manager.install("host", "user", token="tok")
|
||||
mock_executor = MagicMock()
|
||||
manager._executor = mock_executor
|
||||
mock_executor.run.side_effect = AnsibleError("Ansible failed with exit code 1. See full log: /tmp/test.log")
|
||||
with pytest.raises(AnsibleError, match="Ansible failed with exit code 1"):
|
||||
manager.install("host", "user", token="tok")
|
||||
|
||||
def test_update(self) -> None:
|
||||
manager = RunnerManager()
|
||||
with patch("subprocess.run") as mock_run:
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
manager.update("host", "user", key="/key", version="v0.2.0")
|
||||
cmd = mock_run.call_args[0][0]
|
||||
cmd_str = " ".join(cmd)
|
||||
assert "update-runner.yml" in cmd_str
|
||||
assert "--private-key" in cmd_str
|
||||
assert "/key" in cmd_str
|
||||
assert "gitea_runner_version=v0.2.0" in cmd_str
|
||||
assert "runner_mode=docker" in cmd_str
|
||||
assert "--ask-become-pass" not in cmd_str
|
||||
mock_executor = MagicMock()
|
||||
manager._executor = mock_executor
|
||||
|
||||
manager.update("host", "user", key="/key", version="v0.2.0")
|
||||
cmd = mock_executor.run.call_args.args[0]
|
||||
cmd_str = " ".join(cmd)
|
||||
assert "update-runner.yml" in cmd_str
|
||||
assert "--private-key" in cmd_str
|
||||
assert "/key" in cmd_str
|
||||
assert "gitea_runner_version=v0.2.0" in cmd_str
|
||||
assert "runner_mode=docker" in cmd_str
|
||||
assert "--ask-become-pass" not in cmd_str
|
||||
assert "Updating Gitea Runner on host" in mock_executor.run.call_args.kwargs["description"]
|
||||
|
||||
def test_update_ask_become_pass(self) -> None:
|
||||
manager = RunnerManager()
|
||||
with patch("subprocess.run") as mock_run:
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
manager.update("host", "user", ask_become_pass=True)
|
||||
cmd = mock_run.call_args[0][0]
|
||||
cmd_str = " ".join(cmd)
|
||||
assert "--ask-become-pass" in cmd_str
|
||||
assert "runner_mode=docker" in cmd_str
|
||||
mock_executor = MagicMock()
|
||||
manager._executor = mock_executor
|
||||
|
||||
manager.update("host", "user", ask_become_pass=True)
|
||||
cmd = mock_executor.run.call_args.args[0]
|
||||
cmd_str = " ".join(cmd)
|
||||
assert "--ask-become-pass" in cmd_str
|
||||
assert "runner_mode=docker" in cmd_str
|
||||
|
||||
def test_update_binary_mode(self) -> None:
|
||||
manager = RunnerManager()
|
||||
with patch("subprocess.run") as mock_run:
|
||||
mock_run.return_value = MagicMock(returncode=0)
|
||||
manager.update("host", "user", mode="binary")
|
||||
cmd = mock_run.call_args[0][0]
|
||||
cmd_str = " ".join(cmd)
|
||||
assert "runner_mode=binary" in cmd_str
|
||||
mock_executor = MagicMock()
|
||||
manager._executor = mock_executor
|
||||
|
||||
manager.update("host", "user", mode="binary")
|
||||
cmd = mock_executor.run.call_args.args[0]
|
||||
cmd_str = " ".join(cmd)
|
||||
assert "runner_mode=binary" in cmd_str
|
||||
|
||||
def test_update_playbook_not_found(self) -> None:
|
||||
manager = RunnerManager()
|
||||
@@ -129,7 +146,40 @@ class TestRunnerManager:
|
||||
|
||||
def test_update_ansible_failure(self) -> None:
|
||||
manager = RunnerManager()
|
||||
with patch("subprocess.run") as mock_run:
|
||||
mock_run.return_value = MagicMock(returncode=2)
|
||||
with pytest.raises(AnsibleError, match="Ansible failed with exit code 2"):
|
||||
manager.update("host", "user")
|
||||
mock_executor = MagicMock()
|
||||
manager._executor = mock_executor
|
||||
mock_executor.run.side_effect = AnsibleError("Ansible failed with exit code 2. See full log: /tmp/test.log")
|
||||
with pytest.raises(AnsibleError, match="Ansible failed with exit code 2"):
|
||||
manager.update("host", "user")
|
||||
|
||||
|
||||
class TestBuildCmd:
|
||||
def test_build_cmd_basic(self) -> None:
|
||||
manager = RunnerManager()
|
||||
with patch.object(Path, "exists", return_value=True):
|
||||
cmd = manager._build_cmd("test.yml", "host1", "user1", "foo=bar")
|
||||
cmd_str = " ".join(cmd)
|
||||
assert "ansible-playbook" in cmd_str
|
||||
assert "test.yml" in cmd_str
|
||||
assert "host1," in cmd_str
|
||||
assert "user1" in cmd_str
|
||||
assert "foo=bar" in cmd_str
|
||||
|
||||
def test_build_cmd_with_key(self) -> None:
|
||||
manager = RunnerManager()
|
||||
with patch.object(Path, "exists", return_value=True):
|
||||
cmd = manager._build_cmd("test.yml", "host1", "user1", "foo=bar", key="/key")
|
||||
assert "--private-key" in cmd
|
||||
assert "/key" in cmd
|
||||
|
||||
def test_build_cmd_ask_become_pass(self) -> None:
|
||||
manager = RunnerManager()
|
||||
with patch.object(Path, "exists", return_value=True):
|
||||
cmd = manager._build_cmd("test.yml", "host1", "user1", "foo=bar", ask_become_pass=True)
|
||||
assert "--ask-become-pass" in cmd
|
||||
|
||||
def test_build_cmd_playbook_not_found(self) -> None:
|
||||
manager = RunnerManager()
|
||||
with patch.object(Path, "exists", return_value=False):
|
||||
with pytest.raises(AnsibleError, match="Playbook not found"):
|
||||
manager._build_cmd("missing.yml", "host1", "user1", "foo=bar")
|
||||
|
||||
Reference in New Issue
Block a user