Add ktest cases for frame components

This commit is contained in:
Fabing Li 2025-03-25 08:41:05 +00:00 committed by Tate, Hongliang Tian
parent 4fff7cdc22
commit 1e3098d734
4 changed files with 519 additions and 208 deletions

View File

@ -463,211 +463,3 @@ where
self.meta.is_untyped() self.meta.is_untyped()
} }
} }
#[cfg(ktest)]
mod test {
use super::*;
use crate::{impl_untyped_frame_meta_for, mm::FrameAllocOptions, prelude::ktest};
#[derive(Debug)]
struct MyMeta {
mark: usize,
}
impl_untyped_frame_meta_for!(MyMeta);
#[ktest]
fn linked_list_push_pop() {
let alloc_options = FrameAllocOptions::new();
let frame1 = alloc_options
.alloc_frame_with(Link::new(MyMeta { mark: 1 }))
.unwrap();
let frame2 = alloc_options
.alloc_frame_with(Link::new(MyMeta { mark: 2 }))
.unwrap();
let frame3 = alloc_options
.alloc_frame_with(Link::new(MyMeta { mark: 3 }))
.unwrap();
let mut list = LinkedList::new();
assert!(list.is_empty());
list.push_front(frame1.try_into().unwrap());
// 1
list.push_front(frame2.try_into().unwrap());
// 2 1
list.push_back(frame3.try_into().unwrap());
// 2 1 3
assert_eq!(list.size(), 3);
let mut cursor = list.cursor_front_mut();
// *2 1 3 ()
assert_eq!(cursor.current_meta().unwrap().mark, 2);
cursor.move_next();
// 2 *1 3 ()
assert_eq!(cursor.current_meta().unwrap().mark, 1);
cursor.move_next();
// 2 1 *3 ()
assert_eq!(cursor.current_meta().unwrap().mark, 3);
cursor.move_next();
// 2 1 3 *()
assert!(cursor.current_meta().is_none());
assert_eq!(cursor.as_list().size(), 3);
assert_eq!(list.pop_front().unwrap().meta().mark, 2);
assert_eq!(list.size(), 2);
// 1 3
assert_eq!(list.pop_back().unwrap().meta().mark, 3);
assert_eq!(list.size(), 1);
// 1
assert_eq!(list.pop_front().unwrap().meta().mark, 1);
assert_eq!(list.size(), 0);
}
#[ktest]
fn linked_list_cursor_at() {
let alloc_options = FrameAllocOptions::new();
let frame1 = alloc_options
.alloc_frame_with(Link::new(MyMeta { mark: 1 }))
.unwrap();
let frame1_addr = frame1.start_paddr();
let frame2 = alloc_options
.alloc_frame_with(Link::new(MyMeta { mark: 2 }))
.unwrap();
let frame2_addr = frame2.start_paddr();
let frame3 = alloc_options
.alloc_frame_with(Link::new(MyMeta { mark: 3 }))
.unwrap();
let frame3_addr = frame3.start_paddr();
let frame_outside = alloc_options
.alloc_frame_with(Link::new(MyMeta { mark: 4 }))
.unwrap();
let mut list = LinkedList::new();
list.push_front(frame1.try_into().unwrap());
list.push_front(frame2.try_into().unwrap());
list.push_front(frame3.try_into().unwrap());
assert!(!list.contains(frame_outside.start_paddr()));
assert!(list.cursor_mut_at(frame_outside.start_paddr()).is_none());
assert!(list.contains(frame1_addr));
assert!(list.contains(frame2_addr));
assert!(list.contains(frame3_addr));
let mut cursor = list.cursor_mut_at(frame1_addr).unwrap();
assert_eq!(cursor.current_meta().unwrap().mark, 1);
let mut cursor = list.cursor_mut_at(frame2_addr).unwrap();
assert_eq!(cursor.current_meta().unwrap().mark, 2);
let mut cursor = list.cursor_mut_at(frame3_addr).unwrap();
assert_eq!(cursor.current_meta().unwrap().mark, 3);
}
#[ktest]
fn linked_list_cursor_ops() {
let alloc_options = FrameAllocOptions::new();
let frame1 = alloc_options
.alloc_frame_with(Link::new(MyMeta { mark: 1 }))
.unwrap();
let frame2 = alloc_options
.alloc_frame_with(Link::new(MyMeta { mark: 2 }))
.unwrap();
let frame3 = alloc_options
.alloc_frame_with(Link::new(MyMeta { mark: 3 }))
.unwrap();
let frame4 = alloc_options
.alloc_frame_with(Link::new(MyMeta { mark: 4 }))
.unwrap();
let frame5 = alloc_options
.alloc_frame_with(Link::new(MyMeta { mark: 5 }))
.unwrap();
let mut list = LinkedList::new();
assert!(list.is_empty());
list.push_front(frame1.try_into().unwrap());
// 1 *()
list.push_front(frame2.try_into().unwrap());
// 2 *1 ()
assert_eq!(list.size(), 2);
let mut cursor = list.cursor_front_mut();
// *2 1 ()
assert_eq!(cursor.current_meta().unwrap().mark, 2);
cursor.move_next();
// 2 *1 ()
assert_eq!(cursor.current_meta().unwrap().mark, 1);
cursor.insert_before(frame3.try_into().unwrap());
// 2 3 *1 ()
assert_eq!(cursor.current_meta().unwrap().mark, 1);
cursor.insert_before(frame4.try_into().unwrap());
// 2 3 4 *1 ()
assert_eq!(cursor.current_meta().unwrap().mark, 1);
cursor.move_next();
// 2 3 4 1 *()
assert!(cursor.current_meta().is_none());
cursor.insert_before(frame5.try_into().unwrap());
// 2 3 4 1 5 *()
assert!(cursor.current_meta().is_none());
assert_eq!(cursor.as_list().size(), 5);
let mut cursor = list.cursor_front_mut();
assert_eq!(cursor.current_meta().unwrap().mark, 2);
cursor.move_next();
assert_eq!(cursor.current_meta().unwrap().mark, 3);
cursor.move_next();
assert_eq!(cursor.current_meta().unwrap().mark, 4);
cursor.move_next();
assert_eq!(cursor.current_meta().unwrap().mark, 1);
cursor.move_next();
assert_eq!(cursor.current_meta().unwrap().mark, 5);
cursor.move_next();
assert!(cursor.current_meta().is_none());
// 2 3 4 1 5 *()
cursor.move_prev();
// 2 3 4 1 *5 ()
assert_eq!(cursor.current_meta().unwrap().mark, 5);
cursor.move_prev();
// 2 3 4 *1 5 ()
assert_eq!(cursor.current_meta().unwrap().mark, 1);
let frame1 = cursor.take_current().unwrap();
// 2 3 4 *5 ()
assert_eq!(frame1.meta().mark, 1);
assert_eq!(cursor.current_meta().unwrap().mark, 5);
cursor.move_next();
// 2 3 4 5 *()
assert!(cursor.current_meta().is_none());
cursor.move_prev();
// 2 3 4 *5 ()
assert_eq!(cursor.current_meta().unwrap().mark, 5);
cursor.move_prev();
// 2 3 *4 5 ()
assert_eq!(cursor.current_meta().unwrap().mark, 4);
cursor.move_prev();
// 2 *3 4 5 ()
assert_eq!(cursor.current_meta().unwrap().mark, 3);
cursor.move_prev();
// *2 3 4 5 ()
assert_eq!(cursor.current_meta().unwrap().mark, 2);
let frame2 = cursor.take_current().unwrap();
// *3 4 5 ()
assert_eq!(frame2.meta().mark, 2);
assert_eq!(cursor.current_meta().unwrap().mark, 3);
cursor.move_next();
// 3 *4 5 ()
assert_eq!(cursor.current_meta().unwrap().mark, 4);
cursor.move_next();
// 3 4 *5 ()
assert_eq!(cursor.current_meta().unwrap().mark, 5);
// 3 4 *()
let frame5 = cursor.take_current().unwrap();
assert_eq!(frame5.meta().mark, 5);
assert!(cursor.current_meta().is_none());
assert_eq!(cursor.as_list().size(), 2);
}
}

