From: Vishal Chillara Srinivas Date: Thu, 17 Jul 2025 14:11:21 +0000 (+0530) Subject: test: resolve: add integration tests for browsing services X-Git-Tag: v258-rc1~33^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F22532%2Fhead;p=thirdparty%2Fsystemd.git test: resolve: add integration tests for browsing services Co-authored-by: Frantisek Sumsal Co-authored-by: Vishwanath Chandapur --- diff --git a/test/integration-tests/TEST-89-RESOLVED-MDNS/meson.build b/test/integration-tests/TEST-89-RESOLVED-MDNS/meson.build new file mode 100644 index 00000000000..9cca5c79a3c --- /dev/null +++ b/test/integration-tests/TEST-89-RESOLVED-MDNS/meson.build @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +integration_tests += [ + integration_test_template + { + 'name' : 'TEST-89-RESOLVED-MDNS', + }, +] diff --git a/test/integration-tests/meson.build b/test/integration-tests/meson.build index 5fb92b172af..19cd5b53102 100644 --- a/test/integration-tests/meson.build +++ b/test/integration-tests/meson.build @@ -101,6 +101,7 @@ foreach dirname : [ 'TEST-86-MULTI-PROFILE-UKI', 'TEST-87-AUX-UTILS-VM', 'TEST-88-UPGRADE', + 'TEST-89-RESOLVED-MDNS', ] subdir(dirname) endforeach diff --git a/test/units/TEST-89-RESOLVED-MDNS.service b/test/units/TEST-89-RESOLVED-MDNS.service new file mode 100644 index 00000000000..e7ed92c99a4 --- /dev/null +++ b/test/units/TEST-89-RESOLVED-MDNS.service @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later +[Unit] +Description=TEST-89-RESOLVED-MDNS + +[Service] +ExecStartPre=rm -f /failed /testok +ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh +Type=oneshot diff --git a/test/units/TEST-89-RESOLVED-MDNS.sh b/test/units/TEST-89-RESOLVED-MDNS.sh new file mode 100755 index 00000000000..b6e200582f7 --- /dev/null +++ b/test/units/TEST-89-RESOLVED-MDNS.sh @@ -0,0 +1,254 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -eux +set -o pipefail + +# shellcheck source=test/units/test-control.sh +. "$(dirname "$0")"/test-control.sh + +SERVICE_TYPE_COUNT=10 +SERVICE_COUNT=20 +CONTAINER_ZONE="test-$RANDOM" +CONTAINER_1="test-mdns-1" +CONTAINER_2="test-mdns-2" + +# Prepare containers +create_container() { + local container="${1:?}" + local stype sid svc + + # Prepare container's /etc + # + # Since we also need the various test suite related dropins from the host's /etc, + # we'll overlay our customizations on top of that + mkdir -p "/var/lib/machines/$container/etc/systemd/dnssd" + # Create 20 test services for each service type (_testServiceX._udp) and number them sequentially, + # i.e. create services 0-19 for _testService0._udp, services 20-39 for _testService1._udp, and so on + for stype in $(seq 0 $((SERVICE_TYPE_COUNT - 1))); do + for sid in $(seq 0 $((SERVICE_COUNT - 1))); do + svc=$((stype * SERVICE_COUNT + sid)) + + cat >"/var/lib/machines/$container/etc/systemd/dnssd/test-service-$container-$svc.dnssd" <"/run/systemd/system/systemd-nspawn@$container.service.d/override.conf" <&2 "Found a record from an unreachable container" + cat "$result_file" + exit 1 + fi + done + + # We got all records and all of them are what we expect + return 0 + fi + + return 1 +} + +run_and_check_services() { + local service_id="${1:?}" + local check_func="${2:?}" + local unit_name="varlinkctl-$service_id-$SRANDOM.service" + local i out_file parameters service_type svc tmp_file + + out_file="$(mktemp)" + error_file="$(mktemp)" + tmp_file="$(mktemp)" + service_type="_testService$service_id._udp" + parameters="{ \"domain\": \"$service_type.local\", \"type\": \"\", \"ifindex\": ${BRIDGE_INDEX:?}, \"flags\": 16785432 }" + + systemd-run --unit="$unit_name" --service-type=exec -p StandardOutput="file:$out_file" -p StandardError="file:$error_file" \ + varlinkctl call --more /run/systemd/resolve/io.systemd.Resolve io.systemd.Resolve.BrowseServices "$parameters" + + # shellcheck disable=SC2064 + # Note: unregister the trap once it's fired, otherwise it'll get propagated to functions that call this + # one, *sigh* + + trap "trap - RETURN; systemctl stop $unit_name" RETURN + + for _ in {0..14}; do + # The response format, for reference (it's JSON-SEQ): + # + # { + # "browser_service_data": [ + # { + # "updateFlag": true, + # "family": 10, + # "name": "Test Service 13 on test-mdns-1", + # "type": "_testService0._udp", + # "domain": "local", + # "interface": 3 + # }, + # ... + # ] + # } + if [[ -s "$out_file" ]]; then + # Extract the service name from each valid record... + # jq --slurp --raw-output \ + # ".[].browser_service_data[] | select(.updateFlag == true and .type == \"$service_type\" and .family == 10).name" "$out_file" | sort | tee "$tmp_file" + grep -o '"name":"[^"]*"' "$out_file" | sed 's/"name":"//;s/"//g' | sort | tee "$tmp_file" + # ...and compare them with what we expect + if "$check_func" "$service_id" "$tmp_file"; then + return 0 + fi + fi + + sleep 2 + done + + cat "$out_file" + cat "$error_file" + return 1 +} + +testcase_all_sequential() { + : "Test each service type (sequentially)" + resolvectl flush-caches + for id in $(seq 0 $((SERVICE_TYPE_COUNT - 1))); do + run_and_check_services "$id" check_both + done + + echo testcase_end +} + +testcase_all_parallel() { + : "Test each service type (in parallel)" + resolvectl flush-caches + for id in $(seq 0 $((SERVICE_TYPE_COUNT - 1))); do + run_and_check_services "$id" check_both & + done + wait +} + +testcase_single_service_multiple_times() { + : "Test one service type multiple times" + resolvectl flush-caches + for _ in {0..4}; do + run_and_check_services 4 check_both + done +} + +testcase_second_unreachable() { + : "Test each service type while the second container is unreachable" + systemd-run -M "$CONTAINER_2" --wait --pipe -- networkctl down host0 + resolvectl flush-caches + for id in $(seq 0 $((SERVICE_TYPE_COUNT - 1))); do + run_and_check_services "$id" check_first + done + + + : "Test each service type after bringing the second container back up again" + systemd-run -M "$CONTAINER_2" --wait --pipe -- networkctl up host0 + systemd-run -M "$CONTAINER_2" --wait --pipe -- \ + /usr/lib/systemd/systemd-networkd-wait-online --ipv4 --ipv6 --interface=host0 --operational-state=degraded --timeout=30 + for id in $(seq 0 $((SERVICE_TYPE_COUNT - 1))); do + run_and_check_services "$id" check_both + done +} + +: "Setup host & containers" +# Note: create the drop-in intentionally under /run/ and copy it manually into the containers +mkdir -p /run/systemd/resolved.conf.d/ +cat >/run/systemd/resolved.conf.d/99-mdns-llmnr.conf <