about summary refs log tree commit diff
path: root/src/liballoc/raw_vec/tests.rs
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-08-02 01:40:56 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2019-08-02 01:59:01 +0300
commit3d0d6ee271a34d2329235b9a04cf4a421d9026cd (patch)
treebdd574c1b42fe28031d69a18d7f7694ce8742021 /src/liballoc/raw_vec/tests.rs
parent310b9fc76002066feb89dcfbf8e88b34fe5f4ad3 (diff)
downloadrust-3d0d6ee271a34d2329235b9a04cf4a421d9026cd.tar.gz
rust-3d0d6ee271a34d2329235b9a04cf4a421d9026cd.zip
liballoc: Unconfigure tests during normal build
Remove additional libcore-like restrictions from liballoc, turns out the testing works ok if the tests are a part of liballoc itself.
Diffstat (limited to 'src/liballoc/raw_vec/tests.rs')
-rw-r--r--src/liballoc/raw_vec/tests.rs73
1 files changed, 73 insertions, 0 deletions
diff --git a/src/liballoc/raw_vec/tests.rs b/src/liballoc/raw_vec/tests.rs
new file mode 100644
index 00000000000..c389898d1ef
--- /dev/null
+++ b/src/liballoc/raw_vec/tests.rs
@@ -0,0 +1,73 @@
+use super::*;
+
+#[test]
+fn allocator_param() {
+    use crate::alloc::AllocErr;
+
+    // Writing a test of integration between third-party
+    // allocators and RawVec is a little tricky because the RawVec
+    // API does not expose fallible allocation methods, so we
+    // cannot check what happens when allocator is exhausted
+    // (beyond detecting a panic).
+    //
+    // Instead, this just checks that the RawVec methods do at
+    // least go through the Allocator API when it reserves
+    // storage.
+
+    // A dumb allocator that consumes a fixed amount of fuel
+    // before allocation attempts start failing.
+    struct BoundedAlloc { fuel: usize }
+    unsafe impl Alloc for BoundedAlloc {
+        unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<u8>, AllocErr> {
+            let size = layout.size();
+            if size > self.fuel {
+                return Err(AllocErr);
+            }
+            match Global.alloc(layout) {
+                ok @ Ok(_) => { self.fuel -= size; ok }
+                err @ Err(_) => err,
+            }
+        }
+        unsafe fn dealloc(&mut self, ptr: NonNull<u8>, layout: Layout) {
+            Global.dealloc(ptr, layout)
+        }
+    }
+
+    let a = BoundedAlloc { fuel: 500 };
+    let mut v: RawVec<u8, _> = RawVec::with_capacity_in(50, a);
+    assert_eq!(v.a.fuel, 450);
+    v.reserve(50, 150); // (causes a realloc, thus using 50 + 150 = 200 units of fuel)
+    assert_eq!(v.a.fuel, 250);
+}
+
+#[test]
+fn reserve_does_not_overallocate() {
+    {
+        let mut v: RawVec<u32> = RawVec::new();
+        // First `reserve` allocates like `reserve_exact`
+        v.reserve(0, 9);
+        assert_eq!(9, v.capacity());
+    }
+
+    {
+        let mut v: RawVec<u32> = RawVec::new();
+        v.reserve(0, 7);
+        assert_eq!(7, v.capacity());
+        // 97 if more than double of 7, so `reserve` should work
+        // like `reserve_exact`.
+        v.reserve(7, 90);
+        assert_eq!(97, v.capacity());
+    }
+
+    {
+        let mut v: RawVec<u32> = RawVec::new();
+        v.reserve(0, 12);
+        assert_eq!(12, v.capacity());
+        v.reserve(12, 3);
+        // 3 is less than half of 12, so `reserve` must grow
+        // exponentially. At the time of writing this test grow
+        // factor is 2, so new capacity is 24, however, grow factor
+        // of 1.5 is OK too. Hence `>= 18` in assert.
+        assert!(v.capacity() >= 12 + 12 / 2);
+    }
+}