use std::collections::HashMap;
use crate::RaftLogReader;
use crate::engine::LogIdList;
use crate::engine::leader_log_ids::LeaderLogIds;
use crate::engine::testing::UTConfig;
use crate::engine::testing::UtClid;
use crate::engine::testing::log_id;
use crate::entry::RaftEntry;
use crate::log_id::raft_log_id_ext::RaftLogIdExt;
use crate::type_config::TypeConfigExt;
use crate::type_config::alias::LogIdOf;
struct MockLogReader {
logs: HashMap<u64, LogIdOf<UTConfig>>,
}
impl MockLogReader {
fn new(logs: Vec<LogIdOf<UTConfig>>) -> Self {
let mut map = HashMap::new();
for log_id in logs {
map.insert(log_id.index(), log_id);
}
Self { logs: map }
}
}
impl RaftLogReader<UTConfig> for MockLogReader {
async fn try_get_log_entries<RNG>(
&mut self,
range: RNG,
) -> Result<Vec<<UTConfig as crate::RaftTypeConfig>::Entry>, std::io::Error>
where
RNG: std::ops::RangeBounds<u64> + Clone + std::fmt::Debug + crate::OptionalSend,
{
use std::ops::Bound;
let start = match range.start_bound() {
Bound::Included(&s) => s,
Bound::Excluded(&s) => s + 1,
Bound::Unbounded => 0,
};
let end = match range.end_bound() {
Bound::Included(&e) => e + 1,
Bound::Excluded(&e) => e,
Bound::Unbounded => u64::MAX,
};
let mut entries = Vec::new();
for i in start..end {
if let Some(log_id) = self.logs.get(&i) {
entries.push(crate::type_config::alias::EntryOf::<UTConfig>::new_blank(*log_id));
}
}
Ok(entries)
}
async fn read_vote(&mut self) -> Result<Option<<UTConfig as crate::RaftTypeConfig>::Vote>, std::io::Error> {
Ok(None)
}
}
#[test]
fn test_log_id_list_extend_from_same_leader() -> anyhow::Result<()> {
let mut ids = LogIdList::<UtClid>::default();
ids.extend_from_same_leader([log_id(1, 1, 2)]);
assert_eq!(vec![log_id(1, 1, 2)], ids.key_log_ids());
ids.extend_from_same_leader([
log_id(1, 1, 3), log_id(1, 1, 4),
]);
assert_eq!(
vec![log_id(1, 1, 4)],
ids.key_log_ids(),
"same leader as the last, replace with last"
);
ids.extend_from_same_leader([
log_id(2, 1, 5), log_id(2, 1, 6),
log_id(2, 1, 7),
]);
assert_eq!(
vec![
log_id(1, 1, 4), log_id(2, 1, 7)
],
ids.key_log_ids(),
"different leader as the last"
);
Ok(())
}
#[test]
fn test_log_id_list_extend() -> anyhow::Result<()> {
let mut ids = LogIdList::<UtClid>::default();
ids.extend([log_id(1, 1, 2)]);
assert_eq!(vec![log_id(1, 1, 2)], ids.key_log_ids());
ids.extend([
log_id(1, 1, 3), log_id(1, 1, 4),
]);
assert_eq!(vec![log_id(1, 1, 4)], ids.key_log_ids(), "same leader as the last");
ids.extend([
log_id(1, 1, 5), log_id(2, 1, 6),
log_id(2, 1, 7),
]);
assert_eq!(
vec![
log_id(1, 1, 5), log_id(2, 1, 7)
],
ids.key_log_ids(),
"last 2 have the same leaders"
);
ids.extend([
log_id(2, 1, 8), log_id(2, 1, 9),
log_id(3, 1, 10),
]);
assert_eq!(
vec![
log_id(1, 1, 5), log_id(2, 1, 9),
log_id(3, 1, 10),
],
ids.key_log_ids(),
"last 2 have different leaders"
);
Ok(())
}
#[test]
fn test_log_id_list_append() -> anyhow::Result<()> {
let mut ids = LogIdList::<UtClid>::default();
let cases = vec![
(log_id(1, 1, 2), vec![log_id(1, 1, 2)]),
(log_id(1, 1, 3), vec![log_id(1, 1, 3)]), (log_id(1, 1, 4), vec![log_id(1, 1, 4)]), (log_id(2, 1, 5), vec![log_id(1, 1, 4), log_id(2, 1, 5)]), (log_id(2, 1, 7), vec![log_id(1, 1, 4), log_id(2, 1, 7)]), (log_id(2, 1, 9), vec![log_id(1, 1, 4), log_id(2, 1, 9)]), ];
for (new_log_id, want) in cases {
ids.append(new_log_id);
assert_eq!(want, ids.key_log_ids());
}
Ok(())
}
#[test]
fn test_log_id_list_truncate() -> anyhow::Result<()> {
let make_ids = || {
LogIdList::<UtClid>::new(None, vec![
log_id(2, 1, 2), log_id(3, 1, 5), log_id(6, 1, 8), log_id(9, 1, 11), ])
};
let cases = vec![
(0, vec![]), (1, vec![log_id(2, 1, 0)]), (2, vec![log_id(2, 1, 1)]), (3, vec![log_id(2, 1, 2)]), (4, vec![log_id(2, 1, 2), log_id(3, 1, 3)]), (5, vec![log_id(2, 1, 2), log_id(3, 1, 4)]), (6, vec![log_id(2, 1, 2), log_id(3, 1, 5)]), (7, vec![log_id(2, 1, 2), log_id(3, 1, 5), log_id(6, 1, 6)]), (8, vec![log_id(2, 1, 2), log_id(3, 1, 5), log_id(6, 1, 7)]), (9, vec![log_id(2, 1, 2), log_id(3, 1, 5), log_id(6, 1, 8)]), (10, vec![
log_id(2, 1, 2),
log_id(3, 1, 5),
log_id(6, 1, 8),
log_id(9, 1, 9),
]), (11, vec![
log_id(2, 1, 2),
log_id(3, 1, 5),
log_id(6, 1, 8),
log_id(9, 1, 10),
]), (12, vec![
log_id(2, 1, 2),
log_id(3, 1, 5),
log_id(6, 1, 8),
log_id(9, 1, 11),
]), (13, vec![
log_id(2, 1, 2),
log_id(3, 1, 5),
log_id(6, 1, 8),
log_id(9, 1, 11),
]), ];
for (at, want) in cases {
let mut ids = make_ids();
ids.truncate(at);
assert_eq!(want, ids.key_log_ids(), "truncate since: [{}, +oo)", at);
}
Ok(())
}
#[test]
fn test_log_id_list_purge() -> anyhow::Result<()> {
{
let mut ids = LogIdList::<UtClid>::new(None, vec![]);
ids.purge(&log_id(2, 1, 2));
assert_eq!(Some(&log_id(2, 1, 2)), ids.purged());
assert!(ids.key_log_ids().is_empty());
}
let make_ids = || {
LogIdList::<UtClid>::new(None, vec![
log_id(2, 1, 2), log_id(3, 1, 5), log_id(6, 1, 8), log_id(9, 1, 11), ])
};
let cases: Vec<(_, Option<_>, Vec<_>)> = vec![
(log_id(2, 1, 1), Some(log_id(2, 1, 1)), vec![
log_id(2, 1, 2),
log_id(3, 1, 5),
log_id(6, 1, 8),
log_id(9, 1, 11),
]),
(log_id(2, 1, 2), Some(log_id(2, 1, 2)), vec![
log_id(3, 1, 5),
log_id(6, 1, 8),
log_id(9, 1, 11),
]),
(log_id(3, 1, 3), Some(log_id(3, 1, 3)), vec![
log_id(3, 1, 5),
log_id(6, 1, 8),
log_id(9, 1, 11),
]),
(log_id(3, 1, 4), Some(log_id(3, 1, 4)), vec![
log_id(3, 1, 5),
log_id(6, 1, 8),
log_id(9, 1, 11),
]),
(log_id(3, 1, 5), Some(log_id(3, 1, 5)), vec![
log_id(6, 1, 8),
log_id(9, 1, 11),
]),
(log_id(6, 1, 6), Some(log_id(6, 1, 6)), vec![
log_id(6, 1, 8),
log_id(9, 1, 11),
]),
(log_id(6, 1, 7), Some(log_id(6, 1, 7)), vec![
log_id(6, 1, 8),
log_id(9, 1, 11),
]),
(log_id(6, 1, 8), Some(log_id(6, 1, 8)), vec![log_id(9, 1, 11)]),
(log_id(9, 1, 9), Some(log_id(9, 1, 9)), vec![log_id(9, 1, 11)]),
(log_id(9, 1, 10), Some(log_id(9, 1, 10)), vec![log_id(9, 1, 11)]),
(log_id(9, 1, 11), Some(log_id(9, 1, 11)), vec![]),
(log_id(9, 1, 12), Some(log_id(9, 1, 12)), vec![]),
(log_id(10, 1, 12), Some(log_id(10, 1, 12)), vec![]),
];
for (upto, want_purged, want_key_log_ids) in cases {
let mut ids = make_ids();
ids.purge(&upto);
assert_eq!(
want_purged.as_ref(),
ids.purged(),
"purge upto: {} - purged field",
upto
);
assert_eq!(
want_key_log_ids,
ids.key_log_ids(),
"purge upto: {} - key_log_ids",
upto
);
}
Ok(())
}
#[test]
fn test_log_id_list_get_log_id() -> anyhow::Result<()> {
let ids = LogIdList::<UtClid>::default();
assert!(ids.get(0).is_none());
assert!(ids.get(1).is_none());
assert!(ids.get(2).is_none());
let ids = LogIdList::<UtClid>::new(None, vec![
log_id(1, 1, 2), log_id(3, 1, 5), log_id(5, 1, 7), log_id(7, 1, 10), ]);
assert_eq!(Some(log_id(1, 1, 0)), ids.get(0));
assert_eq!(Some(log_id(1, 1, 1)), ids.get(1));
assert_eq!(Some(log_id(1, 1, 2)), ids.get(2));
assert_eq!(Some(log_id(3, 1, 3)), ids.get(3));
assert_eq!(Some(log_id(3, 1, 4)), ids.get(4));
assert_eq!(Some(log_id(3, 1, 5)), ids.get(5));
assert_eq!(Some(log_id(5, 1, 6)), ids.get(6));
assert_eq!(Some(log_id(5, 1, 7)), ids.get(7));
assert_eq!(Some(log_id(7, 1, 8)), ids.get(8));
assert_eq!(Some(log_id(7, 1, 9)), ids.get(9));
assert_eq!(Some(log_id(7, 1, 10)), ids.get(10));
assert_eq!(None, ids.get(11));
Ok(())
}
#[test]
fn test_log_id_list_by_last_leader() -> anyhow::Result<()> {
let ids = LogIdList::<UtClid>::default();
assert_eq!(ids.by_last_leader(), None);
let ids = LogIdList::<UtClid>::new(None, [log_id(1, 1, 1)]);
assert_eq!(
Some(LeaderLogIds::new(*log_id(1, 1, 0).committed_leader_id(), 0, 1)),
ids.by_last_leader()
);
let ids = LogIdList::<UtClid>::new(None, [log_id(1, 1, 1), log_id(3, 1, 3)]);
assert_eq!(
Some(LeaderLogIds::new(*log_id(3, 1, 0).committed_leader_id(), 2, 3)),
ids.by_last_leader()
);
let ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), [log_id(1, 1, 5)]);
assert_eq!(
Some(LeaderLogIds::new(*log_id(1, 1, 0).committed_leader_id(), 3, 5)),
ids.by_last_leader()
);
let ids = LogIdList::<UtClid>::new(None, [log_id(1, 1, 2), log_id(7, 1, 10)]);
assert_eq!(
Some(LeaderLogIds::new(*log_id(7, 1, 0).committed_leader_id(), 3, 10)),
ids.by_last_leader()
);
Ok(())
}
#[test]
fn test_log_id_list_last() -> anyhow::Result<()> {
let ids = LogIdList::<UtClid>::default();
assert_eq!(None, ids.last());
let ids = LogIdList::<UtClid>::new(Some(log_id(2, 1, 5)), vec![]);
assert_eq!(Some(&log_id(2, 1, 5)), ids.last());
let ids = LogIdList::<UtClid>::new(None, vec![log_id(1, 1, 3)]);
assert_eq!(Some(&log_id(1, 1, 3)), ids.last());
let ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![log_id(1, 1, 5)]);
assert_eq!(Some(&log_id(1, 1, 5)), ids.last());
let ids = LogIdList::<UtClid>::new(None, vec![log_id(1, 1, 3), log_id(2, 1, 6)]);
assert_eq!(Some(&log_id(2, 1, 6)), ids.last());
let ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![log_id(1, 1, 5), log_id(2, 1, 8)]);
assert_eq!(Some(&log_id(2, 1, 8)), ids.last());
Ok(())
}
#[test]
fn test_log_id_list_first() -> anyhow::Result<()> {
let ids = LogIdList::<UtClid>::default();
assert_eq!(None, ids.first());
let ids = LogIdList::<UtClid>::new(Some(log_id(2, 1, 5)), vec![]);
assert_eq!(None, ids.first());
let ids = LogIdList::<UtClid>::new(None, vec![log_id(1, 1, 3)]);
assert_eq!(Some(log_id(1, 1, 0).to_ref()), ids.first());
let ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![log_id(1, 1, 5)]);
assert_eq!(Some(log_id(1, 1, 3).to_ref()), ids.first());
let ids = LogIdList::<UtClid>::new(None, vec![log_id(1, 1, 3), log_id(2, 1, 6)]);
assert_eq!(Some(log_id(1, 1, 0).to_ref()), ids.first());
let ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![log_id(1, 1, 5), log_id(2, 1, 8)]);
assert_eq!(Some(log_id(1, 1, 3).to_ref()), ids.first());
Ok(())
}
#[test]
fn test_log_id_list_ref_at_with_purged() -> anyhow::Result<()> {
let ids = LogIdList::<UtClid>::new(Some(log_id(2, 1, 5)), vec![log_id(2, 1, 8)]);
assert_eq!(None, ids.ref_at(4));
assert_eq!(Some(log_id(2, 1, 5).to_ref()), ids.ref_at(5));
assert_eq!(Some(log_id(2, 1, 6).to_ref()), ids.ref_at(6));
assert_eq!(Some(log_id(2, 1, 7).to_ref()), ids.ref_at(7));
assert_eq!(Some(log_id(2, 1, 8).to_ref()), ids.ref_at(8));
assert_eq!(None, ids.ref_at(9));
let ids = LogIdList::<UtClid>::new(Some(log_id(2, 1, 5)), vec![]);
assert_eq!(Some(log_id(2, 1, 5).to_ref()), ids.ref_at(5));
assert_eq!(None, ids.ref_at(4));
assert_eq!(None, ids.ref_at(6));
Ok(())
}
#[test]
fn test_log_id_list_get_with_purged() -> anyhow::Result<()> {
let ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![log_id(1, 1, 5), log_id(3, 1, 8)]);
assert_eq!(None, ids.get(0));
assert_eq!(None, ids.get(1));
assert_eq!(Some(log_id(1, 1, 2)), ids.get(2));
assert_eq!(Some(log_id(1, 1, 3)), ids.get(3));
assert_eq!(Some(log_id(1, 1, 4)), ids.get(4));
assert_eq!(Some(log_id(1, 1, 5)), ids.get(5));
assert_eq!(Some(log_id(3, 1, 6)), ids.get(6));
assert_eq!(Some(log_id(3, 1, 7)), ids.get(7));
assert_eq!(Some(log_id(3, 1, 8)), ids.get(8));
assert_eq!(None, ids.get(9));
Ok(())
}
#[test]
fn test_log_id_list_truncate_with_purged() -> anyhow::Result<()> {
let make_ids = || LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![log_id(1, 1, 5), log_id(2, 1, 8)]);
{
let mut ids = make_ids();
ids.truncate(3);
assert_eq!(Some(&log_id(1, 1, 2)), ids.purged());
assert!(ids.key_log_ids().is_empty());
}
{
let mut ids = make_ids();
ids.truncate(4);
assert_eq!(Some(&log_id(1, 1, 2)), ids.purged());
assert_eq!(vec![log_id(1, 1, 3)], ids.key_log_ids());
}
{
let mut ids = make_ids();
ids.truncate(5);
assert_eq!(Some(&log_id(1, 1, 2)), ids.purged());
assert_eq!(vec![log_id(1, 1, 4)], ids.key_log_ids());
}
{
let mut ids = make_ids();
ids.truncate(6);
assert_eq!(Some(&log_id(1, 1, 2)), ids.purged());
assert_eq!(vec![log_id(1, 1, 5)], ids.key_log_ids());
}
{
let mut ids = make_ids();
ids.truncate(7);
assert_eq!(Some(&log_id(1, 1, 2)), ids.purged());
assert_eq!(vec![log_id(1, 1, 5), log_id(2, 1, 6)], ids.key_log_ids());
}
{
let mut ids = make_ids();
ids.truncate(8);
assert_eq!(Some(&log_id(1, 1, 2)), ids.purged());
assert_eq!(vec![log_id(1, 1, 5), log_id(2, 1, 7)], ids.key_log_ids());
}
{
let mut ids = make_ids();
ids.truncate(9);
assert_eq!(Some(&log_id(1, 1, 2)), ids.purged());
assert_eq!(vec![log_id(1, 1, 5), log_id(2, 1, 8)], ids.key_log_ids());
}
Ok(())
}
#[test]
fn test_log_id_list_append_with_purged() -> anyhow::Result<()> {
let mut ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![]);
ids.append(log_id(1, 1, 3));
assert_eq!(Some(&log_id(1, 1, 2)), ids.purged());
assert_eq!(vec![log_id(1, 1, 3)], ids.key_log_ids());
ids.append(log_id(1, 1, 4));
assert_eq!(vec![log_id(1, 1, 4)], ids.key_log_ids());
ids.append(log_id(2, 1, 5));
assert_eq!(vec![log_id(1, 1, 4), log_id(2, 1, 5)], ids.key_log_ids());
Ok(())
}
#[test]
fn test_log_id_list_append_with_purged_different_leader() -> anyhow::Result<()> {
let mut ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![]);
ids.append(log_id(2, 1, 3));
assert_eq!(Some(&log_id(1, 1, 2)), ids.purged());
assert_eq!(vec![log_id(2, 1, 3)], ids.key_log_ids());
Ok(())
}
#[test]
fn test_log_id_list_extend_with_purged() -> anyhow::Result<()> {
{
let mut ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![]);
ids.extend([log_id(1, 1, 3), log_id(1, 1, 4)]);
assert_eq!(Some(&log_id(1, 1, 2)), ids.purged());
assert_eq!(vec![log_id(1, 1, 4)], ids.key_log_ids());
}
{
let mut ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![]);
ids.extend([log_id(2, 1, 3), log_id(2, 1, 4)]);
assert_eq!(Some(&log_id(1, 1, 2)), ids.purged());
assert_eq!(vec![log_id(2, 1, 4)], ids.key_log_ids());
}
{
let mut ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![]);
ids.extend([log_id(1, 1, 3), log_id(2, 1, 4), log_id(2, 1, 5)]);
assert_eq!(Some(&log_id(1, 1, 2)), ids.purged());
assert_eq!(vec![log_id(1, 1, 3), log_id(2, 1, 5)], ids.key_log_ids());
}
Ok(())
}
#[test]
fn test_log_id_list_extend_from_same_leader_with_purged() -> anyhow::Result<()> {
{
let mut ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![]);
ids.extend_from_same_leader([log_id(1, 1, 3), log_id(1, 1, 4), log_id(1, 1, 5)]);
assert_eq!(Some(&log_id(1, 1, 2)), ids.purged());
assert_eq!(vec![log_id(1, 1, 5)], ids.key_log_ids());
}
{
let mut ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![]);
ids.extend_from_same_leader([log_id(2, 1, 3), log_id(2, 1, 4), log_id(2, 1, 5)]);
assert_eq!(Some(&log_id(1, 1, 2)), ids.purged());
assert_eq!(vec![log_id(2, 1, 5)], ids.key_log_ids());
}
Ok(())
}
#[test]
fn test_log_id_list_purge_edge_cases() -> anyhow::Result<()> {
{
let mut ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![]);
ids.purge(&log_id(2, 1, 5));
assert_eq!(Some(&log_id(2, 1, 5)), ids.purged());
assert!(ids.key_log_ids().is_empty());
}
{
let mut ids = LogIdList::<UtClid>::new(None, vec![log_id(1, 1, 3)]);
ids.purge(&log_id(1, 1, 1));
assert_eq!(Some(&log_id(1, 1, 1)), ids.purged());
assert_eq!(vec![log_id(1, 1, 3)], ids.key_log_ids());
}
{
let mut ids = LogIdList::<UtClid>::new(None, vec![log_id(1, 1, 3)]);
ids.purge(&log_id(1, 1, 3));
assert_eq!(Some(&log_id(1, 1, 3)), ids.purged());
assert!(ids.key_log_ids().is_empty());
}
{
let mut ids = LogIdList::<UtClid>::new(None, vec![log_id(1, 1, 3)]);
ids.purge(&log_id(1, 1, 5));
assert_eq!(Some(&log_id(1, 1, 5)), ids.purged());
assert!(ids.key_log_ids().is_empty());
}
{
let mut ids = LogIdList::<UtClid>::new(None, vec![log_id(1, 1, 3), log_id(2, 1, 6)]);
ids.purge(&log_id(1, 1, 2));
assert_eq!(Some(&log_id(1, 1, 2)), ids.purged());
assert_eq!(vec![log_id(1, 1, 3), log_id(2, 1, 6)], ids.key_log_ids());
}
{
let mut ids = LogIdList::<UtClid>::new(None, vec![log_id(1, 1, 3), log_id(2, 1, 6)]);
ids.purge(&log_id(1, 1, 3));
assert_eq!(Some(&log_id(1, 1, 3)), ids.purged());
assert_eq!(vec![log_id(2, 1, 6)], ids.key_log_ids());
}
{
let mut ids = LogIdList::<UtClid>::new(None, vec![log_id(1, 1, 3), log_id(2, 1, 6)]);
ids.purge(&log_id(2, 1, 5));
assert_eq!(Some(&log_id(2, 1, 5)), ids.purged());
assert_eq!(vec![log_id(2, 1, 6)], ids.key_log_ids());
}
Ok(())
}
#[test]
fn test_log_id_list_by_last_leader_edge_cases() -> anyhow::Result<()> {
let ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 5)), vec![]);
assert_eq!(
Some(LeaderLogIds::new(*log_id(1, 1, 0).committed_leader_id(), 5, 5)),
ids.by_last_leader()
);
let ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![log_id(1, 1, 5)]);
assert_eq!(
Some(LeaderLogIds::new(*log_id(1, 1, 0).committed_leader_id(), 3, 5)),
ids.by_last_leader()
);
let ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![log_id(2, 1, 5)]);
assert_eq!(
Some(LeaderLogIds::new(*log_id(2, 1, 0).committed_leader_id(), 3, 5)),
ids.by_last_leader()
);
let ids = LogIdList::<UtClid>::new(Some(log_id(1, 1, 2)), vec![log_id(1, 1, 4), log_id(2, 1, 7)]);
assert_eq!(
Some(LeaderLogIds::new(*log_id(2, 1, 0).committed_leader_id(), 5, 7)),
ids.by_last_leader()
);
Ok(())
}
#[test]
fn test_get_key_log_ids_single_log() {
UTConfig::<()>::run(async {
let logs = vec![log_id(1, 1, 0)];
let mut reader = MockLogReader::new(logs);
let result = LogIdList::get_key_log_ids(log_id(1, 1, 0)..=log_id(1, 1, 0), &mut reader).await.unwrap();
assert_eq!(vec![log_id(1, 1, 0)], result);
});
}
#[test]
fn test_get_key_log_ids_all_same_leader() {
UTConfig::<()>::run(async {
let logs = vec![log_id(1, 1, 0), log_id(1, 1, 1), log_id(1, 1, 2)];
let mut reader = MockLogReader::new(logs);
let result = LogIdList::get_key_log_ids(log_id(1, 1, 0)..=log_id(1, 1, 2), &mut reader).await.unwrap();
assert_eq!(vec![log_id(1, 1, 2)], result);
});
}
#[test]
fn test_get_key_log_ids_two_adjacent_leaders() {
UTConfig::<()>::run(async {
let logs = vec![log_id(1, 1, 0), log_id(2, 1, 1)];
let mut reader = MockLogReader::new(logs);
let result = LogIdList::get_key_log_ids(log_id(1, 1, 0)..=log_id(2, 1, 1), &mut reader).await.unwrap();
assert_eq!(vec![log_id(1, 1, 0), log_id(2, 1, 1)], result);
});
}
#[test]
fn test_get_key_log_ids_case_aac() {
UTConfig::<()>::run(async {
let logs = vec![log_id(1, 1, 0), log_id(1, 1, 1), log_id(2, 1, 2)];
let mut reader = MockLogReader::new(logs);
let result = LogIdList::get_key_log_ids(log_id(1, 1, 0)..=log_id(2, 1, 2), &mut reader).await.unwrap();
assert_eq!(vec![log_id(1, 1, 1), log_id(2, 1, 2)], result);
});
}
#[test]
fn test_get_key_log_ids_case_acc() {
UTConfig::<()>::run(async {
let logs = vec![log_id(1, 1, 0), log_id(2, 1, 1), log_id(2, 1, 2), log_id(2, 1, 3)];
let mut reader = MockLogReader::new(logs);
let result = LogIdList::get_key_log_ids(log_id(1, 1, 0)..=log_id(2, 1, 3), &mut reader).await.unwrap();
assert_eq!(vec![log_id(1, 1, 0), log_id(2, 1, 3)], result);
});
}
#[test]
fn test_get_key_log_ids_case_abc() {
UTConfig::<()>::run(async {
let logs = vec![log_id(1, 1, 0), log_id(2, 1, 1), log_id(3, 1, 2)];
let mut reader = MockLogReader::new(logs);
let result = LogIdList::get_key_log_ids(log_id(1, 1, 0)..=log_id(3, 1, 2), &mut reader).await.unwrap();
assert_eq!(vec![log_id(1, 1, 0), log_id(2, 1, 1), log_id(3, 1, 2)], result);
});
}
#[test]
fn test_get_key_log_ids_many_same_leader() {
UTConfig::<()>::run(async {
let logs = vec![
log_id(1, 1, 0),
log_id(2, 1, 1),
log_id(2, 1, 2),
log_id(2, 1, 3),
log_id(2, 1, 4),
];
let mut reader = MockLogReader::new(logs);
let result = LogIdList::get_key_log_ids(log_id(1, 1, 0)..=log_id(2, 1, 4), &mut reader).await.unwrap();
assert_eq!(vec![log_id(1, 1, 0), log_id(2, 1, 4)], result);
});
}
#[test]
fn test_get_key_log_ids_three_leaders() {
UTConfig::<()>::run(async {
let logs = vec![
log_id(1, 1, 0),
log_id(2, 1, 1),
log_id(2, 1, 2),
log_id(2, 1, 3),
log_id(3, 1, 4),
log_id(3, 1, 5),
];
let mut reader = MockLogReader::new(logs);
let result = LogIdList::get_key_log_ids(log_id(1, 1, 0)..=log_id(3, 1, 5), &mut reader).await.unwrap();
assert_eq!(vec![log_id(1, 1, 0), log_id(2, 1, 3), log_id(3, 1, 5)], result);
});
}
#[test]
fn test_get_key_log_ids_long_same_leader() {
UTConfig::<()>::run(async {
let logs: Vec<_> = (0..10).map(|i| log_id(1, 1, i)).collect();
let mut reader = MockLogReader::new(logs);
let result = LogIdList::get_key_log_ids(log_id(1, 1, 0)..=log_id(1, 1, 9), &mut reader).await.unwrap();
assert_eq!(vec![log_id(1, 1, 9)], result);
});
}