diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index cf382297..0bd560e0 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -22,6 +22,7 @@ function(add_test_instance file mode lib option) add_dependencies(tests_${mode} ${target}) add_dependencies(${target} ${lib}) target_link_libraries(${target} PUBLIC ${lib}) + target_include_directories(${target} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) set_property(TARGET ${target} PROPERTY LANGUAGE CXX) set_property(TARGET ${target} PROPERTY CXX_STANDARD 17) if (option STREQUAL "Router") diff --git a/tests/run_with_router.sh b/tests/run_with_router.sh index e7b951ad..f7b460a7 100644 --- a/tests/run_with_router.sh +++ b/tests/run_with_router.sh @@ -17,103 +17,7 @@ TESTBIN="$1" TESTDIR=$(dirname "$0") ZENOH_BRANCH="$2" -resolve_interface_ip() { - case "${RUNNER_OS:-$(uname -s)}" in - Linux) - ip route get 1.1.1.1 | - awk '{ for (i = 1; i <= NF; i++) if ($i == "src") { print $(i + 1); exit } }' | - select_private_ipv4 - ;; - macOS|Darwin) - INTERFACE=$(route -n get default | awk '/interface:/{print $2; exit}') - ipconfig getifaddr "$INTERFACE" | select_private_ipv4 - ;; - Windows|MINGW*|MSYS*) - powershell.exe -NoProfile -Command ' - $ErrorActionPreference = "Stop" - try { - $route = Get-NetRoute ` - -AddressFamily IPv4 ` - -DestinationPrefix "0.0.0.0/0" ` - -PolicyStore ActiveStore | - Sort-Object @{Expression = { $_.RouteMetric + $_.InterfaceMetric }} | - Select-Object -First 1 - - if ($null -eq $route) { exit 1 } - - $ip = Get-NetIPAddress ` - -AddressFamily IPv4 ` - -InterfaceIndex $route.InterfaceIndex ` - -AddressState Preferred | - Where-Object { - $_.IPAddress -match "^(10\.|192\.168\.|172\.(1[6-9]|2[0-9]|3[0-1])\.)" - } | - Select-Object -First 1 -ExpandProperty IPAddress - - if ($ip) { - $ip - exit 0 - } - - exit 1 - } catch { - exit 1 - } - ' | - tr -d '\015' - ;; - *) - return 1 - ;; - esac -} - -select_private_ipv4() { - while IFS= read -r candidate; do - if is_private_ipv4 "$candidate"; then - printf '%s\n' "$candidate" - return 0 - fi - done - return 1 -} - -is_valid_ipv4() { - printf '%s\n' "$1" | awk -F. ' - NF != 4 { exit 1 } - { - for (i = 1; i <= 4; i++) { - if ($i !~ /^[0-9]+$/ || $i < 0 || $i > 255) exit 1 - } - } - ' -} - -is_private_ipv4() { - is_valid_ipv4 "$1" || return 1 - - case "$1" in - 10.*|192.168.*|172.16.*|172.17.*|172.18.*|172.19.*|172.2[0-9].*|172.3[0-1].*) - return 0 - ;; - *) - return 1 - ;; - esac -} - -if [ -z "${ZENOH_TEST_ROUTER_LISTENER:-}" ]; then - INTERFACE_IP=$(resolve_interface_ip) - if ! is_private_ipv4 "$INTERFACE_IP"; then - echo "ERROR: could not resolve a private IPv4 address for the test interface." >&2 - echo "Resolved address: ${INTERFACE_IP:-}" >&2 - echo "Set ZENOH_TEST_ROUTER_LISTENER to a concrete interface address before running ctest, or connect this machine to a private network." >&2 - echo "Refusing to fall back to tcp/0.0.0.0:7447: that would expose the unauthenticated test router on every network interface." >&2 - exit 1 - fi - ZENOH_TEST_ROUTER_LISTENER="tcp/$INTERFACE_IP:7447" - export ZENOH_TEST_ROUTER_LISTENER -fi +LOCATOR="tcp/127.0.0.1:7447" # get vinary name without extension TEST_NAME_WE=$(basename -- "$TESTBIN") @@ -164,33 +68,34 @@ fi chmod +x zenohd -LOCATORS="$ZENOH_TEST_ROUTER_LISTENER" -for LOCATOR in $(echo "$LOCATORS" | xargs); do - sleep 1 +sleep 1 - echo "> Running zenohd ... $LOCATOR" - RUST_LOG=debug ./zenohd --plugin-search-dir "$TESTDIR/zenoh-git/target/debug" -l "$LOCATOR" > zenohd."$TEST_NAME_WE".log 2>&1 & - ZPID=$! +echo "> Running zenohd ... $LOCATOR" +RUST_LOG=debug ./zenohd --plugin-search-dir "$TESTDIR/zenoh-git/target/debug" -l "$LOCATOR" > zenohd."$TEST_NAME_WE".log 2>&1 & +ZPID=$! - sleep 5 +sleep 5 - echo "> Running $TESTBIN ..." - "$TESTBIN" "$LOCATOR" > client."$TEST_NAME_WE".log 2>&1 - RETCODE=$? +echo "> Running $TESTBIN ..." +if command -v stdbuf >/dev/null 2>&1; then + stdbuf -oL -eL "$TESTBIN" > client."$TEST_NAME_WE".log 2>&1 +else + "$TESTBIN" > client."$TEST_NAME_WE".log 2>&1 +fi +RETCODE=$? - echo "> Logs of $TESTBIN ..." - cat client."$TEST_NAME_WE".log +echo "> Logs of $TESTBIN ..." +cat client."$TEST_NAME_WE".log - echo "> Stopping zenohd ..." - stop_router +echo "> Stopping zenohd ..." +stop_router - sleep 1 +sleep 1 - echo "> Logs of zenohd ..." - cat zenohd."$TEST_NAME_WE".log +echo "> Logs of zenohd ..." +cat zenohd."$TEST_NAME_WE".log - [ "$RETCODE" -lt 0 ] && exit "$RETCODE" -done +[ "$RETCODE" -lt 0 ] && exit "$RETCODE" echo "> Done ($RETCODE)." exit "$RETCODE" diff --git a/tests/test_config.hxx b/tests/test_config.hxx new file mode 100644 index 00000000..09a08281 --- /dev/null +++ b/tests/test_config.hxx @@ -0,0 +1,26 @@ +// +// Copyright (c) 2026 ZettaScale Technology +// +// This program and the accompanying materials are made available under the +// terms of the Eclipse Public License 2.0 which is available at +// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 +// which is available at https://www.apache.org/licenses/LICENSE-2.0. +// +// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 +// + +#pragma once + +#include "zenoh.hxx" + +inline zenoh::Config test_config() { + auto config = zenoh::Config::create_default(); + +#ifdef ZENOHCXX_ZENOHPICO + // Pico's multicast scouting cannot discover the loopback-only test router, so connect directly instead. + config.insert(Z_CONFIG_CONNECT_KEY, "tcp/127.0.0.1:7447"); + config.insert(Z_CONFIG_MULTICAST_SCOUTING_KEY, "false"); +#endif + + return config; +} diff --git a/tests/universal/network/advanced_pub_sub.cxx b/tests/universal/network/advanced_pub_sub.cxx index 36cdc648..04502972 100644 --- a/tests/universal/network/advanced_pub_sub.cxx +++ b/tests/universal/network/advanced_pub_sub.cxx @@ -19,6 +19,7 @@ #include #include +#include "test_config.hxx" #include "zenoh.hxx" using namespace zenoh; @@ -32,13 +33,13 @@ std::array VALUES_TO_PUBLISH = {"test_value_1", "test_value_2", void test_pub_sub() { KeyExpr ke("zenoh/advanced_pub_sub_test"); - auto config1 = Config::create_default(); + auto config1 = test_config(); #if defined(ZENOHCXX_ZENOHC) config1.insert_json5(Z_CONFIG_ADD_TIMESTAMP_KEY, "true"); #endif auto session1 = Session::open(std::move(config1)); - auto session2 = Session::open(Config::create_default()); + auto session2 = Session::open(test_config()); ext::SessionExt::AdvancedPublisherOptions opts; opts.cache.emplace().max_samples = VALUES_TO_PUBLISH.size(); @@ -83,13 +84,13 @@ void test_pub_sub() { void test_pub_sub_channels() { KeyExpr ke("zenoh/advanced_pub_sub_chennels_test"); - auto config1 = Config::create_default(); + auto config1 = test_config(); #if defined(ZENOHCXX_ZENOHC) config1.insert_json5(Z_CONFIG_ADD_TIMESTAMP_KEY, "true"); #endif auto session1 = Session::open(std::move(config1)); - auto session2 = Session::open(Config::create_default()); + auto session2 = Session::open(test_config()); ext::SessionExt::AdvancedPublisherOptions opts; opts.cache.emplace().max_samples = VALUES_TO_PUBLISH.size(); diff --git a/tests/universal/network/cancellation.cxx b/tests/universal/network/cancellation.cxx index 049ce4fb..7f3af732 100644 --- a/tests/universal/network/cancellation.cxx +++ b/tests/universal/network/cancellation.cxx @@ -15,6 +15,7 @@ #include #include +#include "test_config.hxx" #include "zenoh.hxx" using namespace zenoh; @@ -26,8 +27,8 @@ using namespace std::chrono_literals; void test_get() { std::cout << "test_get\n"; - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); KeyExpr ke("zenoh-cpp/query/cancellation/test"); auto queryable = session1.declare_queryable(ke, channels::FifoChannel(3)); std::this_thread::sleep_for(1s); @@ -100,8 +101,8 @@ void test_get() { void test_querier_get() { std::cout << "test_querier_get\n"; - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); KeyExpr ke("zenoh-cpp/querier/cancellation/test"); auto queryable = session1.declare_queryable(ke, channels::FifoChannel(3)); auto querier = session2.declare_querier(ke); @@ -175,8 +176,8 @@ void test_querier_get() { void test_liveliness_get() { std::cout << "test_liveliness_get\n"; - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); KeyExpr ke("zenoh-cpp/liveliness/cancellation/test"); auto liveliness_token = session1.liveliness_declare_token(ke); std::this_thread::sleep_for(1s); diff --git a/tests/universal/network/keyexpr.cxx b/tests/universal/network/keyexpr.cxx index 6eea781e..78b4809e 100644 --- a/tests/universal/network/keyexpr.cxx +++ b/tests/universal/network/keyexpr.cxx @@ -17,6 +17,8 @@ using namespace zenoh; #undef NDEBUG #include +#include "test_config.hxx" + void key_expr() { KeyExpr foo("FOO"); assert(interop::detail::check(foo)); @@ -113,7 +115,7 @@ int main(int argc, char** argv) { intersects(); // Session based tests - Config config = Config::create_default(); + Config config = test_config(); auto session = Session::open(std::move(config)); declare(session); } diff --git a/tests/universal/network/liveliness.cxx b/tests/universal/network/liveliness.cxx index 3a2ec0eb..565652f5 100644 --- a/tests/universal/network/liveliness.cxx +++ b/tests/universal/network/liveliness.cxx @@ -16,6 +16,7 @@ #include #include +#include "test_config.hxx" #include "zenoh.hxx" using namespace zenoh; @@ -27,8 +28,8 @@ using namespace std::chrono_literals; void test_liveliness_get() { KeyExpr ke("zenoh/liveliness/test/*"); KeyExpr token_ke("zenoh/liveliness/test/1"); - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); auto token = session1.liveliness_declare_token(token_ke); std::this_thread::sleep_for(1s); @@ -54,8 +55,8 @@ void test_liveliness_subscriber() { KeyExpr ke("zenoh/liveliness/test/*"); KeyExpr token_ke1("zenoh/liveliness/test/1"); KeyExpr token_ke2("zenoh/liveliness/test/2"); - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); std::unordered_set put_tokens; std::unordered_set delete_tokens; diff --git a/tests/universal/network/pub_sub.cxx b/tests/universal/network/pub_sub.cxx index 35838fbe..92b4b839 100644 --- a/tests/universal/network/pub_sub.cxx +++ b/tests/universal/network/pub_sub.cxx @@ -15,6 +15,7 @@ #include #include +#include "test_config.hxx" #include "zenoh.hxx" using namespace zenoh; @@ -47,8 +48,8 @@ class SHMAllocator { template void pub_sub(Talloc& alloc) { KeyExpr ke("zenoh/test"); - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); auto publisher = session1.declare_publisher(ke); @@ -83,8 +84,8 @@ void pub_sub(Talloc& alloc) { template void put_sub(Talloc& alloc) { KeyExpr ke("zenoh/test"); - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); std::this_thread::sleep_for(1s); @@ -115,8 +116,8 @@ void put_sub(Talloc& alloc) { template void put_sub_fifo_channel(Talloc& alloc) { KeyExpr ke("zenoh/test"); - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); std::this_thread::sleep_for(1s); @@ -160,8 +161,8 @@ void put_sub_fifo_channel(Talloc& alloc) { template void put_sub_ring_channel(Talloc& alloc) { KeyExpr ke("zenoh/test"); - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); std::this_thread::sleep_for(1s); @@ -228,7 +229,7 @@ void test_with_alloc() { void publisher_get_keyexpr() { KeyExpr ke("zenoh/test_publisher_keyexpr"); - auto session = Session::open(Config::create_default()); + auto session = Session::open(test_config()); auto publisher = session.declare_publisher(ke); assert(publisher.get_keyexpr().as_string_view() == "zenoh/test_publisher_keyexpr"); } diff --git a/tests/universal/network/queryable_get.cxx b/tests/universal/network/queryable_get.cxx index 27ef8cb8..b11df9f3 100644 --- a/tests/universal/network/queryable_get.cxx +++ b/tests/universal/network/queryable_get.cxx @@ -15,6 +15,7 @@ #include #include +#include "test_config.hxx" #include "zenoh.hxx" using namespace zenoh; @@ -39,8 +40,8 @@ void queryable_get() { std::vector replies; std::vector errors; bool queryable_dropped = false; - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); size_t queries_processed = 0; auto queryable = session1.declare_queryable( @@ -111,8 +112,8 @@ void queryable_get_channel() { KeyExpr ke("zenoh/test/*"); KeyExpr selector("zenoh/test/1"); std::vector queries; - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); size_t queries_processed = 0; auto queryable = session1.declare_queryable(ke, channels::FifoChannel(3)); std::this_thread::sleep_for(1s); @@ -165,7 +166,7 @@ void queryable_get_channel() { void queryable_get_keyexpr() { KeyExpr ke("zenoh/test_queryable_keyexpr"); - auto session = Session::open(Config::create_default()); + auto session = Session::open(test_config()); auto queryable = session.declare_queryable(ke, channels::FifoChannel(3)); assert(queryable.get_keyexpr().as_string_view() == "zenoh/test_queryable_keyexpr"); } @@ -186,8 +187,8 @@ void queryable_get_accept_replies() { KeyExpr query_ke("zenoh/test/accept_replies/1"); KeyExpr disjoint_reply_ke("zenoh/test/accept_replies/2"); - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); // --- Test 1: default accept_replies (Z_REPLY_KEYEXPR_MATCHING_QUERY) --- // The queryable inspects the query's accept_replies setting and verifies it matches @@ -294,8 +295,8 @@ void queryable_querier_accept_replies() { KeyExpr query_ke("zenoh/test/querier_accept_replies/1"); KeyExpr disjoint_reply_ke("zenoh/test/querier_accept_replies/2"); - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); // --- Test 1: default accept_replies (Z_REPLY_KEYEXPR_MATCHING_QUERY) --- { diff --git a/tests/universal/network/source_info.cxx b/tests/universal/network/source_info.cxx index 34d2e57c..a7b8e1eb 100644 --- a/tests/universal/network/source_info.cxx +++ b/tests/universal/network/source_info.cxx @@ -15,6 +15,7 @@ #include #include +#include "test_config.hxx" #include "zenoh.hxx" #undef NDEBUG #include @@ -24,8 +25,8 @@ using namespace std::chrono_literals; void pub_sub() { std::cout << "Test source info: pub_sub\n"; - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); KeyExpr ke = "test/source_info/pub_sub"; auto publisher = session1.declare_publisher(ke); auto subscriber = session2.declare_subscriber(ke, channels::FifoChannel(16)); @@ -64,8 +65,8 @@ void pub_sub() { void put_sub() { std::cout << "Test source info: put_sub\n"; - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); KeyExpr ke = "test/source_info/put_sub"; auto subscriber = session2.declare_subscriber(ke, channels::FifoChannel(16)); @@ -103,8 +104,8 @@ void put_sub() { void query_reply() { std::cout << "Test source info: query_reply\n"; - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); KeyExpr ke = "test/source_info/query_reply"; auto queryable = session2.declare_queryable(ke, channels::FifoChannel(16)); @@ -168,8 +169,8 @@ void query_reply() { void querier_reply() { std::cout << "Test source info: querier_reply\n"; - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); KeyExpr ke = "test/source_info/querier_reply"; auto querier = session1.declare_querier(ke); auto queryable = session2.declare_queryable(ke, channels::FifoChannel(16)); diff --git a/tests/zenohpico/network/batching.cxx b/tests/zenohpico/network/batching.cxx index 05aea330..2debc7ac 100644 --- a/tests/zenohpico/network/batching.cxx +++ b/tests/zenohpico/network/batching.cxx @@ -15,6 +15,7 @@ #include #include +#include "test_config.hxx" #include "zenoh.hxx" using namespace zenoh; @@ -24,7 +25,7 @@ using namespace std::chrono_literals; #include void test_multiple_batching() { - auto session1 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); auto batch_guard = session1.start_batching(); ZResult err = Z_OK; @@ -33,8 +34,8 @@ void test_multiple_batching() { } void test_batching() { - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); auto subscriber = session2.declare_subscriber("test/batching", channels::FifoChannel(3)); std::this_thread::sleep_for(1s); @@ -56,8 +57,8 @@ void test_batching() { } void test_batching_drop() { - auto session1 = Session::open(Config::create_default()); - auto session2 = Session::open(Config::create_default()); + auto session1 = Session::open(test_config()); + auto session2 = Session::open(test_config()); auto subscriber = session2.declare_subscriber("test/batching", channels::FifoChannel(3)); std::this_thread::sleep_for(1s); diff --git a/zenoh-c b/zenoh-c index 15a2e77c..304cacee 160000 --- a/zenoh-c +++ b/zenoh-c @@ -1 +1 @@ -Subproject commit 15a2e77ce0830a06785068ea05b22477d1af8d22 +Subproject commit 304caceeaf67ef4e82c68da8884482b9cee90772 diff --git a/zenoh-pico b/zenoh-pico index 9506765a..2571c8f6 160000 --- a/zenoh-pico +++ b/zenoh-pico @@ -1 +1 @@ -Subproject commit 9506765abb71aee598aefe744d44314e8b8ac004 +Subproject commit 2571c8f6f7f4908a013e20180f98a1060ec6eae3