Skip to content

Commit

Permalink
Allow tests to run concurrently
Browse files Browse the repository at this point in the history
  • Loading branch information
chrissie-c committed Jun 21, 2021
1 parent 401026a commit fbd7ed1
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 22 deletions.
1 change: 1 addition & 0 deletions libknet/bindings/rust/tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ cc = "1.0"

[dependencies]
kronosnet = { path = ".." }
libc = "0.2.97"

[[bin]]
name = "knet-test"
Expand Down
116 changes: 94 additions & 22 deletions libknet/bindings/rust/tests/src/bin/knet-test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,7 @@ fn logging_thread(recvr: Receiver<knet::LogMsg>)
eprintln!("Logging thread finished");
}

fn setup_node(our_hostid: &knet::HostId, other_hostid: &knet::HostId,
name: &str) -> Result<knet::Handle>
fn setup_node(our_hostid: &knet::HostId, other_hostid: &knet::HostId, name: &str) -> Result<knet::Handle>
{
let (log_sender, log_receiver) = channel::<knet::LogMsg>();
spawn(move || logging_thread(log_receiver));
Expand All @@ -120,19 +119,94 @@ fn setup_node(our_hostid: &knet::HostId, other_hostid: &knet::HostId,
println!("Error from host_add: {}", e);
return Err(e);
}
if let Err(e) = knet::link_set_config(knet_handle, &other_hostid, 0,
knet::TransportId::Udp,
&SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8000+(our_hostid.to_u16())),
Some(&SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8000+(other_hostid.to_u16()))),
knet::LinkFlags::NONE) {
println!("Error from link_set_config: {}", e);
return Err(e);
}
if let Err(e) = knet::host_set_name(knet_handle, &other_hostid, name) {
println!("Error from host_set_name: {}", e);
return Err(e);
}

Ok(knet_handle)
}

// Called by the ACL tests to get a free port for a dynamic link
fn setup_dynamic_link(handle: knet::Handle, hostid: &knet::HostId, link: u8) -> Result<()>
{
let mut src_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 0);
for p in 1025..=65535 {
src_addr.set_port(p);

if let Err(e) = knet::link_set_config(handle, hostid, link,
knet::TransportId::Udp,
&src_addr,
None,
knet::LinkFlags::NONE) {
if let Some(os_err) = e.raw_os_error() {
if os_err != libc::EADDRINUSE {
println!("Error from link_set_config(dyn): {}", e);
return Err(e);
}
// In use - try the next port number
}
} else {
return Ok(())
}
}
Err(Error::new(ErrorKind::Other, "No ports available"))
}

// This is the bit that configures two links on two handles that talk to each other
// while also making sure they don't clash with anything else on the system
fn setup_links(handle1: knet::Handle, hostid1: &knet::HostId,
handle2: knet::Handle, hostid2: &knet::HostId) -> Result<()>
{
let mut src_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 0);
let mut dst_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 0);
for p in 1025..=65534 {
src_addr.set_port(p);
dst_addr.set_port(p+1);

if let Err(e) = knet::link_set_config(handle1, hostid2, 0,
knet::TransportId::Udp,
&src_addr,
Some(&dst_addr),
knet::LinkFlags::NONE) {
if let Some(os_err) = e.raw_os_error() {
if os_err != libc::EADDRINUSE {
println!("Error from link_set_config(1): {}", e);
return Err(e);
}
// In use - try the next port number
} else {
return Err(Error::new(ErrorKind::Other, "Error returned from link_set_config(1) was not an os_error"));
}
} else {
// Now try the other handle
if let Err(e) = knet::link_set_config(handle2, hostid1, 0,
knet::TransportId::Udp,
&dst_addr,
Some(&src_addr),
knet::LinkFlags::NONE) {
if let Some(os_err) = e.raw_os_error() {
if os_err != libc::EADDRINUSE {
println!("Error from link_set_config(2): {}", e);
return Err(e);
} else {
// In use - clear handle1 and try next pair of ports
knet::link_clear_config(handle1, hostid2, 0)?;
}
} else {
return Err(Error::new(ErrorKind::Other, "Error returned from link_set_config(1) was not an os_error"));
}
}
println!("Bound to ports {} & {}",p, p+1);
return Ok(())
}
}
Err(Error::new(ErrorKind::Other, "No ports available"))
}

// Finish configuring links
fn configure_link(knet_handle: knet::Handle, our_hostid: &knet::HostId, other_hostid: &knet::HostId) -> Result<()>
{
if let Err(e) = knet::handle_enable_sock_notify(knet_handle, our_hostid.to_u16() as u64, Some(sock_notify_fn)) {
println!("Error from handle_enable_sock_notify: {}", e);
return Err(e);
Expand Down Expand Up @@ -188,7 +262,7 @@ fn setup_node(our_hostid: &knet::HostId, other_hostid: &knet::HostId,
match knet::link_get_ping_timers(knet_handle, &other_hostid, 0) {
Ok((a,b,c)) => {
if a != 500 || b != 1000 || c != 1024 {
println!("get_link_ping_timers return wronte values {}, {},{} (s/b 500,1000,1024)",
println!("get_link_ping_timers returned wrong values {}, {},{} (s/b 500,1000,1024)",
a,b,c);
return Err(Error::new(ErrorKind::Other, "Error in ping timers"));
}
Expand Down Expand Up @@ -240,9 +314,7 @@ fn setup_node(our_hostid: &knet::HostId, other_hostid: &knet::HostId,
}
}



Ok(knet_handle)
Ok(())
}

fn recv_stuff(handle: knet::Handle, host: knet::HostId) -> Result<()>
Expand Down Expand Up @@ -670,11 +742,7 @@ fn test_acl(handle: knet::Handle, host: &knet::HostId) -> Result<()>
}

// Dynamic link for testing ACL APIs (it never gets used)
if let Err(e) = knet::link_set_config(handle, host, 1,
knet::TransportId::Udp,
&SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8003_u16),
None,
knet::LinkFlags::NONE) {
if let Err(e) = setup_dynamic_link(handle, host, 1) {
println!("Error from link_set_config (dynamic): {}", e);
return Err(e);
}
Expand Down Expand Up @@ -767,8 +835,9 @@ fn main() -> Result<()>
// Now test traffic
let handle1 = setup_node(&host1, &host2, "host2")?;
let handle2 = setup_node(&host2, &host1, "host1")?;

test_acl(handle1, &host2)?;
setup_links(handle1, &host1, handle2, &host2)?;
configure_link(handle1, &host1, &host2)?;
configure_link(handle2, &host2, &host1)?;

// Copy stuff for the threads
let handle1_clone = handle1;
Expand All @@ -784,7 +853,8 @@ fn main() -> Result<()>
// Start recv threads for each handle
let thread_handles = vec![
spawn(move || recv_stuff(handle1_clone, host1_clone)),
spawn(move || recv_stuff(handle2_clone, host2_clone))];
spawn(move || recv_stuff(handle2_clone, host2_clone))
];

send_messages(handle1, false)?;
send_messages(handle2, false)?;
Expand All @@ -801,6 +871,8 @@ fn main() -> Result<()>
send_messages(handle1, true)?;
send_messages(handle2, true)?;

test_acl(handle1, &host2)?;

// Wait for recv threads to finish
for handle in thread_handles {
if let Err(error) = handle.join() {
Expand Down

0 comments on commit fbd7ed1

Please sign in to comment.