refactor(proptests): One PairSetup to rule all random interaction proptests

This commit is contained in:
Philipp Krüger
2026-04-13 17:55:40 +02:00
parent 8ff996a617
commit ca6b59acb3
2 changed files with 259 additions and 200 deletions
+254 -189
View File
@@ -12,20 +12,21 @@ use test_strategy::proptest;
use tracing::error;
use crate::{
Connection, ConnectionClose, ConnectionError, Event, PathStatus, Side, TransportConfig,
TransportErrorCode,
ClientConfig, Connection, ConnectionClose, ConnectionError, Event, PathStatus, Side,
TransportConfig, TransportErrorCode,
tests::{
Pair, RoutingTable,
Pair, RoutingTable, client_config,
random_interaction::{TestOp, run_random_interaction},
server_config, subscribe,
},
};
const MAX_PATHS: u32 = 3;
const MAX_PATHS: u32 = 12;
const MAX_QNT_ADDRS: u8 = 12;
const CLIENT_PORT: u16 = 44433;
const SERVER_PORT: u16 = 4433;
const CLIENT_ADDRS: [SocketAddr; MAX_PATHS as usize] = [
const CLIENT_ADDRS: [SocketAddr; 3] = [
SocketAddr::new(
IpAddr::V6(Ipv4Addr::new(1, 1, 1, 0).to_ipv6_mapped()),
CLIENT_PORT,
@@ -39,7 +40,7 @@ const CLIENT_ADDRS: [SocketAddr; MAX_PATHS as usize] = [
CLIENT_PORT,
),
];
const SERVER_ADDRS: [SocketAddr; MAX_PATHS as usize] = [
const SERVER_ADDRS: [SocketAddr; 3] = [
SocketAddr::new(
IpAddr::V6(Ipv4Addr::new(2, 2, 2, 0).to_ipv6_mapped()),
SERVER_PORT,
@@ -54,67 +55,104 @@ const SERVER_ADDRS: [SocketAddr; MAX_PATHS as usize] = [
),
];
fn setup_deterministic_with_multipath(
seed: [u8; 32],
routes: RoutingTable,
qlog_prefix: &'static str,
) -> Pair {
let mut pair = Pair::seeded(seed);
let mut cfg = server_config();
let transport = multipath_transport_config(qlog_prefix);
cfg.transport = Arc::new(transport);
pair.server.endpoint.set_server_config(Some(Arc::new(cfg)));
pair.client.addr = routes.client_addr(0).unwrap();
pair.server.addr = routes.server_addr(0).unwrap();
pair.routes = Some(routes);
pair
#[derive(Debug, test_strategy::Arbitrary)]
struct PairSetup {
seed: Seed,
multipath: bool,
qnt: bool,
routing_setup: RoutingSetup,
}
fn multipath_transport_config(qlog_prefix: &'static str) -> TransportConfig {
let mut cfg = TransportConfig::default();
// enable multipath
cfg.max_concurrent_multipath_paths(MAX_PATHS);
cfg.default_path_max_idle_timeout(Some(std::time::Duration::from_secs(15)));
cfg.default_path_keep_alive_interval(Some(std::time::Duration::from_secs(5)));
// cfg.mtu_discovery_config(None);
#[cfg(feature = "qlog")]
cfg.qlog_from_env(qlog_prefix);
#[cfg(not(feature = "qlog"))]
let _ = qlog_prefix;
cfg
#[derive(Debug, test_strategy::Arbitrary)]
enum RoutingSetup {
None,
SimpleSymmetric,
Complex(#[strategy(routing_table())] RoutingTable),
}
#[derive(Debug, test_strategy::Arbitrary)]
enum Seed {
Zeroes,
Generated(#[strategy(any::<[u8; 32]>().no_shrink())] [u8; 32]),
}
impl PairSetup {
fn run(self, prefix: &'static str) -> (Pair, ClientConfig) {
let mut pair = Pair::seeded(self.seed.into_slice());
// Initialize the transport config
let mut transport = TransportConfig::default();
// Set the qlog prefix, if the feature is enabled
#[cfg(feature = "qlog")]
transport.qlog_from_env(prefix);
#[cfg(not(feature = "qlog"))]
let _ = prefix;
if self.multipath {
// enable multipath
transport.max_concurrent_multipath_paths(MAX_PATHS);
transport.default_path_max_idle_timeout(Some(std::time::Duration::from_secs(15)));
transport.default_path_keep_alive_interval(Some(std::time::Duration::from_secs(5)));
}
if self.qnt {
// enable QNT:
transport.set_max_remote_nat_traversal_addresses(12);
}
// Initialize the server config
let mut server_cfg = server_config();
server_cfg.transport = Arc::new(transport.clone());
pair.server
.endpoint
.set_server_config(Some(Arc::new(server_cfg)));
// Initialize the client config
let mut client_cfg = client_config();
client_cfg.transport = Arc::new(transport);
// Add routing, if enabled
match self.routing_setup {
RoutingSetup::None => {
pair.routes = None;
}
RoutingSetup::SimpleSymmetric => {
let routes = RoutingTable::simple_symmetric(CLIENT_ADDRS, SERVER_ADDRS);
pair.client.addr = routes.client_addr(0).unwrap();
pair.server.addr = routes.server_addr(0).unwrap();
pair.routes = Some(routes);
}
RoutingSetup::Complex(routes) => {
pair.client.addr = routes.client_addr(0).unwrap();
pair.server.addr = routes.server_addr(0).unwrap();
pair.routes = Some(routes);
}
}
(pair, client_cfg)
}
}
impl Seed {
fn into_slice(&self) -> [u8; 32] {
match self {
Seed::Zeroes => [0u8; 32],
Seed::Generated(generated) => *generated,
}
}
}
#[proptest(cases = 256)]
fn random_interaction(
#[strategy(any::<[u8; 32]>().no_shrink())] seed: [u8; 32],
setup: PairSetup,
#[strategy(vec(any::<TestOp>(), 0..100))] interactions: Vec<TestOp>,
) {
let prefix = "random_interaction";
let mut pair = Pair::seeded(seed);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
prop_assert!(!pair.drive_bounded(1000), "connection never became idle");
prop_assert!(allowed_error(poll_to_close(
pair.client_conn_mut(client_ch)
)));
prop_assert!(allowed_error(poll_to_close(
pair.server_conn_mut(server_ch)
)));
}
#[proptest(cases = 256)]
fn random_interaction_with_multipath_simple_routing(
#[strategy(any::<[u8; 32]>().no_shrink())] seed: [u8; 32],
#[strategy(vec(any::<TestOp>(), 0..100))] interactions: Vec<TestOp>,
) {
let prefix = "random_interaction_with_multipath_simple_routing";
let routes = RoutingTable::simple_symmetric(CLIENT_ADDRS, SERVER_ADDRS);
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run("random_interaction");
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
prop_assert!(!pair.drive_bounded(1000), "connection never became idle");
prop_assert!(allowed_error(poll_to_close(
@@ -158,26 +196,6 @@ fn routing_table() -> impl Strategy<Value = RoutingTable> {
})
}
#[proptest(cases = 256)]
fn random_interaction_with_multipath_complex_routing(
#[strategy(any::<[u8; 32]>().no_shrink())] seed: [u8; 32],
#[strategy(vec(any::<TestOp>(), 0..100))] interactions: Vec<TestOp>,
#[strategy(routing_table())] routes: RoutingTable,
) {
let prefix = "random_interaction_with_multipath_complex_routing";
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
prop_assert!(!pair.drive_bounded(1000), "connection never became idle");
prop_assert!(allowed_error(poll_to_close(
pair.client_conn_mut(client_ch)
)));
prop_assert!(allowed_error(poll_to_close(
pair.server_conn_mut(server_ch)
)));
}
/// All outgoing links go to first destination interface.
///
/// Client and server have multiple interfaces, but all outgoing links go to the first
@@ -231,10 +249,15 @@ fn poll_to_close(conn: &mut Connection) -> Option<ConnectionError> {
#[test]
fn regression_unset_packet_acked() {
let prefix = "regression_unset_packet_acked";
let seed: [u8; 32] = [
60, 116, 60, 165, 136, 238, 239, 131, 14, 159, 221, 16, 80, 60, 30, 15, 15, 69, 133, 33,
89, 203, 28, 107, 123, 117, 6, 54, 215, 244, 47, 1,
];
let setup = PairSetup {
seed: Seed::Generated([
60, 116, 60, 165, 136, 238, 239, 131, 14, 159, 221, 16, 80, 60, 30, 15, 15, 69, 133,
33, 89, 203, 28, 107, 123, 117, 6, 54, 215, 244, 47, 1,
]),
multipath: true,
qnt: false,
routing_setup: RoutingSetup::Complex(old_routing_table()),
};
let interactions = vec![
TestOp::OpenPath {
side: Side::Client,
@@ -253,13 +276,8 @@ fn regression_unset_packet_acked() {
];
let _guard = subscribe();
let routes = old_routing_table();
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
#[allow(unused_mut)]
let mut cfg = TransportConfig::default();
#[cfg(feature = "qlog")]
cfg.qlog_from_env(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, cfg);
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
assert!(!pair.drive_bounded(1000), "connection never became idle");
assert!(allowed_error(poll_to_close(
@@ -273,10 +291,15 @@ fn regression_unset_packet_acked() {
#[test]
fn regression_invalid_key() {
let prefix = "regression_invalid_key";
let seed = [
41, 24, 232, 72, 136, 73, 31, 115, 14, 101, 61, 219, 30, 168, 130, 122, 120, 238, 6, 130,
117, 84, 250, 190, 50, 237, 14, 167, 60, 5, 140, 149,
];
let setup = PairSetup {
seed: Seed::Generated([
41, 24, 232, 72, 136, 73, 31, 115, 14, 101, 61, 219, 30, 168, 130, 122, 120, 238, 6,
130, 117, 84, 250, 190, 50, 237, 14, 167, 60, 5, 140, 149,
]),
multipath: true,
qnt: false,
routing_setup: RoutingSetup::Complex(old_routing_table()),
};
let interactions = vec![
TestOp::OpenPath {
side: Side::Client,
@@ -293,10 +316,8 @@ fn regression_invalid_key() {
];
let _guard = subscribe();
let routes = old_routing_table();
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
assert!(!pair.drive_bounded(1000), "connection never became idle");
assert!(allowed_error(poll_to_close(
@@ -321,7 +342,12 @@ fn regression_invalid_key() {
#[test]
fn regression_invalid_key2() {
let prefix = "regression_invalid_key2";
let seed = [0u8; 32];
let setup = PairSetup {
seed: Seed::Zeroes,
multipath: true,
qnt: false,
routing_setup: RoutingSetup::SimpleSymmetric,
};
let interactions = vec![
TestOp::CloseConn {
side: Side::Client,
@@ -342,10 +368,8 @@ fn regression_invalid_key2() {
];
let _guard = subscribe();
let routes = RoutingTable::simple_symmetric(CLIENT_ADDRS, SERVER_ADDRS);
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
assert!(!pair.drive_bounded(1000), "connection never became idle");
assert!(allowed_error(poll_to_close(
@@ -359,10 +383,15 @@ fn regression_invalid_key2() {
#[test]
fn regression_key_update_error() {
let prefix = "regression_key_update_error";
let seed: [u8; 32] = [
68, 93, 15, 237, 88, 31, 93, 255, 246, 51, 203, 224, 20, 124, 107, 163, 143, 43, 193, 187,
208, 54, 158, 239, 190, 82, 198, 62, 91, 51, 53, 226,
];
let setup = PairSetup {
seed: Seed::Generated([
68, 93, 15, 237, 88, 31, 93, 255, 246, 51, 203, 224, 20, 124, 107, 163, 143, 43, 193,
187, 208, 54, 158, 239, 190, 82, 198, 62, 91, 51, 53, 226,
]),
multipath: true,
qnt: false,
routing_setup: RoutingSetup::Complex(old_routing_table()),
};
let interactions = vec![
TestOp::OpenPath {
side: Side::Client,
@@ -374,10 +403,8 @@ fn regression_key_update_error() {
];
let _guard = subscribe();
let routes = old_routing_table();
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
assert!(!pair.drive_bounded(1000), "connection never became idle");
assert!(allowed_error(poll_to_close(
@@ -391,7 +418,12 @@ fn regression_key_update_error() {
#[test]
fn regression_never_idle() {
let prefix = "regression_never_idle";
let seed = [0u8; 32];
let setup = PairSetup {
seed: Seed::Zeroes,
multipath: true,
qnt: false,
routing_setup: RoutingSetup::Complex(old_routing_table()),
};
let interactions = vec![
TestOp::OpenPath {
side: Side::Client,
@@ -411,10 +443,8 @@ fn regression_never_idle() {
];
let _guard = subscribe();
let routes = old_routing_table();
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
assert!(!pair.drive_bounded(1000), "connection never became idle");
assert!(allowed_error(poll_to_close(
@@ -428,7 +458,12 @@ fn regression_never_idle() {
#[test]
fn regression_never_idle2() {
let prefix = "regression_never_idle2";
let seed = [0u8; 32];
let setup = PairSetup {
seed: Seed::Zeroes,
multipath: true,
qnt: false,
routing_setup: RoutingSetup::Complex(old_routing_table()),
};
let interactions = vec![
TestOp::OpenPath {
side: Side::Client,
@@ -450,10 +485,8 @@ fn regression_never_idle2() {
];
let _guard = subscribe();
let routes = old_routing_table();
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
// We needed to increase the bounds. It eventually times out.
assert!(!pair.drive_bounded(1000), "connection never became idle");
@@ -468,7 +501,12 @@ fn regression_never_idle2() {
#[test]
fn regression_packet_number_space_missing() {
let prefix = "regression_packet_number_space_missing";
let seed = [0u8; 32];
let setup = PairSetup {
seed: Seed::Zeroes,
multipath: true,
qnt: false,
routing_setup: RoutingSetup::SimpleSymmetric,
};
let interactions = vec![
TestOp::OpenPath {
side: Side::Client,
@@ -490,10 +528,8 @@ fn regression_packet_number_space_missing() {
];
let _guard = subscribe();
let routes = RoutingTable::simple_symmetric([CLIENT_ADDRS[0]], [SERVER_ADDRS[0]]);
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
assert!(!pair.drive_bounded(1000), "connection never became idle");
assert!(allowed_error(poll_to_close(
@@ -507,7 +543,12 @@ fn regression_packet_number_space_missing() {
#[test]
fn regression_peer_failed_to_respond_with_path_abandon() {
let prefix = "regression_peer_failed_to_respond_with_path_abandon";
let seed = [0u8; 32];
let setup = PairSetup {
seed: Seed::Zeroes,
multipath: true,
qnt: false,
routing_setup: RoutingSetup::Complex(old_routing_table()),
};
let interactions = vec![
TestOp::OpenPath {
side: Side::Client,
@@ -522,10 +563,8 @@ fn regression_peer_failed_to_respond_with_path_abandon() {
];
let _guard = subscribe();
let routes = old_routing_table();
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
assert!(!pair.drive_bounded(1000), "connection never became idle");
assert!(allowed_error(poll_to_close(
@@ -539,7 +578,12 @@ fn regression_peer_failed_to_respond_with_path_abandon() {
#[test]
fn regression_peer_failed_to_respond_with_path_abandon2() {
let prefix = "regression_peer_failed_to_respond_with_path_abandon2";
let seed = [0u8; 32];
let setup = PairSetup {
seed: Seed::Zeroes,
multipath: true,
qnt: false,
routing_setup: RoutingSetup::SimpleSymmetric,
};
let interactions = vec![
TestOp::OpenPath {
side: Side::Client,
@@ -564,10 +608,8 @@ fn regression_peer_failed_to_respond_with_path_abandon2() {
];
let _guard = subscribe();
let routes = RoutingTable::simple_symmetric(CLIENT_ADDRS, SERVER_ADDRS);
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
assert!(!pair.drive_bounded(1000), "connection never became idle");
assert!(allowed_error(poll_to_close(
@@ -612,7 +654,18 @@ fn regression_peer_failed_to_respond_with_path_abandon2() {
#[test]
fn regression_path_validation() {
let prefix = "regression_path_validation";
let seed = [0u8; 32];
let setup = PairSetup {
seed: Seed::Zeroes,
multipath: true,
qnt: false,
routing_setup: RoutingSetup::Complex(RoutingTable::from_routes(
vec![("[::ffff:1.1.1.0]:44433".parse().unwrap(), 0)],
vec![
("[::ffff:2.2.2.0]:4433".parse().unwrap(), 0),
("[::ffff:2.2.2.1]:4433".parse().unwrap(), 0),
],
)),
};
let interactions = vec![
TestOp::OpenPath {
side: Side::Client,
@@ -633,18 +686,10 @@ fn regression_path_validation() {
error_code: 0,
},
];
let routes = RoutingTable::from_routes(
vec![("[::ffff:1.1.1.0]:44433".parse().unwrap(), 0)],
vec![
("[::ffff:2.2.2.0]:4433".parse().unwrap(), 0),
("[::ffff:2.2.2.1]:4433".parse().unwrap(), 0),
],
);
let _guard = subscribe();
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
assert!(!pair.drive_bounded(1000), "connection never became idle");
assert!(allowed_error(poll_to_close(
@@ -674,7 +719,12 @@ fn regression_path_validation() {
#[test]
fn regression_never_idle3() {
let prefix = "regression_never_idle3";
let seed = [0u8; 32];
let setup = PairSetup {
seed: Seed::Zeroes,
multipath: true,
qnt: false,
routing_setup: RoutingSetup::SimpleSymmetric,
};
let interactions = vec![
TestOp::CloseConn {
side: Side::Server,
@@ -696,10 +746,8 @@ fn regression_never_idle3() {
];
let _guard = subscribe();
let routes = RoutingTable::simple_symmetric([CLIENT_ADDRS[0]], [SERVER_ADDRS[0]]);
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
assert!(!pair.drive_bounded(1000), "connection never became idle");
assert!(allowed_error(poll_to_close(
@@ -713,7 +761,12 @@ fn regression_never_idle3() {
#[test]
fn regression_frame_encoding_error() {
let prefix = "regression_frame_encoding_error";
let seed = [0u8; 32];
let setup = PairSetup {
seed: Seed::Zeroes,
multipath: true,
qnt: false,
routing_setup: RoutingSetup::SimpleSymmetric,
};
let interactions = vec![
TestOp::OpenPath {
side: Side::Client,
@@ -733,10 +786,8 @@ fn regression_frame_encoding_error() {
];
let _guard = subscribe();
let routes = RoutingTable::simple_symmetric(CLIENT_ADDRS, SERVER_ADDRS);
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
assert!(!pair.drive_bounded(1000), "connection never became idle");
assert!(allowed_error(poll_to_close(
@@ -750,7 +801,12 @@ fn regression_frame_encoding_error() {
#[test]
fn regression_there_should_be_at_least_one_path() {
let prefix = "regression_there_should_be_at_least_one_path";
let seed = [0u8; 32];
let setup = PairSetup {
seed: Seed::Zeroes,
multipath: true,
qnt: false,
routing_setup: RoutingSetup::SimpleSymmetric,
};
let interactions = vec![
TestOp::PassiveMigration {
side: Side::Client,
@@ -763,10 +819,8 @@ fn regression_there_should_be_at_least_one_path() {
];
let _guard = subscribe();
let routes = RoutingTable::simple_symmetric([CLIENT_ADDRS[0]], [SERVER_ADDRS[0]]);
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
assert!(!pair.drive_bounded(1000), "connection never became idle");
assert!(allowed_error(poll_to_close(
@@ -799,7 +853,12 @@ fn regression_there_should_be_at_least_one_path() {
#[test]
fn regression_conn_never_idle5() {
let prefix = "regression_conn_never_idle5";
let seed = [0u8; 32];
let setup = PairSetup {
seed: Seed::Zeroes,
multipath: true,
qnt: false,
routing_setup: RoutingSetup::SimpleSymmetric,
};
let interactions = vec![
TestOp::PassiveMigration {
side: Side::Server,
@@ -813,10 +872,8 @@ fn regression_conn_never_idle5() {
];
let _guard = subscribe();
let routes = RoutingTable::simple_symmetric([CLIENT_ADDRS[0]], [SERVER_ADDRS[0]]);
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
assert!(!pair.drive_bounded(1000), "connection never became idle");
assert!(allowed_error(poll_to_close(
@@ -852,8 +909,12 @@ fn regression_conn_never_idle5() {
#[test]
fn regression_peer_ignored_path_abandon() {
let prefix = "regression_peer_ignored_path_abandon";
let seed = [0u8; 32];
let setup = PairSetup {
seed: Seed::Zeroes,
multipath: true,
qnt: false,
routing_setup: RoutingSetup::SimpleSymmetric,
};
let interactions = vec![
TestOp::OpenPath {
side: Side::Client,
@@ -880,10 +941,8 @@ fn regression_peer_ignored_path_abandon() {
];
let _guard = subscribe();
let routes = RoutingTable::simple_symmetric(CLIENT_ADDRS, SERVER_ADDRS);
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
assert!(!pair.drive_bounded(1000), "connection never became idle");
assert!(allowed_error(poll_to_close(
@@ -920,7 +979,18 @@ fn regression_peer_ignored_path_abandon() {
#[test]
fn regression_never_idle4() {
let prefix = "regression_never_idle4";
let seed = [0u8; 32];
let setup = PairSetup {
seed: Seed::Zeroes,
multipath: true,
qnt: false,
routing_setup: RoutingSetup::Complex(RoutingTable::from_routes(
vec![
("[::ffff:1.1.1.0]:44433".parse().unwrap(), 0),
("[::ffff:1.1.1.1]:44433".parse().unwrap(), 0),
],
vec![("[::ffff:2.2.2.0]:4433".parse().unwrap(), 0)],
)),
};
let interactions = vec![
// Open path 1 with the same remote address as path 0
TestOp::OpenPath {
@@ -959,18 +1029,10 @@ fn regression_never_idle4() {
addr_idx: 0,
},
];
let routes = RoutingTable::from_routes(
vec![
("[::ffff:1.1.1.0]:44433".parse().unwrap(), 0),
("[::ffff:1.1.1.1]:44433".parse().unwrap(), 0),
],
vec![("[::ffff:2.2.2.0]:4433".parse().unwrap(), 0)],
);
let _guard = subscribe();
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
assert!(!pair.drive_bounded(1000), "connection never became idle");
assert!(allowed_error(poll_to_close(
@@ -1008,7 +1070,12 @@ fn regression_never_idle4() {
#[test]
fn regression_infinite_loop() {
let prefix = "regression_infinite_loop";
let seed = [0u8; 32];
let setup = PairSetup {
seed: Seed::Zeroes,
multipath: true,
qnt: false,
routing_setup: RoutingSetup::SimpleSymmetric,
};
let interactions = vec![
TestOp::OpenPath {
side: Side::Client,
@@ -1027,10 +1094,8 @@ fn regression_infinite_loop() {
];
let _guard = subscribe();
let routes = RoutingTable::simple_symmetric(CLIENT_ADDRS, SERVER_ADDRS);
let mut pair = setup_deterministic_with_multipath(seed, routes, prefix);
let (client_ch, server_ch) =
run_random_interaction(&mut pair, interactions, multipath_transport_config(prefix));
let (mut pair, client_config) = setup.run(prefix);
let (client_ch, server_ch) = run_random_interaction(&mut pair, interactions, client_config);
// This bug originally occurred at exactly 4540 iterations.
// At 4539 it still finishes (but fails the assertion).
+5 -11
View File
@@ -1,16 +1,12 @@
use std::{
net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4},
sync::Arc,
};
use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4};
use bytes::Bytes;
use test_strategy::Arbitrary;
use tracing::{debug, error, info, trace};
use crate::{
Connection, ConnectionHandle, Dir, FourTuple, PathId, PathStatus, Side, StreamId,
TransportConfig,
tests::{Pair, TestEndpoint, client_config},
ClientConfig, Connection, ConnectionHandle, Dir, FourTuple, PathId, PathStatus, Side, StreamId,
tests::{Pair, TestEndpoint},
};
#[derive(Debug, Clone, Copy, Arbitrary)]
@@ -335,11 +331,9 @@ fn inc_last_addr_octet(addr: SocketAddr) -> SocketAddr {
pub(super) fn run_random_interaction(
pair: &mut Pair,
interactions: Vec<TestOp>,
transport_config: TransportConfig,
client_config: ClientConfig,
) -> (ConnectionHandle, ConnectionHandle) {
let mut client_cfg = client_config();
client_cfg.transport = Arc::new(transport_config);
let (client_ch, server_ch) = pair.connect_with(client_cfg);
let (client_ch, server_ch) = pair.connect_with(client_config);
pair.drive(); // finish establishing the connection;
info!("INTERACTION SETUP FINISHED");
let mut client = State::new(Side::Client, client_ch);