|
19 | 19 |
|
20 | 20 | import pytest |
21 | 21 | from pydantic import TypeAdapter |
| 22 | +from tenacity import retry, retry_if_exception_type, stop_after_attempt, wait_fixed |
22 | 23 |
|
23 | 24 | from _openmetadata_testutils.pydantic.test_utils import assert_equal_pydantic_objects |
24 | 25 | from metadata.data_quality.api.models import TestCaseDefinition |
@@ -223,14 +224,35 @@ def test_lineage(self) -> None: |
223 | 224 | if hasattr(self, "get_service_type"): |
224 | 225 | service_type = self.get_service_type() |
225 | 226 |
|
| 227 | + # Metadata ingest runs once; the lineage ingest is retried separately |
| 228 | + # because DB audit logs (BigQuery INFORMATION_SCHEMA.JOBS_BY_PROJECT, |
| 229 | + # MSSQL sys.dm_exec_query_stats, Postgres pg_stat_statements) have |
| 230 | + # eventual consistency — newly executed queries may not appear for |
| 231 | + # 30-120s, causing the first lineage run to return 0 records. |
226 | 232 | self.run_command() |
227 | | - self.build_config_file( |
228 | | - E2EType.LINEAGE, |
229 | | - {"source": f"{service_type}-lineage", **self.get_lineage_config_args()}, |
| 233 | + |
| 234 | + # Re-run the full lineage ingest + assert on each retry so that the |
| 235 | + # ingestion re-reads the audit log (which may now be populated) and |
| 236 | + # writes fresh lineage edges to OpenMetadata before asserting. |
| 237 | + @retry( |
| 238 | + retry=retry_if_exception_type((AssertionError, IndexError)), |
| 239 | + wait=wait_fixed(30), |
| 240 | + stop=stop_after_attempt(3), |
| 241 | + reraise=True, |
230 | 242 | ) |
231 | | - result = self.run_command() |
232 | | - sink_status, source_status = self.retrieve_statuses(result) |
233 | | - self.assert_for_test_lineage(source_status, sink_status) |
| 243 | + def _run_lineage_and_assert() -> None: |
| 244 | + self.build_config_file( |
| 245 | + E2EType.LINEAGE, |
| 246 | + { |
| 247 | + "source": f"{service_type}-lineage", |
| 248 | + **self.get_lineage_config_args(), |
| 249 | + }, |
| 250 | + ) |
| 251 | + result = self.run_command() |
| 252 | + sink_status, source_status = self.retrieve_statuses(result) |
| 253 | + self.assert_for_test_lineage(source_status, sink_status) |
| 254 | + |
| 255 | + _run_lineage_and_assert() |
234 | 256 |
|
235 | 257 | @pytest.mark.order(12) |
236 | 258 | def test_profiler_with_time_partition(self) -> None: |
|
0 commit comments