| //! These tests are not run automatically right now. Please run these tests manually by copying them |
| //! to a separate project when modifying any related code. |
| |
| use super::alloc::*; |
| use super::time::system_time_internal::{from_uefi, to_uefi}; |
| use crate::io::{IoSlice, IoSliceMut}; |
| use crate::time::Duration; |
| |
| const SECS_IN_MINUTE: u64 = 60; |
| |
| const MAX_UEFI_TIME: Duration = from_uefi(r_efi::efi::Time { |
| year: 9999, |
| month: 12, |
| day: 31, |
| hour: 23, |
| minute: 59, |
| second: 59, |
| nanosecond: 999_999_999, |
| timezone: 1440, |
| daylight: 0, |
| pad1: 0, |
| pad2: 0, |
| }); |
| |
| #[test] |
| fn align() { |
| // UEFI ABI specifies that allocation alignment minimum is always 8. So this can be |
| // statically verified. |
| assert_eq!(POOL_ALIGNMENT, 8); |
| |
| // Loop over allocation-request sizes from 0-256 and alignments from 1-128, and verify |
| // that in case of overalignment there is at least space for one additional pointer to |
| // store in the allocation. |
| for i in 0..256 { |
| for j in &[1, 2, 4, 8, 16, 32, 64, 128] { |
| if *j <= 8 { |
| assert_eq!(align_size(i, *j), i); |
| } else { |
| assert!(align_size(i, *j) > i + size_of::<*mut ()>()); |
| } |
| } |
| } |
| } |
| |
| // UEFI Time cannot implement Eq due to uninitilaized pad1 and pad2 |
| fn uefi_time_cmp(t1: r_efi::efi::Time, t2: r_efi::efi::Time) -> bool { |
| t1.year == t2.year |
| && t1.month == t2.month |
| && t1.day == t2.day |
| && t1.hour == t2.hour |
| && t1.minute == t2.minute |
| && t1.second == t2.second |
| && t1.nanosecond == t2.nanosecond |
| && t1.timezone == t2.timezone |
| && t1.daylight == t2.daylight |
| } |
| |
| #[test] |
| fn systemtime_start() { |
| let t = r_efi::efi::Time { |
| year: 1900, |
| month: 1, |
| day: 1, |
| hour: 0, |
| minute: 0, |
| second: 0, |
| pad1: 0, |
| nanosecond: 0, |
| timezone: -1440, |
| daylight: 0, |
| pad2: 0, |
| }; |
| assert_eq!(from_uefi(&t), Duration::new(0, 0)); |
| assert!(uefi_time_cmp(t, to_uefi(&from_uefi(&t), -1440, 0).unwrap())); |
| assert!(to_uefi(&from_uefi(&t), 0, 0).is_err()); |
| } |
| |
| #[test] |
| fn systemtime_utc_start() { |
| let t = r_efi::efi::Time { |
| year: 1900, |
| month: 1, |
| day: 1, |
| hour: 0, |
| minute: 0, |
| second: 0, |
| pad1: 0, |
| nanosecond: 0, |
| timezone: 0, |
| daylight: 0, |
| pad2: 0, |
| }; |
| assert_eq!(from_uefi(&t), Duration::new(1440 * SECS_IN_MINUTE, 0)); |
| assert!(uefi_time_cmp(t, to_uefi(&from_uefi(&t), 0, 0).unwrap())); |
| assert!(to_uefi(&from_uefi(&t), -1440, 0).is_ok()); |
| } |
| |
| #[test] |
| fn systemtime_end() { |
| let t = r_efi::efi::Time { |
| year: 9999, |
| month: 12, |
| day: 31, |
| hour: 23, |
| minute: 59, |
| second: 59, |
| pad1: 0, |
| nanosecond: 0, |
| timezone: 1440, |
| daylight: 0, |
| pad2: 0, |
| }; |
| assert!(to_uefi(&from_uefi(&t), 1440, 0).is_ok()); |
| assert!(to_uefi(&from_uefi(&t), 1439, 0).is_err()); |
| } |
| |
| #[test] |
| fn min_time() { |
| let inp = Duration::from_secs(1440 * SECS_IN_MINUTE); |
| let new_tz = to_uefi(&inp, 1440, 0).err().unwrap(); |
| assert_eq!(new_tz, 0); |
| assert!(to_uefi(&inp, new_tz, 0).is_ok()); |
| |
| let inp = Duration::from_secs(1450 * SECS_IN_MINUTE); |
| let new_tz = to_uefi(&inp, 1440, 0).err().unwrap(); |
| assert_eq!(new_tz, 10); |
| assert!(to_uefi(&inp, new_tz, 0).is_ok()); |
| |
| let inp = Duration::from_secs(1450 * SECS_IN_MINUTE + 10); |
| let new_tz = to_uefi(&inp, 1440, 0).err().unwrap(); |
| assert_eq!(new_tz, 10); |
| assert!(to_uefi(&inp, new_tz, 0).is_ok()); |
| |
| let inp = Duration::from_secs(1430 * SECS_IN_MINUTE); |
| let new_tz = to_uefi(&inp, 1440, 0).err().unwrap(); |
| assert_eq!(new_tz, -10); |
| assert!(to_uefi(&inp, new_tz, 0).is_ok()); |
| } |
| |
| #[test] |
| fn max_time() { |
| let inp = MAX_UEFI_TIME.0; |
| let new_tz = to_uefi(&inp, -1440, 0).err().unwrap(); |
| assert_eq!(new_tz, 1440); |
| assert!(to_uefi(&inp, new_tz, 0).is_ok()); |
| |
| let inp = MAX_UEFI_TIME.0 - Duration::from_secs(1440 * SECS_IN_MINUTE); |
| let new_tz = to_uefi(&inp, -1440, 0).err().unwrap(); |
| assert_eq!(new_tz, 0); |
| assert!(to_uefi(&inp, new_tz, 0).is_ok()); |
| |
| let inp = MAX_UEFI_TIME.0 - Duration::from_secs(1440 * SECS_IN_MINUTE + 10); |
| let new_tz = to_uefi(&inp, -1440, 0).err().unwrap(); |
| assert_eq!(new_tz, 0); |
| assert!(to_uefi(&inp, new_tz, 0).is_ok()); |
| } |
| |
| // UEFI IoSlice and IoSliceMut Tests |
| // |
| // Strictly speaking, vectored read/write types for UDP4, UDP6, TCP4, TCP6 are defined |
| // separately in the UEFI Spec. However, they have the same signature. These tests just ensure |
| // that `IoSlice` and `IoSliceMut` are compatible with the vectored types for all the |
| // networking protocols. |
| |
| unsafe fn to_slice<T>(val: &T) -> &[u8] { |
| let len = size_of_val(val); |
| unsafe { crate::slice::from_raw_parts(crate::ptr::from_ref(val).cast(), len) } |
| } |
| |
| #[test] |
| fn io_slice_single() { |
| let mut data = [0, 1, 2, 3, 4]; |
| |
| let tcp4_frag = r_efi::protocols::tcp4::FragmentData { |
| fragment_length: data.len().try_into().unwrap(), |
| fragment_buffer: data.as_mut_ptr().cast(), |
| }; |
| let tcp6_frag = r_efi::protocols::tcp6::FragmentData { |
| fragment_length: data.len().try_into().unwrap(), |
| fragment_buffer: data.as_mut_ptr().cast(), |
| }; |
| let udp4_frag = r_efi::protocols::udp4::FragmentData { |
| fragment_length: data.len().try_into().unwrap(), |
| fragment_buffer: data.as_mut_ptr().cast(), |
| }; |
| let udp6_frag = r_efi::protocols::udp6::FragmentData { |
| fragment_length: data.len().try_into().unwrap(), |
| fragment_buffer: data.as_mut_ptr().cast(), |
| }; |
| let io_slice = IoSlice::new(&data); |
| |
| unsafe { |
| assert_eq!(to_slice(&io_slice), to_slice(&tcp4_frag)); |
| assert_eq!(to_slice(&io_slice), to_slice(&tcp6_frag)); |
| assert_eq!(to_slice(&io_slice), to_slice(&udp4_frag)); |
| assert_eq!(to_slice(&io_slice), to_slice(&udp6_frag)); |
| } |
| } |
| |
| #[test] |
| fn io_slice_mut_single() { |
| let mut data = [0, 1, 2, 3, 4]; |
| |
| let tcp4_frag = r_efi::protocols::tcp4::FragmentData { |
| fragment_length: data.len().try_into().unwrap(), |
| fragment_buffer: data.as_mut_ptr().cast(), |
| }; |
| let tcp6_frag = r_efi::protocols::tcp6::FragmentData { |
| fragment_length: data.len().try_into().unwrap(), |
| fragment_buffer: data.as_mut_ptr().cast(), |
| }; |
| let udp4_frag = r_efi::protocols::udp4::FragmentData { |
| fragment_length: data.len().try_into().unwrap(), |
| fragment_buffer: data.as_mut_ptr().cast(), |
| }; |
| let udp6_frag = r_efi::protocols::udp6::FragmentData { |
| fragment_length: data.len().try_into().unwrap(), |
| fragment_buffer: data.as_mut_ptr().cast(), |
| }; |
| let io_slice_mut = IoSliceMut::new(&mut data); |
| |
| unsafe { |
| assert_eq!(to_slice(&io_slice_mut), to_slice(&tcp4_frag)); |
| assert_eq!(to_slice(&io_slice_mut), to_slice(&tcp6_frag)); |
| assert_eq!(to_slice(&io_slice_mut), to_slice(&udp4_frag)); |
| assert_eq!(to_slice(&io_slice_mut), to_slice(&udp6_frag)); |
| } |
| } |
| |
| #[test] |
| fn io_slice_multi() { |
| let mut data = [0, 1, 2, 3, 4]; |
| |
| let tcp4_frag = r_efi::protocols::tcp4::FragmentData { |
| fragment_length: data.len().try_into().unwrap(), |
| fragment_buffer: data.as_mut_ptr().cast(), |
| }; |
| let rhs = |
| [tcp4_frag.clone(), tcp4_frag.clone(), tcp4_frag.clone(), tcp4_frag.clone(), tcp4_frag]; |
| let lhs = [ |
| IoSlice::new(&data), |
| IoSlice::new(&data), |
| IoSlice::new(&data), |
| IoSlice::new(&data), |
| IoSlice::new(&data), |
| ]; |
| |
| unsafe { |
| assert_eq!(to_slice(&lhs), to_slice(&rhs)); |
| } |
| } |
| |
| #[test] |
| fn io_slice_basic() { |
| let data = [0, 1, 2, 3, 4]; |
| let mut io_slice = IoSlice::new(&data); |
| |
| assert_eq!(data, io_slice.as_slice()); |
| io_slice.advance(2); |
| assert_eq!(&data[2..], io_slice.as_slice()); |
| } |
| |
| #[test] |
| fn io_slice_mut_basic() { |
| let data = [0, 1, 2, 3, 4]; |
| let mut data_clone = [0, 1, 2, 3, 4]; |
| let mut io_slice_mut = IoSliceMut::new(&mut data_clone); |
| |
| assert_eq!(data, io_slice_mut.as_slice()); |
| assert_eq!(data, io_slice_mut.as_mut_slice()); |
| |
| io_slice_mut.advance(2); |
| assert_eq!(&data[2..], io_slice_mut.into_slice()); |
| } |