summaryrefslogtreecommitdiff
path: root/vendor/bytes/tests/test_bytes_odd_alloc.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/bytes/tests/test_bytes_odd_alloc.rs')
-rw-r--r--vendor/bytes/tests/test_bytes_odd_alloc.rs147
1 files changed, 147 insertions, 0 deletions
diff --git a/vendor/bytes/tests/test_bytes_odd_alloc.rs b/vendor/bytes/tests/test_bytes_odd_alloc.rs
new file mode 100644
index 00000000..4758dc2f
--- /dev/null
+++ b/vendor/bytes/tests/test_bytes_odd_alloc.rs
@@ -0,0 +1,147 @@
+//! Test using `Bytes` with an allocator that hands out "odd" pointers for
+//! vectors (pointers where the LSB is set).
+
+#![cfg(not(miri))] // Miri does not support custom allocators (also, Miri is "odd" by default with 50% chance)
+
+use std::alloc::{GlobalAlloc, Layout, System};
+use std::ptr;
+
+use bytes::{Bytes, BytesMut};
+
+#[global_allocator]
+static ODD: Odd = Odd;
+
+struct Odd;
+
+unsafe impl GlobalAlloc for Odd {
+ unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+ if layout.align() == 1 && layout.size() > 0 {
+ // Allocate slightly bigger so that we can offset the pointer by 1
+ let size = layout.size() + 1;
+ let new_layout = match Layout::from_size_align(size, 1) {
+ Ok(layout) => layout,
+ Err(_err) => return ptr::null_mut(),
+ };
+ let ptr = System.alloc(new_layout);
+ if !ptr.is_null() {
+ ptr.offset(1)
+ } else {
+ ptr
+ }
+ } else {
+ System.alloc(layout)
+ }
+ }
+
+ unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
+ if layout.align() == 1 && layout.size() > 0 {
+ let size = layout.size() + 1;
+ let new_layout = match Layout::from_size_align(size, 1) {
+ Ok(layout) => layout,
+ Err(_err) => std::process::abort(),
+ };
+ System.dealloc(ptr.offset(-1), new_layout);
+ } else {
+ System.dealloc(ptr, layout);
+ }
+ }
+}
+
+#[test]
+fn sanity_check_odd_allocator() {
+ let vec = vec![33u8; 1024];
+ let p = vec.as_ptr() as usize;
+ assert!(p & 0x1 == 0x1, "{:#b}", p);
+}
+
+#[test]
+fn test_bytes_from_vec_drop() {
+ let vec = vec![33u8; 1024];
+ let _b = Bytes::from(vec);
+}
+
+#[test]
+fn test_bytes_clone_drop() {
+ let vec = vec![33u8; 1024];
+ let b1 = Bytes::from(vec);
+ let _b2 = b1.clone();
+}
+
+#[test]
+fn test_bytes_into_vec() {
+ let vec = vec![33u8; 1024];
+
+ // Test cases where kind == KIND_VEC
+ let b1 = Bytes::from(vec.clone());
+ assert_eq!(Vec::from(b1), vec);
+
+ // Test cases where kind == KIND_ARC, ref_cnt == 1
+ let b1 = Bytes::from(vec.clone());
+ drop(b1.clone());
+ assert_eq!(Vec::from(b1), vec);
+
+ // Test cases where kind == KIND_ARC, ref_cnt == 2
+ let b1 = Bytes::from(vec.clone());
+ let b2 = b1.clone();
+ assert_eq!(Vec::from(b1), vec);
+
+ // Test cases where vtable = SHARED_VTABLE, kind == KIND_ARC, ref_cnt == 1
+ assert_eq!(Vec::from(b2), vec);
+
+ // Test cases where offset != 0
+ let mut b1 = Bytes::from(vec.clone());
+ let b2 = b1.split_off(20);
+
+ assert_eq!(Vec::from(b2), vec[20..]);
+ assert_eq!(Vec::from(b1), vec[..20]);
+}
+
+#[test]
+fn test_bytesmut_from_bytes_vec() {
+ let vec = vec![33u8; 1024];
+
+ // Test case where kind == KIND_VEC
+ let b1 = Bytes::from(vec.clone());
+ let b1m = BytesMut::from(b1);
+ assert_eq!(b1m, vec);
+}
+
+#[test]
+fn test_bytesmut_from_bytes_arc_1() {
+ let vec = vec![33u8; 1024];
+
+ // Test case where kind == KIND_ARC, ref_cnt == 1
+ let b1 = Bytes::from(vec.clone());
+ drop(b1.clone());
+ let b1m = BytesMut::from(b1);
+ assert_eq!(b1m, vec);
+}
+
+#[test]
+fn test_bytesmut_from_bytes_arc_2() {
+ let vec = vec![33u8; 1024];
+
+ // Test case where kind == KIND_ARC, ref_cnt == 2
+ let b1 = Bytes::from(vec.clone());
+ let b2 = b1.clone();
+ let b1m = BytesMut::from(b1);
+ assert_eq!(b1m, vec);
+
+ // Test case where vtable = SHARED_VTABLE, kind == KIND_ARC, ref_cnt == 1
+ let b2m = BytesMut::from(b2);
+ assert_eq!(b2m, vec);
+}
+
+#[test]
+fn test_bytesmut_from_bytes_arc_offset() {
+ let vec = vec![33u8; 1024];
+
+ // Test case where offset != 0
+ let mut b1 = Bytes::from(vec.clone());
+ let b2 = b1.split_off(20);
+ let b1m = BytesMut::from(b1);
+ let b2m = BytesMut::from(b2);
+
+ assert_eq!(b2m, vec[20..]);
+ assert_eq!(b1m, vec[..20]);
+}