Skip to content

Commit

Permalink
Implement few election tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tailhook committed Oct 12, 2015
1 parent 1af0bca commit 73fa215
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 6 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ scan_dir = "0.2.0"
time = "0.1.32"
rand = "0.3.11"
libc = "0.1.10"
matches = "0.1.2"
29 changes: 29 additions & 0 deletions src/elect/action.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use time::SteadyTime;


#[derive(PartialEq, Eq, Debug)]
pub enum Action {
LeaderPing,
}

#[derive(PartialEq, Eq, Debug)]
pub struct ActionList {
pub next_wakeup: SteadyTime,
pub action: Option<Action>,
}

impl Action {
pub fn and_wait(self, time: SteadyTime) -> ActionList {
ActionList {
next_wakeup: time,
action: Some(self),
}
}
pub fn wait(time: SteadyTime) -> ActionList {
ActionList {
next_wakeup: time,
action: None,
}
}
}

2 changes: 2 additions & 0 deletions src/elect/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ use time::SteadyTime;
use time::Timespec;

mod node;
mod action;
mod settings;
mod external;
#[cfg(test)] mod test_node;
#[cfg(test)] mod test_mesh;
#[cfg(test)] mod test_util;
#[cfg(test)] mod test_split_brain;
Expand Down
30 changes: 29 additions & 1 deletion src/elect/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ use rand::{thread_rng, Rng};
use time::{SteadyTime, Duration};

use super::{Node, Machine, ExternalData};
use super::settings::start_timeout;
use super::settings::{start_timeout, HEARTBEAT_INTERVAL};
use super::action::{Action, ActionList};


impl Node {
Expand All @@ -15,4 +16,31 @@ impl Node {
ext: ExternalData::empty(),
}
}
pub fn time_passed(self, now: SteadyTime) -> (Node, ActionList) {
use super::Machine::*;
let (machine, action) = match self.machine {
Starting { leader_deadline } if leader_deadline <= now => {
info!("[{}] Time passed. Electing as a leader", self.id);
if self.ext.all_hosts.len() == 0 {
// No other hosts. May safefully become a leader
let next_ping = now +
Duration::milliseconds(HEARTBEAT_INTERVAL);
(Leader { ping_time: next_ping },
Action::LeaderPing.and_wait(next_ping))
} else {
unimplemented!();
}
}
Starting { leader_deadline: dline }
=> (Starting { leader_deadline: dline }, Action::wait(dline)),
_ => unimplemented!(),
};
return (
Node {
machine: machine,
id: self.id,
ext: self.ext,
},
action)
}
}
2 changes: 1 addition & 1 deletion src/elect/settings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub const MAX_MESSAGE_TIMEOUT: i64 = 3000;
/// system. There is no good reason to wait so long for original Raft. I.e.
/// it wants to reestablish consistency as fast as possible. But it may be
/// nicer to keep lower elections for us.
pub const HEARTBEAT_INTERVAL: u64 = 600;
pub const HEARTBEAT_INTERVAL: i64 = 600;


pub fn start_timeout() -> Duration {
Expand Down
1 change: 0 additions & 1 deletion src/elect/test_mesh.sh

This file was deleted.

30 changes: 30 additions & 0 deletions src/elect/test_node.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//! Tests for the case of single node
//!
use time::SteadyTime;

use super::{Node, Machine};
use super::action::Action;
use super::test_util::TimeScale;


#[test]
fn test_starting() {
let mut scale = TimeScale::new();
let node = Node::new("one", scale.now());
assert!(matches!(node.machine, Machine::Starting { .. }));
}

#[test]
fn test_alone() {
let mut scale = TimeScale::new();
let node = Node::new("one", scale.now());
assert!(matches!(node.machine, Machine::Starting { .. }));
scale.advance_ms(100); // Small time, just continue starting
let (node, act) = node.time_passed(scale.now());
assert!(matches!(node.machine, Machine::Starting { .. }));
assert!(act.action == None);
scale.advance_ms(10000); // Large timeout, should already become a leader
let (node, act) = node.time_passed(scale.now());
assert!(matches!(node.machine, Machine::Leader { .. }));
assert!(act.action == Some(Action::LeaderPing));
}
15 changes: 12 additions & 3 deletions src/elect/test_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,21 @@ use time::{SteadyTime, Duration};



struct TimeScale {
pub struct TimeScale {
now: SteadyTime,
}

impl TimeScale {
fn advance_ms(&mut self, ms: u64) {
self.now += Duration::milliseconds(ms);
pub fn new() -> TimeScale {
TimeScale {
// unfortunately we can't create arbitrary steady time value
now: SteadyTime::now(),
}
}
pub fn advance_ms(&mut self, ms: i64) {
self.now = self.now + Duration::milliseconds(ms);
}
pub fn now(&self) -> SteadyTime {
self.now
}
}
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ extern crate libc;
extern crate lua;
extern crate scan_dir;
extern crate yaml_rust;
#[macro_use] extern crate matches;
#[macro_use] extern crate log;
#[macro_use] extern crate quick_error;

Expand Down

0 comments on commit 73fa215

Please sign in to comment.