mirror of https://github.com/railgun-rs/actix-raft
97 lines
3.2 KiB
Rust
97 lines
3.2 KiB
Rust
mod fixtures;
|
|
|
|
use std::sync::Arc;
|
|
use std::time::Duration;
|
|
|
|
use anyhow::Result;
|
|
use async_raft::raft::MembershipConfig;
|
|
use async_raft::{Config, SnapshotPolicy};
|
|
use maplit::hashset;
|
|
use tokio::time::delay_for;
|
|
|
|
use fixtures::RaftRouter;
|
|
|
|
/// Compaction test.
|
|
///
|
|
/// What does this test do?
|
|
///
|
|
/// - build a stable single node cluster.
|
|
/// - send enough requests to the node that log compaction will be triggered.
|
|
/// - add new nodes and assert that they receive the snapshot.
|
|
///
|
|
/// RUST_LOG=async_raft,memstore,compaction=trace cargo test -p async-raft --test compaction
|
|
#[tokio::test(core_threads = 4)]
|
|
async fn compaction() -> Result<()> {
|
|
fixtures::init_tracing();
|
|
|
|
// Setup test dependencies.
|
|
let config = Arc::new(
|
|
Config::build("test".into())
|
|
.snapshot_policy(SnapshotPolicy::LogsSinceLast(500))
|
|
.validate()
|
|
.expect("failed to build Raft config"),
|
|
);
|
|
let router = Arc::new(RaftRouter::new(config.clone()));
|
|
router.new_raft_node(0).await;
|
|
|
|
// Assert all nodes are in non-voter state & have no entries.
|
|
delay_for(Duration::from_secs(10)).await;
|
|
router.assert_pristine_cluster().await;
|
|
|
|
// Initialize the cluster, then assert that a stable cluster was formed & held.
|
|
tracing::info!("--- initializing cluster");
|
|
router.initialize_from_single_node(0).await?;
|
|
delay_for(Duration::from_secs(10)).await;
|
|
router.assert_stable_cluster(Some(1), Some(1)).await;
|
|
|
|
// Send enough requests to the cluster that compaction on the node should be triggered.
|
|
router.client_request_many(0, "0", 499).await; // Puts us exactly at the configured snapshot policy threshold.
|
|
delay_for(Duration::from_secs(5)).await; // Wait to ensure there is enough time for a snapshot to be built (this is way more than enough).
|
|
router.assert_stable_cluster(Some(1), Some(500)).await;
|
|
router
|
|
.assert_storage_state(
|
|
1,
|
|
500,
|
|
Some(0),
|
|
500,
|
|
Some((
|
|
500.into(),
|
|
1,
|
|
MembershipConfig {
|
|
members: hashset![0],
|
|
members_after_consensus: None,
|
|
},
|
|
)),
|
|
)
|
|
.await;
|
|
|
|
// Add a new node and assert that it received the same snapshot.
|
|
router.new_raft_node(1).await;
|
|
router.add_non_voter(0, 1).await.expect("failed to add new node as non-voter");
|
|
router
|
|
.change_membership(0, hashset![0, 1])
|
|
.await
|
|
.expect("failed to modify cluster membership");
|
|
delay_for(Duration::from_secs(5)).await; // Wait to ensure metrics are updated (this is way more than enough).
|
|
router.assert_stable_cluster(Some(1), Some(502)).await; // We expect index to be 500 + 2 (joint & uniform config change entries).
|
|
router
|
|
.assert_storage_state(
|
|
1,
|
|
502,
|
|
None,
|
|
500,
|
|
Some((
|
|
500.into(),
|
|
1,
|
|
MembershipConfig {
|
|
members: hashset![0u64],
|
|
members_after_consensus: None,
|
|
},
|
|
)),
|
|
)
|
|
.await;
|
|
// -------------------------------- ^^^^ this value is None because non-voters do not vote.
|
|
|
|
Ok(())
|
|
}
|