Skip to content

Commit b413026

Browse files
yufengwangcaCopilotrestyled-commits
committed
[WEBRTCR] Send command to DUT via websocket in CI (#41486)
* [WEBRTCR] Send command to DUT via websocket in CI * Update src/python_testing/TC_WEBRTCR_2_2.py Co-authored-by: Copilot <[email protected]> * Update src/python_testing/TC_WEBRTCR_2_6.py Co-authored-by: Copilot <[email protected]> * Update src/python_testing/TC_WEBRTCR_2_7.py Co-authored-by: Copilot <[email protected]> * Restyled by autopep8 * Restyled by isort * Address review comments --------- Co-authored-by: Copilot <[email protected]> Co-authored-by: Restyled.io <[email protected]>
1 parent ab13593 commit b413026

File tree

9 files changed

+174
-59
lines changed

9 files changed

+174
-59
lines changed
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#
2+
# Copyright (c) 2025 Project CHIP Authors
3+
# All rights reserved.
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
18+
import logging
19+
20+
import websockets
21+
22+
from matter.testing.matter_testing import MatterBaseTest
23+
24+
# WebSocket server URI for sending commands to the DUT
25+
SERVER_URI = "ws://localhost:9002"
26+
27+
28+
class WEBRTCRTestBase(MatterBaseTest):
29+
"""
30+
Base class for WebRTC Transport Requestor test cases.
31+
32+
Provides common functionality including:
33+
- WebSocket-based command sending to the DUT
34+
- Shared SERVER_URI constant
35+
"""
36+
37+
async def send_command(self, command):
38+
"""
39+
Send a command to the DUT via WebSocket and wait for response.
40+
41+
Args:
42+
command: The command string to send to the DUT
43+
44+
This method:
45+
1. Connects to the WebSocket server at SERVER_URI
46+
2. Sends the command
47+
3. Waits for and receives the response
48+
4. Logs the connection, command, and response status
49+
50+
Raises:
51+
Exception: Re-raises any exceptions after logging them clearly
52+
"""
53+
try:
54+
async with websockets.connect(SERVER_URI) as websocket:
55+
logging.info(f"Connected to {SERVER_URI}")
56+
57+
# Send command
58+
logging.info(f"Sending command: {command}")
59+
await websocket.send(command)
60+
61+
# Receive response
62+
await websocket.recv()
63+
logging.info("Received command response")
64+
65+
except ConnectionRefusedError as e:
66+
logging.error(f"Failed to connect to WebSocket server at {SERVER_URI}: Connection refused. "
67+
f"Is the DUT WebSocket server running? Error: {e}")
68+
raise
69+
70+
except websockets.exceptions.WebSocketException as e:
71+
logging.error(f"WebSocket error while communicating with {SERVER_URI}: {e}")
72+
raise
73+
74+
except OSError as e:
75+
logging.error(f"Network error while connecting to {SERVER_URI}: {e}")
76+
raise
77+
78+
except Exception as e:
79+
logging.error(f"Unexpected error while sending command '{command}' to {SERVER_URI}: {e}")
80+
raise

src/python_testing/TC_WEBRTCR_2_1.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
# === BEGIN CI TEST ARGUMENTS ===
2222
# test-runner-runs:
2323
# run1:
24+
# app: ${CAMERA_CONTROLLER_APP}
25+
# app-args: interactive server
2426
# script-args: >
2527
# --PICS src/app/tests/suites/certification/ci-pics-values
2628
# --storage-path admin_storage.json
@@ -38,14 +40,15 @@
3840
from time import sleep
3941

4042
from mobly import asserts
43+
from TC_WEBRTCRTestBase import WEBRTCRTestBase
4144

4245
import matter.clusters as Clusters
4346
from matter import ChipDeviceCtrl
4447
from matter.testing.apps import AppServerSubprocess
45-
from matter.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
48+
from matter.testing.matter_testing import TestStep, async_test_body, default_matter_test_main
4649

4750

48-
class TC_WebRTCR_2_1(MatterBaseTest):
51+
class TC_WebRTCR_2_1(WEBRTCRTestBase):
4952
def setup_class(self):
5053
super().setup_class()
5154

@@ -152,7 +155,7 @@ async def test_TC_WebRTCR_2_1(self):
152155
)
153156

154157
if self.is_pics_sdk_ci_only:
155-
# TODO: send command to DUT via websocket
158+
await self.send_command(f"pairing onnetwork 1 {passcode}")
156159
resp = 'Y'
157160
else:
158161
resp = self.wait_for_user_input(prompt_msg)
@@ -201,8 +204,17 @@ async def test_TC_WebRTCR_2_1(self):
201204
)
202205

