Pin reporting datasets to published Dataflow runs
This commit is contained in:
@@ -8,6 +8,10 @@ from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from govoplan_core.db.base import Base
|
||||
from govoplan_core.core.dataflows import (
|
||||
CAPABILITY_DATAFLOW_DATASET_OUTPUT,
|
||||
DataflowDatasetResult,
|
||||
)
|
||||
from govoplan_core.core.files import (
|
||||
CAPABILITY_FILES_ARTIFACT_STORE,
|
||||
ManagedArtifactRef,
|
||||
@@ -132,6 +136,34 @@ class ArtifactStore:
|
||||
)
|
||||
|
||||
|
||||
class DataflowOutput:
|
||||
def __init__(self, rows: list[dict[str, object]]) -> None:
|
||||
self.rows = tuple(dict(item) for item in rows)
|
||||
self.last_request = None
|
||||
|
||||
def list_outputs(self, *_args, **_kwargs):
|
||||
return ()
|
||||
|
||||
def read_output(self, _session, _principal, *, request):
|
||||
self.last_request = request
|
||||
return DataflowDatasetResult(
|
||||
pipeline_ref=request.pipeline_ref,
|
||||
revision=request.revision,
|
||||
definition_hash=request.expected_definition_hash or "pipeline-hash",
|
||||
rows=self.rows,
|
||||
total_rows=len(self.rows),
|
||||
truncated=False,
|
||||
output_hash="d" * 64,
|
||||
executor_version="duckdb-v1",
|
||||
run_ref=request.run_ref,
|
||||
source_fingerprints=(
|
||||
{"node_id": "source", "fingerprint": "source-v1"},
|
||||
),
|
||||
generated_at=NOW,
|
||||
provenance={"immutable_run": bool(request.run_ref)},
|
||||
)
|
||||
|
||||
|
||||
class ReportingServiceTests(unittest.TestCase):
|
||||
def setUp(self) -> None:
|
||||
self.engine = create_engine("sqlite+pysqlite:///:memory:")
|
||||
@@ -352,6 +384,44 @@ class ReportingServiceTests(unittest.TestCase):
|
||||
)
|
||||
self.assertTrue(raised.exception.execution_id)
|
||||
|
||||
def test_dataflow_dataset_can_pin_an_exact_published_run(self) -> None:
|
||||
payload = dataset_payload()
|
||||
rows = list(payload.pop("static_rows"))
|
||||
payload.update(
|
||||
{
|
||||
"source_kind": "dataflow",
|
||||
"source_ref": "pipeline:monthly-comparison",
|
||||
"source_revision": 4,
|
||||
"source_run_ref": "dataflow-run:published-july",
|
||||
"definition_hash": "pipeline-hash",
|
||||
}
|
||||
)
|
||||
self._create("dataset", "dataset-1", payload)
|
||||
self._create("semantic_model", "semantic-1", semantic_payload())
|
||||
self._create("report", "report-1", report_payload())
|
||||
provider = DataflowOutput(rows)
|
||||
registry = CapabilityRegistry()
|
||||
registry.providers[CAPABILITY_DATAFLOW_DATASET_OUTPUT] = provider
|
||||
|
||||
result = execute_report(
|
||||
self.session,
|
||||
self.principal,
|
||||
registry=registry,
|
||||
report_id="report-1",
|
||||
report_revision=1,
|
||||
parameters={},
|
||||
query=None,
|
||||
idempotency_key="published-dataflow-run",
|
||||
)
|
||||
|
||||
self.assertEqual("succeeded", result["status"])
|
||||
self.assertIsNotNone(provider.last_request)
|
||||
self.assertEqual(
|
||||
"dataflow-run:published-july",
|
||||
provider.last_request.run_ref,
|
||||
)
|
||||
self.assertTrue(result["provenance"]["source"]["immutable_run"])
|
||||
|
||||
def test_restricted_access_and_service_scope_guards(self) -> None:
|
||||
self._create_report_graph(
|
||||
report_access={
|
||||
|
||||
Reference in New Issue
Block a user