View File

@ -169,6 +169,13 @@ macro_rules! impl_frame_meta_for {
($t:ty) => { ($t:ty) => {
// SAFETY: `on_drop` won't read the page. // SAFETY: `on_drop` won't read the page.
unsafe impl $crate::mm::frame::meta::AnyFrameMeta for $t {} unsafe impl $crate::mm::frame::meta::AnyFrameMeta for $t {}
$crate::const_assert!(
core::mem::size_of::<$t>() <= $crate::mm::frame::meta::FRAME_METADATA_MAX_SIZE
);
$crate::const_assert!(
$crate::mm::frame::meta::FRAME_METADATA_MAX_ALIGN % core::mem::align_of::<$t>() == 0
);
}; };
} }

View File

@ -38,6 +38,9 @@ pub mod segment;
pub mod unique; pub mod unique;
pub mod untyped; pub mod untyped;
#[cfg(ktest)]
mod test;
use core::{ use core::{
marker::PhantomData, marker::PhantomData,
mem::ManuallyDrop, mem::ManuallyDrop,

509
ostd/src/mm/frame/test.rs Normal file
View File

@ -0,0 +1,509 @@
// SPDX-License-Identifier: MPL-2.0
use super::{allocator::FrameAllocOptions, *};
use crate::{impl_frame_meta_for, impl_untyped_frame_meta_for, prelude::*};
/// Typed mock metadata struct for testing
#[derive(Debug, Default)]
struct MockFrameMeta {
value: u32,
}
impl_frame_meta_for!(MockFrameMeta);
/// Untyped mock metadata struct for testing
#[derive(Debug, Default)]
struct MockUFrameMeta {
value: u32,
}
impl_untyped_frame_meta_for!(MockUFrameMeta);
// Frame allocation and management tests
mod frame {
use super::*;
#[ktest]
fn frame_allocation() {
let meta = MockFrameMeta { value: 42 };
let frame = FrameAllocOptions::new()
.alloc_frame_with(meta)
.expect("Failed to allocate single frame");
assert_eq!(frame.meta().value, 42);
assert_eq!(frame.reference_count(), 1);
assert_eq!(frame.size(), PAGE_SIZE);
assert_eq!(frame.level(), 1);
}
#[ktest]
fn frame_clone() {
let meta = MockFrameMeta { value: 42 };
let frame1 = FrameAllocOptions::new()
.alloc_frame_with(meta)
.expect("Failed to allocate single frame");
let frame2 = frame1.clone();
assert_eq!(frame1.start_paddr(), frame2.start_paddr());
assert_eq!(frame1.meta().value, frame2.meta().value);
assert_eq!(frame1.reference_count(), 2);
assert_eq!(frame2.reference_count(), 2);
}
#[ktest]
fn frame_drop() {
let metadata = MockFrameMeta { value: 42 };
let frame = FrameAllocOptions::new()
.alloc_frame_with(metadata)
.expect("Failed to allocate single frame");
let ref_count_before = frame.reference_count();
let paddr_before = frame.start_paddr();
assert_eq!(ref_count_before, 1);
drop(frame);
let new_frame = FrameAllocOptions::new()
.alloc_frame_with(MockFrameMeta { value: 42 })
.expect("Failed to allocate single frame");
assert_eq!(new_frame.start_paddr(), paddr_before);
assert_eq!(new_frame.reference_count(), 1);
assert_eq!(new_frame.meta().value, 42);
}
#[ktest]
fn frame_to_uframe() {
let frame = FrameAllocOptions::new()
.alloc_frame_with(MockUFrameMeta { value: 42 })
.unwrap();
let uframe: UFrame = frame.into();
assert_eq!(uframe.size(), PAGE_SIZE);
}
#[ktest]
fn frame_conversions() {
let frame = FrameAllocOptions::new()
.alloc_frame_with(MockFrameMeta { value: 42 })
.unwrap();
let dyn_frame: Frame<dyn AnyFrameMeta> = frame.into();
assert!(!dyn_frame.dyn_meta().is_untyped());
let result: core::result::Result<Frame<MockFrameMeta>, _> = Frame::try_from(dyn_frame);
assert!(result.is_ok());
assert_eq!(result.unwrap().meta().value, 42);
}
}
// Frame linked list tests
mod linked_list {
use super::*;
use crate::mm::frame::linked_list::{Link, LinkedList};
#[ktest]
fn linked_list_push_pop() {
let alloc_options = FrameAllocOptions::new();
let frame1 = alloc_options
.alloc_frame_with(Link::new(MockUFrameMeta { value: 1 }))
.unwrap();
let frame2 = alloc_options
.alloc_frame_with(Link::new(MockUFrameMeta { value: 2 }))
.unwrap();
let frame3 = alloc_options
.alloc_frame_with(Link::new(MockUFrameMeta { value: 3 }))
.unwrap();
let mut list = LinkedList::new();
assert!(list.is_empty());
list.push_front(frame1.try_into().unwrap());
// 1
list.push_front(frame2.try_into().unwrap());
// 2 1
list.push_back(frame3.try_into().unwrap());
// 2 1 3
assert_eq!(list.size(), 3);
let mut cursor = list.cursor_front_mut();
// *2 1 3 ()
assert_eq!(cursor.current_meta().unwrap().value, 2);
cursor.move_next();
// 2 *1 3 ()
assert_eq!(cursor.current_meta().unwrap().value, 1);
cursor.move_next();
// 2 1 *3 ()
assert_eq!(cursor.current_meta().unwrap().value, 3);
cursor.move_next();
// 2 1 3 *()
assert!(cursor.current_meta().is_none());
assert_eq!(cursor.as_list().size(), 3);
assert_eq!(list.pop_front().unwrap().meta().value, 2);
assert_eq!(list.size(), 2);
// 1 3
assert_eq!(list.pop_back().unwrap().meta().value, 3);
assert_eq!(list.size(), 1);
// 1
assert_eq!(list.pop_front().unwrap().meta().value, 1);
assert_eq!(list.size(), 0);
}
#[ktest]
fn linked_list_cursor_at() {
let alloc_options = FrameAllocOptions::new();
let frame1 = alloc_options
.alloc_frame_with(Link::new(MockUFrameMeta { value: 1 }))
.unwrap();
let frame1_addr = frame1.start_paddr();
let frame2 = alloc_options
.alloc_frame_with(Link::new(MockUFrameMeta { value: 2 }))
.unwrap();
let frame2_addr = frame2.start_paddr();
let frame3 = alloc_options
.alloc_frame_with(Link::new(MockUFrameMeta { value: 3 }))
.unwrap();
let frame3_addr = frame3.start_paddr();
let frame_outside = alloc_options
.alloc_frame_with(Link::new(MockUFrameMeta { value: 4 }))
.unwrap();
let mut list = LinkedList::new();
list.push_front(frame1.try_into().unwrap());
list.push_front(frame2.try_into().unwrap());
list.push_front(frame3.try_into().unwrap());
assert!(!list.contains(frame_outside.start_paddr()));
assert!(list.cursor_mut_at(frame_outside.start_paddr()).is_none());
assert!(list.contains(frame1_addr));
assert!(list.contains(frame2_addr));
assert!(list.contains(frame3_addr));
let mut cursor = list.cursor_mut_at(frame1_addr).unwrap();
assert_eq!(cursor.current_meta().unwrap().value, 1);
let mut cursor = list.cursor_mut_at(frame2_addr).unwrap();
assert_eq!(cursor.current_meta().unwrap().value, 2);
let mut cursor = list.cursor_mut_at(frame3_addr).unwrap();
assert_eq!(cursor.current_meta().unwrap().value, 3);
}
#[ktest]
fn linked_list_cursor_ops() {
let alloc_options = FrameAllocOptions::new();
let frame1 = alloc_options
.alloc_frame_with(Link::new(MockUFrameMeta { value: 1 }))
.unwrap();
let frame2 = alloc_options
.alloc_frame_with(Link::new(MockUFrameMeta { value: 2 }))
.unwrap();
let frame3 = alloc_options
.alloc_frame_with(Link::new(MockUFrameMeta { value: 3 }))
.unwrap();
let frame4 = alloc_options
.alloc_frame_with(Link::new(MockUFrameMeta { value: 4 }))
.unwrap();
let frame5 = alloc_options
.alloc_frame_with(Link::new(MockUFrameMeta { value: 5 }))
.unwrap();
let mut list = LinkedList::new();
assert!(list.is_empty());
list.push_front(frame1.try_into().unwrap());
// 1 *()
list.push_front(frame2.try_into().unwrap());
// 2 *1 ()
assert_eq!(list.size(), 2);
let mut cursor = list.cursor_front_mut();
// *2 1 ()
assert_eq!(cursor.current_meta().unwrap().value, 2);
cursor.move_next();
// 2 *1 ()
assert_eq!(cursor.current_meta().unwrap().value, 1);
cursor.insert_before(frame3.try_into().unwrap());
// 2 3 *1 ()
assert_eq!(cursor.current_meta().unwrap().value, 1);
cursor.insert_before(frame4.try_into().unwrap());
// 2 3 4 *1 ()
assert_eq!(cursor.current_meta().unwrap().value, 1);
cursor.move_next();
// 2 3 4 1 *()
assert!(cursor.current_meta().is_none());
cursor.insert_before(frame5.try_into().unwrap());
// 2 3 4 1 5 *()
assert!(cursor.current_meta().is_none());
assert_eq!(cursor.as_list().size(), 5);
let mut cursor = list.cursor_front_mut();
assert_eq!(cursor.current_meta().unwrap().value, 2);
cursor.move_next();
assert_eq!(cursor.current_meta().unwrap().value, 3);
cursor.move_next();
assert_eq!(cursor.current_meta().unwrap().value, 4);
cursor.move_next();
assert_eq!(cursor.current_meta().unwrap().value, 1);
cursor.move_next();
assert_eq!(cursor.current_meta().unwrap().value, 5);
cursor.move_next();
assert!(cursor.current_meta().is_none());
// 2 3 4 1 5 *()
cursor.move_prev();
// 2 3 4 1 *5 ()
assert_eq!(cursor.current_meta().unwrap().value, 5);
cursor.move_prev();
// 2 3 4 *1 5 ()
assert_eq!(cursor.current_meta().unwrap().value, 1);
let frame1 = cursor.take_current().unwrap();
// 2 3 4 *5 ()
assert_eq!(frame1.meta().value, 1);
assert_eq!(cursor.current_meta().unwrap().value, 5);
cursor.move_next();
// 2 3 4 5 *()
assert!(cursor.current_meta().is_none());
cursor.move_prev();
// 2 3 4 *5 ()
assert_eq!(cursor.current_meta().unwrap().value, 5);
cursor.move_prev();
// 2 3 *4 5 ()
assert_eq!(cursor.current_meta().unwrap().value, 4);
cursor.move_prev();
// 2 *3 4 5 ()
assert_eq!(cursor.current_meta().unwrap().value, 3);
cursor.move_prev();
// *2 3 4 5 ()
assert_eq!(cursor.current_meta().unwrap().value, 2);
let frame2 = cursor.take_current().unwrap();
// *3 4 5 ()
assert_eq!(frame2.meta().value, 2);
assert_eq!(cursor.current_meta().unwrap().value, 3);
cursor.move_next();
// 3 *4 5 ()
assert_eq!(cursor.current_meta().unwrap().value, 4);
cursor.move_next();
// 3 4 *5 ()
assert_eq!(cursor.current_meta().unwrap().value, 5);
// 3 4 *()
let frame5 = cursor.take_current().unwrap();
assert_eq!(frame5.meta().value, 5);
assert!(cursor.current_meta().is_none());
assert_eq!(cursor.as_list().size(), 2);
}
}
// Segment tests
mod segment {
use super::*;
use crate::{mm::USegment, Error};
#[ktest]
fn segment_creation() {
let range = 512 * PAGE_SIZE..1024 * PAGE_SIZE;
let segment = FrameAllocOptions::new()
.alloc_segment(range.len() / PAGE_SIZE)
.expect("Failed to allocate segment");
assert_eq!(segment.size(), range.len());
assert_eq!(segment.end_paddr() - segment.start_paddr(), range.len());
}
#[ktest]
#[should_panic]
fn max_segment_creation() {
// Upstream FrameAllocator panics when attempting to allocate a segment with usize::MAX frames
let max_frames = usize::MAX;
let _ = FrameAllocOptions::new().alloc_segment(max_frames);
}
#[ktest]
fn empty_segment_creation() {
let result = FrameAllocOptions::new().alloc_segment(0);
assert!(
matches!(result, Err(Error::InvalidArgs)),
"Expected `InvalidArgs` error when allocating a zero-sized segment"
);
}
#[ktest]
fn zeroed_segment_creation() {
let segment = FrameAllocOptions::new()
.zeroed(true)
.alloc_segment(1)
.expect("Failed to allocate segment");
let mut reader = segment.reader();
let mut buffer = [0; PAGE_SIZE];
reader.read(&mut buffer.as_mut_slice().into());
assert!(buffer.iter().all(|&x| x == 0));
}
#[ktest]
fn segment_split() {
let total_frames = 2;
let segment = FrameAllocOptions::new()
.alloc_segment(total_frames)
.expect("Failed to allocate segment");
let (first, second) = segment.split(PAGE_SIZE);
assert_eq!(first.size(), PAGE_SIZE);
assert_eq!(second.size(), PAGE_SIZE);
}
#[ktest]
fn segment_slice() {
let total_frames = 3;
let segment = FrameAllocOptions::new()
.alloc_segment(total_frames)
.expect("Failed to allocate segment");
let slice = segment.slice(&(PAGE_SIZE..PAGE_SIZE * 2));
assert_eq!(slice.size(), PAGE_SIZE);
assert_eq!(slice.start_paddr(), segment.start_paddr() + PAGE_SIZE);
}
#[ktest]
fn segment_iteration() {
let total_frames = 2;
let segment = FrameAllocOptions::new()
.alloc_segment_with(total_frames, |_| MockFrameMeta { value: 42 })
.expect("Failed to allocate segment");
let mut count = 0;
for frame in segment {
assert_eq!(frame.meta().value, 42);
count += 1;
}
assert_eq!(count, total_frames);
}
#[ktest]
#[should_panic]
fn invalid_segment_split() {
let total_frames = 2;
let segment = FrameAllocOptions::new()
.alloc_segment(total_frames)
.expect("Failed to allocate segment");
// Attempts to split at zero, which should panic
segment.split(0);
}
#[ktest]
fn segment_to_usegment() {
let options = FrameAllocOptions::new();
let segment = options.alloc_segment(1).unwrap();
let dyn_segment: Segment<dyn AnyFrameMeta> = segment.clone().into();
let result: core::result::Result<USegment, Segment<_>> = USegment::try_from(dyn_segment);
assert!(result.is_ok());
let usegment = result.unwrap();
assert_eq!(usegment.size(), PAGE_SIZE);
assert_eq!(usegment.start_paddr(), segment.start_paddr());
}
#[ktest]
fn segment_to_segment() {
let options = FrameAllocOptions::new();
let segment = options
.alloc_segment_with(1, |_| MockFrameMeta { value: 42 })
.unwrap();
let dyn_segment: Segment<dyn AnyFrameMeta> = segment.into();
let result: core::result::Result<Segment<MockFrameMeta>, Segment<_>> =
Segment::try_from(dyn_segment);
assert!(result.is_ok());
let segment = result.unwrap();
assert_eq!(segment.size(), PAGE_SIZE);
for frame in segment {
assert_eq!(frame.meta().value, 42);
}
}
#[ktest]
fn frame_to_segment() {
let frame = FrameAllocOptions::new()
.alloc_frame_with(MockFrameMeta { value: 42 })
.unwrap();
let paddr = frame.start_paddr();
let segment: Segment<MockFrameMeta> = frame.into();
assert_eq!(segment.size(), PAGE_SIZE);
assert_eq!(segment.start_paddr(), paddr);
for frame in segment {
assert_eq!(frame.meta().value, 42);
}
}
#[ktest]
fn segment_drop() {
let options = FrameAllocOptions::new();
let segment = options.alloc_segment(1).unwrap();
let paddr_before = segment.start_paddr();
drop(segment);
let new_segment = options.alloc_segment(1).unwrap();
assert_eq!(new_segment.start_paddr(), paddr_before);
}
}
// Untyped frame/segment tests
mod untyped {
use super::*;
use crate::mm::frame::untyped::FrameRef;
#[ktest]
fn untyped_frame_reader_writer() {
let frame = FrameAllocOptions::new()
.alloc_frame_with(())
.expect("Failed to allocate frame");
// Tests the frame reader
let mut reader = frame.reader();
assert_eq!(reader.remain(), PAGE_SIZE);
// Tests the frame writer
let mut writer = frame.writer();
assert_eq!(writer.avail(), PAGE_SIZE);
// Writes data to the frame
let data = [0xAA; 128];
writer.write(&mut data.as_slice().into());
// Reads data back
let mut buffer = [0; 128];
reader.read(&mut buffer.as_mut_slice().into());
assert_eq!(buffer, data);
}
#[ktest]
fn untyped_segment_reader_writer() {
let segment = FrameAllocOptions::new()
.alloc_segment(2)
.expect("Failed to allocate segment");
// Tests the segment reader
let mut reader = segment.reader();
assert_eq!(reader.remain(), 2 * PAGE_SIZE);
// Tests the segment writer
let mut writer = segment.writer();
assert_eq!(writer.avail(), 2 * PAGE_SIZE);
// Writes data to the segment
let data = [0xBB; 256];
writer.write(&mut data.as_slice().into());
// Reads data back
let mut buffer = [0; 256];
reader.read(&mut buffer.as_mut_slice().into());
assert_eq!(buffer, data);
}
#[ktest]
fn xarray_item_entry() {
use xarray::ItemEntry;
let init_val = 42;
let frame = FrameAllocOptions::new()
.alloc_frame_with(MockUFrameMeta { value: init_val })
.expect("Failed to allocate frame");
let ptr = frame.start_paddr();
let uframe: UFrame = frame.into();
// Converts and retrieves the frame from raw pointer
let raw_ptr = ItemEntry::into_raw(uframe);
let frame_from_raw: Frame<MockUFrameMeta> = unsafe { ItemEntry::from_raw(raw_ptr) };
assert_eq!(frame_from_raw.start_paddr(), ptr);
assert_eq!(frame_from_raw.meta().value, init_val);
// References the frame from raw pointer
let frame_ref: FrameRef<MockUFrameMeta> = unsafe { Frame::raw_as_ref(raw_ptr) };
assert_eq!(frame_ref.start_paddr(), ptr);
}
}