Files
kumacli/tests/test_cli_integration.py
Pim van Pelt e2e65add2e Add tests
2025-08-02 20:03:32 +02:00

254 lines
9.3 KiB
Python

#!/usr/bin/env python3
import pytest
from unittest.mock import Mock, patch, MagicMock
import argparse
from io import StringIO
import sys
from kumacli.cmd.monitor import setup_monitor_parser, handle_monitor_command
from kumacli.cmd.maintenance import setup_maintenance_parser, handle_maintenance_command
from kumacli.cmd.info import setup_info_parser, handle_info_command
class TestCLIIntegration:
def test_monitor_parser_setup(self):
"""Test monitor parser setup"""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="resource")
monitor_parser = setup_monitor_parser(subparsers)
# Verify parser is created
assert monitor_parser is not None
assert hasattr(setup_monitor_parser, '_parser')
def test_maintenance_parser_setup(self):
"""Test maintenance parser setup"""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="resource")
maintenance_parser = setup_maintenance_parser(subparsers)
# Verify parser is created
assert maintenance_parser is not None
assert hasattr(setup_maintenance_parser, '_parser')
def test_info_parser_setup(self):
"""Test info parser setup"""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="resource")
info_parser = setup_info_parser(subparsers)
# Verify parser is created
assert info_parser is not None
def test_monitor_help_message(self, mock_client, capsys):
"""Test monitor command shows help when no action specified"""
# Setup
mock_args = Mock()
mock_args.monitor_action = None
# Setup parser reference
mock_parser = Mock()
setup_monitor_parser._parser = mock_parser
# Execute
result = handle_monitor_command(mock_args, mock_client)
# Verify
assert result is False
mock_parser.print_help.assert_called_once()
def test_maintenance_help_message(self, mock_client, capsys):
"""Test maintenance command shows help when no action specified"""
# Setup
mock_args = Mock()
mock_args.maintenance_action = None
# Setup parser reference
mock_parser = Mock()
setup_maintenance_parser._parser = mock_parser
# Execute
result = handle_maintenance_command(mock_args, mock_client)
# Verify
assert result is False
mock_parser.print_help.assert_called_once()
def test_monitor_command_with_full_args(self, mock_client):
"""Test monitor command with complete argument structure"""
# Setup
mock_args = Mock()
mock_args.monitor_action = "pause"
mock_args.monitor = ["test*"]
mock_args.group = ["web-services"]
# Mock client methods
mock_client.find_monitors_by_pattern.return_value = [
{"id": 1, "name": "test-monitor"}
]
mock_client.get_monitors_in_groups.return_value = [
{"id": 2, "name": "web-service-monitor"}
]
mock_client.api.pause_monitor.return_value = {"msg": "Paused Successfully."}
# Execute
result = handle_monitor_command(mock_args, mock_client)
# Verify
assert result is True
mock_client.find_monitors_by_pattern.assert_called_once_with(["test*"])
mock_client.get_monitors_in_groups.assert_called_once_with(["web-services"])
# Should pause both monitors (deduplicated)
assert mock_client.api.pause_monitor.call_count == 2
def test_resume_all_monitors_integration(self, mock_client, mock_monitors):
"""Test resume all monitors integration"""
# Setup
mock_args = Mock()
mock_args.monitor_action = "resume"
mock_args.monitor = None
mock_args.group = None
mock_args.all = True
mock_client.api.get_monitors.return_value = mock_monitors
mock_client.api.resume_monitor.return_value = {"msg": "Resumed Successfully."}
# Execute
result = handle_monitor_command(mock_args, mock_client)
# Verify
assert result is True
mock_client.api.get_monitors.assert_called_once()
# Should resume only paused monitors (ID 2 and 4 from mock_monitors)
assert mock_client.api.resume_monitor.call_count == 2
mock_client.api.resume_monitor.assert_any_call(2)
mock_client.api.resume_monitor.assert_any_call(4)
class TestArgumentParsing:
def test_monitor_list_arguments(self):
"""Test monitor list command argument parsing"""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="resource")
setup_monitor_parser(subparsers)
# Test with monitor patterns
args = parser.parse_args(["monitor", "list", "--monitor", "web*", "--monitor", "api*"])
assert args.resource == "monitor"
assert args.monitor_action == "list"
assert args.monitor == ["web*", "api*"]
def test_monitor_pause_arguments(self):
"""Test monitor pause command argument parsing"""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="resource")
setup_monitor_parser(subparsers)
# Test with group patterns
args = parser.parse_args(["monitor", "pause", "--group", "production"])
assert args.resource == "monitor"
assert args.monitor_action == "pause"
assert args.group == ["production"]
def test_monitor_resume_all_arguments(self):
"""Test monitor resume all command argument parsing"""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="resource")
setup_monitor_parser(subparsers)
# Test with --all flag
args = parser.parse_args(["monitor", "resume", "--all"])
assert args.resource == "monitor"
assert args.monitor_action == "resume"
assert args.all is True
def test_maintenance_add_arguments(self):
"""Test maintenance add command argument parsing"""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="resource")
setup_maintenance_parser(subparsers)
# Test maintenance add
args = parser.parse_args([
"maintenance", "add",
"--title", "Server Update",
"--description", "Updating server software",
"--duration", "2h",
"--monitor", "server*"
])
assert args.resource == "maintenance"
assert args.maintenance_action == "add"
assert args.title == "Server Update"
assert args.description == "Updating server software"
assert args.duration == "2h"
assert args.monitor == ["server*"]
def test_maintenance_delete_arguments(self):
"""Test maintenance delete command argument parsing"""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="resource")
setup_maintenance_parser(subparsers)
# Test delete by ID
args = parser.parse_args(["maintenance", "delete", "--id", "123"])
assert args.resource == "maintenance"
assert args.maintenance_action == "delete"
assert args.id == 123
# Test delete all
args = parser.parse_args(["maintenance", "delete", "--all"])
assert args.resource == "maintenance"
assert args.maintenance_action == "delete"
assert args.all is True
def test_info_arguments(self):
"""Test info command argument parsing"""
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="resource")
setup_info_parser(subparsers)
# Test info command
args = parser.parse_args(["info"])
assert args.resource == "info"
class TestErrorHandling:
def test_monitor_command_resilience(self, mock_client, capsys):
"""Test monitor command handles various error conditions"""
# Setup
mock_args = Mock()
mock_args.monitor_action = "pause"
mock_args.monitor = ["nonexistent*"]
mock_args.group = None
# Mock no matches found
mock_client.find_monitors_by_pattern.return_value = []
# Execute
result = handle_monitor_command(mock_args, mock_client)
# Verify error handling
assert result is True # Command completes even with no matches
captured = capsys.readouterr()
assert "Error: No monitors found matching the specified patterns or groups" in captured.out
def test_maintenance_command_resilience(self, mock_client, capsys):
"""Test maintenance command handles API errors"""
# Setup
mock_args = Mock()
mock_args.maintenance_action = "list"
# Mock API error
mock_client.api.get_maintenances.side_effect = Exception("Connection timeout")
# Execute
result = handle_maintenance_command(mock_args, mock_client)
# Verify error handling
assert result is True # Command completes even with error
captured = capsys.readouterr()
assert "Error listing maintenances: Connection timeout" in captured.out