From d530aab1057f00295cd463381ddf7cf9534056c5 Mon Sep 17 00:00:00 2001 From: John Spray Date: Fri, 27 Sep 2024 16:50:23 +0100 Subject: [PATCH] tests: add test_image_layer_reads --- test_runner/fixtures/workload.py | 28 +++++++++++++++++------- test_runner/regress/test_compaction.py | 30 ++++++++++++++++++++++++++ 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/test_runner/fixtures/workload.py b/test_runner/fixtures/workload.py index 065a78bf9b..c7c71526aa 100644 --- a/test_runner/fixtures/workload.py +++ b/test_runner/fixtures/workload.py @@ -56,20 +56,32 @@ class Workload: with ENDPOINT_LOCK: self._endpoint.reconfigure() - def endpoint(self, pageserver_id: Optional[int] = None) -> Endpoint: + def go_readonly(self): + self.stop() + self._endpoint = self.make_endpoint(readonly=True, pageserver_id=None) + self._endpoint.start(pageserver_id=None) + + def make_endpoint(self, readonly: bool, pageserver_id: Optional[int] = None) -> Endpoint: # We may be running alongside other Workloads for different tenants. Full TTID is # obnoxiously long for use here, but a cut-down version is still unique enough for tests. endpoint_id = f"ep-workload-{str(self.tenant_id)[0:4]}-{str(self.timeline_id)[0:4]}" + if readonly: + self._endpoint_opts["hot_standby"] = True + + return self.env.endpoints.create( + self.branch_name, + tenant_id=self.tenant_id, + pageserver_id=pageserver_id, + endpoint_id=endpoint_id, + **self._endpoint_opts, + ) + + def endpoint(self, pageserver_id: Optional[int] = None) -> Endpoint: with ENDPOINT_LOCK: if self._endpoint is None: - self._endpoint = self.env.endpoints.create( - self.branch_name, - tenant_id=self.tenant_id, - pageserver_id=pageserver_id, - endpoint_id=endpoint_id, - **self._endpoint_opts, - ) + self._endpoint = self.make_endpoint(pageserver_id=pageserver_id, readonly=False) + self._endpoint.start(pageserver_id=pageserver_id) else: self._endpoint.reconfigure(pageserver_id=pageserver_id) diff --git a/test_runner/regress/test_compaction.py b/test_runner/regress/test_compaction.py index cb34551b53..adabc745fb 100644 --- a/test_runner/regress/test_compaction.py +++ b/test_runner/regress/test_compaction.py @@ -11,6 +11,7 @@ from fixtures.neon_fixtures import ( generate_uploads_and_deletions, ) from fixtures.pageserver.http import PageserverApiException +from fixtures.pageserver.utils import wait_for_last_record_lsn from fixtures.utils import wait_until from fixtures.workload import Workload @@ -412,3 +413,32 @@ def test_image_layer_compression(neon_env_builder: NeonEnvBuilder, enabled: bool f"SELECT count(*) FROM foo WHERE id={v} and val=repeat('abcde{v:0>3}', 500)" ) assert res[0][0] == 1 + + +def test_image_layer_reads(neon_env_builder: NeonEnvBuilder): + env = neon_env_builder.init_start() + tenant_id = env.initial_tenant + timeline_id = env.initial_timeline + + workload = Workload(env, tenant_id, timeline_id) + workload.init() + workload.write_rows(256) + workload.validate() + + # wait_for_wal_insert_lsn(env, workload._endpoint, tenant_id, timeline_id) + + workload.go_readonly() + + commit_lsn = env.safekeepers[0].http_client().get_commit_lsn(tenant_id, timeline_id) + wait_for_last_record_lsn(env.pageserver.http_client(), tenant_id, timeline_id, commit_lsn) + log.info(f"Ingested up to commit_lsn {commit_lsn}") + + env.pageserver.http_client().timeline_compact( + tenant_id, timeline_id, force_image_layer_creation=True + ) + + # This should send getpage requests at the same LSN where we just created image layers + workload.validate() + + # Nothing should have written in the meantime + assert commit_lsn == env.safekeepers[0].http_client().get_commit_lsn(tenant_id, timeline_id)