- 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.
104 lines
3.7 KiB
Python
104 lines
3.7 KiB
Python
"""
|
|
Test bootstrap: stub optional `sientia_do` submodules not shipped in minimal installs.
|
|
|
|
Must run before importing `model_manager.sientia.models` (pulled in via TrainModelParams).
|
|
Stubs Evidently submodules so `model_manager.sientia.reports` imports (via DataManagerRepository).
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sys
|
|
from types import ModuleType
|
|
|
|
|
|
def _make_dummy(name: str) -> type:
|
|
return type(name, (), {})
|
|
|
|
|
|
def _stub_evidently() -> None:
|
|
"""Minimal Evidently API surface required to import `model_manager.sientia.reports`."""
|
|
ev = ModuleType('evidently')
|
|
sys.modules['evidently'] = ev
|
|
|
|
mp = ModuleType('evidently.metric_preset')
|
|
mp.DataDriftPreset = _make_dummy('DataDriftPreset') # type: ignore[attr-defined]
|
|
sys.modules['evidently.metric_preset'] = mp
|
|
|
|
metrics = ModuleType('evidently.metrics')
|
|
_metric_names = (
|
|
'ColumnSummaryMetric',
|
|
'ConflictTargetMetric',
|
|
'DatasetCorrelationsMetric',
|
|
'DatasetSummaryMetric',
|
|
'RegressionAbsPercentageErrorPlot',
|
|
'RegressionDummyMetric',
|
|
'RegressionErrorDistribution',
|
|
'RegressionErrorPlot',
|
|
'RegressionPerformanceMetrics',
|
|
'RegressionPredictedVsActualPlot',
|
|
'RegressionPredictedVsActualScatter',
|
|
)
|
|
for n in _metric_names:
|
|
setattr(metrics, n, _make_dummy(n))
|
|
sys.modules['evidently.metrics'] = metrics
|
|
|
|
base = ModuleType('evidently.metrics.base_metric')
|
|
|
|
def generate_column_metrics(*_a, **_k):
|
|
return []
|
|
|
|
base.generate_column_metrics = generate_column_metrics # type: ignore[attr-defined]
|
|
sys.modules['evidently.metrics.base_metric'] = base
|
|
|
|
opt = ModuleType('evidently.options')
|
|
opt.ColorOptions = _make_dummy('ColorOptions') # type: ignore[attr-defined]
|
|
sys.modules['evidently.options'] = opt
|
|
|
|
pipeline = ModuleType('evidently.pipeline')
|
|
sys.modules['evidently.pipeline'] = pipeline
|
|
|
|
colmap = ModuleType('evidently.pipeline.column_mapping')
|
|
colmap.ColumnMapping = _make_dummy('ColumnMapping') # type: ignore[attr-defined]
|
|
sys.modules['evidently.pipeline.column_mapping'] = colmap
|
|
|
|
rep = ModuleType('evidently.report')
|
|
rep.Report = _make_dummy('Report') # type: ignore[attr-defined]
|
|
sys.modules['evidently.report'] = rep
|
|
|
|
|
|
def pytest_configure(config) -> None: # noqa: ARG001
|
|
"""Register stub modules so imports used by production code resolve in CI/dev venvs."""
|
|
_stub_evidently()
|
|
|
|
if 'sientia_do.operations.df_preprocessor' not in sys.modules:
|
|
df_pre = ModuleType('sientia_do.operations.df_preprocessor')
|
|
|
|
def create_features(input_data, *_a, **_k):
|
|
return input_data
|
|
|
|
def limit_dataset(input_data, low_lim, upp_lim, *_a, **_k):
|
|
return input_data, low_lim, upp_lim
|
|
|
|
def treat_nan(input_data, *_a, **_k):
|
|
return input_data
|
|
|
|
df_pre.create_features = create_features # type: ignore[attr-defined]
|
|
df_pre.limit_dataset = limit_dataset # type: ignore[attr-defined]
|
|
df_pre.treat_nan = treat_nan # type: ignore[attr-defined]
|
|
sys.modules['sientia_do.operations.df_preprocessor'] = df_pre
|
|
|
|
sys.modules.setdefault('sientia_do.operations', ModuleType('sientia_do.operations'))
|
|
|
|
if 'sientia_do.timeseries.analyzer' not in sys.modules:
|
|
ts_an = ModuleType('sientia_do.timeseries.analyzer')
|
|
|
|
class TimeSeriesDiscontinuityAnalyzer: # noqa: D401
|
|
"""Stub for tests."""
|
|
|
|
pass
|
|
|
|
ts_an.TimeSeriesDiscontinuityAnalyzer = TimeSeriesDiscontinuityAnalyzer # type: ignore[attr-defined]
|
|
sys.modules['sientia_do.timeseries.analyzer'] = ts_an
|
|
|
|
sys.modules.setdefault('sientia_do.timeseries', ModuleType('sientia_do.timeseries'))
|