Update README, requirements, and E2E tests for improved configuration and functionality - Enhanced the README with updated model configuration examples, including the addition of an alias for production. - Removed the `requirements-light.txt` file and updated `requirements-local.txt` and `requirements.txt` to replace `asyncua` with `opcua`. - Refactored E2E test scenarios to utilize scenario input files for better maintainability and clarity. - Improved test coverage for MinIO offload functionality and added new helper functions for loading scenario inputs. - Updated `values.yaml` to reflect new global configurations and environment variables for the laborious worker.
13 KiB
E2E Scenario Documentation - Predictions Batch
This document describes the end-to-end scenarios for predictions_batch and its child workflows:
prediction_process and format_and_export_prediction.
It is a functional reference of scenario behavior, inputs, and expected outcomes.
Execution Context
- Tests run under
e2e/and are marked with@pytest.mark.integration. - PostgreSQL and MinIO are provisioned with testcontainers.
test_minio_offload.pyuses real MinIO I/O; other scenario suites may use stubs/mocks for optional outputs.
1. Main Workflow Scenarios
Source: e2e/test_predictions_batch_main_workflow.py
1.1.1 Happy Path - Complete Success
Summary: Full workflow succeeds with valid query and default gate behavior.
Description:
- Query returns rows for a model.
prediction_processruns transform and predict paths.- Final prediction and transformed data are persisted.
Expected Outcome:
- Exactly one prediction row is created.
- Transform rows are created.
- Confidence/status/comments are success values.
1.2.1 SQL Query Execution Error
Summary: Invalid SQL leads to no persisted prediction.
Description:
- Input query is invalid.
- Load step fails and workflow follows error/short-circuit path.
Expected Outcome:
- No prediction rows for the model.
- Workflow does not require retry-loop assumptions in assertions.
1.2.2 Missing Required Parameters
Summary: Missing required fields prevent workflow completion path.
Description:
- Required input key (e.g.
query) is omitted. - Workflow fails to produce actionable input for child flow.
Expected Outcome:
- No prediction rows are persisted.
- Workflow handle may require explicit terminate in E2E harness.
1.2.3 Invalid Datetime Column Specification (de-prioritized)
Summary: Legacy invalid datetime-column case is retained only as low-priority legacy coverage.
Description:
datetime_columnsreferences non-existing columns.- Behavior may vary by query shape and parser fallback.
Expected Outcome:
- No predictions persisted in the covered legacy assertion path.
- Scenario is not considered primary behavior coverage.
2. Prediction Process Scenarios
Source: e2e/test_predictions_batch_prediction_process.py
2.1 Input Gate Path Decisions
2.1.1 CONTINUE
Summary: Input filter flags quality issue but allows continuation via default path.
Description:
- Input gate returns
CONTINUE. - MLFlow transform/predict are skipped.
- Export path persists default-style prediction with warning context.
2.1.2 STOP
Summary: Input filter blocks processing.
Description:
- Input gate returns
STOP. - Workflow exits without export.
2.1.3 REPEAT with history
Summary: Prior prediction is reused.
Description:
- Input gate returns
REPEAT. repeat_last_predictionpath is executed using existing historical row.
2.1.4 REPEAT without history
Summary: Repeat requested but no previous prediction exists.
Description:
- Input gate returns
REPEAT. - No prior row is available to duplicate.
Expected Outcome:
- No new prediction rows are created for the model.
2.2 Transform Gate Decisions
2.2.1 CONTINUE on transform response error
Summary: Transform response is degraded, but workflow continues.
2.2.2 STOP on transform response error
Summary: Transform response error blocks downstream processing.
2.2.3 REPEAT on transform response error
Summary: Transform response error triggers repeat-last-prediction path.
2.2.4 STOP on transform content NaN
Summary: Content gate (NAN_VALUES) blocks on all-NaN transform payload.
2.3 Predict Gate Decisions
2.3.1 CONTINUE on predict response error
Summary: Predict response degraded; workflow exports with degraded metadata.
2.3.2 STOP on predict response error
Summary: Predict response error blocks export.
2.3.3 REPEAT on predict response error
Summary: Predict response error routes to repeat-last-prediction.
2.4.1 Priority Conflict Resolution
Summary: Deterministic selection when multiple filters produce different flags.
Description:
- Multiple filters may produce
STOP,CONTINUE, and/orREPEAT. path_prioritydefines precedence.
Expected Outcome:
- Highest-priority flag is applied consistently.
- Executed branch matches configured priority ordering.
3. Format and Export Scenarios
Source: e2e/test_predictions_batch_format_export.py
3.1 Output Combination Scenarios
3.1.1 Default prediction export
Summary: Non-None path flag uses format_default_prediction.
Description:
- Default prediction is generated.
- Transform export is skipped.
- Optional outputs (PI/OPC) still execute when configured.
3.1.2 OPC only
Summary: Postgres + OPC writes, PI Web API disabled.
3.1.3 PI Web API only
Summary: Postgres + PI writes, OPC disabled.
3.1.4 Postgres only
Summary: Both optional outputs disabled; only Postgres persistence and metrics.
3.1.5 No transformed data export
Summary: Prediction is persisted; transformed table is not written.
3.2 Degraded-but-successful Completion
3.2.1 PI Web API write error
Summary: PI write failure does not fail workflow.
Expected Outcome:
- Workflow completes.
- Prediction persisted with degraded confidence/comments (PI error semantics).
3.2.2 OPC write error
Summary: OPC write failure does not fail workflow.
Expected Outcome:
- Workflow completes.
- Prediction persisted with OPC degraded confidence/comments.
3.2.3 PI Web API partial write error
Summary: Partial PI acknowledgement is treated as degraded success.
Expected Outcome:
- Workflow completes.
- Prediction persisted with PI error confidence and descriptive comment.
3.3.1 Combined Optional Outputs (PI + OPC)
Summary: Both external output channels are enabled together.
Description:
- PI Web API and OPC configs are both present.
- Output mutation order matters for final persisted payload.
Expected Outcome:
- PI write executes before OPC write in workflow sequence.
- Final Postgres payload reflects any confidence/comment updates.
- OPC metrics are emitted when tag writes return response times.
4. MinIO Offload Scenarios
Source: e2e/test_minio_offload.py
4.1.1 Forced offload to MinIO
Summary: Very low threshold forces parquet upload.
Description:
- Payload is offloaded (
object_keypresent, inline data absent/empty). - Object is present in MinIO under
prediction_datasets/.... - Retrieval reconstructs the dataframe.
4.1.2 Full workflow with offloaded load payload
Summary: Offload path works during full predictions_batch execution.
Expected Outcome:
- Workflow completes.
- Prediction row is persisted.
4.2.1 Inline payload below threshold
Summary: Data remains inline when threshold is not exceeded.
Expected Outcome:
- Payload stores inline
data. object_keyisNone.- Downstream persistence behavior matches offload scenario semantics.
5. Drift Workflow Scenarios
Source: e2e/test_drift.py
The drift suite mocks sientia.ModelAnalysis.ModelAnalysis (not installed; see
CODE_ISSUES.md issue #1) through the controllable _FakeModelAnalysis stub
exposed by the model_analysis_stub fixture. The mlflow_repository_stub
provides the reference-data CSV via download_artifacts. Every scenario asserts
postgres rows in predictions_schema.drift against this canonical schema:
id, model_id, feature, method, value, drift, chunk, timestamp, timestamp_end, accurate, created_at, updated_at.
5.1 Happy paths
D.1.1 Full pipeline persists all columns with reference data
Summary: ModelAnalysis returns a deterministic drift dataframe; the reference CSV is downloaded from the MLflow stub.
Expected Outcome:
- One row per
(chunk, feature, method)plus amultivariateblock per chunk. - Every drift column is populated and
accurate=True. timestamp_endpreserves the high-precision string (HH:MM:59.999999999).p_valueis dropped before persistence.driftflags propagate per(feature, method)configuration.
D.1.2 30% fallback when reference data is unavailable
Summary: get_reference_data fails alias resolution and returns None;
calculate_drift uses the first 30% of target rows as reference.
Expected Outcome:
- Persisted rows carry
accurate=False. - A
MODEL_METRICS_REFERENCE_DATA_WARNINGnotification is emitted to MongoDB.
5.2 Filtering / dedup invariants
D.2.1 Deduplication and p_value removal
Summary: ModelAnalysis returns duplicate (timestamp, method, feature) rows
plus a p_value column.
Expected Outcome:
- Duplicates are collapsed keeping the first occurrence.
p_valueis absent from the persisted rows.
D.2.2 Out-of-range timestamps filtered
Summary: Drift rows whose timestamps are not present in the target window must be discarded before persistence.
5.3 Failure paths
D.3.1 Empty target data short-circuits the workflow
Summary: load_custom_query returns no rows; ModelAnalysis is never
instantiated and no drift rows are written.
D.3.2 ModelAnalysis raises during dataframe assembly
Summary: get_drift_metrics_dataframe raises. The activity catches the
error, sends a MODEL_METRICS_GET_DRIFT_METRICS_ERROR notification, and the
workflow completes without persisting drift rows.
5.4 Configuration paths
D.4.1 Default drift metrics propagated to analyzer
Summary: Omitting drift_metrics defaults to
['kolmogorov_smirnov', 'jensen_shannon', 'wasserstein'] and forwards the
exact list to detect_univariate_drift.
D.4.2 Invalid chunk_period raises ValueError
Summary: Anything other than min / s is rejected by calculate_drift.
D.4.3 chunk_period='s' keeps seconds in timestamp filtering
Summary: Truncated YYYY-MM-DD HH:MM rows are filtered out when chunking
runs at second granularity.
6. Simple Metrics Workflow Scenarios
Source: e2e/test_simple_metrics.py
Validates predictions_schema.simple_metrics_data columns:
id, model_id, metric, value, timestamp, data_size, interval_minutes, created_at.
6.1 Happy paths
S.1.1 rmse/mse/mae/r2 happy path
Summary: Prediction/target pairs are inserted; the activity computes all four metrics with closed-form expected values.
Expected Outcome:
- One row per metric is persisted; all columns populated.
data_sizematches the joined row count andinterval_minutes=60.
S.1.2 Subset metrics
Summary: Requesting metrics=['rmse'] writes only the rmse row.
6.2 Edge cases
S.2.1 Zero-variance target returns r2=0
Summary: When all targets are equal, ss_tot=0; the activity must guard
against division by zero and return r2=0.
6.3 Failure paths
S.3.1 No overlapping data short-circuits persistence
Summary: With no laborious_data rows for the configured target variable
the workflow exits before calculate_simple_metrics and writes nothing.
7. Minimal Retrain Workflow Scenarios
Source: e2e/test_minimal_retrain.py
The MLflow registry is fully mocked (no real artifacts in test container).
Validates predictions_schema.retrain_reports columns:
id, model_id, model_name, timestamp, status, version, mlflow_run_id, mlflow_experiment_id, created_at.
7.1 Happy path
MR.1.1 Successful retrain + promotion
Summary: Training data loads via MinIO offload, wrapper.retrain succeeds,
the new version is promoted to the production alias.
Expected Outcome:
- Report row has success status,
version='7',mlflow_run_id='retrain-run-id',mlflow_experiment_id='experiment-id'. mlflow.log_artifactis called with the input CSV.promote_to_aliasis called once with the resolved version and alias.
7.2 Failure paths
MR.2.1 Wrapper retrain raises
Summary: wrapper.retrain raises RuntimeError. The activity returns
success=False, update_production_model is NOT invoked.
Expected Outcome:
- Report row carries the error message and
version/mlflow_*columns are NULL.
MR.2.2 Missing model_config.target
Summary: Empty model config short-circuits before any MLflow call.
Expected Outcome:
- Report row carries the explicit guard message.
get_cached_modelis never invoked.
MR.3.1 No training data
Summary: The training query returns no rows; the workflow does not
persist any report row. The current code raises plain ValueError from the
workflow function, which Temporal treats as a workflow-task failure (see
CODE_ISSUES.md issue MR-1).
Input Contract Reference
Common scenario input fields:
schedule_namemodel_namemodel_idqueryschematable_nametransform_table_nameinput_filtersmlflow_transform_filtersmlflow_predict_filterspath_priority(default order:STOP,CONTINUE,REPEAT)save_transformprediction_store_policymodel_config.targetdatetime_columns(when query returns temporal fields)
Optional outputs:
opc_output_configpi_web_api_output_config