diff --git a/test_runner/fixtures/safekeeper/http.py b/test_runner/fixtures/safekeeper/http.py index 96c84d1616..7f170eeea3 100644 --- a/test_runner/fixtures/safekeeper/http.py +++ b/test_runner/fixtures/safekeeper/http.py @@ -8,6 +8,7 @@ import requests from fixtures.common_types import Lsn, TenantId, TenantTimelineId, TimelineId from fixtures.log_helper import log from fixtures.metrics import Metrics, MetricsGetter, parse_metrics +from fixtures.utils import wait_until # Walreceiver as returned by sk's timeline status endpoint. @@ -161,6 +162,16 @@ class SafekeeperHttpClient(requests.Session, MetricsGetter): walreceivers=walreceivers, ) + # Get timeline_start_lsn, waiting until it's nonzero. It is a way to ensure + # that the timeline is fully initialized at the safekeeper. + def get_non_zero_timeline_start_lsn(self, tenant_id: TenantId, timeline_id: TimelineId) -> Lsn: + def timeline_start_lsn_non_zero() -> Lsn: + s = self.timeline_status(tenant_id, timeline_id).timeline_start_lsn + assert s > Lsn(0) + return s + + return wait_until(30, 1, timeline_start_lsn_non_zero) + def get_commit_lsn(self, tenant_id: TenantId, timeline_id: TimelineId) -> Lsn: return self.timeline_status(tenant_id, timeline_id).commit_lsn diff --git a/test_runner/regress/test_wal_acceptor.py b/test_runner/regress/test_wal_acceptor.py index 8ee548bdb0..adfe292c24 100644 --- a/test_runner/regress/test_wal_acceptor.py +++ b/test_runner/regress/test_wal_acceptor.py @@ -2084,8 +2084,13 @@ def test_timeline_copy(neon_env_builder: NeonEnvBuilder, insert_rows: int): endpoint.safe_psql("create table t(key int, value text)") - timeline_status = env.safekeepers[0].http_client().timeline_status(tenant_id, timeline_id) - timeline_start_lsn = timeline_status.timeline_start_lsn + # Note: currently timelines on sks are created by compute and commit of + # transaction above is finished when 2/3 sks received it, so there is a + # small chance that timeline on this sk is not created/initialized yet, + # hence the usage of waiting function to prevent flakiness. + timeline_start_lsn = ( + env.safekeepers[0].http_client().get_non_zero_timeline_start_lsn(tenant_id, timeline_id) + ) log.info(f"Timeline start LSN: {timeline_start_lsn}") current_percent = 0.0