#[cfg(feature = "addr")]
#[test]
fn test_addr_primitives() {
use wbase::addr::*;
assert_eq!(ADDRESS_BITS, 48);
assert_eq!(ADDRESS_MASK, 0x0000_FFFF_FFFF_FFFF);
assert_eq!(READ_CACHE_BIT, 1u64 << 47);
assert_eq!(ABSOLUTE_ADDRESS_MASK, 0x0000_7FFF_FFFF_FFFF);
assert_eq!(INVALID_ADDRESS, 0);
let raw = 0x1234_5678_9ABC;
assert!(is_valid(raw));
assert!(!is_read_cache(raw));
assert_eq!(to_absolute(raw), raw);
let rc_addr = with_read_cache(raw);
assert!(is_read_cache(rc_addr));
assert_eq!(to_absolute(rc_addr), raw);
let log_addr = LogAddress::new(rc_addr);
assert!(log_addr.is_valid());
assert!(log_addr.is_read_cache());
assert_eq!(log_addr.absolute().as_raw(), raw);
assert_eq!(*log_addr, rc_addr);
assert_eq!(log_addr.as_u64(), rc_addr);
assert_eq!(log_addr.into_raw(), rc_addr);
assert_eq!(u64::from(log_addr), rc_addr);
assert_eq!(LogAddress::from(rc_addr), log_addr);
let formatted = format!("{}", log_addr);
assert!(formatted.starts_with("RC:"));
}
#[cfg(feature = "align")]
#[test]
fn test_align_primitives() {
use wbase::align::*;
assert_eq!(CACHELINE_BYTES, 64);
assert_eq!(DEFAULT_SECTOR_SIZE, 4096);
assert_eq!(MIN_SECTOR_SIZE, 512);
assert!(is_aligned(4096, 4096));
assert!(!is_aligned(4095, 4096));
assert_eq!(align_down(4097, 4096), 4096);
assert_eq!(align_up(4097, 4096), 8192);
assert_eq!(align_up(4096, 4096), 4096);
assert_eq!(checked_align_up(u64::MAX - 10, 4096), None);
assert!(is_cacheline_aligned(128));
assert!(!is_cacheline_aligned(127));
assert_eq!(align_to_cacheline(65), 128);
assert!(is_valid_sector_size(512));
assert!(is_valid_sector_size(4096));
assert!(!is_valid_sector_size(300));
assert!(!is_valid_sector_size(256));
let range = SectorRange::calculate(100, 200, DEFAULT_SECTOR_SIZE).unwrap();
assert_eq!(range.aligned_offset, 0);
assert_eq!(range.aligned_len, 4096);
assert_eq!(range.internal_offset, 100);
assert_eq!(range.sector_count(DEFAULT_SECTOR_SIZE), 1);
assert_eq!(range.sub_range(50), 100..150);
}
#[cfg(feature = "backoff")]
#[test]
fn test_backoff_stages() {
use std::time::Duration;
use wbase::backoff::*;
let mut b = Backoff::new();
assert_eq!(b.stage(), BackoffStage::Spin);
assert!(b.stage().is_spin());
assert!(!b.is_sleep());
for _ in 0..SPIN_LIMIT {
b.advance();
}
assert_eq!(b.stage(), BackoffStage::Yield);
assert!(b.stage().is_yield());
assert!(!b.is_sleep());
for _ in SPIN_LIMIT..YIELD_LIMIT {
b.advance();
}
assert_eq!(b.stage(), BackoffStage::Sleep);
assert!(b.stage().is_sleep());
assert!(b.is_sleep());
assert_eq!(SLEEP_DURATION, Duration::from_micros(50));
b.reset();
assert_eq!(b.stage(), BackoffStage::Spin);
assert_eq!(b.step_count(), 0);
}
#[cfg(feature = "thread")]
#[test]
fn test_thread_id_uniqueness() {
use std::{
collections::HashSet,
sync::{Arc, Mutex},
thread,
};
use wbase::thread::*;
let id1 = current_thread_id();
let id2 = current_thread_id();
assert_eq!(id1, id2, "Same thread should have stable ID");
assert!(id1 > 0);
let set = Arc::new(Mutex::new(HashSet::new()));
let mut handles = Vec::new();
for _ in 0..16 {
let set = Arc::clone(&set);
handles.push(thread::spawn(move || {
let tid = current_thread_id();
let mut lock = set.lock().unwrap();
assert!(lock.insert(tid), "Thread ID must be globally unique");
}));
}
for h in handles {
h.join().unwrap();
}
assert_eq!(set.lock().unwrap().len(), 16);
}
#[cfg(feature = "align")]
#[test]
fn test_cache_padded_layout() {
use core::mem::{align_of, size_of};
use wbase::align::{CachePadded, CachePadded64};
assert_eq!(align_of::<CachePadded<u64>>(), 128);
assert!(size_of::<CachePadded<u64>>() >= 128);
assert_eq!(align_of::<CachePadded64<u64>>(), 64);
assert!(size_of::<CachePadded64<u64>>() >= 64);
let mut padded = CachePadded::new(42u64);
assert_eq!(*padded, 42);
*padded = 100;
assert_eq!(padded.into_inner(), 100);
}
#[cfg(feature = "crc")]
#[test]
fn test_crc_primitives() {
use wbase::crc::*;
let data = b"123456789";
let expected = 0xCBF4_3926; assert_eq!(crc32(data), expected);
let mut hasher = Crc32Hasher::new();
hasher.update(b"12345");
hasher.update(b"6789");
assert_eq!(hasher.finalize(), expected);
let mut h2 = Crc32Hasher::new();
h2.update_u64(0x0102_0304_0506_0708);
assert_ne!(h2.finalize(), 0);
}
#[cfg(feature = "time")]
#[test]
fn test_time_primitives() {
use wbase::time::*;
let secs = now_secs();
let ms = now_ms();
let micros = now_micros();
let nanos = now_nanos();
assert!(secs > 0);
assert!(ms > 0);
assert!(micros > 0);
assert!(nanos > 0);
assert!(ms >= secs * 1000);
assert!(micros >= ms * 1000);
assert!(nanos >= micros * 1000);
}
#[cfg(feature = "simd")]
#[test]
fn test_simd_fast_key_eq() {
use wbase::simd::fast_key_eq;
assert!(fast_key_eq(b"", b""));
assert!(fast_key_eq(b"hello", b"hello"));
assert!(!fast_key_eq(b"hello", b"world"));
assert!(!fast_key_eq(b"short", b"shorter"));
let k1 = b"0123456789abcdef_long_key_vector";
let k2 = b"0123456789abcdef_long_key_vector";
let k3 = b"0123456789abcdef_long_key_vectoX";
assert!(fast_key_eq(k1, k2));
assert!(!fast_key_eq(k1, k3));
}
#[cfg(feature = "base32")]
#[test]
fn test_base32_primitives() {
use std::{ffi::OsStr, path::Path};
use wbase::base32::*;
assert_eq!(BASE32_LEN_U64, 13);
assert_eq!(BASE32_LEN_U128, 26);
assert_eq!(BASE32_LOWER_TABLE.len(), 32);
let val64 = 0x0123_4567_89ab_cdef_u64;
let b32_64 = encode_u64(val64);
assert_eq!(b32_64.len(), BASE32_LEN_U64);
assert_eq!(decode_u64(&b32_64), Some(val64));
assert_eq!(decode_u64(&encode_u64(0)), Some(0));
assert_eq!(decode_u64(&encode_u64(u64::MAX)), Some(u64::MAX));
let upper = b32_64.as_str().to_ascii_uppercase();
assert_eq!(decode_u64(&upper), Some(val64));
assert_eq!(b32_64.as_ref() as &Path, Path::new(b32_64.as_str()));
assert_eq!(b32_64.as_ref() as &OsStr, OsStr::new(b32_64.as_str()));
assert_eq!(b32_64.as_ref() as &str, b32_64.as_str());
assert_eq!(b32_64.as_ref() as &[u8], b32_64.as_bytes());
assert_eq!(&*b32_64, b32_64.as_str());
assert_eq!(b32_64, b32_64.as_str());
assert_eq!(b32_64.as_str(), b32_64);
assert_eq!(format!("{b32_64}"), b32_64.as_str());
assert_eq!(format!("{b32_64:?}"), b32_64.as_str());
let val128 = 0x0123_4567_89ab_cdef_fedc_ba98_7654_3210_u128;
let b32_128 = encode_u128(val128);
assert_eq!(b32_128.len(), BASE32_LEN_U128);
assert_eq!(decode_u128(&b32_128), Some(val128));
assert_eq!(decode_u128(&encode_u128(0)), Some(0));
assert_eq!(decode_u128(&encode_u128(u128::MAX)), Some(u128::MAX));
let upper128 = b32_128.as_str().to_ascii_uppercase();
assert_eq!(decode_u128(&upper128), Some(val128));
assert_eq!(b32_128.as_ref() as &Path, Path::new(b32_128.as_str()));
assert_eq!(b32_128.as_ref() as &OsStr, OsStr::new(b32_128.as_str()));
assert_eq!(b32_128.as_ref() as &str, b32_128.as_str());
assert_eq!(b32_128.as_ref() as &[u8], b32_128.as_bytes());
assert_eq!(&*b32_128, b32_128.as_str());
assert_eq!(b32_128, b32_128.as_str());
assert_eq!(b32_128.as_str(), b32_128);
assert_eq!(format!("{b32_128}"), b32_128.as_str());
assert_eq!(format!("{b32_128:?}"), b32_128.as_str());
let s1 = encode_u64(100);
let s2 = encode_u64(101);
let s3 = encode_u64(0xFFFF_FFFF_0000_0000);
let s4 = encode_u64(0xFFFF_FFFF_0000_0001);
assert!(s1.as_str() < s2.as_str());
assert!(s2.as_str() < s3.as_str());
assert!(s3.as_str() < s4.as_str());
assert!(s1 < s2 && s2 < s3 && s3 < s4);
let u1 = encode_u128(100);
let u2 = encode_u128(101);
let u3 = encode_u128(0xFFFF_FFFF_0000_0000_FFFF_FFFF_0000_0000);
let u4 = encode_u128(0xFFFF_FFFF_0000_0000_FFFF_FFFF_0000_0001);
assert!(u1.as_str() < u2.as_str());
assert!(u2.as_str() < u3.as_str());
assert!(u3.as_str() < u4.as_str());
assert!(u1 < u2 && u2 < u3 && u3 < u4);
assert!(is_base32(""));
assert!(is_base32(b32_64.as_str()));
assert!(is_base32("0123456789abcdefghijklmnopqrstuv"));
assert!(is_base32("0123456789ABCDEFGHIJKLMNOPQRSTUV"));
assert!(!is_base32("w")); assert!(!is_base32("xyz")); assert!(!is_base32("WXYZ"));
assert!(!is_base32("0123 4567"));
assert!(!is_base32("0123-4567"));
let mut s = String::new();
push_base32_u64(val64, &mut s);
assert_eq!(s, b32_64.as_str());
let mut s128 = String::new();
push_base32_u128(val128, &mut s128);
assert_eq!(s128, b32_128.as_str());
assert_eq!(decode_u64(""), None);
assert_eq!(decode_u64("000000000000"), None); assert_eq!(decode_u64("00000000000000"), None); assert_eq!(decode_u64("g000000000000"), None);
assert_eq!(decode_u64("v000000000000"), None);
assert_eq!(decode_u64("fvvvvvvvvvvvv"), Some(u64::MAX)); assert_eq!(decode_u64("000000000000w"), None);
assert_eq!(decode_u64("000000000000z"), None);
assert_eq!(decode_u64("000000-000000"), None);
assert_eq!(decode_u128(""), None);
assert_eq!(decode_u128(&"0".repeat(25)), None);
assert_eq!(decode_u128(&"0".repeat(27)), None);
assert_eq!(decode_u128(&format!("8{}", "0".repeat(25))), None);
assert_eq!(decode_u128(&format!("a{}", "0".repeat(25))), None);
assert_eq!(decode_u128(&format!("v{}", "0".repeat(25))), None);
assert_eq!(
decode_u128(&format!("7{}", "v".repeat(25))),
Some(u128::MAX)
); assert_eq!(decode_u128(&format!("{}w", "0".repeat(25))), None);
assert_eq!(decode_u128(&format!("{}z", "0".repeat(25))), None);
}