2929
3030source "tests/scripts/expect/_common.exp"
3131
32- proc start_otbr_docker_web {name sim_app sim_id pty1 pty2} {
32+ proc start_otbr_docker_web {name sim_app sim_id pty1 pty2 {rest_addr ""} {rest_port ""} } {
3333 # Start the container using its native /init entrypoint (s6-overlay) and custom environment variables
34- exec docker run -d \
35- --name $name \
36- --network infrastructure-link \
37- --cap-add=NET_ADMIN \
38- --privileged \
39- --add-host=host.docker.internal:host-gateway \
40- --sysctl net.ipv6.conf.all.disable_ipv6=0 \
41- --sysctl net.ipv4.conf.all.forwarding=1 \
42- --sysctl net.ipv4.conf.default.forwarding=1 \
43- --sysctl net.ipv6.conf.all.forwarding=1 \
44- --sysctl net.ipv6.conf.default.forwarding=1 \
45- -v $pty2:/dev/ttyUSB0 \
46- -e OT_RCP_DEVICE=spinel+hdlc+uart:///dev/ttyUSB0 \
47- -e OT_INFRA_IF=eth0 \
48- -e OT_THREAD_IF=wpan0 \
49- -e OT_WEB_LISTEN_ADDR=0.0.0.0 \
50- -p 8080:8080 \
51- $::env(EXP_OTBR_DOCKER_IMAGE)
52- sleep 2
34+ set docker_opts [list \
35+ "docker" "run" "-d" \
36+ "--name" $name \
37+ "--network" "infrastructure-link" \
38+ "--cap-add=NET_ADMIN" \
39+ "--privileged" \
40+ "--add-host=host.docker.internal:host-gateway" \
41+ "--sysctl" "net.ipv6.conf.all.disable_ipv6=0" \
42+ "--sysctl" "net.ipv4.conf.all.forwarding=1" \
43+ "--sysctl" "net.ipv4.conf.default.forwarding=1" \
44+ "--sysctl" "net.ipv6.conf.all.forwarding=1" \
45+ "--sysctl" "net.ipv6.conf.default.forwarding=1" \
46+ "-v" "$pty2:/dev/ttyUSB0" \
47+ "-e" "OT_RCP_DEVICE=spinel+hdlc+uart:///dev/ttyUSB0" \
48+ "-e" "OT_INFRA_IF=eth0" \
49+ "-e" "OT_THREAD_IF=wpan0" \
50+ "-e" "OT_WEB_LISTEN_ADDR=0.0.0.0" \
51+ "-p" "8080:8080" \
52+ ]
53+
54+ if {$rest_addr != ""} {
55+ lappend docker_opts "-e" "OT_REST_LISTEN_ADDR=$rest_addr"
56+ }
57+ if {$rest_port != ""} {
58+ lappend docker_opts "-e" "OT_REST_LISTEN_PORT=$rest_port"
59+ lappend docker_opts "-p" "$rest_port:$rest_port"
60+ }
61+
62+ lappend docker_opts $::env(EXP_OTBR_DOCKER_IMAGE)
5363
54- # Now start the simulated RCP binary on the host in a dedicated script restart loop and track its PID
55- exec bash -c "echo 'while true; do \"\$1\" \"\$2\" <\"\$3\" >\"\$3\"; sleep 1; done' > /tmp/ot_rcp_web_loop.sh"
56- exec bash -c "bash /tmp/ot_rcp_web_loop.sh \"$sim_app\" \"$sim_id\" \"$pty1\" </dev/null >/dev/null 2>&1 & echo \$! > /tmp/ot_rcp_web_loop.pid"
57- sleep 5
64+ eval exec $docker_opts
65+ sleep 2
5866}
5967
6068set ptys [create_socat 1]
6169set pty1 [lindex $ptys 0]
6270set pty2 [lindex $ptys 1]
6371set container "otbr-test-container-web"
6472
73+ # Start the simulated RCP binary on the host in a dedicated script restart loop keeping PTY open
74+ exec bash -c "exec 3<>$pty1; while true; do \"$::env(EXP_OT_RCP_PATH)\" 2 <&3 >&3; sleep 1; done </dev/null >/tmp/ot_rcp_web.log 2>&1 & echo \$! > /tmp/ot_rcp_web_loop.pid"
75+ sleep 5
76+
77+ # ==========================================
78+ # SCENARIO 1: Verification with Default Values
79+ # ==========================================
80+ send_user -- "--- SCENARIO 1: Testing Web UI and REST API with Default Values ---\n"
6581start_otbr_docker_web $container $::env(EXP_OT_RCP_PATH) 2 $pty1 $pty2
6682
6783# Wait for otbr-agent to create the domain socket
@@ -74,7 +90,53 @@ for {set i 0} {$i < 10} {incr i} {
7490 sleep 2
7591}
7692if {!$socket_ready} {
77- send_user "Error: ot-ctl failed to communicate with otbr-agent\n"; exit 1
93+ send_user "Error: ot-ctl failed to communicate with otbr-agent in Scenario 1\n"; exit 1
94+ }
95+
96+ # 1. Verify get_rest_api_info returns default values
97+ send_user "Testing Web UI get_rest_api_info for defaults (127.0.0.1:8081)...\n"
98+ set rest_info [exec curl -s http://127.0.0.1:8080/get_rest_api_info]
99+ send_user "get_rest_api_info response: $rest_info\n"
100+ if {[string first "8081" $rest_info] == -1 || [string first "127.0.0.1" $rest_info] == -1} {
101+ send_user "Error: Default REST API port/address not found in get_rest_api_info response\n"
102+ exit 1
103+ }
104+ send_user "Scenario 1 get_rest_api_info verified successfully!\n"
105+
106+ send_user "Scenario 1 default REST API verified successfully!\n"
107+
108+ # Clean up Scenario 1 container and PTYs
109+ exec docker stop $container
110+ exec docker rm $container
111+ catch {exec bash -c "kill \$(cat /tmp/ot_rcp_web_loop.pid) 2>/dev/null"}
112+ dispose_all
113+ sleep 2
114+
115+ # Re-create socat PTYs and RCP loop for Scenario 2
116+ set ptys [create_socat 1]
117+ set pty1 [lindex $ptys 0]
118+ set pty2 [lindex $ptys 1]
119+
120+ exec bash -c "exec 3<>$pty1; while true; do \"$::env(EXP_OT_RCP_PATH)\" 2 <&3 >&3; sleep 1; done </dev/null >/tmp/ot_rcp_web.log 2>&1 & echo \$! > /tmp/ot_rcp_web_loop.pid"
121+ sleep 5
122+
123+ # ==========================================
124+ # SCENARIO 2: Verification with Custom Values
125+ # ==========================================
126+ send_user -- "--- SCENARIO 2: Testing Web UI and REST API with Custom Values (0.0.0.0:9090) ---\n"
127+ start_otbr_docker_web $container $::env(EXP_OT_RCP_PATH) 2 $pty1 $pty2 "0.0.0.0" "9090"
128+
129+ # Wait for otbr-agent to create the domain socket
130+ set socket_ready false
131+ for {set i 0} {$i < 10} {incr i} {
132+ if {![catch {exec docker exec -i $container ot-ctl state}]} {
133+ set socket_ready true
134+ break
135+ }
136+ sleep 2
137+ }
138+ if {!$socket_ready} {
139+ send_user "Error: ot-ctl failed to communicate with otbr-agent in Scenario 2\n"; exit 1
78140}
79141
80142# Stop Thread and down interface initially so we can form network via Web UI
@@ -93,7 +155,7 @@ for {set i 0} {$i < 15} {incr i} {
93155 sleep 2
94156}
95157if {!$web_ready} {
96- send_user "Error: Web UI index.html validation failed\n"
158+ send_user "Error: Web UI index.html validation failed in Scenario 2 \n"
97159 exit 1
98160}
99161send_user "Web UI index.html validated successfully!\n"
@@ -115,6 +177,26 @@ if {[string first "success" $result] == -1} {
115177}
116178send_user "Web UI form_network validated successfully!\n"
117179
180+ # 1. Verify get_rest_api_info returns custom values
181+ send_user "Testing Web UI get_rest_api_info for custom port 9090 and address 0.0.0.0...\n"
182+ set rest_info [exec curl -s http://127.0.0.1:8080/get_rest_api_info]
183+ send_user "get_rest_api_info response: $rest_info\n"
184+ if {[string first "9090" $rest_info] == -1 || [string first "0.0.0.0" $rest_info] == -1} {
185+ send_user "Error: Custom REST API port 9090 or address 0.0.0.0 not found in get_rest_api_info response\n"
186+ exit 1
187+ }
188+ send_user "Scenario 2 get_rest_api_info verified successfully!\n"
189+
190+ # 2. Verify REST API directly from host on custom port 9090
191+ send_user "Testing REST API response from host on custom port 9090...\n"
192+ set rest_node [exec curl -s http://127.0.0.1:9090/api/node]
193+ send_user "api/node response: $rest_node\n"
194+ if {[string first "networkName" $rest_node] == -1} {
195+ send_user "Error: REST API on custom port 9090 failed to respond correctly from host\n"
196+ exit 1
197+ }
198+ send_user "Scenario 2 custom REST API responsiveness verified successfully!\n"
199+
118200catch {exec bash -c "kill \$(cat /tmp/ot_rcp_web_loop.pid) 2>/dev/null"}
119201
120202exec docker stop $container
0 commit comments