From 65c851a4510e061a62a353ceed937e504c7daf5f Mon Sep 17 00:00:00 2001 From: Kirill Bulatov Date: Fri, 31 Dec 2021 01:23:54 +0200 Subject: [PATCH] Test pageserver's timeline http methods z --- pageserver/src/http/routes.rs | 48 ++++++++++++------- .../batch_others/test_pageserver_api.py | 11 ++++- test_runner/fixtures/zenith_fixtures.py | 15 ++++++ 3 files changed, 55 insertions(+), 19 deletions(-) diff --git a/pageserver/src/http/routes.rs b/pageserver/src/http/routes.rs index ecaeb3466f..1a5eeaea72 100644 --- a/pageserver/src/http/routes.rs +++ b/pageserver/src/http/routes.rs @@ -1,6 +1,6 @@ use std::sync::Arc; -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result}; use hyper::header; use hyper::StatusCode; use hyper::{Body, Request, Response, Uri}; @@ -190,18 +190,27 @@ async fn timeline_list_handler(request: Request) -> Result, } #[derive(Debug, Serialize)] -struct TimelineInfo { - #[serde(with = "hex")] - timeline_id: ZTimelineId, - #[serde(with = "hex")] - tenant_id: ZTenantId, - #[serde(with = "opt_display_serde")] - ancestor_timeline_id: Option, - last_record_lsn: Lsn, - prev_record_lsn: Lsn, - start_lsn: Lsn, - disk_consistent_lsn: Lsn, - timeline_state: Option, +#[serde(tag = "type")] +enum TimelineInfo { + Local { + #[serde(with = "hex")] + timeline_id: ZTimelineId, + #[serde(with = "hex")] + tenant_id: ZTenantId, + #[serde(with = "opt_display_serde")] + ancestor_timeline_id: Option, + last_record_lsn: Lsn, + prev_record_lsn: Lsn, + start_lsn: Lsn, + disk_consistent_lsn: Lsn, + timeline_state: Option, + }, + Remote { + #[serde(with = "hex")] + timeline_id: ZTimelineId, + #[serde(with = "hex")] + tenant_id: ZTenantId, + }, } async fn timeline_detail_handler(request: Request) -> Result, ApiError> { @@ -215,9 +224,12 @@ async fn timeline_detail_handler(request: Request) -> Result bail!("Timeline with id {} is not present locally", timeline_id), - Some(timeline) => Ok::<_, anyhow::Error>(TimelineInfo { + Ok::<_, anyhow::Error>(match repo.get_timeline(timeline_id)?.local_timeline() { + None => TimelineInfo::Remote { + timeline_id, + tenant_id, + }, + Some(timeline) => TimelineInfo::Local { timeline_id, tenant_id, ancestor_timeline_id: timeline.get_ancestor_timeline_id(), @@ -226,8 +238,8 @@ async fn timeline_detail_handler(request: Request) -> Result 0 + for timeline_id_str in timelines: + timeline_details = client.timeline_details(tenant_id.hex, timeline_id_str) + assert timeline_details['type'] == 'Local' + assert timeline_details['tenant_id'] == tenant_id.hex + assert timeline_details['timeline_id'] == timeline_id_str + # create branch branch_name = uuid4().hex client.branch_create(tenant_id, branch_name, "main") diff --git a/test_runner/fixtures/zenith_fixtures.py b/test_runner/fixtures/zenith_fixtures.py index f7665c89d8..dfdf5c071b 100644 --- a/test_runner/fixtures/zenith_fixtures.py +++ b/test_runner/fixtures/zenith_fixtures.py @@ -671,6 +671,21 @@ class ZenithPageserverHttpClient(requests.Session): res.raise_for_status() return res.json() + def timeline_list(self, tenant_id: uuid.UUID) -> List[str]: + res = self.get(f"http://localhost:{self.port}/v1/timeline/{tenant_id.hex}") + res.raise_for_status() + res_json = res.json() + assert isinstance(res_json, list) + return res_json + + def timeline_details(self, tenant_id: uuid.UUID, timeline_id: str) -> Dict[Any, Any]: + res = self.get( + f"http://localhost:{self.port}/v1/timeline/{tenant_id.hex}/{timeline_id}") + res.raise_for_status() + res_json = res.json() + assert isinstance(res_json, dict) + return res_json + def get_metrics(self) -> str: res = self.get(f"http://localhost:{self.port}/metrics") res.raise_for_status()