mirror of
https://github.com/johndoe6345789/docker-swarm-termina.git
synced 2026-04-24 21:55:13 +00:00
**Test Improvements:** - Fixed all mock patch paths for refactored module structure - Updated patches to target where functions are used, not defined - Added test_coverage_boost.py with 9 new tests for exception handling **Coverage Breakdown:** - All routes: 100% coverage ✨ - Main app & config: 100% coverage ✨ - Most utilities: 89-100% coverage - Handler logic: 38-100% coverage (edge cases remain) **Test Results:** - Total tests: 88/88 passing ✅ - Coverage: 88% (up from 62%) - All critical paths covered - Remaining 12% is error handling and diagnostics **Uncovered Code:** - Terminal disconnect cleanup (38%) - Terminal input error paths (77%) - Docker diagnostics (58%) - Thread error handling (78%) These are defensive code paths that are difficult to test in isolation but don't affect core functionality. https://claude.ai/code/session_011PzvkCnVrsatoxbY3HbGXz
125 lines
4.7 KiB
Python
125 lines
4.7 KiB
Python
import pytest
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
|
|
class TestContainerExec:
|
|
"""Test container command execution"""
|
|
|
|
def test_exec_unauthorized(self, client):
|
|
"""Test exec without auth"""
|
|
response = client.post('/api/containers/abc123/exec', json={
|
|
'command': 'ls'
|
|
})
|
|
assert response.status_code == 401
|
|
|
|
@patch('routes.containers.exec.get_docker_client')
|
|
def test_exec_simple_command(self, mock_get_client, client, auth_headers, auth_token):
|
|
"""Test executing a simple command"""
|
|
# Mock exec result
|
|
mock_exec_result = MagicMock()
|
|
mock_exec_result.output = b'file1.txt\nfile2.txt\n::WORKDIR::/app'
|
|
mock_exec_result.exit_code = 0
|
|
|
|
mock_container = MagicMock()
|
|
mock_container.exec_run.return_value = mock_exec_result
|
|
|
|
mock_client = MagicMock()
|
|
mock_client.containers.get.return_value = mock_container
|
|
mock_get_client.return_value = mock_client
|
|
|
|
response = client.post('/api/containers/abc123/exec',
|
|
headers=auth_headers,
|
|
json={'command': 'ls'})
|
|
|
|
assert response.status_code == 200
|
|
data = response.get_json()
|
|
assert data['exit_code'] == 0
|
|
assert 'file1.txt' in data['output']
|
|
assert data['workdir'] == '/app'
|
|
|
|
@patch('routes.containers.exec.get_docker_client')
|
|
def test_exec_cd_command(self, mock_get_client, client, auth_headers, auth_token):
|
|
"""Test executing cd command"""
|
|
# Mock exec result for cd command
|
|
mock_exec_result = MagicMock()
|
|
mock_exec_result.output = b'/home/user\n'
|
|
mock_exec_result.exit_code = 0
|
|
|
|
mock_container = MagicMock()
|
|
mock_container.exec_run.return_value = mock_exec_result
|
|
|
|
mock_client = MagicMock()
|
|
mock_client.containers.get.return_value = mock_container
|
|
mock_get_client.return_value = mock_client
|
|
|
|
response = client.post('/api/containers/abc123/exec',
|
|
headers=auth_headers,
|
|
json={'command': 'cd /home/user'})
|
|
|
|
assert response.status_code == 200
|
|
data = response.get_json()
|
|
assert data['exit_code'] == 0
|
|
assert data['workdir'] == '/home/user'
|
|
assert data['output'] == ''
|
|
|
|
@patch('routes.containers.exec.get_docker_client')
|
|
def test_exec_command_with_error(self, mock_get_client, client, auth_headers, auth_token):
|
|
"""Test executing a command that fails"""
|
|
# Mock exec result with error
|
|
mock_exec_result = MagicMock()
|
|
mock_exec_result.output = b'command not found::WORKDIR::/app'
|
|
mock_exec_result.exit_code = 127
|
|
|
|
mock_container = MagicMock()
|
|
mock_container.exec_run.return_value = mock_exec_result
|
|
|
|
mock_client = MagicMock()
|
|
mock_client.containers.get.return_value = mock_container
|
|
mock_get_client.return_value = mock_client
|
|
|
|
response = client.post('/api/containers/abc123/exec',
|
|
headers=auth_headers,
|
|
json={'command': 'invalidcommand'})
|
|
|
|
assert response.status_code == 200
|
|
data = response.get_json()
|
|
assert data['exit_code'] == 127
|
|
assert 'command not found' in data['output']
|
|
|
|
@patch('routes.containers.exec.get_docker_client')
|
|
def test_exec_docker_unavailable(self, mock_get_client, client, auth_headers):
|
|
"""Test exec when Docker is unavailable"""
|
|
mock_get_client.return_value = None
|
|
|
|
response = client.post('/api/containers/abc123/exec',
|
|
headers=auth_headers,
|
|
json={'command': 'ls'})
|
|
|
|
assert response.status_code == 500
|
|
data = response.get_json()
|
|
assert 'error' in data
|
|
|
|
@patch('routes.containers.exec.get_docker_client')
|
|
def test_exec_unicode_handling(self, mock_get_client, client, auth_headers, auth_token):
|
|
"""Test exec with unicode output"""
|
|
# Mock exec result with unicode
|
|
mock_exec_result = MagicMock()
|
|
mock_exec_result.output = 'Hello 世界\n::WORKDIR::/app'.encode('utf-8')
|
|
mock_exec_result.exit_code = 0
|
|
|
|
mock_container = MagicMock()
|
|
mock_container.exec_run.return_value = mock_exec_result
|
|
|
|
mock_client = MagicMock()
|
|
mock_client.containers.get.return_value = mock_container
|
|
mock_get_client.return_value = mock_client
|
|
|
|
response = client.post('/api/containers/abc123/exec',
|
|
headers=auth_headers,
|
|
json={'command': 'echo "Hello 世界"'})
|
|
|
|
assert response.status_code == 200
|
|
data = response.get_json()
|
|
assert data['exit_code'] == 0
|
|
assert '世界' in data['output']
|