feat: enhance configuration and scheduling for cleanup processes

- Updated `.env.example` to include new environment variables for MinIO and PyPI configuration.
- Refactored `create_cleanup_schedule` to utilize runtime-specific task queues and improve schedule reconciliation logic.
- Enhanced `Activities` class to require a default bucket in MinIO configuration.
- Adjusted `requirements.txt` to specify version for `evidently`.
- Updated tests to reflect changes in schedule creation and configuration handling.
This commit is contained in:
vitor-aignosi
2026-04-07 12:57:29 -03:00
parent 09ee92f100
commit c5cd382350
13 changed files with 326 additions and 76 deletions

View File

@@ -754,7 +754,7 @@ async def test_main_schedule_creation_failure_does_not_stop_worker(
@patch('model_manager.worker.worker.get_logger')
@patch('model_manager.worker.worker.start_prometheus_server')
@patch('model_manager.worker.worker.metrics')
async def test_main_missing_runtime_fails_fast(
async def test_main_missing_runtime_uses_single_fallback(
mock_metrics,
mock_start_prometheus,
mock_get_logger,
@@ -771,7 +771,7 @@ async def test_main_missing_runtime_fails_fast(
mock_prepare_worker,
mock_logger,
):
"""Test that main() fails fast when RUNTIME is missing."""
"""Test that main() uses single runtime fallback when RUNTIME is missing."""
from model_manager.worker.worker import main
mock_get_logger.return_value = mock_logger
@@ -792,11 +792,44 @@ async def test_main_missing_runtime_fails_fast(
mock_activities.shutdown = Mock()
mock_activities_class.return_value = mock_activities
with pytest.raises(ValueError, match='RUNTIME environment variable is required'):
mock_runtime = Mock()
mock_runtime_class.return_value = mock_runtime
mock_client_instance = AsyncMock()
mock_client_instance.config = Mock(return_value={'plugins': [], 'interceptors': []})
mock_client_class.connect = AsyncMock(return_value=mock_client_instance)
mock_worker_instance = Mock()
mock_worker_instance.run = AsyncMock(side_effect=asyncio.CancelledError())
mock_prepare_worker.return_value = mock_worker_instance
mock_plugin_store_instance = AsyncMock()
mock_plugin_store_instance.install_runtime = AsyncMock(
return_value={'runtime': 'single', 'installed': []},
)
mock_plugin_store_class.return_value = mock_plugin_store_instance
mock_build_plugin_store_config.return_value = {
'base_url': 'http://sientia-plugin-store.svc.cluster.local',
'owner': 'sientia',
'repo': 'model-library-store',
'branch': 'main',
'username': 'gitea-user',
'password': 'gitea-password',
'pypi_index_url': 'http://library-distribution-server.library.svc.cluster.local:5000',
'pypi_username': None,
'pypi_password': None,
'cache_ttl_seconds': None,
}
mock_app_up = Mock()
mock_metrics.APP_UP.labels.return_value = mock_app_up
with pytest.raises(SystemExit):
await main()
mock_prepare_worker.assert_not_called()
mock_start_prometheus.assert_not_called()
assert mock_prepare_worker.call_count == 2
assert mock_prepare_worker.call_args_list[0].kwargs['runtime'] == 'single'
assert mock_prepare_worker.call_args_list[1].kwargs['runtime'] == 'single'
@patch('model_manager.worker.worker.asyncio.run')