| //! 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::time::system_time_internal::{from_uefi, to_uefi}; | |
| use crate::io::{IoSlice, IoSliceMut}; | |
| use crate::ops::{Deref, DerefMut}; | |
| 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, | |
| }) | |
| .unwrap(); | |
| // 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).unwrap(), Duration::new(0, 0)); | |
| assert!(uefi_time_cmp(t, to_uefi(&from_uefi(&t).unwrap(), -1440, 0).unwrap())); | |
| assert!(to_uefi(&from_uefi(&t).unwrap(), 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).unwrap(), Duration::new(1440 * SECS_IN_MINUTE, 0)); | |
| assert!(uefi_time_cmp(t, to_uefi(&from_uefi(&t).unwrap(), 0, 0).unwrap())); | |
| assert!(to_uefi(&from_uefi(&t).unwrap(), -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).unwrap(), 1440, 0).is_ok()); | |
| assert!(to_uefi(&from_uefi(&t).unwrap(), 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; | |
| 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 - 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 - 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.deref()); | |
| assert_eq!(data, io_slice_mut.deref_mut()); | |
| io_slice_mut.advance(2); | |
| assert_eq!(&data[2..], io_slice_mut.into_slice()); | |
| } |