diff options
Diffstat (limited to 'vendor/bytes/tests/test_bytes_odd_alloc.rs')
| -rw-r--r-- | vendor/bytes/tests/test_bytes_odd_alloc.rs | 147 |
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]); +} |
