extern crate alloc;
use alloc::vec;
use faction::cluster_view::ClusterView;
use faction::conclusion::Conclusion;
use faction::outcome::Outcome;
use faction::peer_state::PeerState;
use faction::transition::Transition;
fn cluster_view(pinging_peers: Vec<u64>, collecting_peers: Vec<u64>) -> ClusterView {
ClusterView::new(
PeerState::Pinging,
false,
pinging_peers,
collecting_peers,
4,
)
}
fn snapshot_exited() -> ClusterView {
ClusterView::new(
PeerState::Bootstrapped,
true,
vec![1, 2, 3],
vec![1, 2, 3, 4, 5],
4,
)
}
#[test]
fn new_stores_previous_state() {
let prev = cluster_view(vec![1], vec![]);
let next = cluster_view(vec![1], vec![1]);
let outputs = vec![Outcome::ParticipationAccepted { peer_id: 1 }];
let transition = Transition::new(prev, outputs, next);
assert_eq!(transition.previous_view(), cluster_view(vec![1], vec![]));
}
#[test]
fn new_stores_new_state() {
let prev = cluster_view(vec![1], vec![]);
let next = cluster_view(vec![1], vec![1]);
let outputs = vec![Outcome::ParticipationAccepted { peer_id: 1 }];
let transition = Transition::new(prev, outputs, next);
assert_eq!(transition.new_view(), cluster_view(vec![1], vec![1]));
}
#[test]
fn new_stores_outputs() {
let prev = cluster_view(vec![], vec![]);
let next = cluster_view(vec![1], vec![]);
let outputs = vec![
Outcome::LocalParticipationCompleted,
Outcome::BroadcastLocalReady,
];
let transition = Transition::new(prev, outputs.clone(), next);
assert_eq!(transition.outputs(), &outputs);
}
#[test]
fn new_handles_empty_outputs() {
let prev = cluster_view(vec![], vec![]);
let next = cluster_view(vec![], vec![1]);
let outputs = vec![];
let transition = Transition::new(prev, outputs.clone(), next);
assert!(transition.outputs().is_empty());
}
#[test]
fn new_previous_view_preserves_snapshot() {
let prev = snapshot_exited();
let next = cluster_view(vec![], vec![]);
let outputs = vec![];
let transition = Transition::new(prev, outputs, next);
let result = transition.previous_view();
assert_eq!(result.peer_state(), PeerState::Bootstrapped);
assert_eq!(result.conclusion(), Some(Conclusion::Bootstrapped));
assert!(result.is_pinging_completed());
assert!(result.is_concluded());
assert_eq!(result.pinging_peers().len(), 3);
assert_eq!(result.collecting_peers().len(), 5);
}
#[test]
fn new_view_preserves_full_snapshot() {
let prev = cluster_view(vec![], vec![]);
let next = snapshot_exited();
let transition = Transition::new(prev, vec![], next);
let result = transition.new_view();
assert_eq!(result.peer_state(), PeerState::Bootstrapped);
assert_eq!(result.conclusion(), Some(Conclusion::Bootstrapped));
assert!(result.is_pinging_completed());
assert!(result.is_concluded());
assert_eq!(result.pinging_peers().len(), 3);
assert_eq!(result.collecting_peers().len(), 5);
}
#[test]
fn new_outputs_immutable() {
let prev = cluster_view(vec![], vec![]);
let next = cluster_view(vec![1], vec![]);
let outputs = vec![Outcome::ReadyAccepted { peer_id: 1 }];
let transition = Transition::new(prev, outputs, next);
assert_eq!(transition.outputs().len(), 1);
assert_eq!(
transition.outputs()[0],
Outcome::ReadyAccepted { peer_id: 1 }
);
}
#[test]
fn clone_produces_equal_transition() {
let prev = cluster_view(vec![1], vec![]);
let next = cluster_view(vec![1], vec![1, 2]);
let outputs = vec![
Outcome::ReadyAccepted { peer_id: 3 },
Outcome::Concluded {
mode: Conclusion::Bootstrapped,
},
];
let transition = Transition::new(prev, outputs.clone(), next);
let cloned = transition.clone();
assert_eq!(cloned.previous_view(), transition.previous_view());
assert_eq!(cloned.new_view(), transition.new_view());
assert_eq!(cloned.outputs(), transition.outputs());
}
#[test]
fn debug_format_does_not_panic() {
let transition = Transition::new(
cluster_view(vec![], vec![]),
vec![],
cluster_view(vec![1], vec![1]),
);
let _ = format!("{:?}", transition);
}