-
Notifications
You must be signed in to change notification settings - Fork 279
[tests] implement DinD test for SRP TC 2.6 Name Compression #3411
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
+287
−0
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,284 @@ | ||
| #!/usr/bin/expect -f | ||
| # | ||
| # Copyright (c) 2026, The OpenThread Authors. | ||
| # All rights reserved. | ||
| # | ||
| # Redistribution and use in source and binary forms, with or without | ||
| # modification, are permitted provided that the following conditions are met: | ||
| # 1. Redistributions of source code must retain the above copyright | ||
| # notice, this list of conditions and the following disclaimer. | ||
| # 2. Redistributions in binary form must reproduce the above copyright | ||
| # notice, this list of conditions and the following disclaimer in the | ||
| # documentation and/or other materials provided with the distribution. | ||
| # 3. Neither the name of the copyright holder nor the | ||
| # names of its contributors may be used to endorse or promote products | ||
| # derived from this software without specific prior written permission. | ||
| # | ||
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
| # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
| # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE | ||
| # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
| # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
| # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
| # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
| # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
| # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||
| # POSSIBILITY OF SUCH DAMAGE. | ||
| # | ||
|
|
||
| source "tests/scripts/expect/_common.exp" | ||
|
|
||
|
|
||
| set pty1 [create_socat_tcp 1 9000] | ||
| set container "otbr-test-container" | ||
| set dataset "0e080000000000010000000300001435060004001fffe002087d61eb42cdc48d6a0708fd0d07fca1b9f0500510ba088fc2bd6c3b3897f7a10f58263ff3030f4f70656e5468726561642d353234660102524f04109dc023ccd447b12b50997ef68020f19e0c0402a0f7f8" | ||
|
|
||
| # Step 1: BR_1 (DUT) Enable: switch on. | ||
| send_user "Starting OTBR Docker container (BR_1 / DUT)...\n" | ||
| start_otbr_docker_dind $container $::env(EXP_OT_RCP_PATH) 2 $pty1 | ||
|
|
||
| # Wait for otbr-agent to create the domain socket | ||
| set socket_ready false | ||
| for {set i 0} {$i < 10} {incr i} { | ||
| if {![catch {exec docker exec -i $container ot-ctl state}]} { | ||
| set socket_ready true | ||
| break | ||
| } | ||
| sleep 2 | ||
| } | ||
| if {!$socket_ready} { | ||
| fail "ot-ctl failed to communicate with otbr-agent" | ||
| } | ||
|
|
||
| # Step 2: Eth_1, ED_1 Enable | ||
| # Setup active dataset on OTBR and start Thread | ||
| exec docker exec -i $container ot-ctl thread stop | ||
| exec docker exec -i $container ot-ctl ifconfig down | ||
| exec docker exec -i $container ot-ctl dataset set active ${dataset} | ||
| exec docker exec -i $container ot-ctl ifconfig up | ||
| exec docker exec -i $container ot-ctl thread start | ||
|
|
||
| # Wait for OTBR to become leader | ||
| set leader false | ||
| for {set i 0} {$i < 20} {incr i} { | ||
| if {![catch {exec docker exec -i $container ot-ctl state} state] && [string match "*leader*" $state]} { | ||
| set leader true | ||
| break | ||
| } | ||
| sleep 2 | ||
| } | ||
| if {!$leader} { | ||
| fail "OTBR did not become leader" | ||
| } | ||
|
|
||
| # Enable SRP server explicitly | ||
| exec docker exec -i $container ot-ctl srp server auto disable | ||
| exec docker exec -i $container ot-ctl srp server enable | ||
| sleep 2 | ||
|
|
||
| # Wait 15 seconds for the dynamic OMR prefix to fully stabilize | ||
| send_user "Waiting 15 seconds for the dynamic OMR prefix to stabilize...\n" | ||
| sleep 15 | ||
|
|
||
| # Step 3: BR_1 (DUT) Automatically adds SRP Server info and configures OMR prefix | ||
| send_user "Step 3: Verifying SRP Server information and ULA OMR prefix in Network Data...\n" | ||
| set netdata [exec docker exec -i $container ot-ctl netdata show] | ||
| check_string_contains $netdata "44970 5d" | ||
| check_string_contains $netdata "fd" | ||
|
|
||
| # Get the running Border Router's active dataset dynamically to configure clients | ||
| set active_dataset [exec docker exec -i $container ot-ctl dataset active -x] | ||
| set active_dataset [string trim $active_dataset] | ||
|
|
||
| # Enable ED_1 (Node 4) | ||
| spawn_node 4 cli $::env(EXP_OT_CLI_PATH) | ||
| send "dataset set active $active_dataset\r\n" | ||
| expect_line "Done" | ||
| send "mode rdn\r\n" | ||
| expect_line "Done" | ||
| send "routereligible disable\r\n" | ||
| expect_line "Done" | ||
| send "ifconfig up\r\n" | ||
| expect_line "Done" | ||
| send "thread start\r\n" | ||
| expect_line "Done" | ||
| wait_for "state" "child" | ||
| expect_line "Done" | ||
|
|
||
| set omr_addr_1 [get_omr_addr] | ||
| expect_line "Done" | ||
| set mleid_1 [get_ipaddr mleid] | ||
| send_user "ED_1 ML-EID Address: $mleid_1\n" | ||
| send_user "ED_1 OMR Address: $omr_addr_1\n" | ||
| sleep 1 | ||
|
|
||
| # Set up test-client container to verify from adjacent infrastructure link (Eth_1) | ||
| set test_client "test-client" | ||
| track_container $test_client | ||
| exec docker run -d \ | ||
| --name $test_client \ | ||
| --network infrastructure-link \ | ||
| --cap-add=NET_ADMIN \ | ||
| --privileged \ | ||
| --sysctl net.ipv6.conf.all.disable_ipv6=0 \ | ||
| --entrypoint /bin/bash \ | ||
| $::env(EXP_TEST_CLIENT_IMAGE) \ | ||
| -c "echo 0 > /proc/sys/net/ipv6/conf/all/autoconf && echo 0 > /proc/sys/net/ipv6/conf/eth0/autoconf && echo 2 > /proc/sys/net/ipv6/conf/all/accept_ra && echo 2 > /proc/sys/net/ipv6/conf/eth0/accept_ra && sleep infinity" | ||
|
|
||
| # Configure routes on test client | ||
| set has_rio [expr {[catch {exec docker exec -i $test_client test -e /proc/sys/net/ipv6/conf/all/accept_ra_rt_info_max_plen}] == 0}] | ||
| if {$has_rio} { | ||
| exec docker exec -i $test_client sysctl -w net.ipv6.conf.all.accept_ra_rt_info_max_plen=64 | ||
| exec docker exec -i $test_client sysctl -w net.ipv6.conf.eth0.accept_ra_rt_info_max_plen=64 | ||
| exec docker exec -i $test_client rdisc6 eth0 | ||
| } else { | ||
| set format {{{range .NetworkSettings.Networks}}{{.GlobalIPv6Address}}{{end}}} | ||
| set otbr_ip [string trim [exec docker inspect $container -f $format]] | ||
| exec docker exec -i $test_client ip -6 route add fc00::/7 via $otbr_ip dev eth0 | ||
| } | ||
| sleep 2 | ||
|
|
||
| # Retrieve Border Router's RLOC or ML-EID address to use as DNS server on ED_1 | ||
| set otbr_addrs [exec docker exec -i $container ot-ctl ipaddr] | ||
| set otbr_dns_addr "" | ||
| foreach addr [split $otbr_addrs "\n"] { | ||
| set addr [string trim $addr] | ||
| if {[string match -nocase "*:ff:fe00:fc00" $addr]} { | ||
| set otbr_dns_addr $addr | ||
| break | ||
| } | ||
| } | ||
| if {$otbr_dns_addr eq ""} { | ||
| set otbr_dns_addr [string trim [lindex [split $otbr_addrs "\n"] 0]] | ||
| } | ||
| send_user "OTBR DNS Server Address: $otbr_dns_addr\n" | ||
|
|
||
| # Step 4: ED_1 sends SRP Update without name compression | ||
| send_user "Step 4: ED_1 sending SRP Update without name compression...\n" | ||
| switch_node 4 | ||
| send "dns compression disable\r\n" | ||
| expect_line "Done" | ||
| send "srp client leaseinterval 1200\r\n" | ||
| expect_line "Done" | ||
| send "srp client keyleaseinterval 1200\r\n" | ||
| expect_line "Done" | ||
| send "srp client host name host-test-1\r\n" | ||
| expect_line "Done" | ||
| send "srp client host address $omr_addr_1\r\n" | ||
| expect_line "Done" | ||
| send "srp client service add service-test-1 _thread-test._udp 55555\r\n" | ||
| expect_line "Done" | ||
| send "srp client autostart enable\r\n" | ||
| expect_line "Done" | ||
|
|
||
| # Step 5: BR_1 (DUT) sends success SRP Update Response | ||
| send_user "Step 5: Verifying SRP registration success (RCODE=0)...\n" | ||
| wait_for "srp client host state" "Registered" | ||
| expect_line "Done" | ||
| send_user "SRP registration without name compression successful.\n" | ||
|
|
||
| # Step 6-7: ED_1 unicast DNS QType=PTR query to DUT | ||
| send_user "Step 6-7: Verifying unicast DNS query from ED_1...\n" | ||
| send "dns config $otbr_dns_addr\r\n" | ||
| expect_line "Done" | ||
| send "dns browse _thread-test._udp.default.service.arpa.\r\n" | ||
| set timeout 30 | ||
| set found_ptr 0 | ||
| expect { | ||
| -re "service-test-1" { | ||
| set found_ptr 1 | ||
| exp_continue | ||
| } | ||
| -re "Done" { | ||
| # Succeeded | ||
| } | ||
| timeout { | ||
| fail "Unicast DNS PTR query timed out" | ||
| } | ||
| } | ||
| if {!$found_ptr} { | ||
| fail "Unicast DNS PTR query response missing 'service-test-1'" | ||
| } | ||
| send_user "Unicast DNS PTR query successful.\n" | ||
|
|
||
| # Step 8-9 & 9b: Eth_1 sends mDNS QType=PTR and SRV queries | ||
| send_user "Step 8-9 & 9b: Verifying mDNS resolution from Eth_1 (test-client) on AIL...\n" | ||
| set py_mdns_check {import time | ||
| from zeroconf import Zeroconf, IPVersion | ||
|
|
||
| zc = Zeroconf(ip_version=IPVersion.V6Only) | ||
| for _ in range(10): | ||
| info = zc.get_service_info('_thread-test._udp.local.', 'service-test-1._thread-test._udp.local.', 2000) | ||
| if info and info.port is not None and info.server is not None: | ||
| print(f'SRV:{info.port},{info.server}') | ||
| break | ||
| time.sleep(1) | ||
| else: | ||
| print('SRV:None') | ||
| zc.close() | ||
| } | ||
|
|
||
| set mdns_res [exec docker exec -i $test_client python3 -c $py_mdns_check] | ||
| set mdns_res [string trim $mdns_res] | ||
| send_user "mDNS Check Result:\n$mdns_res\n" | ||
|
|
||
| if {![string match "*SRV:55555,host-test-1.local.*" $mdns_res]} { | ||
| fail "mDNS SRV resolution incorrect or missing" | ||
| } | ||
| send_user "mDNS PTR and SRV resolution verified successfully.\n" | ||
|
|
||
| # Step 10: Repeat Steps 4 through 9b with name compression enabled | ||
| send_user "Step 10: Repeating Steps 4 through 9b with name compression enabled...\n" | ||
| switch_node 4 | ||
| send "srp client service remove service-test-1 _thread-test._udp\r\n" | ||
| expect_line "Done" | ||
| sleep 2 | ||
|
|
||
| send "dns compression enable\r\n" | ||
| expect_line "Done" | ||
| send "srp client service add service-test-1 _thread-test._udp 55555\r\n" | ||
| expect_line "Done" | ||
|
|
||
| # Verify SRP Update Response (Step 5 equivalent) | ||
| send_user "Verifying SRP registration success with name compression (RCODE=0)...\n" | ||
| wait_for "srp client host state" "Registered" | ||
| expect_line "Done" | ||
| send_user "SRP registration with name compression successful.\n" | ||
|
|
||
| # Repeat Step 6-7 (Unicast DNS query) | ||
| send_user "Repeating unicast DNS PTR query...\n" | ||
| send "dns browse _thread-test._udp.default.service.arpa.\r\n" | ||
| set timeout 30 | ||
| set found_ptr 0 | ||
| expect { | ||
| -re "service-test-1" { | ||
| set found_ptr 1 | ||
| exp_continue | ||
| } | ||
| -re "Done" { | ||
| # Succeeded | ||
| } | ||
| timeout { | ||
| fail "Unicast DNS PTR query timed out" | ||
| } | ||
| } | ||
| if {!$found_ptr} { | ||
| fail "Unicast DNS PTR query response missing 'service-test-1'" | ||
| } | ||
|
|
||
| # Repeat Step 8-9 & 9b (mDNS query) | ||
| send_user "Repeating mDNS check...\n" | ||
| set mdns_res2 [exec docker exec -i $test_client python3 -c $py_mdns_check] | ||
| set mdns_res2 [string trim $mdns_res2] | ||
| send_user "mDNS Check 2 Result:\n$mdns_res2\n" | ||
|
|
||
| if {![string match "*SRV:55555,host-test-1.local.*" $mdns_res2]} { | ||
| fail "mDNS SRV resolution 2 incorrect or missing" | ||
| } | ||
| send_user "mDNS PTR and SRV resolution 2 verified successfully.\n" | ||
|
|
||
| # Cleanup | ||
| dispose_all | ||
| send_user "# Name Compression (1_3_SRP_TC_6) integration test completed successfully!\n" | ||
| exit 0 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.