Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,13 @@ jobs:
- name: Install p4p
run: pip install p4p

- name: Run p4p interop tests
- name: Build workspace binaries
run: cargo build --all

- name: Run p4p provider matrix
env:
PVA_TEST_P4P: "1"
P4P_PROVIDER_CMD: "python3 ${{ github.workspace }}/spvirit-tools/tests/interop/p4p_server.py"
P4P_PROVIDER_READY_MS: "5000"
run: cargo test --all
P4P_TEST_SERVER: "127.0.0.1:5075"
run: cargo test --package spvirit-tools --test interop_tool_matrix -- p4p_provider_matrix
74 changes: 18 additions & 56 deletions spvirit-client/src/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -373,35 +373,16 @@ pub async fn search_pv(
let mut socket_info: Vec<(Arc<UdpSocket>, Vec<u8>, Vec<SocketAddr>)> = Vec::new();

for (bind_ip, group_targets) in &bind_groups {
let bind_addr = SocketAddr::new(*bind_ip, udp_port);
// Always use an ephemeral port for the search client socket.
// We only receive unicast replies, so sharing the server's search
// port is unnecessary — and on Linux with SO_REUSEPORT the kernel
// would route our own outbound packet back to us instead of the
// server.
let bind_addr = SocketAddr::new(*bind_ip, 0);
let (std_sock, actual_bind_addr) = match bind_udp_reuse(bind_addr) {
Ok(sock) => (sock, bind_addr),
Err(err) if err.kind() == std::io::ErrorKind::AddrInUse => {
let fallback = SocketAddr::new(*bind_ip, 0);
match bind_udp_reuse(fallback) {
Ok(sock) => {
let actual = sock.local_addr().unwrap_or(fallback);
if debug_enabled {
debug!(
"pva search bind={} failed (in use), fallback bind={}",
bind_addr, actual
);
}
(sock, actual)
}
Err(fallback_err) => {
if debug_enabled {
debug!(
"pva search skipping bind={} step=bind-fallback kind={:?} err={}",
bind_addr,
fallback_err.kind(),
fallback_err
);
}
last_io_error = Some(fallback_err);
continue;
}
}
Ok(sock) => {
let actual = sock.local_addr().unwrap_or(bind_addr);
(sock, actual)
}
Err(err) => {
if debug_enabled {
Expand Down Expand Up @@ -870,35 +851,16 @@ pub async fn discover_servers(
let mut socket_info: Vec<(Arc<UdpSocket>, Vec<u8>, Vec<SocketAddr>)> = Vec::new();

for (bind_ip, group_targets) in &bind_groups {
let bind_addr = SocketAddr::new(*bind_ip, udp_port);
// Always use an ephemeral port for the discovery client socket.
// We only receive unicast replies, so sharing the server's search
// port is unnecessary — and on Linux with SO_REUSEPORT the kernel
// would route our own outbound packet back to us instead of the
// server.
let bind_addr = SocketAddr::new(*bind_ip, 0);
let (std_sock, actual_bind_addr) = match bind_udp_reuse(bind_addr) {
Ok(sock) => (sock, bind_addr),
Err(err) if err.kind() == std::io::ErrorKind::AddrInUse => {
let fallback = SocketAddr::new(*bind_ip, 0);
match bind_udp_reuse(fallback) {
Ok(sock) => {
let actual = sock.local_addr().unwrap_or(fallback);
if debug_enabled {
debug!(
"pva discover bind={} failed (in use), fallback bind={}",
bind_addr, actual
);
}
(sock, actual)
}
Err(fallback_err) => {
if debug_enabled {
debug!(
"pva discover skipping bind={} step=bind-fallback kind={:?} err={}",
bind_addr,
fallback_err.kind(),
fallback_err
);
}
last_io_error = Some(fallback_err);
continue;
}
}
Ok(sock) => {
let actual = sock.local_addr().unwrap_or(bind_addr);
(sock, actual)
}
Err(err) => {
if debug_enabled {
Expand Down
4 changes: 2 additions & 2 deletions spvirit-tools/tests/interop/p4p_client_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
Expects the server to already be running with the test DB (SIM:* PVs).

Environment variables:
SPVIRIT_TEST_TCP_PORT TCP port of the spvirit server (required)
SPVIRIT_TEST_UDP_PORT UDP port of the spvirit server (required)
SPVIRIT_TEST_TCP_PORT - TCP port of the spvirit server (required)
SPVIRIT_TEST_UDP_PORT - UDP port of the spvirit server (required)

Exit code 0 on success, 1 on any failure.
"""
Expand Down
Loading