use crate::{
event::EventQueue,
network::Network,
record::RecordNetwork,
types::{NetworkError, RouterId, SinglePrefix as P, ASN},
};
use pretty_assertions::assert_eq;
fn setup_simple<Q>(
net: &mut Network<P, Q>,
) -> Result<(RouterId, RouterId, RouterId, RouterId, RouterId, RouterId), NetworkError>
where
Q: EventQueue<P>,
{
let e0 = net.add_router("E0", ASN(1));
let b0 = net.add_router("B0", 65500);
let r0 = net.add_router("R0", 65500);
let r1 = net.add_router("R1", 65500);
let b1 = net.add_router("B1", 65500);
let e1 = net.add_router("E1", ASN(1));
net.add_link(e0, b0)?;
net.add_link(b0, r0)?;
net.add_link(r0, r1)?;
net.add_link(r1, b1)?;
net.add_link(b1, e1)?;
net.set_link_weight(b0, r0, 1.0)?;
net.set_link_weight(r0, b0, 1.0)?;
net.set_link_weight(r0, r1, 1.0)?;
net.set_link_weight(r1, r0, 1.0)?;
net.set_link_weight(r1, b1, 1.0)?;
net.set_link_weight(b1, r1, 1.0)?;
net.set_bgp_session(e0, b0, Some(false))?;
net.set_bgp_session(r0, b0, Some(true))?;
net.set_bgp_session(r0, r1, Some(false))?;
net.set_bgp_session(r1, b1, Some(true))?;
net.set_bgp_session(e1, b1, Some(false))?;
Ok((e0, b0, r0, r1, b1, e1))
}
#[test]
fn test_simple_deterministic() {
let mut net: Network<P, _> = Network::default();
let prefix = P::from(0);
let (e0, b0, r0, r1, b1, e1) = setup_simple(&mut net).unwrap();
net.advertise_route(e0, prefix, vec![ASN(1), ASN(2), ASN(3)], None, None)
.unwrap();
let mut rec = net
.record(|n| n.advertise_route(e1, prefix, vec![ASN(4), ASN(5)], None, None))
.unwrap();
assert_eq!(
rec.trace(),
&vec![
(vec![(e1, vec![b1], vec![u32::MAX.into()])], None.into()),
(vec![(b1, vec![r1], vec![e1])], None.into()),
(vec![(r1, vec![r0], vec![b1])], None.into()),
(vec![(r0, vec![b0], vec![r1])], None.into()),
(vec![(b0, vec![e0], vec![r0])], None.into()),
]
);
let s = rec.state();
assert_eq!(s.get_paths(b0, prefix).unwrap(), vec![vec![b0, e0]]);
assert_eq!(s.get_paths(r0, prefix).unwrap(), vec![vec![r0, b0, e0]]);
assert_eq!(s.get_paths(r1, prefix).unwrap(), vec![vec![r1, r0, b0, e0]]);
assert_eq!(
s.get_paths(b1, prefix).unwrap(),
vec![vec![b1, r1, r0, b0, e0]]
);
rec.step().unwrap();
let s = rec.state();
assert_eq!(s.get_paths(b0, prefix).unwrap(), vec![vec![b0, e0]]);
assert_eq!(s.get_paths(r0, prefix).unwrap(), vec![vec![r0, b0, e0]]);
assert_eq!(s.get_paths(r1, prefix).unwrap(), vec![vec![r1, r0, b0, e0]]);
assert_eq!(
s.get_paths(b1, prefix).unwrap(),
vec![vec![b1, r1, r0, b0, e0]]
);
rec.step().unwrap();
let s = rec.state();
assert_eq!(s.get_paths(b0, prefix).unwrap(), vec![vec![b0, e0]]);
assert_eq!(s.get_paths(r0, prefix).unwrap(), vec![vec![r0, b0, e0]]);
assert_eq!(s.get_paths(r1, prefix).unwrap(), vec![vec![r1, r0, b0, e0]]);
assert_eq!(s.get_paths(b1, prefix).unwrap(), vec![vec![b1, e1]]);
rec.step().unwrap();
let s = rec.state();
assert_eq!(s.get_paths(b0, prefix).unwrap(), vec![vec![b0, e0]]);
assert_eq!(s.get_paths(r0, prefix).unwrap(), vec![vec![r0, b0, e0]]);
assert_eq!(s.get_paths(r1, prefix).unwrap(), vec![vec![r1, b1, e1]]);
assert_eq!(s.get_paths(b1, prefix).unwrap(), vec![vec![b1, e1]]);
rec.step().unwrap();
let s = rec.state();
assert_eq!(s.get_paths(b0, prefix).unwrap(), vec![vec![b0, e0]]);
assert_eq!(s.get_paths(r0, prefix).unwrap(), vec![vec![r0, r1, b1, e1]]);
assert_eq!(s.get_paths(r1, prefix).unwrap(), vec![vec![r1, b1, e1]]);
assert_eq!(s.get_paths(b1, prefix).unwrap(), vec![vec![b1, e1]]);
rec.step().unwrap();
let s = rec.state();
assert_eq!(
s.get_paths(b0, prefix).unwrap(),
vec![vec![b0, r0, r1, b1, e1]]
);
assert_eq!(s.get_paths(r0, prefix).unwrap(), vec![vec![r0, r1, b1, e1]]);
assert_eq!(s.get_paths(r1, prefix).unwrap(), vec![vec![r1, b1, e1]]);
assert_eq!(s.get_paths(b1, prefix).unwrap(), vec![vec![b1, e1]]);
rec.back().unwrap();
let s = rec.state();
assert_eq!(s.get_paths(b0, prefix).unwrap(), vec![vec![b0, e0]]);
assert_eq!(s.get_paths(r0, prefix).unwrap(), vec![vec![r0, r1, b1, e1]]);
assert_eq!(s.get_paths(r1, prefix).unwrap(), vec![vec![r1, b1, e1]]);
assert_eq!(s.get_paths(b1, prefix).unwrap(), vec![vec![b1, e1]]);
rec.back().unwrap();
let s = rec.state();
assert_eq!(s.get_paths(b0, prefix).unwrap(), vec![vec![b0, e0]]);
assert_eq!(s.get_paths(r0, prefix).unwrap(), vec![vec![r0, b0, e0]]);
assert_eq!(s.get_paths(r1, prefix).unwrap(), vec![vec![r1, b1, e1]]);
assert_eq!(s.get_paths(b1, prefix).unwrap(), vec![vec![b1, e1]]);
rec.back().unwrap();
let s = rec.state();
assert_eq!(s.get_paths(b0, prefix).unwrap(), vec![vec![b0, e0]]);
assert_eq!(s.get_paths(r0, prefix).unwrap(), vec![vec![r0, b0, e0]]);
assert_eq!(s.get_paths(r1, prefix).unwrap(), vec![vec![r1, r0, b0, e0]]);
assert_eq!(s.get_paths(b1, prefix).unwrap(), vec![vec![b1, e1]]);
rec.back().unwrap();
let s = rec.state();
assert_eq!(s.get_paths(b0, prefix).unwrap(), vec![vec![b0, e0]]);
assert_eq!(s.get_paths(r0, prefix).unwrap(), vec![vec![r0, b0, e0]]);
assert_eq!(s.get_paths(r1, prefix).unwrap(), vec![vec![r1, r0, b0, e0]]);
assert_eq!(
s.get_paths(b1, prefix).unwrap(),
vec![vec![b1, r1, r0, b0, e0]]
);
rec.back().unwrap();
let s = rec.state();
assert_eq!(s.get_paths(b0, prefix).unwrap(), vec![vec![b0, e0]]);
assert_eq!(s.get_paths(r0, prefix).unwrap(), vec![vec![r0, b0, e0]]);
assert_eq!(s.get_paths(r1, prefix).unwrap(), vec![vec![r1, r0, b0, e0]]);
assert_eq!(
s.get_paths(b1, prefix).unwrap(),
vec![vec![b1, r1, r0, b0, e0]]
);
}