Spaces:
Build error
Build error
File size: 4,585 Bytes
84d2a97 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
use super::local_shard::clock_map::ClockMap;
use super::replica_set::clock_set::ClockSet;
use super::shard::PeerId;
use crate::operations::ClockTag;
#[test]
fn clock_set_clock_map_workflow() {
let mut helper = Helper::new();
// `ClockSet` and `ClockMap` "stick" to tick `0`, until `ClockSet` is advanced at least once
helper.tick_clock().assert(0);
helper.advance_clock_map(false).assert(0, 0, false);
helper.advance_clock_map(false).assert(0, 0, false);
helper.advance_clock(false).assert(0, 0, false);
// `ClockSet` and `ClockMap` tick sequentially and in sync after that
for tick in 1..=10 {
helper.advance_clock(false).assert(tick, tick, true);
}
// `ClockMap` advances to newer ticks
for tick in 11..=50 {
if tick % 10 != 0 {
// Tick `ClockSet` few times, without advancing `ClockMap`...
helper.tick_clock().assert(tick);
} else {
// ...then advance both `ClockMap` and `ClockSet`
helper.advance_clock(false).assert(tick, tick, true);
}
}
// `ClockMap` rejects tick `0` and advances `ClockSet`
helper.clock_set = Default::default();
helper.advance_clock(false).assert(0, 50, false);
helper.tick_clock().assert(51);
// `ClockMap` rejects older (or current) ticks...
helper.clock_set = Default::default();
helper.clock_set.get_clock().advance_to(0);
for tick in 1..=50 {
helper.advance_clock_map(false).assert(tick, 50, false);
}
// ...and advances `ClockSet`
helper.clock_set = Default::default();
helper.clock_set.get_clock().advance_to(42);
helper.advance_clock(false).assert(43, 50, false);
helper.tick_clock().assert(51);
// `ClockMap` advances to newer ticks with `force = true`
helper.clock_set = Default::default();
helper.advance_clock(false).assert(0, 50, false);
for tick in 51..=100 {
helper.advance_clock(true).assert(tick, tick, true);
}
// `ClockMap` accepts older (or current) ticks with `force = true`...
helper.clock_set = Default::default();
for tick in 0..=100 {
helper.advance_clock(true).assert(tick, tick, true);
}
// ...but it does not affect current tick of `ClockMap` in any way
helper.clock_set = Default::default();
helper.clock_set.get_clock().advance_to(42);
helper.advance_clock(false).assert(43, 100, false);
helper.tick_clock().assert(101);
}
#[derive(Clone, Debug)]
struct Helper {
clock_set: ClockSet,
clock_map: ClockMap,
}
const PEER_ID: PeerId = 1337;
impl Helper {
pub fn new() -> Self {
Self {
clock_set: ClockSet::default(),
clock_map: ClockMap::default(),
}
}
pub fn tick_clock(&mut self) -> TickClockStatus {
let mut clock = self.clock_set.get_clock();
let clock_tag = ClockTag::new(PEER_ID, clock.id() as _, clock.tick_once());
TickClockStatus { clock_tag }
}
pub fn advance_clock_map(&mut self, force: bool) -> AdvanceStatus {
self.advance(force, false)
}
pub fn advance_clock(&mut self, force: bool) -> AdvanceStatus {
self.advance(force, true)
}
fn advance(&mut self, force: bool, advance_clock: bool) -> AdvanceStatus {
let mut clock = self.clock_set.get_clock();
let clock_tag = ClockTag::new(PEER_ID, clock.id() as _, clock.tick_once()).force(force);
let mut clock_map_tag = clock_tag;
let accepted = self
.clock_map
.advance_clock_and_correct_tag(&mut clock_map_tag);
assert_eq!(clock_tag.peer_id, clock_map_tag.peer_id);
assert_eq!(clock_tag.clock_id, clock_map_tag.clock_id);
if advance_clock {
clock.advance_to(clock_map_tag.clock_tick);
}
AdvanceStatus {
clock_tag,
clock_map_tag,
accepted,
}
}
}
#[derive(Copy, Clone, Debug)]
struct TickClockStatus {
clock_tag: ClockTag,
}
impl TickClockStatus {
pub fn assert(&self, expected_tick: u64) {
assert_eq!(self.clock_tag.clock_tick, expected_tick)
}
}
#[derive(Copy, Clone, Debug)]
struct AdvanceStatus {
clock_tag: ClockTag,
clock_map_tag: ClockTag,
accepted: bool,
}
impl AdvanceStatus {
pub fn assert(&self, expected_tick: u64, expected_cm_tick: u64, expected_status: bool) {
assert_eq!(expected_tick, self.clock_tag.clock_tick);
assert_eq!(expected_cm_tick, self.clock_map_tag.clock_tick);
assert_eq!(expected_status, self.accepted);
}
}
|