Update E2E test report and enhance drift analysis handling - Updated the E2E test report metrics to reflect the latest test results, showing 47 collected tests with all passing. - Removed outdated sections related to failed tests and their causes, streamlining the report. - Implemented a regression fix in the drift analysis to handle empty merged frames, ensuring workflows skip export when no drift metrics are available. - Enhanced the `insert_sample_data` and `insert_sample_prediction` functions to allow customizable timestamps for better test accuracy. - Refactored E2E tests to improve clarity and maintainability, particularly in handling repeat scenarios with distinct timestamps.
4.7 KiB
Drift: falha explícita quando dados são insuficientes (solução C)
Objetivo
Quando existir dado alvo no intervalo analisado mas o pipeline não produzir nenhuma métrica de drift (DataFrame vazio após DriftAnalysis e/ou após filtros em calculate_drift), o sistema deve responder de forma assertiva: mensagem clara, identificador de notificação estável e falha controlada (exceção ou erro de atividade), não apenas return [] ou workflow que termina sem export e sem erro.
Isso evita estados ambíguos (ex.: e2e ou operação assumindo que “sucesso + zero linhas” é válido quando na verdade o chunk_period ou o volume de pontos não permite calcular drift).
Comportamento atual (resumo)
ModelMetrics.calculate_drift(laborious/activities/model_metrics.py): seget_drift_metricsretornar vazio ou, apósdrift_floor.isin(target_floor), ficar vazio, registra warning e devolve[].Drift.run(laborious/workflows/drift.py): sedrift_datafor falsy, não exporta e o workflow termina sem erro.
Nenhum dos dois distingue “não havia dados alvo” (já tratado com early return / short-circuit) de “havia dados, mas nenhuma métrica foi computada”.
Comportamento desejado (solução C)
Quando considerar “dados insuficientes / nenhuma métrica com dados presentes”
Disparar tratamento assertivo se todas forem verdade:
- Após pivot/
dropna,target_datatem pelo menos uma linha com janela temporal válida. reference_dataestá disponível (ou o fallback de 30% foi aplicado) de forma que a análise deveria poder rodar.reference_columns(features efetivas do drift univariado) não está vazio — caso contrário, falha de configuração, não “insuficiência de amostra”.- O resultado de
get_drift_metricsé vazio, ou fica vazio somente após o filtro portarget_floor/ timestamps.
Opcionalmente, reforçar no sientia_model.analytics.drift_analysis.DriftAnalysis: se analysis_df não for vazio mas não houver chunks ou nenhuma linha univariada/multivariada, levantar exceção específica ou retornar um código/estrutura que o Laborious traduza em falha explícita (evita duplicar heurística só no Laborious).
Resposta assertiva mínima
- Log / notificação com ID estável, por exemplo:
MODEL_METRICS_DRIFT_INSUFFICIENT_DATA(ou nome alinhado ao catálogo interno). - Mensagem incluindo contexto acionável:
model_id,chunk_period, contagem de linhas alvo, contagem de features, intervalo de tempo dos dados. - Falha de atividade: em vez de
return [], levantarValueError(ou exceção de domínio dedicada) após enviar a notificação, para o Temporal marcar a execução como falha e testes/e2e poderem distinguir “sem dados” de “falha de insumos para o granularidade pedida”.
Ajuste no workflow Drift (opcional mas coerente)
Se calculate_drift passar a lançar nesse cenário, o workflow já falha na atividade; não é obrigatório alterar Drift.run além de garantir que erros não sejam engolidos.
Se por política não se quiser falhar o workflow, documentar explicitamente a alternativa (única): retorno estruturado {'status': 'insufficient_data', 'detail': ...} — não é a opção C pedida aqui, que prioriza assertividade e visibilidade.
Impacto em testes
- Cenários e2e que hoje esperam sucesso silencioso com zero linhas (ex.:
test_drift_chunk_period_seconds_preserves_seconds_in_chunk_start_datecom poucos pontos echunk_period='s') devem ser atualizados para esperar falha da atividade com mensagem/notificação, ou o teste deve fornecer volume de dados suficiente para gerar ao menos uma linha de drift — conforme o requisito de produto escolhido após esta mudança.
Appendix: problema REPEAT / UniqueViolation (contexto)
A “solução A” (novo timestamp na linha inserida pelo REPEAT) já está parcialmente implementada em sientia_do: _build_repeat_last_prediction_query faz INSERT ... SELECT com coluna timestamp = parâmetro :last_timestamp, não copia o timestamp da linha anterior.
O e2e ainda falha quando o valor de last_timestamp passado pelo workflow (prediction_process.path_flag_handler) é igual ao timestamp da única predição existente (ex.: seed fixo 2024-01-01 12:00:00+00:00). Nesse caso o INSERT tenta duplicar (model_id, timestamp) e o Postgres aplica unique_model_id_timestamp.
Correção típica: garantir que, no caminho REPEAT, last_timestamp seja o instante do batch / “agora” da execução, distinto do timestamp da última linha persistida — ou ajustar a atividade para derivar um timestamp único quando last_timestamp colide com a última linha.