Files
fips/testing/node-test-groups/flagged-test-in-mod-rs.case
Johnathan Corgan 1ce3f578e4 Check the nextest node test groups against the source
The node-synthetic group is an allow-list of test modules, and an
allow-list goes stale the day the next socket test lands: the new module
runs beside the others and the first sign is a dropped handshake on a
loaded runner, far from the cause.

testing/check-node-test-groups.py recomputes the membership. It flags
every function under src/node/tests/ (and in src/testutil.rs) that uses a
socket primitive or calls a flagged function, to a fixpoint, so modules
that reach a socket only through a helper are caught. Module names come
from mod.rs's declarations. It then evaluates both profiles' overrides in
order, as nextest does, and fails when a test in a flagged module is not
in node-synthetic or a lock_large_network_test() holder is not in
node-large. It also checks the nextest pin in the workflows matches the
config.

It exits 2 rather than pass when it finds no test modules, no flagged
module, no lock holder, or a filter it cannot evaluate, so a moved
directory or a reformatted filter cannot pass vacuously. Uses that open no
socket are exempted one function and primitive at a time, each with its
reason, in testing/node-test-groups/exemptions.toml.

The fixtures beside it cover each way a test reaches a socket and each
check the guard makes; every case names the output it expects, so a case
that fails for the wrong reason fails the runner. Both run from local CI's
guards and from the ci-parity job.
2026-10-21 16:58:16 +00:00

48 lines
1.6 KiB
Plaintext

# A socket test in mod.rs itself, which no module filter can place.
expect exit 1
expect node::tests::a_root_socket_test is a flagged test in mod.rs itself
=== src/node/tests/mod.rs
// Fixture tree for testing/check-node-test-groups.py. It is never compiled;
// the check reads it as text.
use super::*;
mod big;
mod helpers;
mod never_started;
#[path = "renamed_file.rs"]
mod pathed;
mod quiet;
mod rx_shutdown;
#[cfg(target_os = "linux")]
mod sock_direct;
mod vec_drain;
#[cfg(any(target_os = "linux", target_os = "macos"))]
mod via_connected;
mod via_helper;
mod via_testutil;
mod via_two_hops;
/// A root helper with no socket; every module reaches it through `use super::*`.
pub(super) fn make_node() -> Node {
Node::new(Config::new()).unwrap()
}
/// A root helper that installs a real connect()-ed UDP socket on a peer, as
/// the dataplane does; a module that calls it holds a socket.
#[cfg(any(target_os = "linux", target_os = "macos"))]
pub(super) fn install_connected_udp(node: &mut Node, addr: &NodeAddr, transport_id: TransportId) {
let local: std::net::SocketAddr = "0.0.0.0:0".parse().unwrap();
let peer_sa: std::net::SocketAddr = "127.0.0.1:9".parse().unwrap();
let owned = crate::transport::udp::open_connected_fd(local, peer_sa, 65_536, 65_536)
.expect("open a connected UDP socket");
let socket = std::sync::Arc::new(crate::transport::udp::ConnectedPeerSocket::from_fd(
owned, peer_sa, local,
));
node.get_peer_mut(addr).unwrap().set_connected_udp(socket, transport_id);
}
#[tokio::test]
async fn a_root_socket_test() {
let _ = tokio::net::UdpSocket::bind("127.0.0.1:0").await;
}