feat: enhance E2E testing setup and model reporting
- Added a new fixture to manage runtime report artifacts in a writable temp directory during E2E tests, addressing permission issues in local CI/dev environments. - Updated `conftest.py` to include a requirements.txt file in the model packaging path for training activities. - Refactored existing fixtures to use `pytest.fixture` instead of `pytest_asyncio.fixture` for better compatibility. - Enhanced the `Reports` class to include a target alias for report metrics, ensuring compatibility with Evidently's reporting requirements. - Introduced new test scenarios to validate the handling of missing and whitespace-only `date_column` inputs in the training workflow. These changes improve the robustness of the E2E testing framework and enhance the clarity of model reporting metrics.
This commit is contained in:
@@ -125,7 +125,7 @@ def test_cleanup_temp_directories_nonexistent_path(
|
||||
notification_handler=mock_notification_handler,
|
||||
metrics_controller=mock_metrics_controller,
|
||||
)
|
||||
cleanup._emit_metrics = MagicMock()
|
||||
cleanup._emit_metrics = MagicMock() # type: ignore[method-assign]
|
||||
cleanup.warning = MagicMock()
|
||||
|
||||
cleanup.cleanup_temp_directories({'temp_path': '/nonexistent/path', 'metadata': {}})
|
||||
@@ -152,7 +152,7 @@ def test_cleanup_temp_directories_success_with_deletions(
|
||||
notification_handler=mock_notification_handler,
|
||||
metrics_controller=mock_metrics_controller,
|
||||
)
|
||||
cleanup._emit_metrics = MagicMock()
|
||||
cleanup._emit_metrics = MagicMock() # type: ignore[method-assign]
|
||||
|
||||
old_time = (datetime.now() - timedelta(hours=48)).strftime('%Y%m%d_%H%M%S_000000')
|
||||
old_dir = os.path.join(temp_dir, f'old_dir_{old_time}')
|
||||
@@ -187,7 +187,7 @@ def test_cleanup_temp_directories_dry_run(
|
||||
notification_handler=mock_notification_handler,
|
||||
metrics_controller=mock_metrics_controller,
|
||||
)
|
||||
cleanup._emit_metrics = MagicMock()
|
||||
cleanup._emit_metrics = MagicMock() # type: ignore[method-assign]
|
||||
|
||||
old_time = (datetime.now() - timedelta(hours=48)).strftime('%Y%m%d_%H%M%S_000000')
|
||||
old_dir = os.path.join(temp_dir, f'old_dir_{old_time}')
|
||||
@@ -217,7 +217,7 @@ def test_cleanup_temp_directories_delete_error(
|
||||
notification_handler=mock_notification_handler,
|
||||
metrics_controller=mock_metrics_controller,
|
||||
)
|
||||
cleanup._emit_metrics = MagicMock()
|
||||
cleanup._emit_metrics = MagicMock() # type: ignore[method-assign]
|
||||
cleanup.error = MagicMock()
|
||||
|
||||
old_time = (datetime.now() - timedelta(hours=48)).strftime('%Y%m%d_%H%M%S_000000')
|
||||
@@ -276,7 +276,7 @@ def test_cleanup_temp_directories_with_files_and_unmatched_dirs(
|
||||
notification_handler=mock_notification_handler,
|
||||
metrics_controller=mock_metrics_controller,
|
||||
)
|
||||
cleanup._emit_metrics = MagicMock()
|
||||
cleanup._emit_metrics = MagicMock() # type: ignore[method-assign]
|
||||
cleanup.debug = MagicMock()
|
||||
|
||||
# Create a file and a directory with a non-matching name
|
||||
@@ -310,7 +310,7 @@ def test_cleanup_temp_directories_invalid_timestamp_format(
|
||||
notification_handler=mock_notification_handler,
|
||||
metrics_controller=mock_metrics_controller,
|
||||
)
|
||||
cleanup._emit_metrics = MagicMock()
|
||||
cleanup._emit_metrics = MagicMock() # type: ignore[method-assign]
|
||||
cleanup.error = MagicMock()
|
||||
|
||||
# Create a directory with a malformed timestamp that matches the regex but fails parsing
|
||||
@@ -340,7 +340,7 @@ def test_cleanup_temp_directories_generic_exception(
|
||||
notification_handler=mock_notification_handler,
|
||||
metrics_controller=mock_metrics_controller,
|
||||
)
|
||||
cleanup._emit_metrics = MagicMock()
|
||||
cleanup._emit_metrics = MagicMock() # type: ignore[method-assign]
|
||||
cleanup.send_notification = MagicMock()
|
||||
|
||||
with patch('os.listdir', side_effect=Exception('Unexpected OS Error')):
|
||||
|
||||
@@ -136,6 +136,11 @@ def test_experiment_tracking_del_with_engine_exception(
|
||||
et.engine = MagicMock()
|
||||
|
||||
class MockSuperWithError:
|
||||
_should_raise: bool
|
||||
|
||||
def __init__(self) -> None:
|
||||
self._should_raise = False
|
||||
|
||||
def __del__(self):
|
||||
# Only raise error if not being cleaned up by garbage collector
|
||||
# This prevents the PytestUnraisableExceptionWarning
|
||||
@@ -215,7 +220,7 @@ def test_update_experiment_run_status_success(
|
||||
mock_execute(*args, **kwargs)
|
||||
return {'rowcount': 1}
|
||||
|
||||
et._execute_update = mock_execute_update
|
||||
et._execute_update = mock_execute_update # type: ignore[method-assign]
|
||||
et.info = MagicMock()
|
||||
|
||||
input_data = {
|
||||
@@ -293,7 +298,7 @@ def test_update_experiment_run_status_with_error_success(
|
||||
mock_execute(*args, **kwargs)
|
||||
return {'rowcount': 1}
|
||||
|
||||
et._execute_update = mock_execute_update
|
||||
et._execute_update = mock_execute_update # type: ignore[method-assign]
|
||||
et.info = MagicMock()
|
||||
|
||||
input_data = {
|
||||
@@ -339,7 +344,7 @@ def test_update_experiment_run_status_with_error_truncate_message(
|
||||
mock_execute(*args, **kwargs)
|
||||
return {'rowcount': 1}
|
||||
|
||||
et._execute_update = mock_execute_update
|
||||
et._execute_update = mock_execute_update # type: ignore[method-assign]
|
||||
et.info = MagicMock()
|
||||
|
||||
long_error = 'x' * 2000
|
||||
@@ -416,7 +421,7 @@ def test_update_experiment_run_model_saved_success(
|
||||
mock_execute(*args, **kwargs)
|
||||
return {'rowcount': 1}
|
||||
|
||||
et._execute_update = mock_execute_update
|
||||
et._execute_update = mock_execute_update # type: ignore[method-assign]
|
||||
et.info = MagicMock()
|
||||
|
||||
input_data = {
|
||||
@@ -526,7 +531,7 @@ def test_update_experiment_run_no_rows_updated(
|
||||
def mock_execute_update(*args, **kwargs):
|
||||
return {'rowcount': 0}
|
||||
|
||||
et._execute_update = mock_execute_update
|
||||
et._execute_update = mock_execute_update # type: ignore[method-assign]
|
||||
et.send_notification = MagicMock()
|
||||
|
||||
input_data = {
|
||||
|
||||
@@ -131,13 +131,15 @@ def test_train_model_success_serializes_result(mock_mlflow, training):
|
||||
|
||||
training.minio_repository.download_file = MagicMock(return_value=b'csv')
|
||||
training.data_manager_repository.prepare_training_data = MagicMock(return_value=tmr)
|
||||
|
||||
def _set_metrics(x, _w, **_kw):
|
||||
x.mse_val = 0.1
|
||||
x.mae_val = 0.2
|
||||
x.r2_val = 0.9
|
||||
return x
|
||||
|
||||
training.data_manager_repository.compute_regression_metrics = MagicMock(
|
||||
side_effect=lambda x, _w, **_kw: (
|
||||
setattr(x, 'mse_val', 0.1),
|
||||
setattr(x, 'mae_val', 0.2),
|
||||
setattr(x, 'r2_val', 0.9),
|
||||
x,
|
||||
)[-1]
|
||||
side_effect=_set_metrics
|
||||
)
|
||||
|
||||
def _fill_report(x, **_kw):
|
||||
|
||||
Reference in New Issue
Block a user