Files
neon/safekeeper/tests/misc_test.rs
Arpad Müller d8cee52637 Update rust to 1.86.0 (#11431)
We keep the practice of keeping the compiler up to date, pointing to the
latest release. This is done by many other projects in the Rust
ecosystem as well.

[Announcement blog
post](https://blog.rust-lang.org/2025/04/03/Rust-1.86.0.html).

Prior update was in #10914.
2025-04-03 14:53:28 +00:00

156 lines
4.6 KiB
Rust

use std::sync::Arc;
use tracing::{info, warn};
use utils::lsn::Lsn;
use crate::walproposer_sim::log::{init_logger, init_tracing_logger};
use crate::walproposer_sim::simulation::{
Schedule, TestAction, TestConfig, generate_network_opts, generate_schedule,
};
pub mod walproposer_sim;
// Test that simulation supports restarting (crashing) safekeepers.
#[test]
fn crash_safekeeper() {
let clock = init_logger();
let config = TestConfig::new(Some(clock));
let test = config.start(1337);
let lsn = test.sync_safekeepers().unwrap();
assert_eq!(lsn, Lsn(0));
info!("Sucessfully synced empty safekeepers at 0/0");
let mut wp = test.launch_walproposer(lsn);
// Write some WAL and crash safekeeper 0 without waiting for replication.
test.poll_for_duration(30);
wp.write_tx(3);
test.servers[0].restart();
// Wait some time, so that walproposer can reconnect.
test.poll_for_duration(2000);
}
// Test that walproposer can be crashed (stopped).
#[test]
fn test_simple_restart() {
let clock = init_logger();
let config = TestConfig::new(Some(clock));
let test = config.start(1337);
let lsn = test.sync_safekeepers().unwrap();
assert_eq!(lsn, Lsn(0));
info!("Sucessfully synced empty safekeepers at 0/0");
let mut wp = test.launch_walproposer(lsn);
test.poll_for_duration(30);
wp.write_tx(3);
test.poll_for_duration(100);
wp.stop();
drop(wp);
let lsn = test.sync_safekeepers().unwrap();
info!("Sucessfully synced safekeepers at {}", lsn);
}
// Test runnning a simple schedule, restarting everything a several times.
#[test]
fn test_simple_schedule() -> anyhow::Result<()> {
let clock = init_logger();
let mut config = TestConfig::new(Some(clock));
config.network.keepalive_timeout = Some(100);
let test = config.start(1337);
let schedule: Schedule = vec![
(0, TestAction::RestartWalProposer),
(50, TestAction::WriteTx(5)),
(100, TestAction::RestartSafekeeper(0)),
(100, TestAction::WriteTx(5)),
(110, TestAction::RestartSafekeeper(1)),
(110, TestAction::WriteTx(5)),
(120, TestAction::RestartSafekeeper(2)),
(120, TestAction::WriteTx(5)),
(201, TestAction::RestartWalProposer),
(251, TestAction::RestartSafekeeper(0)),
(251, TestAction::RestartSafekeeper(1)),
(251, TestAction::RestartSafekeeper(2)),
(251, TestAction::WriteTx(5)),
(255, TestAction::WriteTx(5)),
(1000, TestAction::WriteTx(5)),
];
test.run_schedule(&schedule)?;
info!("Test finished, stopping all threads");
test.world.deallocate();
Ok(())
}
// Test that simulation can process 10^4 transactions.
#[test]
fn test_many_tx() -> anyhow::Result<()> {
let clock = init_logger();
let config = TestConfig::new(Some(clock));
let test = config.start(1337);
let mut schedule: Schedule = vec![];
for i in 0..100 {
schedule.push((i * 10, TestAction::WriteTx(100)));
}
test.run_schedule(&schedule)?;
info!("Test finished, stopping all threads");
test.world.stop_all();
let events = test.world.take_events();
info!("Events: {:?}", events);
let last_commit_lsn = events
.iter()
.filter_map(|event| {
if event.data.starts_with("commit_lsn;") {
let lsn: u64 = event.data.split(';').nth(1).unwrap().parse().unwrap();
return Some(lsn);
}
None
})
.next_back()
.unwrap();
let initdb_lsn = 21623024;
let diff = last_commit_lsn - initdb_lsn;
info!("Last commit lsn: {}, diff: {}", last_commit_lsn, diff);
// each tx is at least 8 bytes, it's written a 100 times for in a loop for 100 times
assert!(diff > 100 * 100 * 8);
Ok(())
}
// Checks that we don't have nasty circular dependencies, preventing Arc from deallocating.
// This test doesn't really assert anything, you need to run it manually to check if there
// is any issue.
#[test]
fn test_res_dealloc() -> anyhow::Result<()> {
let clock = init_tracing_logger(true);
let mut config = TestConfig::new(Some(clock));
let seed = 123456;
config.network = generate_network_opts(seed);
let test = config.start(seed);
warn!("Running test with seed {}", seed);
let schedule = generate_schedule(seed);
info!("schedule: {:?}", schedule);
test.run_schedule(&schedule).unwrap();
test.world.stop_all();
let world = test.world.clone();
drop(test);
info!("world strong count: {}", Arc::strong_count(&world));
world.deallocate();
info!("world strong count: {}", Arc::strong_count(&world));
Ok(())
}