You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
147 lines
3.3 KiB
147 lines
3.3 KiB
//! Unit tests
|
|
use std::sync::Arc;
|
|
use std::thread::{
|
|
self,
|
|
};
|
|
use super::*;
|
|
|
|
#[macro_export] macro_rules! assert_binds {
|
|
($expr:expr, $pat:pat, $msg:literal) => {
|
|
match $expr {
|
|
$pat => (),
|
|
_ => {
|
|
panic!("Pattern matched assertion `{}` failed: {}", stringify!($pat), $msg)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// Testing iteration
|
|
mod iteration {
|
|
use super::*;
|
|
#[test]
|
|
fn single_threaded_trivial()
|
|
{
|
|
let pop = Populator::new(10);
|
|
|
|
for r in pop.iter()
|
|
{
|
|
r.insert(1usize);
|
|
}
|
|
|
|
assert_eq!(10usize, pop.complete().into_iter().sum::<usize>(), "Did not set all elements to 1");
|
|
}
|
|
#[test]
|
|
fn single_threaded_nontrivial()
|
|
{
|
|
let pop = Populator::new(10);
|
|
|
|
for r in pop.iter()
|
|
{
|
|
r.insert(String::from("1"));
|
|
}
|
|
|
|
assert_eq!(10usize, pop.complete().into_iter()
|
|
.map(|x| x.parse::<usize>().unwrap())
|
|
.sum::<usize>(), "Did not set all elements to 1");
|
|
}
|
|
|
|
#[test]
|
|
fn multi_threaded_trivial()
|
|
{
|
|
let pop = Arc::new(Populator::<usize>::new(10));
|
|
|
|
let t1 = thread::spawn({
|
|
let pop = pop.clone();
|
|
move || {
|
|
for (i,r) in (10..).zip(pop.iter_slice(0..5)) {
|
|
r.insert(i);
|
|
}
|
|
}
|
|
});
|
|
let t2 = thread::spawn({
|
|
let pop = pop.clone();
|
|
move || {
|
|
for (i, r) in (0..).zip(pop.iter_slice(5..10)) {
|
|
r.insert(i);
|
|
}
|
|
}
|
|
});
|
|
thread::yield_now();
|
|
|
|
assert_binds!((t1.join(), t2.join()), (Ok(_), Ok(_)), "One or more of the threads panicked");
|
|
|
|
assert_eq!(&pop.complete_owned()[..], &[
|
|
10, 11, 12, 13, 14,
|
|
0, 1, 2, 3, 4,
|
|
], "Bad order of elements");
|
|
}
|
|
|
|
|
|
#[test]
|
|
fn multi_threaded_nontrivial()
|
|
{
|
|
let pop = Arc::new(Populator::<String>::new(10));
|
|
|
|
let t1 = thread::spawn({
|
|
let pop = pop.clone();
|
|
move || {
|
|
for (i,r) in (10..).zip(pop.iter_slice(0..5)) {
|
|
r.insert(i.to_string());
|
|
}
|
|
}
|
|
});
|
|
let t2 = thread::spawn({
|
|
let pop = pop.clone();
|
|
move || {
|
|
for (i, r) in (0..).zip(pop.iter_slice(5..10)) {
|
|
r.insert(i.to_string());
|
|
}
|
|
}
|
|
});
|
|
thread::yield_now();
|
|
|
|
assert_binds!((t1.join(), t2.join()), (Ok(_), Ok(_)), "One or more of the threads panicked");
|
|
|
|
assert_eq!(&pop.complete_owned()[..], &[
|
|
"10", "11", "12", "13", "14",
|
|
"0", "1", "2", "3", "4",
|
|
], "Bad order of elements");
|
|
}
|
|
|
|
#[test]
|
|
fn single_threaded_overlapping_trivial()
|
|
{
|
|
let pop = Populator::new(10);
|
|
for (i, x) in (0..).zip(pop.iter_slice(0..5)) {
|
|
_ = x.try_insert(i);
|
|
}
|
|
for (i, x) in (0..).zip(pop.iter_slice(3..10)) {
|
|
_ = x.try_insert(i);
|
|
}
|
|
assert!(pop.try_insert(3, 100).is_err(), "Insertion of completed populator successed when it shouldn't have");
|
|
assert_eq!(&pop.complete()[..],
|
|
[0, 1, 2, 3, 4, 2, 3, 4, 5, 6],
|
|
"Overlapping insertions failed");
|
|
}
|
|
|
|
#[test]
|
|
fn single_threaded_overlapping_nontrivial()
|
|
{
|
|
let pop = Populator::new(10);
|
|
for (i, x) in (0..).zip(pop.iter_slice(0..5)) {
|
|
_ = x.try_insert(i.to_string());
|
|
}
|
|
for (i, x) in (0..).zip(pop.iter_slice(3..10)) {
|
|
_ = x.try_insert(i.to_string());
|
|
}
|
|
assert!(pop.try_insert(3, "hiya".to_string()).is_err(), "Insertion of completed populator successed when it shouldn't have");
|
|
assert_eq!(&pop.complete()[..],
|
|
["0", "1", "2", "3", "4",
|
|
"2", "3", "4", "5", "6"],
|
|
"Overlapping insertions failed");
|
|
}
|
|
//TODO: multi-threaded overlapping
|
|
}
|