more time module tests
Some checks failed
Rust/spacepackets/pipeline/head There was a failure building this commit

This commit is contained in:
Robin Müller 2023-12-05 15:05:00 +01:00
parent 149b4d65a2
commit 71e043e159
4 changed files with 107 additions and 22 deletions

View File

@ -343,7 +343,6 @@ pub mod tests {
use alloc::string::ToString; use alloc::string::ToString;
use crate::cfdp::lv::Lv; use crate::cfdp::lv::Lv;
use crate::cfdp::pdu::eof::EofPdu;
use crate::cfdp::pdu::metadata::{ use crate::cfdp::pdu::metadata::{
build_metadata_opts_from_slice, build_metadata_opts_from_vec, MetadataGenericParams, build_metadata_opts_from_slice, build_metadata_opts_from_vec, MetadataGenericParams,
MetadataPduCreator, MetadataPduReader, MetadataPduCreator, MetadataPduReader,

View File

@ -1307,6 +1307,7 @@ mod tests {
use super::*; use super::*;
use crate::time::TimestampError::{ByteConversion, InvalidTimeCode}; use crate::time::TimestampError::{ByteConversion, InvalidTimeCode};
use crate::ByteConversionError::{FromSliceTooSmall, ToSliceTooSmall}; use crate::ByteConversionError::{FromSliceTooSmall, ToSliceTooSmall};
use alloc::string::ToString;
use chrono::{Datelike, NaiveDate, Timelike}; use chrono::{Datelike, NaiveDate, Timelike};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use postcard::{from_bytes, to_allocvec}; use postcard::{from_bytes, to_allocvec};
@ -1415,6 +1416,11 @@ mod tests {
fn test_write() { fn test_write() {
let mut buf = [0; 16]; let mut buf = [0; 16];
let time_stamper_0 = TimeProvider::new_with_u16_days(0, 0); let time_stamper_0 = TimeProvider::new_with_u16_days(0, 0);
let unix_stamp = time_stamper_0.unix_stamp();
assert_eq!(
unix_stamp.unix_seconds,
(DAYS_CCSDS_TO_UNIX * SECONDS_PER_DAY as i32).into()
);
let mut res = time_stamper_0.write_to_bytes(&mut buf); let mut res = time_stamper_0.write_to_bytes(&mut buf);
assert!(res.is_ok()); assert!(res.is_ok());
assert_eq!(buf[0], (CcsdsTimeCodes::Cds as u8) << 4); assert_eq!(buf[0], (CcsdsTimeCodes::Cds as u8) << 4);
@ -1447,10 +1453,15 @@ mod tests {
for i in 0..6 { for i in 0..6 {
let res = time_stamper.write_to_bytes(&mut buf[0..i]); let res = time_stamper.write_to_bytes(&mut buf[0..i]);
assert!(res.is_err()); assert!(res.is_err());
match res.unwrap_err() { let error = res.unwrap_err();
match error {
ByteConversion(ToSliceTooSmall { found, expected }) => { ByteConversion(ToSliceTooSmall { found, expected }) => {
assert_eq!(found, i); assert_eq!(found, i);
assert_eq!(expected, 7); assert_eq!(expected, 7);
assert_eq!(
error.to_string(),
"time stamp: target slice with size 0 is too small, expected size of at least 7"
);
} }
_ => panic!( _ => panic!(
"{}", "{}",
@ -1492,12 +1503,13 @@ mod tests {
let res = TimeProvider::<DaysLen16Bits>::from_bytes(&buf); let res = TimeProvider::<DaysLen16Bits>::from_bytes(&buf);
assert!(res.is_err()); assert!(res.is_err());
let err = res.unwrap_err(); let err = res.unwrap_err();
match err { if let InvalidTimeCode { expected, found } = err {
InvalidTimeCode { expected, found } => { assert_eq!(expected, CcsdsTimeCodes::Cds);
assert_eq!(expected, CcsdsTimeCodes::Cds); assert_eq!(found, 0);
assert_eq!(found, 0); assert_eq!(
} err.to_string(),
_ => {} "invalid raw time code value 0 for time code Cds"
);
} }
} }
@ -1942,7 +1954,7 @@ mod tests {
let invalid_unix_secs: i64 = (u16::MAX as i64 + 1) * SECONDS_PER_DAY as i64; let invalid_unix_secs: i64 = (u16::MAX as i64 + 1) * SECONDS_PER_DAY as i64;
let subsec_millis = 0; let subsec_millis = 0;
match TimeProvider::from_unix_secs_with_u16_days(&UnixTimestamp::const_new( match TimeProvider::from_unix_secs_with_u16_days(&UnixTimestamp::const_new(
invalid_unix_secs as i64, invalid_unix_secs,
subsec_millis, subsec_millis,
)) { )) {
Ok(_) => { Ok(_) => {
@ -1954,6 +1966,7 @@ mod tests {
days, days,
unix_to_ccsds_days(invalid_unix_secs / SECONDS_PER_DAY as i64) unix_to_ccsds_days(invalid_unix_secs / SECONDS_PER_DAY as i64)
); );
assert_eq!(e.to_string(), "cds error: invalid ccsds days 69919");
} else { } else {
panic!("unexpected error {}", e) panic!("unexpected error {}", e)
} }

View File

@ -7,6 +7,7 @@ use chrono::Datelike;
use core::fmt::Debug; use core::fmt::Debug;
use core::ops::{Add, AddAssign}; use core::ops::{Add, AddAssign};
use core::time::Duration; use core::time::Duration;
use core::u64;
const MIN_CUC_LEN: usize = 2; const MIN_CUC_LEN: usize = 2;
@ -95,8 +96,14 @@ pub enum CucError {
InvalidCounterWidth(u8), InvalidCounterWidth(u8),
InvalidFractionResolution(FractionalResolution), InvalidFractionResolution(FractionalResolution),
/// Invalid counter supplied. /// Invalid counter supplied.
InvalidCounter(u8, u64), InvalidCounter {
InvalidFractions(FractionalResolution, u64), width: u8,
counter: u64,
},
InvalidFractions {
resolution: FractionalResolution,
value: u64,
},
} }
impl Display for CucError { impl Display for CucError {
@ -108,11 +115,14 @@ impl Display for CucError {
CucError::InvalidFractionResolution(w) => { CucError::InvalidFractionResolution(w) => {
write!(f, "invalid cuc fractional part byte width {w:?}") write!(f, "invalid cuc fractional part byte width {w:?}")
} }
CucError::InvalidCounter(w, c) => { CucError::InvalidCounter { width, counter } => {
write!(f, "invalid cuc counter {c} for width {w}") write!(f, "invalid cuc counter {counter} for width {width}")
} }
CucError::InvalidFractions(w, c) => { CucError::InvalidFractions { resolution, value } => {
write!(f, "invalid cuc fractional part {c} for width {w:?}") write!(
f,
"invalid cuc fractional part {value} for resolution {resolution:?}"
)
} }
} }
} }
@ -290,7 +300,11 @@ impl TimeProviderCcsdsEpoch {
)); ));
} }
if ccsds_epoch > u32::MAX as i64 { if ccsds_epoch > u32::MAX as i64 {
return Err(CucError::InvalidCounter(4, ccsds_epoch as u64).into()); return Err(CucError::InvalidCounter {
width: 4,
counter: ccsds_epoch as u64,
}
.into());
} }
let mut fractions = None; let mut fractions = None;
if let Some(subsec_millis) = unix_stamp.subsecond_millis { if let Some(subsec_millis) = unix_stamp.subsecond_millis {
@ -343,7 +357,10 @@ impl TimeProviderCcsdsEpoch {
) -> Result<Self, CucError> { ) -> Result<Self, CucError> {
Self::verify_counter_width(counter.0)?; Self::verify_counter_width(counter.0)?;
if counter.1 > (2u64.pow(counter.0 as u32 * 8) - 1) as u32 { if counter.1 > (2u64.pow(counter.0 as u32 * 8) - 1) as u32 {
return Err(CucError::InvalidCounter(counter.0, counter.1 as u64)); return Err(CucError::InvalidCounter {
width: counter.0,
counter: counter.1 as u64,
});
} }
if let Some(fractions) = fractions { if let Some(fractions) = fractions {
Self::verify_fractions_width(fractions.0)?; Self::verify_fractions_width(fractions.0)?;
@ -441,7 +458,10 @@ impl TimeProviderCcsdsEpoch {
fn verify_fractions_value(val: FractionalPart) -> Result<(), CucError> { fn verify_fractions_value(val: FractionalPart) -> Result<(), CucError> {
if val.1 > 2u32.pow((val.0 as u32) * 8) - 1 { if val.1 > 2u32.pow((val.0 as u32) * 8) - 1 {
return Err(CucError::InvalidFractions(val.0, val.1 as u64)); return Err(CucError::InvalidFractions {
resolution: val.0,
value: val.1 as u64,
});
} }
Ok(()) Ok(())
} }
@ -713,6 +733,7 @@ impl Add<Duration> for &TimeProviderCcsdsEpoch {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use alloc::string::ToString;
use chrono::{Datelike, Timelike}; use chrono::{Datelike, Timelike};
#[allow(unused_imports)] #[allow(unused_imports)]
use std::println; use std::println;
@ -861,6 +882,7 @@ mod tests {
#[test] #[test]
fn invalid_buf_len_for_read() {} fn invalid_buf_len_for_read() {}
#[test] #[test]
fn write_read_three_byte_cntr_stamp() { fn write_read_three_byte_cntr_stamp() {
let mut buf = [0; 4]; let mut buf = [0; 4];
@ -1128,4 +1150,17 @@ mod tests {
cuc_stamp += duration; cuc_stamp += duration;
assert_eq!(cuc_stamp.counter.1, 10); assert_eq!(cuc_stamp.counter.1, 10);
} }
#[test]
fn test_invalid_width_param() {
let error = TimeProviderCcsdsEpoch::new_generic(WidthCounterPair(8, 0), None);
assert!(error.is_err());
let error = error.unwrap_err();
if let CucError::InvalidCounterWidth(width) = error {
assert_eq!(width, 8);
assert_eq!(error.to_string(), "invalid cuc counter byte width 8");
} else {
panic!("unexpected error: {}", error);
}
}
} }

View File

@ -82,13 +82,13 @@ impl Display for TimestampError {
) )
} }
TimestampError::Cds(e) => { TimestampError::Cds(e) => {
write!(f, "cds error {e}") write!(f, "cds error: {e}")
} }
TimestampError::Cuc(e) => { TimestampError::Cuc(e) => {
write!(f, "cuc error {e}") write!(f, "cuc error: {e}")
} }
TimestampError::ByteConversion(e) => { TimestampError::ByteConversion(e) => {
write!(f, "byte conversion error {e}") write!(f, "time stamp: {e}")
} }
TimestampError::DateBeforeCcsdsEpoch(e) => { TimestampError::DateBeforeCcsdsEpoch(e) => {
write!(f, "datetime with date before ccsds epoch: {e}") write!(f, "datetime with date before ccsds epoch: {e}")
@ -412,7 +412,11 @@ impl Add<Duration> for &UnixTimestamp {
#[cfg(all(test, feature = "std"))] #[cfg(all(test, feature = "std"))]
mod tests { mod tests {
use super::*; use alloc::string::ToString;
use chrono::{Datelike, Timelike};
use std::format;
use super::{cuc::CucError, *};
#[test] #[test]
fn test_days_conversion() { fn test_days_conversion() {
@ -426,6 +430,14 @@ mod tests {
assert!(sec_floats > 0.0); assert!(sec_floats > 0.0);
} }
#[test]
fn test_ms_of_day() {
let ms = ms_of_day(0.0);
assert_eq!(ms, 0);
let ms = ms_of_day(5.0);
assert_eq!(ms, 5000);
}
#[test] #[test]
fn test_ccsds_epoch() { fn test_ccsds_epoch() {
let now = SystemTime::now() let now = SystemTime::now()
@ -534,6 +546,25 @@ mod tests {
assert!(stamp1.subsecond_millis().is_none()); assert!(stamp1.subsecond_millis().is_none());
} }
#[test]
fn test_as_dt() {
let stamp = UnixTimestamp::new_only_seconds(0);
let dt = stamp.as_date_time().unwrap();
assert_eq!(dt.year(), 1970);
assert_eq!(dt.month(), 1);
assert_eq!(dt.day(), 1);
assert_eq!(dt.hour(), 0);
assert_eq!(dt.minute(), 0);
assert_eq!(dt.second(), 0);
}
#[test]
fn test_from_now() {
let stamp_now = UnixTimestamp::from_now().unwrap();
let dt_now = stamp_now.as_date_time().unwrap();
assert!(dt_now.year() >= 2020);
}
#[test] #[test]
fn test_addition_spillover() { fn test_addition_spillover() {
let mut stamp0 = UnixTimestamp::new(1, 900).unwrap(); let mut stamp0 = UnixTimestamp::new(1, 900).unwrap();
@ -544,4 +575,11 @@ mod tests {
assert_eq!(stamp0.unix_seconds, 3); assert_eq!(stamp0.unix_seconds, 3);
assert_eq!(stamp0.subsecond_millis().unwrap(), 100); assert_eq!(stamp0.subsecond_millis().unwrap(), 100);
} }
#[test]
fn test_cuc_error_printout() {
let cuc_error = CucError::InvalidCounterWidth(12);
let stamp_error = TimestampError::from(cuc_error);
assert_eq!(stamp_error.to_string(), format!("cuc error: {cuc_error}"));
}
} }