mod.rs 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. //! Test automation.
  2. use ralloc;
  3. use std::{thread, mem};
  4. /// Magic trait for boxed `FnOnce`s.
  5. ///
  6. /// This is a temporary replacement as the trait from libstd is stabilized.
  7. trait FnBox {
  8. /// Call the closure.
  9. fn call_box(self: Box<Self>);
  10. }
  11. impl<F: FnOnce()> FnBox for F {
  12. fn call_box(self: Box<Self>) { (*self)() }
  13. }
  14. /// Like `std::thread::spawn`, but without the closure bounds.
  15. unsafe fn spawn_unsafe<'a, F: FnOnce() + Send + 'a>(func: F) -> thread::JoinHandle<()> {
  16. let closure: Box<FnBox + 'a> = Box::new(func);
  17. let closure: Box<FnBox + Send> = mem::transmute(closure);
  18. thread::spawn(move || closure.call_box())
  19. }
  20. /// Spawn three threads and `join` them.
  21. fn spawn_double<F: Fn() + Sync + Send>(func: F) {
  22. let handle;
  23. unsafe {
  24. handle = spawn_unsafe(|| func());
  25. }
  26. func();
  27. handle.join().unwrap();
  28. }
  29. /// "Multiply" a closure, by running it in multiple threads at the same time.
  30. ///
  31. /// This will test for memory leaks, as well as acid wrapping.
  32. #[allow(dead_code)]
  33. pub fn multiply<F: Fn() + Sync + Send + 'static>(func: F) {
  34. spawn_double(|| spawn_double(|| acid(|| func())));
  35. ralloc::lock().debug_assert_no_leak();
  36. }
  37. /// Wrap a block in acid tests.
  38. ///
  39. /// This performs a number of temporary allocations to try to detect inconsistency.
  40. ///
  41. /// The basic idea is that if the allocator is broken, it might allocate the same memory twice, or
  42. /// corrupt when allocating. Thus, we allocate some temporary segment and override it. This way we
  43. /// might be able to detect memory corruption through asserting memory consistency after the
  44. /// closure is completed.
  45. #[allow(dead_code)]
  46. pub fn acid<F: FnOnce()>(func: F) {
  47. let mut vec = vec!["something", "yep", "yup"];
  48. let mut _v = vec![Box::new(2), Box::new(5)];
  49. let mut bx = Box::new(2389);
  50. let abc = Box::new("abc");
  51. vec.shrink_to_fit();
  52. vec.extend(["lol", "lulz"].iter());
  53. vec.shrink_to_fit();
  54. vec.extend(["we", "are"].iter());
  55. func();
  56. *bx = 500;
  57. vec.push("heyaya");
  58. *bx = 55;
  59. assert_eq!(vec, ["something", "yep", "yup", "lol", "lulz", "we", "are", "heyaya"]);
  60. assert_eq!(*bx, 55);
  61. assert_eq!(*abc, "abc");
  62. }