203206
if self.is_pics_sdk_ci_only:
204-
# TODO: send command to DUT via websocket
205-
resp = 'Y'
207+
self.th_server.set_output_match("NOT_FOUND")
208+
self.th_server.event.clear()
209+
210+
try:
211+
await self.send_command("webrtc establish-session 1 --offer-type 1")
212+
# Wait up to 90s until the provider logs that the data‑channel opened
213+
if not self.th_server.event.wait(90):
214+
raise TimeoutError("PeerConnection is not connected within 90s")
215+
resp = 'Y'
216+
except TimeoutError:
217+
resp = 'N'
206218
else:
207219
resp = self.wait_for_user_input(prompt_msg)
208220

src/python_testing/TC_WEBRTCR_2_2.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
# === BEGIN CI TEST ARGUMENTS ===
2222
# test-runner-runs:
2323
# run1:
24+
# app: ${CAMERA_CONTROLLER_APP}
25+
# app-args: interactive server
2426
# script-args: >
2527
# --PICS src/app/tests/suites/certification/ci-pics-values
2628
# --storage-path admin_storage.json
@@ -38,14 +40,15 @@
3840
from time import sleep
3941

4042
from mobly import asserts
43+
from TC_WEBRTCRTestBase import WEBRTCRTestBase
4144

4245
import matter.clusters as Clusters
4346
from matter import ChipDeviceCtrl
4447
from matter.testing.apps import AppServerSubprocess
45-
from matter.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
48+
from matter.testing.matter_testing import TestStep, async_test_body, default_matter_test_main
4649

4750

48-
class TC_WebRTCR_2_2(MatterBaseTest):
51+
class TC_WebRTCR_2_2(WEBRTCRTestBase):
4952
def setup_class(self):
5053
super().setup_class()
5154

@@ -152,7 +155,7 @@ async def test_TC_WebRTCR_2_2(self):
152155
)
153156

154157
if self.is_pics_sdk_ci_only:
155-
# TODO: send command to DUT via websocket
158+
await self.send_command(f"pairing onnetwork 1 {passcode}")
156159
resp = 'Y'
157160
else:
158161
resp = self.wait_for_user_input(prompt_msg)
@@ -201,8 +204,17 @@ async def test_TC_WebRTCR_2_2(self):
201204
)
202205

203206
if self.is_pics_sdk_ci_only:
204-
# TODO: send command to DUT via websocket
205-
resp = 'Y'
207+
self.th_server.set_output_match("NOT_FOUND")
208+
self.th_server.event.clear()
209+
210+
try:
211+
await self.send_command("webrtc establish-session 1")
212+
# Wait up to 90s until the provider logs that the data‑channel opened
213+
if not self.th_server.event.wait(90):
214+
raise TimeoutError("PeerConnection is not connected within 90s")
215+
resp = 'Y'
216+
except TimeoutError:
217+
resp = 'N'
206218
else:
207219
resp = self.wait_for_user_input(prompt_msg)
208220

src/python_testing/TC_WEBRTCR_2_3.py

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,14 @@
3838
import os
3939
import tempfile
4040

41-
import websockets
4241
from mobly import asserts
42+
from TC_WEBRTCRTestBase import WEBRTCRTestBase
4343

4444
from matter.testing.apps import AppServerSubprocess
45-
from matter.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
45+
from matter.testing.matter_testing import TestStep, async_test_body, default_matter_test_main
4646

47-
SERVER_URI = "ws://localhost:9002"
4847

49-
50-
class TC_WebRTCR_2_3(MatterBaseTest):
48+
class TC_WebRTCR_2_3(WEBRTCRTestBase):
5149
def setup_class(self):
5250
super().setup_class()
5351

@@ -119,18 +117,6 @@ def pics_TC_WebRTCR_2_3(self) -> list[str]:
119117
def default_timeout(self) -> int:
120118
return 3 * 60
121119

122-
async def send_command(self, command):
123-
async with websockets.connect(SERVER_URI) as websocket:
124-
logging.info(f"Connected to {SERVER_URI}")
125-
126-
# Send command
127-
logging.info(f"Sending command: {command}")
128-
await websocket.send(command)
129-
130-
# Receive response
131-
await websocket.recv()
132-
logging.info("Received command response")
133-
134120
@async_test_body
135121
async def test_TC_WebRTCR_2_3(self):
136122
"""

src/python_testing/TC_WEBRTCR_2_4.py

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,14 @@
3838
import os
3939
import tempfile
4040

41-
import websockets
4241
from mobly import asserts
42+
from TC_WEBRTCRTestBase import WEBRTCRTestBase
4343

4444
from matter.testing.apps import AppServerSubprocess
45-
from matter.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
45+
from matter.testing.matter_testing import TestStep, async_test_body, default_matter_test_main
4646

47-
SERVER_URI = "ws://localhost:9002"
4847

49-
50-
class TC_WebRTCR_2_4(MatterBaseTest):
48+
class TC_WebRTCR_2_4(WEBRTCRTestBase):
5149
def setup_class(self):
5250
super().setup_class()
5351

@@ -119,18 +117,6 @@ def pics_TC_WebRTCR_2_4(self) -> list[str]:
119117
def default_timeout(self) -> int:
120118
return 3 * 60
121119

122-
async def send_command(self, command):
123-
async with websockets.connect(SERVER_URI) as websocket:
124-
logging.info(f"Connected to {SERVER_URI}")
125-
126-
# Send command
127-
logging.info(f"Sending command: {command}")
128-
await websocket.send(command)
129-
130-
# Receive response
131-
await websocket.recv()
132-
logging.info("Received command response")
133-
134120
@async_test_body
135121
async def test_TC_WebRTCR_2_4(self):
136122
"""

