Harden Dataflow preview behavior
This commit is contained in:
@@ -2,7 +2,7 @@ from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
|
||||
from govoplan_dataflow.backend.executor import execute_preview
|
||||
from govoplan_dataflow.backend.executor import PipelineExecutionError, execute_preview
|
||||
from govoplan_dataflow.backend.schemas import (
|
||||
GraphEdge,
|
||||
GraphNode,
|
||||
@@ -120,6 +120,89 @@ class DataflowGraphAndSqlTests(unittest.TestCase):
|
||||
self.assertEqual(3, result.total_rows)
|
||||
self.assertTrue(result.truncated)
|
||||
|
||||
def test_empty_aggregate_and_null_sort_are_deterministic(self) -> None:
|
||||
graph, _, _ = compile_sql(
|
||||
"""
|
||||
SELECT status, COUNT(*) AS records
|
||||
FROM monthly_files
|
||||
GROUP BY status
|
||||
ORDER BY status DESC
|
||||
""",
|
||||
source_nodes=[
|
||||
inline_source().model_copy(
|
||||
update={
|
||||
"config": {
|
||||
"source_name": "monthly_files",
|
||||
"rows": [
|
||||
{"status": None},
|
||||
{"status": "open"},
|
||||
{"status": "closed"},
|
||||
],
|
||||
}
|
||||
}
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
first = execute_preview(graph, row_limit=100)
|
||||
second = execute_preview(graph, row_limit=100)
|
||||
|
||||
self.assertEqual(first.rows, second.rows)
|
||||
self.assertEqual(
|
||||
[
|
||||
{"status": "open", "records": 1},
|
||||
{"status": "closed", "records": 1},
|
||||
{"status": None, "records": 1},
|
||||
],
|
||||
first.rows,
|
||||
)
|
||||
self.assertEqual(
|
||||
[
|
||||
diagnostic.model_dump(exclude={"duration_ms"})
|
||||
for diagnostic in first.node_diagnostics
|
||||
],
|
||||
[
|
||||
diagnostic.model_dump(exclude={"duration_ms"})
|
||||
for diagnostic in second.node_diagnostics
|
||||
],
|
||||
)
|
||||
|
||||
def test_empty_global_aggregate_returns_a_count_row(self) -> None:
|
||||
graph, _, _ = compile_sql(
|
||||
"SELECT COUNT(*) AS records FROM monthly_files",
|
||||
source_nodes=[
|
||||
inline_source().model_copy(
|
||||
update={"config": {"source_name": "monthly_files", "rows": []}}
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
result = execute_preview(graph, row_limit=100)
|
||||
|
||||
self.assertEqual([{"records": 0}], result.rows)
|
||||
self.assertEqual(0, result.input_row_count)
|
||||
|
||||
def test_invalid_runtime_comparison_is_scoped_to_the_node(self) -> None:
|
||||
graph, _, _ = compile_sql(
|
||||
"SELECT * FROM monthly_files WHERE amount > 10",
|
||||
source_nodes=[
|
||||
inline_source().model_copy(
|
||||
update={
|
||||
"config": {
|
||||
"source_name": "monthly_files",
|
||||
"rows": [{"amount": "not-a-number"}],
|
||||
}
|
||||
}
|
||||
)
|
||||
],
|
||||
)
|
||||
|
||||
with self.assertRaises(PipelineExecutionError) as raised:
|
||||
execute_preview(graph, row_limit=100)
|
||||
|
||||
self.assertEqual("filter-1", raised.exception.node_id)
|
||||
self.assertIn("Cannot apply", str(raised.exception))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user