diff --git a/pageserver/src/layered_repository/layer_map.rs b/pageserver/src/layered_repository/layer_map.rs index cbdd26f474..6a5c2a2f58 100644 --- a/pageserver/src/layered_repository/layer_map.rs +++ b/pageserver/src/layered_repository/layer_map.rs @@ -370,3 +370,78 @@ impl<'a> Iterator for HistoricLayerIter<'a> { } } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::PageServerConf; + use std::str::FromStr; + use zenith_utils::zid::{ZTenantId, ZTimelineId}; + + /// Arbitrary relation tag, for testing. + const TESTREL_A: RelishTag = RelishTag::Relation(RelTag { + spcnode: 0, + dbnode: 111, + relnode: 1000, + forknum: 0, + }); + + /// Construct a dummy InMemoryLayer for testing + fn dummy_inmem_layer( + conf: &'static PageServerConf, + segno: u32, + start_lsn: Lsn, + oldest_pending_lsn: Lsn, + ) -> Arc { + Arc::new( + InMemoryLayer::create( + conf, + ZTimelineId::from_str("00000000000000000000000000000000").unwrap(), + ZTenantId::from_str("00000000000000000000000000000000").unwrap(), + SegmentTag { + rel: TESTREL_A, + segno, + }, + start_lsn, + oldest_pending_lsn, + ) + .unwrap(), + ) + } + + #[test] + fn test_open_layers() -> Result<()> { + let conf = PageServerConf::dummy_conf(PageServerConf::test_repo_dir("dummy_inmem_layer")); + let conf = Box::leak(Box::new(conf)); + + let mut layers = LayerMap::default(); + + let gen1 = layers.increment_generation(); + layers.insert_open(dummy_inmem_layer(conf, 0, Lsn(100), Lsn(100))); + layers.insert_open(dummy_inmem_layer(conf, 1, Lsn(100), Lsn(200))); + layers.insert_open(dummy_inmem_layer(conf, 2, Lsn(100), Lsn(120))); + layers.insert_open(dummy_inmem_layer(conf, 3, Lsn(100), Lsn(110))); + + let gen2 = layers.increment_generation(); + layers.insert_open(dummy_inmem_layer(conf, 4, Lsn(100), Lsn(110))); + layers.insert_open(dummy_inmem_layer(conf, 5, Lsn(100), Lsn(100))); + + // A helper function (closure) to pop the next oldest open entry from the layer map, + // and assert that it is what we'd expect + let mut assert_pop_layer = |expected_segno: u32, expected_generation: u64| { + let (l, generation) = layers.peek_oldest_open().unwrap(); + assert!(l.get_seg_tag().segno == expected_segno); + assert!(generation == expected_generation); + layers.pop_oldest_open(); + }; + + assert_pop_layer(0, gen1); // 100 + assert_pop_layer(5, gen2); // 100 + assert_pop_layer(3, gen1); // 110 + assert_pop_layer(4, gen2); // 110 + assert_pop_layer(2, gen1); // 120 + assert_pop_layer(1, gen1); // 200 + + Ok(()) + } +} diff --git a/pageserver/src/lib.rs b/pageserver/src/lib.rs index 1fef6462b2..314e6c1e33 100644 --- a/pageserver/src/lib.rs +++ b/pageserver/src/lib.rs @@ -110,4 +110,25 @@ impl PageServerConf { pub fn pg_lib_dir(&self) -> PathBuf { self.pg_distrib_dir.join("lib") } + + #[cfg(test)] + fn test_repo_dir(test_name: &str) -> PathBuf { + PathBuf::from(format!("../tmp_check/test_{}", test_name)) + } + + #[cfg(test)] + fn dummy_conf(repo_dir: PathBuf) -> Self { + PageServerConf { + daemonize: false, + gc_horizon: 64 * 1024 * 1024, + gc_period: Duration::from_secs(10), + listen_addr: "127.0.0.1:5430".to_string(), + http_endpoint_addr: "127.0.0.1:9898".to_string(), + superuser: "zenith_admin".to_string(), + workdir: repo_dir, + pg_distrib_dir: "".into(), + auth_type: AuthType::Trust, + auth_validation_public_key_path: None, + } + } } diff --git a/pageserver/src/repository.rs b/pageserver/src/repository.rs index 293cf03550..310a8f67e9 100644 --- a/pageserver/src/repository.rs +++ b/pageserver/src/repository.rs @@ -210,7 +210,6 @@ mod tests { use crate::PageServerConf; use postgres_ffi::pg_constants; use std::fs; - use std::path::PathBuf; use std::str::FromStr; use std::time::Duration; use zenith_utils::postgres_backend::AuthType; @@ -243,7 +242,7 @@ mod tests { static ZERO_PAGE: Bytes = Bytes::from_static(&[0u8; 8192]); fn get_test_repo(test_name: &str) -> Result> { - let repo_dir = PathBuf::from(format!("../tmp_check/test_{}", test_name)); + let repo_dir = PageServerConf::test_repo_dir(test_name); let _ = fs::remove_dir_all(&repo_dir); fs::create_dir_all(&repo_dir)?; fs::create_dir_all(&repo_dir.join("timelines"))?;