src/python_testing/TC_WEBRTCR_2_5.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
# === BEGIN CI TEST ARGUMENTS ===
2222
# test-runner-runs:
2323
# run1:
24+
# app: ${CAMERA_CONTROLLER_APP}
25+
# app-args: interactive server
2426
# script-args: >
2527
# --PICS src/app/tests/suites/certification/ci-pics-values
2628
# --storage-path admin_storage.json
@@ -38,13 +40,14 @@
3840
from time import sleep
3941

4042
from mobly import asserts
43+
from TC_WEBRTCRTestBase import WEBRTCRTestBase
4144

4245
from matter import ChipDeviceCtrl
4346
from matter.testing.apps import AppServerSubprocess
44-
from matter.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
47+
from matter.testing.matter_testing import TestStep, async_test_body, default_matter_test_main
4548

4649

47-
class TC_WebRTCR_2_5(MatterBaseTest):
50+
class TC_WebRTCR_2_5(WEBRTCRTestBase):
4851
def setup_class(self):
4952
super().setup_class()
5053

@@ -156,7 +159,7 @@ async def test_TC_WebRTCR_2_5(self):
156159
)
157160

158161
if self.is_pics_sdk_ci_only:
159-
# TODO: send command to DUT via websocket
162+
await self.send_command(f"pairing onnetwork 1 {passcode}")
160163
resp = 'Y'
161164
else:
162165
resp = self.wait_for_user_input(prompt_msg)
@@ -204,8 +207,17 @@ async def test_TC_WebRTCR_2_5(self):
204207
)
205208

206209
if self.is_pics_sdk_ci_only:
207-
# TODO: establish session via websocket
208-
resp = 'Y'
210+
self.th_server.set_output_match("PeerConnection State: Connected")
211+
self.th_server.event.clear()
212+
213+
try:
214+
await self.send_command("webrtc establish-session 1")
215+
# Wait up to 90s until the provider logs that the data‑channel opened
216+
if not self.th_server.event.wait(90):
217+
raise TimeoutError("PeerConnection is not connected within 90s")
218+
resp = 'Y'
219+
except TimeoutError:
220+
resp = 'N'
209221
else:
210222
resp = self.wait_for_user_input(prompt_msg)
211223

src/python_testing/TC_WEBRTCR_2_6.py

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
# === BEGIN CI TEST ARGUMENTS ===
2222
# test-runner-runs:
2323
# run1:
24+
# app: ${CAMERA_CONTROLLER_APP}
25+
# app-args: interactive server
2426
# script-args: >
2527
# --PICS src/app/tests/suites/certification/ci-pics-values
2628
# --storage-path admin_storage.json
@@ -38,14 +40,15 @@
3840
from time import sleep
3941

4042
from mobly import asserts
43+
from TC_WEBRTCRTestBase import WEBRTCRTestBase
4144

4245
import matter.clusters as Clusters
4346
from matter import ChipDeviceCtrl
4447
from matter.testing.apps import AppServerSubprocess
45-
from matter.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
48+
from matter.testing.matter_testing import TestStep, async_test_body, default_matter_test_main
4649

4750

48-
class TC_WebRTCR_2_6(MatterBaseTest):
51+
class TC_WebRTCR_2_6(WEBRTCRTestBase):
4952
def setup_class(self):
5053
super().setup_class()
5154

@@ -153,7 +156,7 @@ async def test_TC_WebRTCR_2_6(self):
153156
)
154157

155158
if self.is_pics_sdk_ci_only:
156-
# TODO: send command to DUT via websocket
159+
await self.send_command(f"pairing onnetwork 1 {passcode}")
157160
resp = 'Y'
158161
else:
159162
resp = self.wait_for_user_input(prompt_msg)
@@ -203,8 +206,17 @@ async def test_TC_WebRTCR_2_6(self):
203206
)
204207

205208
if self.is_pics_sdk_ci_only:
206-
# TODO: send command to DUT via websocket
207-
resp = 'Y'
209+
self.th_server.set_output_match("NOT_FOUND")
210+
self.th_server.event.clear()
211+
212+
try:
213+
await self.send_command("webrtc establish-session 1")
214+
# Wait up to 90s until the provider logs that the data‑channel opened
215+
if not self.th_server.event.wait(90):
216+
raise TimeoutError("PeerConnection is not connected within 90s")
217+
resp = 'Y'
218+
except TimeoutError:
219+
resp = 'N'
208220
else:
209221
resp = self.wait_for_user_input(prompt_msg)
210222

0 commit comments

Comments
 (0)