1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
// SPDX-License-Identifier: Apache-2.0
// Copyright (c) 2026 Fábio Henrique de Lima Silva (fhl.bsb@gmail.com) All rights reserved.
use super::*;
use libc::sysconf;
#[test]
fn test_mirror_buf_page_alignment() -> Result<(), Box<dyn std::error::Error>> {
// SAFETY: Low-level virtual memory manipulation (mmap/ftruncate) with checked parameters.
let page_size = unsafe { sysconf(libc::_SC_PAGESIZE) } as usize;
let element_size = std::mem::size_of::<f32>();
// Request 1 element, should round to 1 page
let buf = MirroredBuffer::<f32>::new(1)?;
let expected_elements = page_size / element_size;
assert_eq!(buf.size(), expected_elements);
assert_eq!(buf.len(), expected_elements * 2);
Ok(())
}
#[test]
fn test_mirror_buf_mirroring() -> Result<(), Box<dyn std::error::Error>> {
// Mirroring Test: Verifies that the virtual memory "trick" works.
// Any value written to the first half should instantly appear in the
// second half (the mirror), since both windows point to the same physical location.
// Creates a small buffer (will be rounded to 1 page)
let mut buf = MirroredBuffer::<u32>::new(1)?;
let size = buf.size();
// 1. Write at the start of the first half
buf[0] = 0x12345678;
// Should be visible at the start of the second half (mirror)
assert_eq!(buf[size], 0x12345678);
// 2. Write at the end of the first half
buf[size - 1] = 0xDEADBEEF;
// Should be visible at the end of the second half
assert_eq!(buf[2 * size - 1], 0xDEADBEEF);
// 3. Contiguous access crossing the boundary (the "Ace in the Hole")
// Let's write a sequence of values that crosses exactly the buffer midpoint.
// In a regular buffer this would require two loops or an 'if', but here it is linear.
let middle = size;
let start = middle - 8;
for i in 0..16 {
buf[start + i] = i as u32;
}
// Verifies that the first half (original) reflects the changes
// The first 8 values were written at the end of the first half
for i in 0..8 {
assert_eq!(buf[size - 8 + i], i as u32);
}
// The next 8 values were written at the start of the second half,
// which should have modified the start of the physical FIRST half.
for i in 8..16 {
assert_eq!(buf[i - 8], i as u32);
}
Ok(())
}
#[test]
fn test_mirror_buf_clone() -> Result<(), Box<dyn std::error::Error>> {
let mut buf = MirroredBuffer::<i32>::new(100)?;
buf[0] = 42;
let buf2 = buf.clone();
assert_eq!(buf2[0], 42);
assert_eq!(buf2.size(), buf.size());
// Modifies the original, the clone should remain unchanged
buf[0] = 99;
assert_eq!(buf2[0], 42, "MirroredBuffer clones must be independent");
Ok(())
}
#[test]
fn test_mirror_buf_zst_error() {
assert!(MirroredBuffer::<()>::new(1024).is_err());
}
#[test]
fn test_mirror_buf_large_allocation() -> Result<(), Box<dyn std::error::Error>> {
// Tests allocation of ~1MB
let size = 1024 * 1024 / 4;
let buf = MirroredBuffer::<f32>::new(size)?;
assert!(buf.size() >= size);
// Just ensures no panic occurred and mmap succeeded
Ok(())
}
#[test]
fn test_mirror_buf_debug() -> Result<(), Box<dyn std::error::Error>> {
let buf = MirroredBuffer::<f32>::new(1024)?;
let debug_str = format!("{:?}", buf);
assert!(debug_str.contains("MirroredBuffer"));
assert!(debug_str.contains("ptr"));
assert!(debug_str.contains("size_elements"));
Ok(())
}
#[test]
fn test_mirror_buf_channel_alignment() -> Result<(), Box<dyn std::error::Error>> {
// MirroredBuffer::new_aligned guarantees size_elements % channels == 0
// for all channel counts, including non-power-of-two channels (6, 12 — Lite).
let min_buffer_frames = 3648usize;
for &ch in &[4usize, 6, 8, 12, 16] {
let min_elems = min_buffer_frames * ch;
let buf = MirroredBuffer::<f32>::new_aligned(min_elems, ch)?;
assert_eq!(
buf.size() % ch,
0,
"MirroredBuffer size_elements={} must be divisible by channels={ch}",
buf.size()
);
}
Ok(())
}