import pytest from backup.config import Config, Setting from backup.debugworker import DebugWorker from backup.util import GlobalInfo from backup.logger import getLogger from dev.simulationserver import SimulationServer from .helpers import skipForWindows from backup.server import ErrorStore from .conftest import FakeTime @pytest.mark.asyncio async def test_dns_info(debug_worker: DebugWorker, config: Config): skipForWindows() config.override(Setting.SEND_ERROR_REPORTS, True) config.override(Setting.DRIVE_HOST_NAME, "localhost") await debug_worker.doWork() assert '127.0.0.1' in debug_worker.dns_info['localhost'] assert 'localhost' in debug_worker.dns_info['localhost'] @pytest.mark.asyncio async def test_bad_host(debug_worker: DebugWorker, config: Config): skipForWindows() config.override(Setting.DRIVE_HOST_NAME, "dasdfdfgvxcvvsoejbr.com") await debug_worker.doWork() assert "Name or service not known" in debug_worker.dns_info['dasdfdfgvxcvvsoejbr.com']['dasdfdfgvxcvvsoejbr.com'] @pytest.mark.asyncio async def test_send_error_report(time, debug_worker: DebugWorker, config: Config, global_info: GlobalInfo, server, error_store: ErrorStore): config.override(Setting.SEND_ERROR_REPORTS, True) config.override(Setting.DRIVE_HOST_NAME, "localhost") global_info.sync() global_info.success() global_info.sync() global_info.success() global_info.sync() global_info.failed(Exception()) await debug_worker.doWork() report = error_store.last_error assert report['report']['sync_success_count'] == 2 assert report['report']['sync_count'] == 3 assert report['report']['failure_count'] == 1 assert report['report']['sync_last_start'] == time.now().isoformat() assert report['report']['failure_time'] == time.now().isoformat() assert report['report']['error'] == getLogger("test").formatException(Exception()) @pytest.mark.asyncio async def test_dont_send_error_report(time, debug_worker: DebugWorker, config: Config, global_info: GlobalInfo, server: SimulationServer, error_store: ErrorStore): config.override(Setting.SEND_ERROR_REPORTS, False) config.override(Setting.DRIVE_HOST_NAME, "localhost") global_info.failed(Exception()) await debug_worker.doWork() assert error_store.last_error is None @pytest.mark.asyncio async def test_only_send_duplicates(time, debug_worker: DebugWorker, config: Config, global_info: GlobalInfo, server, error_store: ErrorStore): config.override(Setting.SEND_ERROR_REPORTS, True) config.override(Setting.DRIVE_HOST_NAME, "localhost") global_info.failed(Exception("boom1")) firstExceptionTime = time.now() await debug_worker.doWork() report = error_store.last_error assert report['report']["error"] == getLogger("test").formatException(Exception("boom1")) assert report['report']["time"] == firstExceptionTime.isoformat() # Same exception shouldn't cause us to send the error report again time.advance(days=1) global_info.failed(Exception("boom1")) await debug_worker.doWork() report = error_store.last_error assert report['report']["error"] == getLogger("test").formatException(Exception("boom1")) assert report['report']["time"] == firstExceptionTime.isoformat() # Btu a new one will send a new report global_info.failed(Exception("boom2")) await debug_worker.doWork() report = error_store.last_error assert report['report']["error"] == getLogger("test").formatException(Exception("boom2")) assert report['report']["time"] == time.now().isoformat() @pytest.mark.asyncio async def test_send_clear(time, debug_worker: DebugWorker, config: Config, global_info: GlobalInfo, server, error_store: ErrorStore): config.override(Setting.SEND_ERROR_REPORTS, True) config.override(Setting.DRIVE_HOST_NAME, "localhost") # Simulate failure global_info.failed(Exception("boom")) await debug_worker.doWork() # And then success global_info.success() time.advance(days=1) await debug_worker.doWork() report = error_store.last_error assert report['report'] == { 'duration': '1 day, 0:00:00' } @pytest.mark.asyncio async def test_health_check_timing_success(server_url, time: FakeTime, debug_worker: DebugWorker, config: Config, server: SimulationServer): # Only do successfull checks once a day await debug_worker.doWork() assert server.interceptor.urlWasCalled("/health") server.interceptor.clear() await debug_worker.doWork() assert not server.interceptor.urlWasCalled("/health") time.advance(hours=23) await debug_worker.doWork() assert not server.interceptor.urlWasCalled("/health") time.advance(hours=2) await debug_worker.doWork() assert server.interceptor.urlWasCalled("/health") @pytest.mark.asyncio async def test_health_check_timing_failure(server_url, time: FakeTime, debug_worker: DebugWorker, config: Config, server: SimulationServer): # Failed helath checks retry after a minute server.interceptor.setError("/health", 500) await debug_worker.doWork() assert server.interceptor.urlWasCalled("/health") server.interceptor.clear() await debug_worker.doWork() assert not server.interceptor.urlWasCalled("/health") time.advance(seconds=59) await debug_worker.doWork() assert not server.interceptor.urlWasCalled("/health") time.advance(seconds=2) await debug_worker.doWork() assert server.interceptor.urlWasCalled("/health")