Refactor DNS resolution: remove background service components, simplify manual resolution, and update configuration and tests accordingly.
This commit is contained in:
parent
b2d48be045
commit
f8b235ab24
6 changed files with 177 additions and 348 deletions
|
@ -253,66 +253,23 @@ class TestDNSService:
|
|||
|
||||
def test_initialization(self):
|
||||
"""Test DNS service initialization."""
|
||||
service = DNSService(update_interval=600, enabled=True, timeout=10.0)
|
||||
service = DNSService(enabled=True, timeout=10.0)
|
||||
|
||||
assert service.update_interval == 600
|
||||
assert service.enabled is True
|
||||
assert service.timeout == 10.0
|
||||
assert service._background_task is None
|
||||
assert service._resolution_cache == {}
|
||||
|
||||
def test_update_callback_setting(self):
|
||||
"""Test setting update callback."""
|
||||
def test_initialization_defaults(self):
|
||||
"""Test DNS service initialization with defaults."""
|
||||
service = DNSService()
|
||||
callback = MagicMock()
|
||||
|
||||
service.set_update_callback(callback)
|
||||
assert service._update_callback is callback
|
||||
assert service.enabled is True
|
||||
assert service.timeout == 5.0
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_background_service_lifecycle(self):
|
||||
"""Test starting and stopping background service."""
|
||||
async def test_resolve_entry_async_enabled(self):
|
||||
"""Test async resolution when service is enabled."""
|
||||
service = DNSService(enabled=True)
|
||||
|
||||
# Start service
|
||||
await service.start_background_resolution()
|
||||
assert service._background_task is not None
|
||||
assert not service._stop_event.is_set()
|
||||
|
||||
# Stop service
|
||||
await service.stop_background_resolution()
|
||||
assert service._background_task is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_background_service_disabled(self):
|
||||
"""Test background service when disabled."""
|
||||
service = DNSService(enabled=False)
|
||||
|
||||
await service.start_background_resolution()
|
||||
assert service._background_task is None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_resolve_entry_async_cache_hit(self):
|
||||
"""Test async resolution with cache hit."""
|
||||
service = DNSService()
|
||||
|
||||
# Add entry to cache
|
||||
cached_resolution = DNSResolution(
|
||||
hostname="example.com",
|
||||
resolved_ip="192.0.2.1",
|
||||
status=DNSResolutionStatus.RESOLVED,
|
||||
resolved_at=datetime.now(),
|
||||
)
|
||||
service._resolution_cache["example.com"] = cached_resolution
|
||||
|
||||
resolution = await service.resolve_entry_async("example.com")
|
||||
assert resolution is cached_resolution
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_resolve_entry_async_cache_miss(self):
|
||||
"""Test async resolution with cache miss."""
|
||||
service = DNSService()
|
||||
|
||||
with patch("src.hosts.core.dns.resolve_hostname") as mock_resolve:
|
||||
mock_resolution = DNSResolution(
|
||||
hostname="example.com",
|
||||
|
@ -325,84 +282,47 @@ class TestDNSService:
|
|||
resolution = await service.resolve_entry_async("example.com")
|
||||
|
||||
assert resolution is mock_resolution
|
||||
assert service._resolution_cache["example.com"] is mock_resolution
|
||||
mock_resolve.assert_called_once_with("example.com", 5.0)
|
||||
|
||||
def test_resolve_entry_sync_cache_hit(self):
|
||||
"""Test synchronous resolution with cache hit."""
|
||||
service = DNSService()
|
||||
|
||||
# Add entry to cache
|
||||
cached_resolution = DNSResolution(
|
||||
hostname="example.com",
|
||||
resolved_ip="192.0.2.1",
|
||||
status=DNSResolutionStatus.RESOLVED,
|
||||
resolved_at=datetime.now(),
|
||||
)
|
||||
service._resolution_cache["example.com"] = cached_resolution
|
||||
|
||||
resolution = service.resolve_entry("example.com")
|
||||
assert resolution is cached_resolution
|
||||
|
||||
def test_resolve_entry_sync_cache_miss(self):
|
||||
"""Test synchronous resolution with cache miss."""
|
||||
service = DNSService(enabled=True)
|
||||
|
||||
with patch("asyncio.create_task") as mock_create_task:
|
||||
resolution = service.resolve_entry("example.com")
|
||||
|
||||
assert resolution.hostname == "example.com"
|
||||
assert resolution.status == DNSResolutionStatus.RESOLVING
|
||||
assert resolution.resolved_ip is None
|
||||
mock_create_task.assert_called_once()
|
||||
|
||||
def test_resolve_entry_sync_disabled(self):
|
||||
"""Test synchronous resolution when service is disabled."""
|
||||
@pytest.mark.asyncio
|
||||
async def test_resolve_entry_async_disabled(self):
|
||||
"""Test async resolution when service is disabled."""
|
||||
service = DNSService(enabled=False)
|
||||
|
||||
with patch("asyncio.create_task") as mock_create_task:
|
||||
resolution = service.resolve_entry("example.com")
|
||||
resolution = await service.resolve_entry_async("example.com")
|
||||
|
||||
assert resolution.hostname == "example.com"
|
||||
assert resolution.status == DNSResolutionStatus.RESOLVING
|
||||
mock_create_task.assert_not_called()
|
||||
assert resolution.hostname == "example.com"
|
||||
assert resolution.resolved_ip is None
|
||||
assert resolution.status == DNSResolutionStatus.NOT_RESOLVED
|
||||
assert resolution.error_message == "DNS resolution is disabled"
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_refresh_entry(self):
|
||||
"""Test manual entry refresh."""
|
||||
service = DNSService()
|
||||
|
||||
# Add stale entry to cache
|
||||
stale_resolution = DNSResolution(
|
||||
hostname="example.com",
|
||||
resolved_ip="192.0.2.1",
|
||||
status=DNSResolutionStatus.RESOLVED,
|
||||
resolved_at=datetime.now() - timedelta(hours=1),
|
||||
)
|
||||
service._resolution_cache["example.com"] = stale_resolution
|
||||
service = DNSService(enabled=True)
|
||||
|
||||
with patch("src.hosts.core.dns.resolve_hostname") as mock_resolve:
|
||||
fresh_resolution = DNSResolution(
|
||||
mock_resolution = DNSResolution(
|
||||
hostname="example.com",
|
||||
resolved_ip="192.0.2.2",
|
||||
resolved_ip="192.0.2.1",
|
||||
status=DNSResolutionStatus.RESOLVED,
|
||||
resolved_at=datetime.now(),
|
||||
)
|
||||
mock_resolve.return_value = fresh_resolution
|
||||
mock_resolve.return_value = mock_resolution
|
||||
|
||||
result = await service.refresh_entry("example.com")
|
||||
|
||||
assert result is fresh_resolution
|
||||
assert service._resolution_cache["example.com"] is fresh_resolution
|
||||
assert "example.com" not in service._resolution_cache or service._resolution_cache["example.com"].resolved_ip == "192.0.2.2"
|
||||
assert result is mock_resolution
|
||||
mock_resolve.assert_called_once_with("example.com", 5.0)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_refresh_all_entries(self):
|
||||
"""Test manual refresh of all entries."""
|
||||
service = DNSService()
|
||||
async def test_refresh_all_entries_enabled(self):
|
||||
"""Test manual refresh of all entries when enabled."""
|
||||
service = DNSService(enabled=True)
|
||||
hostnames = ["example.com", "test.example"]
|
||||
|
||||
with patch("src.hosts.core.dns.resolve_hostnames_batch") as mock_batch:
|
||||
fresh_resolutions = [
|
||||
mock_resolutions = [
|
||||
DNSResolution(
|
||||
hostname="example.com",
|
||||
resolved_ip="192.0.2.1",
|
||||
|
@ -416,57 +336,27 @@ class TestDNSService:
|
|||
resolved_at=datetime.now(),
|
||||
),
|
||||
]
|
||||
mock_batch.return_value = fresh_resolutions
|
||||
mock_batch.return_value = mock_resolutions
|
||||
|
||||
results = await service.refresh_all_entries(hostnames)
|
||||
|
||||
assert results == fresh_resolutions
|
||||
assert len(service._resolution_cache) == 2
|
||||
assert service._resolution_cache["example.com"].resolved_ip == "192.0.2.1"
|
||||
assert service._resolution_cache["test.example"].resolved_ip == "192.0.2.2"
|
||||
assert results == mock_resolutions
|
||||
mock_batch.assert_called_once_with(hostnames, 5.0)
|
||||
|
||||
def test_cache_operations(self):
|
||||
"""Test cache operations."""
|
||||
service = DNSService()
|
||||
@pytest.mark.asyncio
|
||||
async def test_refresh_all_entries_disabled(self):
|
||||
"""Test manual refresh of all entries when disabled."""
|
||||
service = DNSService(enabled=False)
|
||||
hostnames = ["example.com", "test.example"]
|
||||
|
||||
# Test empty cache
|
||||
assert service.get_cached_resolution("example.com") is None
|
||||
results = await service.refresh_all_entries(hostnames)
|
||||
|
||||
# Add to cache
|
||||
resolution = DNSResolution(
|
||||
hostname="example.com",
|
||||
resolved_ip="192.0.2.1",
|
||||
status=DNSResolutionStatus.RESOLVED,
|
||||
resolved_at=datetime.now(),
|
||||
)
|
||||
service._resolution_cache["example.com"] = resolution
|
||||
|
||||
# Test cache retrieval
|
||||
assert service.get_cached_resolution("example.com") is resolution
|
||||
|
||||
# Test cache stats
|
||||
stats = service.get_cache_stats()
|
||||
assert stats["total_entries"] == 1
|
||||
assert stats["successful"] == 1
|
||||
assert stats["failed"] == 0
|
||||
|
||||
# Add failed resolution
|
||||
failed_resolution = DNSResolution(
|
||||
hostname="failed.example",
|
||||
resolved_ip=None,
|
||||
status=DNSResolutionStatus.RESOLUTION_FAILED,
|
||||
resolved_at=datetime.now(),
|
||||
)
|
||||
service._resolution_cache["failed.example"] = failed_resolution
|
||||
|
||||
stats = service.get_cache_stats()
|
||||
assert stats["total_entries"] == 2
|
||||
assert stats["successful"] == 1
|
||||
assert stats["failed"] == 1
|
||||
|
||||
# Clear cache
|
||||
service.clear_cache()
|
||||
assert len(service._resolution_cache) == 0
|
||||
assert len(results) == 2
|
||||
for i, result in enumerate(results):
|
||||
assert result.hostname == hostnames[i]
|
||||
assert result.resolved_ip is None
|
||||
assert result.status == DNSResolutionStatus.NOT_RESOLVED
|
||||
assert result.error_message == "DNS resolution is disabled"
|
||||
|
||||
|
||||
class TestHostEntryDNSIntegration:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue