mod fake;
mod items;
mod walks;
use super::*;
use fake::{FakeNode, Mood};
use std::io;
fn quick() -> Config {
Config {
alpha: 3,
k: 3,
round: Duration::from_millis(300),
max_queries: 64,
}
}
fn client(bootstrap: Vec<SocketAddr>, config: Config) -> Dht {
let udp = Udp::bind("127.0.0.1:0".parse().unwrap()).unwrap();
Dht::new(Box::new(udp), bootstrap, config).unwrap()
}
fn id(fill: u8) -> NodeId {
NodeId([fill; 20])
}
fn topology() -> [FakeNode; 4] {
let a = FakeNode::bind(id(0x00));
let b = FakeNode::bind(id(0x0f));
let c = FakeNode::bind(id(0x10));
let d = FakeNode::bind(id(0xf0));
[a, b, c, d]
}
fn serve(nodes: &mut [FakeNode; 4], items_on_c: Vec<Mutable>, items_on_d: Vec<Mutable>) {
let (b, c, d) = (nodes[1].node(), nodes[2].node(), nodes[3].node());
let unreachable = Node {
id: id(0xfe),
addr: "[::1]:9".parse().unwrap(),
};
nodes[0].serve(vec![b, c, unreachable], Mood::Answer, vec![]);
nodes[1].serve(vec![d], Mood::Answer, vec![]);
nodes[2].serve(vec![], Mood::Answer, items_on_c);
nodes[3].serve(vec![], Mood::Answer, items_on_d);
}
#[test]
fn the_defaults_are_the_beps() {
let c = Config::default();
assert_eq!(
(c.alpha, c.k, c.round, c.max_queries),
(3, 8, Duration::from_secs(2), 64)
);
}
#[test]
fn a_client_mints_an_id_and_counts_transactions_around_the_wrap() {
let mut dht = client(vec![], quick());
assert_ne!(dht.id(), NodeId([0; 20]));
assert_eq!(dht.next_tid(), vec![0, 1]);
dht.tid = u16::MAX;
assert_eq!(dht.next_tid(), vec![0, 0]);
}
struct Stub {
sends: bool,
}
impl Transport for Stub {
fn send(&self, _: SocketAddr, _: &[u8]) -> io::Result<()> {
self.sends
.then_some(())
.ok_or_else(|| io::Error::other("no route"))
}
fn recv(&self, _: Duration) -> io::Result<Option<(SocketAddr, Vec<u8>)>> {
Err(io::Error::other("socket died"))
}
}
#[test]
fn a_socket_that_dies_is_the_walks_error() {
let mut dht = Dht::new(
Box::new(Stub { sends: true }),
vec!["127.0.0.1:9".parse().unwrap()],
quick(),
)
.unwrap();
assert_eq!(dht.lookup(id(1)).unwrap_err(), "DHT socket: socket died");
}
#[test]
fn a_transport_that_sends_nothing_hears_nothing() {
let mut dht = Dht::new(
Box::new(Stub { sends: false }),
vec!["127.0.0.1:9".parse().unwrap()],
quick(),
)
.unwrap();
let e = dht.lookup(id(0xff)).unwrap_err();
assert_eq!(
e,
format!("no DHT node answered find_node for {}", "ff".repeat(20))
);
}