Skip to content

Commit

Permalink
Merge pull request #41 from vpetrigo/feature/issue-39-async-tests
Browse files Browse the repository at this point in the history
sntpc: Add async API unit tests
  • Loading branch information
vpetrigo authored Dec 26, 2024
2 parents a35f653 + a265d79 commit d95f1fc
Show file tree
Hide file tree
Showing 2 changed files with 160 additions and 82 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
240 changes: 159 additions & 81 deletions sntpc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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() {
Expand All @@ -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!(
Expand All @@ -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!(
Expand All @@ -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
);
}
}
}
}

0 comments on commit d95f1fc

Please sign in to comment.