diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7198298..279cd79 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,6 +46,6 @@ jobs: cargo build -p sntpc --no-default-features cargo build -p example-simple-no-std --profile no-std - name: Run tests with std - run: cargo test + run: cargo test --all-features - name: Run tests with no_std run: cargo test --no-default-features diff --git a/sntpc/src/lib.rs b/sntpc/src/lib.rs index c2c7546..3e75585 100644 --- a/sntpc/src/lib.rs +++ b/sntpc/src/lib.rs @@ -1072,11 +1072,44 @@ pub fn fraction_to_picoseconds(sec_fraction: u32) -> u64 { #[cfg(test)] mod sntpc_ntp_result_tests { + use crate::types::Units; use crate::{ fraction_to_microseconds, fraction_to_milliseconds, - fraction_to_nanoseconds, fraction_to_picoseconds, NtpResult, + fraction_to_nanoseconds, fraction_to_picoseconds, offset_calculate, + NtpResult, }; + struct Timestamps(u64, u64, u64, u64); + struct OffsetCalcTestCase { + timestamp: Timestamps, + expected: i64, + } + + impl OffsetCalcTestCase { + fn new(t1: u64, t2: u64, t3: u64, t4: u64, expected: i64) -> Self { + OffsetCalcTestCase { + timestamp: Timestamps(t1, t2, t3, t4), + expected, + } + } + + fn t1(&self) -> u64 { + self.timestamp.0 + } + + fn t2(&self) -> u64 { + self.timestamp.1 + } + + fn t3(&self) -> u64 { + self.timestamp.2 + } + + fn t4(&self) -> u64 { + self.timestamp.3 + } + } + #[test] fn test_ntp_result() { let result1 = NtpResult::new(0, 0, 0, 0, 1, -2); @@ -1169,44 +1202,70 @@ mod sntpc_ntp_result_tests { let picoseconds = fraction_to_picoseconds(result.seconds_fraction); assert_eq!(0u64, picoseconds); } -} - -#[cfg(all(test, feature = "std", feature = "std-socket", feature = "sync"))] -mod sntpc_tests { - use crate::sync::get_time; - use crate::{offset_calculate, Error, NtpContext, StdTimestampGen, Units}; - use std::net::{ToSocketAddrs, UdpSocket}; - - struct Timestamps(u64, u64, u64, u64); - struct OffsetCalcTestCase { - timestamp: Timestamps, - expected: i64, - } - - impl OffsetCalcTestCase { - fn new(t1: u64, t2: u64, t3: u64, t4: u64, expected: i64) -> Self { - OffsetCalcTestCase { - timestamp: Timestamps(t1, t2, t3, t4), - expected, - } - } - fn t1(&self) -> u64 { - self.timestamp.0 - } + #[test] + fn test_offset_calculate() { + let tests = [ + OffsetCalcTestCase::new( + 16_893_142_954_672_769_962, + 16_893_142_959_053_084_959, + 16_893_142_959_053_112_968, + 16_893_142_954_793_063_406, + 1_005_870, + ), + OffsetCalcTestCase::new( + 16_893_362_966_131_575_843, + 16_893_362_966_715_800_791, + 16_893_362_966_715_869_584, + 16_893_362_967_084_349_913, + 25115, + ), + OffsetCalcTestCase::new( + 16_893_399_716_399_327_198, + 16_893_399_716_453_045_029, + 16_893_399_716_453_098_083, + 16_893_399_716_961_924_964, + -52981, + ), + OffsetCalcTestCase::new( + 9_487_534_663_484_046_772u64, + 16_882_120_099_581_835_046u64, + 16_882_120_099_583_884_144u64, + 9_487_534_663_651_464_597u64, + 1_721_686_086_620_926, + ), + ]; - fn t2(&self) -> u64 { - self.timestamp.1 + for t in tests { + let offset = offset_calculate( + t.t1(), + t.t2(), + t.t3(), + t.t4(), + Units::Microseconds, + ); + let expected = t.expected; + assert_eq!(offset, expected); } + } +} - fn t3(&self) -> u64 { - self.timestamp.2 - } +#[cfg(all(test, feature = "std"))] +mod sntpc_std_tests { + use crate::types::Units; - fn t4(&self) -> u64 { - self.timestamp.3 - } + #[test] + fn test_units_str_representation() { + assert_eq!(format!("{}", Units::Milliseconds), "ms"); + assert_eq!(format!("{}", Units::Microseconds), "us"); } +} + +#[cfg(all(test, feature = "std", feature = "std-socket", feature = "sync"))] +mod sntpc_sync_tests { + use crate::sync::get_time; + use crate::{Error, NtpContext, StdTimestampGen}; + use std::net::{SocketAddr, ToSocketAddrs, UdpSocket}; #[test] fn test_ntp_request_sntpv4_supported() { @@ -1225,7 +1284,9 @@ mod sntpc_tests { .set_read_timeout(Some(std::time::Duration::from_secs(2))) .expect("Unable to set up socket timeout"); - for address in pool.to_socket_addrs().unwrap() { + for address in + pool.to_socket_addrs().unwrap().filter(SocketAddr::is_ipv4) + { let result = get_time(address, &socket, context); assert!( @@ -1248,10 +1309,12 @@ mod sntpc_tests { for pool in &pools { let socket = UdpSocket::bind("0.0.0.0:0").unwrap(); socket - .set_read_timeout(Some(std::time::Duration::from_secs(2))) + .set_read_timeout(Some(std::time::Duration::from_secs(5))) .expect("Unable to set up socket timeout"); - for address in pool.to_socket_addrs().unwrap() { + for address in + pool.to_socket_addrs().unwrap().filter(SocketAddr::is_ipv4) + { let result = get_time(address, &socket, context); assert!(result.is_err(), "{pool} is ok"); assert_eq!( @@ -1267,62 +1330,77 @@ mod sntpc_tests { let pool = "asdf.asdf.asdf:123"; let socket = UdpSocket::bind("0.0.0.0:0").unwrap(); socket - .set_read_timeout(Some(std::time::Duration::from_secs(2))) + .set_read_timeout(Some(std::time::Duration::from_secs(5))) .expect("Unable to set up socket timeout"); let result = pool.to_socket_addrs(); assert!(result.is_err(), "{pool} is ok"); } +} + +#[cfg(all(test, feature = "std", feature = "std-socket"))] +mod sntpc_async_tests { + use crate::get_time; + use crate::{Error, NtpContext, StdTimestampGen}; + use miniloop::executor::Executor; + use std::net::{SocketAddr, ToSocketAddrs, UdpSocket}; #[test] - fn test_units_str_representation() { - assert_eq!(format!("{}", Units::Milliseconds), "ms"); - assert_eq!(format!("{}", Units::Microseconds), "us"); + fn test_ntp_async_request_sntpv4_supported() { + let context = NtpContext::new(StdTimestampGen::default()); + let pools = [ + "pool.ntp.org:123", + "time.google.com:123", + "time.apple.com:123", + "time.cloudflare.com:123", + "time.facebook.com:123", + ]; + + for pool in &pools { + let socket = UdpSocket::bind("0.0.0.0:0").unwrap(); + socket + .set_read_timeout(Some(std::time::Duration::from_secs(5))) + .expect("Unable to set up socket timeout"); + + for address in + pool.to_socket_addrs().unwrap().filter(SocketAddr::is_ipv4) + { + let result = Executor::new() + .block_on(get_time(address, &socket, context)); + + assert!( + result.is_ok(), + "{pool} is bad - {:?}", + result.unwrap_err() + ); + assert_ne!(result.unwrap().seconds, 0); + } + } } #[test] - fn test_offset_calculate() { - let tests = [ - OffsetCalcTestCase::new( - 16_893_142_954_672_769_962, - 16_893_142_959_053_084_959, - 16_893_142_959_053_112_968, - 16_893_142_954_793_063_406, - 1_005_870, - ), - OffsetCalcTestCase::new( - 16_893_362_966_131_575_843, - 16_893_362_966_715_800_791, - 16_893_362_966_715_869_584, - 16_893_362_967_084_349_913, - 25115, - ), - OffsetCalcTestCase::new( - 16_893_399_716_399_327_198, - 16_893_399_716_453_045_029, - 16_893_399_716_453_098_083, - 16_893_399_716_961_924_964, - -52981, - ), - OffsetCalcTestCase::new( - 9_487_534_663_484_046_772u64, - 16_882_120_099_581_835_046u64, - 16_882_120_099_583_884_144u64, - 9_487_534_663_651_464_597u64, - 1_721_686_086_620_926, - ), - ]; + fn test_ntp_async_request_sntpv3_not_supported() { + let context = NtpContext::new(StdTimestampGen::default()); - for t in tests { - let offset = offset_calculate( - t.t1(), - t.t2(), - t.t3(), - t.t4(), - Units::Microseconds, - ); - let expected = t.expected; - assert_eq!(offset, expected); + let pools = ["time.nist.gov:123", "time.windows.com:123"]; + + for pool in &pools { + let socket = UdpSocket::bind("0.0.0.0:0").unwrap(); + socket + .set_read_timeout(Some(std::time::Duration::from_secs(5))) + .expect("Unable to set up socket timeout"); + + for address in + pool.to_socket_addrs().unwrap().filter(SocketAddr::is_ipv4) + { + let result = Executor::new() + .block_on(get_time(address, &socket, context)); + assert!(result.is_err(), "{pool} is ok"); + assert_eq!( + result.unwrap_err(), + Error::IncorrectResponseVersion + ); + } } } }