123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778 |
- //! Test automation.
- use ralloc;
- use std::{thread, mem};
- /// Magic trait for boxed `FnOnce`s.
- ///
- /// This is a temporary replacement as the trait from libstd is stabilized.
- trait FnBox {
- /// Call the closure.
- fn call_box(self: Box<Self>);
- }
- impl<F: FnOnce()> FnBox for F {
- fn call_box(self: Box<Self>) { (*self)() }
- }
- /// Like `std::thread::spawn`, but without the closure bounds.
- unsafe fn spawn_unsafe<'a, F: FnOnce() + Send + 'a>(func: F) -> thread::JoinHandle<()> {
- let closure: Box<FnBox + 'a> = Box::new(func);
- let closure: Box<FnBox + Send> = mem::transmute(closure);
- thread::spawn(move || closure.call_box())
- }
- /// Spawn three threads and `join` them.
- fn spawn_double<F: Fn() + Sync + Send>(func: F) {
- let handle;
- unsafe {
- handle = spawn_unsafe(|| func());
- }
- func();
- handle.join().unwrap();
- }
- /// "Multiply" a closure, by running it in multiple threads at the same time.
- ///
- /// This will test for memory leaks, as well as acid wrapping.
- #[allow(dead_code)]
- pub fn multiply<F: Fn() + Sync + Send + 'static>(func: F) {
- spawn_double(|| spawn_double(|| acid(|| func())));
- ralloc::lock().debug_assert_no_leak();
- }
- /// Wrap a block in acid tests.
- ///
- /// This performs a number of temporary allocations to try to detect inconsistency.
- ///
- /// The basic idea is that if the allocator is broken, it might allocate the same memory twice, or
- /// corrupt when allocating. Thus, we allocate some temporary segment and override it. This way we
- /// might be able to detect memory corruption through asserting memory consistency after the
- /// closure is completed.
- #[allow(dead_code)]
- pub fn acid<F: FnOnce()>(func: F) {
- let mut vec = vec!["something", "yep", "yup"];
- let mut _v = vec![Box::new(2), Box::new(5)];
- let mut bx = Box::new(2389);
- let abc = Box::new("abc");
- vec.shrink_to_fit();
- vec.extend(["lol", "lulz"].iter());
- vec.shrink_to_fit();
- vec.extend(["we", "are"].iter());
- func();
- *bx = 500;
- vec.push("heyaya");
- *bx = 55;
- assert_eq!(vec, ["something", "yep", "yup", "lol", "lulz", "we", "are", "heyaya"]);
- assert_eq!(*bx, 55);
- assert_eq!(*abc, "abc");
- }
|