use crate::cx::Cx;
use crate::types::{Budget, Time};
use std::time::Duration;
pub const TEST_BUDGET_DEADLINE_MS: u64 = 5_000;
pub const TEST_BUDGET: Budget =
Budget::new().with_deadline(Time::from_millis(TEST_BUDGET_DEADLINE_MS));
pub const TEST_TIMEOUT: Duration = Duration::from_secs(10);
pub fn test_cx() -> Cx {
Cx::for_testing_with_budget(TEST_BUDGET)
}
pub mod test_data {
pub const SMALL_DATA: &[u8] = &[0x42; 64];
pub const MEDIUM_DATA: &[u8] = &[0xAB; 4096];
pub fn pattern_data(size: usize) -> Vec<u8> {
(0..size).map(|i| (i % 256) as u8).collect()
}
pub fn deterministic_data(size: usize, seed: u64) -> Vec<u8> {
let mut data = Vec::with_capacity(size);
let mut state = seed;
for _ in 0..size {
state = state.wrapping_mul(1103515245).wrapping_add(12345);
data.push((state >> 16) as u8);
}
data
}
}
pub mod assertions {
use crate::types::Outcome;
pub fn assert_atp_ok<T, E>(outcome: Outcome<T, E>) -> T
where
E: std::fmt::Debug,
{
match outcome {
Outcome::Ok(value) => value,
Outcome::Err(err) => panic!("Expected Ok, got Err: {:?}", err),
Outcome::Cancelled(_) => panic!("Expected Ok, got Cancelled"),
Outcome::Panicked(_) => panic!("Expected Ok, got Panicked"),
}
}
pub fn assert_atp_cancelled<T, E>(outcome: Outcome<T, E>)
where
T: std::fmt::Debug,
E: std::fmt::Debug,
{
match outcome {
Outcome::Cancelled(_) => {}
other => panic!("Expected Cancelled, got: {:?}", other),
}
}
pub fn assert_atp_err<T, E>(outcome: Outcome<T, E>) -> E
where
T: std::fmt::Debug,
{
match outcome {
Outcome::Err(err) => err,
Outcome::Ok(value) => panic!("Expected Err, got Ok: {:?}", value),
Outcome::Cancelled(_) => panic!("Expected Err, got Cancelled"),
Outcome::Panicked(_) => panic!("Expected Err, got Panicked"),
}
}
}
pub mod fixtures {
use crate::net::atp::protocol::{
AtpFeature, ClientHello, PeerId, SessionContextKind, SessionId, SessionNegotiator,
SessionPolicy, SessionTraceId, TransferNonce,
};
pub fn test_peer_id(suffix: u64) -> PeerId {
PeerId::from_label(&format!("test_peer_{}", suffix))
}
pub fn test_session_id(suffix: u64) -> SessionId {
let initiator = PeerId::from_label(&format!("fixture_initiator_{suffix}"));
let responder = PeerId::from_label(&format!("fixture_responder_{suffix}"));
let nonce = TransferNonce::from_seed(&format!("fixture_nonce_{suffix}"));
let hello = ClientHello::new(
initiator,
responder,
nonce,
SessionContextKind::Direct,
SessionTraceId::new(suffix),
)
.with_features(&[AtpFeature::EncryptionPolicy]);
let mut policy = SessionPolicy::new(responder, suffix);
let mut server = SessionNegotiator::server(responder);
let (server_hello, _, _) = server
.accept_client_hello(&hello, &mut policy)
.expect("fixture ATP session negotiation should succeed");
server_hello.session_id
}
}
#[cfg(test)]
mod tests {
use super::assertions::*;
use super::test_data::*;
use super::*;
use crate::types::{CancelReason, Outcome};
#[test]
fn test_cx_creation() {
let cx = test_cx();
assert_eq!(
cx.budget().deadline.map(Time::as_millis),
Some(TEST_BUDGET_DEADLINE_MS)
);
}
#[test]
fn test_pattern_data() {
let data = pattern_data(256);
assert_eq!(data.len(), 256);
assert_eq!(data[0], 0);
assert_eq!(data[255], 255);
assert_eq!(data[128], 128);
}
#[test]
fn test_deterministic_data() {
let data1 = deterministic_data(100, 42);
let data2 = deterministic_data(100, 42);
let data3 = deterministic_data(100, 43);
assert_eq!(data1, data2, "Same seed should produce same data");
assert_ne!(data1, data3, "Different seed should produce different data");
assert_eq!(data1.len(), 100);
}
#[test]
fn test_assert_atp_ok() {
let outcome: Outcome<i32, String> = Outcome::Ok(42);
let value = assert_atp_ok(outcome);
assert_eq!(value, 42);
}
#[test]
#[should_panic(expected = "Expected Ok, got Cancelled")]
fn test_assert_atp_ok_with_cancelled() {
let outcome: Outcome<i32, String> = Outcome::cancelled(CancelReason::user("test"));
assert_atp_ok(outcome);
}
#[test]
fn test_assert_atp_cancelled() {
let outcome: Outcome<i32, String> = Outcome::cancelled(CancelReason::user("test"));
assert_atp_cancelled(outcome);
}
#[test]
fn test_assert_atp_err() {
let outcome: Outcome<i32, String> = Outcome::Err("test error".to_string());
let err = assert_atp_err(outcome);
assert_eq!(err, "test error");
}
#[test]
fn test_fixture_peer_ids() {
let peer1 = fixtures::test_peer_id(1);
let peer2 = fixtures::test_peer_id(2);
let peer1_again = fixtures::test_peer_id(1);
assert_eq!(
peer1, peer1_again,
"Same suffix should produce same peer ID"
);
assert_ne!(
peer1, peer2,
"Different suffix should produce different peer ID"
);
}
#[test]
fn test_fixture_session_ids() {
let session1 = fixtures::test_session_id(100);
let session2 = fixtures::test_session_id(200);
let session1_again = fixtures::test_session_id(100);
assert_eq!(
session1, session1_again,
"Same suffix should produce same session ID"
);
assert_ne!(
session1, session2,
"Different suffix should produce different session ID"
);
}
}