Skip to content

Commit b23e75e

Browse files
authored
test(pageserver): ensure offload cleans up metrics (#12127)
Add a test to ensure timeline metrics are fully cleaned up after offloading. Signed-off-by: Alex Chi Z <[email protected]>
1 parent 24d7c37 commit b23e75e

File tree

1 file changed

+60
-1
lines changed

1 file changed

+60
-1
lines changed

test_runner/regress/test_tenants.py

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
import pytest
1414
import requests
15-
from fixtures.common_types import Lsn, TenantId, TimelineId
15+
from fixtures.common_types import Lsn, TenantId, TimelineArchivalState, TimelineId
1616
from fixtures.log_helper import log
1717
from fixtures.metrics import (
1818
PAGESERVER_GLOBAL_METRICS,
@@ -299,6 +299,65 @@ def get_ps_metric_samples_for_tenant(tenant_id: TenantId) -> list[Sample]:
299299
assert post_detach_samples == set()
300300

301301

302+
def test_pageserver_metrics_removed_after_offload(neon_env_builder: NeonEnvBuilder):
303+
"""Tests that when a timeline is offloaded, the tenant specific metrics are not left behind"""
304+
305+
neon_env_builder.enable_pageserver_remote_storage(RemoteStorageKind.MOCK_S3)
306+
307+
neon_env_builder.num_safekeepers = 3
308+
309+
env = neon_env_builder.init_start()
310+
tenant_1, _ = env.create_tenant()
311+
312+
timeline_1 = env.create_timeline("test_metrics_removed_after_offload_1", tenant_id=tenant_1)
313+
timeline_2 = env.create_timeline("test_metrics_removed_after_offload_2", tenant_id=tenant_1)
314+
315+
endpoint_tenant1 = env.endpoints.create_start(
316+
"test_metrics_removed_after_offload_1", tenant_id=tenant_1
317+
)
318+
endpoint_tenant2 = env.endpoints.create_start(
319+
"test_metrics_removed_after_offload_2", tenant_id=tenant_1
320+
)
321+
322+
for endpoint in [endpoint_tenant1, endpoint_tenant2]:
323+
with closing(endpoint.connect()) as conn:
324+
with conn.cursor() as cur:
325+
cur.execute("CREATE TABLE t(key int primary key, value text)")
326+
cur.execute("INSERT INTO t SELECT generate_series(1,100000), 'payload'")
327+
cur.execute("SELECT sum(key) FROM t")
328+
assert cur.fetchone() == (5000050000,)
329+
endpoint.stop()
330+
331+
def get_ps_metric_samples_for_timeline(
332+
tenant_id: TenantId, timeline_id: TimelineId
333+
) -> list[Sample]:
334+
ps_metrics = env.pageserver.http_client().get_metrics()
335+
samples = []
336+
for metric_name in ps_metrics.metrics:
337+
for sample in ps_metrics.query_all(
338+
name=metric_name,
339+
filter={"tenant_id": str(tenant_id), "timeline_id": str(timeline_id)},
340+
):
341+
samples.append(sample)
342+
return samples
343+
344+
for timeline in [timeline_1, timeline_2]:
345+
pre_offload_samples = set(
346+
[x.name for x in get_ps_metric_samples_for_timeline(tenant_1, timeline)]
347+
)
348+
assert len(pre_offload_samples) > 0, f"expected at least one sample for {timeline}"
349+
env.pageserver.http_client().timeline_archival_config(
350+
tenant_1,
351+
timeline,
352+
state=TimelineArchivalState.ARCHIVED,
353+
)
354+
env.pageserver.http_client().timeline_offload(tenant_1, timeline)
355+
post_offload_samples = set(
356+
[x.name for x in get_ps_metric_samples_for_timeline(tenant_1, timeline)]
357+
)
358+
assert post_offload_samples == set()
359+
360+
302361
def test_pageserver_with_empty_tenants(neon_env_builder: NeonEnvBuilder):
303362
env = neon_env_builder.init_start()
304363

0 commit comments

Comments
 (0)