Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions src/python_testing/TC_WEBRTCRTestBase.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#
# Copyright (c) 2025 Project CHIP Authors
# All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import logging

import websockets

from matter.testing.matter_testing import MatterBaseTest

# WebSocket server URI for sending commands to the DUT
SERVER_URI = "ws://localhost:9002"


class WEBRTCRTestBase(MatterBaseTest):
"""
Base class for WebRTC Transport Requestor test cases.

Provides common functionality including:
- WebSocket-based command sending to the DUT
- Shared SERVER_URI constant
"""

async def send_command(self, command):
"""
Send a command to the DUT via WebSocket and wait for response.

Args:
command: The command string to send to the DUT

This method:
1. Connects to the WebSocket server at SERVER_URI
2. Sends the command
3. Waits for and receives the response
4. Logs the connection, command, and response status

Raises:
Exception: Re-raises any exceptions after logging them clearly
"""
try:
async with websockets.connect(SERVER_URI) as websocket:
logging.info(f"Connected to {SERVER_URI}")

# Send command
logging.info(f"Sending command: {command}")
await websocket.send(command)

# Receive response
await websocket.recv()
logging.info("Received command response")

except ConnectionRefusedError as e:
logging.error(f"Failed to connect to WebSocket server at {SERVER_URI}: Connection refused. "
f"Is the DUT WebSocket server running? Error: {e}")
raise

except websockets.exceptions.WebSocketException as e:
logging.error(f"WebSocket error while communicating with {SERVER_URI}: {e}")
raise

except OSError as e:
logging.error(f"Network error while connecting to {SERVER_URI}: {e}")
raise

except Exception as e:
logging.error(f"Unexpected error while sending command '{command}' to {SERVER_URI}: {e}")
raise
22 changes: 17 additions & 5 deletions src/python_testing/TC_WEBRTCR_2_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
# === BEGIN CI TEST ARGUMENTS ===
# test-runner-runs:
# run1:
# app: ${CAMERA_CONTROLLER_APP}
# app-args: interactive server
# script-args: >
# --PICS src/app/tests/suites/certification/ci-pics-values
# --storage-path admin_storage.json
Expand All @@ -38,14 +40,15 @@
from time import sleep

from mobly import asserts
from TC_WEBRTCRTestBase import WEBRTCRTestBase

import matter.clusters as Clusters
from matter import ChipDeviceCtrl
from matter.testing.apps import AppServerSubprocess
from matter.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
from matter.testing.matter_testing import TestStep, async_test_body, default_matter_test_main


class TC_WebRTCR_2_1(MatterBaseTest):
class TC_WebRTCR_2_1(WEBRTCRTestBase):
def setup_class(self):
super().setup_class()

Expand Down Expand Up @@ -152,7 +155,7 @@ async def test_TC_WebRTCR_2_1(self):
)

if self.is_pics_sdk_ci_only:
# TODO: send command to DUT via websocket
await self.send_command(f"pairing onnetwork 1 {passcode}")
resp = 'Y'
else:
resp = self.wait_for_user_input(prompt_msg)
Expand Down Expand Up @@ -201,8 +204,17 @@ async def test_TC_WebRTCR_2_1(self):
)

if self.is_pics_sdk_ci_only:
# TODO: send command to DUT via websocket
resp = 'Y'
self.th_server.set_output_match("NOT_FOUND")
self.th_server.event.clear()

try:
await self.send_command("webrtc establish-session 1 --offer-type 1")
# Wait up to 90s until the provider logs that the data‑channel opened
if not self.th_server.event.wait(90):
raise TimeoutError("PeerConnection is not connected within 90s")
resp = 'Y'
except TimeoutError:
resp = 'N'
else:
resp = self.wait_for_user_input(prompt_msg)

Expand Down
22 changes: 17 additions & 5 deletions src/python_testing/TC_WEBRTCR_2_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
# === BEGIN CI TEST ARGUMENTS ===
# test-runner-runs:
# run1:
# app: ${CAMERA_CONTROLLER_APP}
# app-args: interactive server
# script-args: >
# --PICS src/app/tests/suites/certification/ci-pics-values
# --storage-path admin_storage.json
Expand All @@ -38,14 +40,15 @@
from time import sleep

from mobly import asserts
from TC_WEBRTCRTestBase import WEBRTCRTestBase

import matter.clusters as Clusters
from matter import ChipDeviceCtrl
from matter.testing.apps import AppServerSubprocess
from matter.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
from matter.testing.matter_testing import TestStep, async_test_body, default_matter_test_main


class TC_WebRTCR_2_2(MatterBaseTest):
class TC_WebRTCR_2_2(WEBRTCRTestBase):
def setup_class(self):
super().setup_class()

Expand Down Expand Up @@ -152,7 +155,7 @@ async def test_TC_WebRTCR_2_2(self):
)

if self.is_pics_sdk_ci_only:
# TODO: send command to DUT via websocket
await self.send_command(f"pairing onnetwork 1 {passcode}")
resp = 'Y'
else:
resp = self.wait_for_user_input(prompt_msg)
Expand Down Expand Up @@ -201,8 +204,17 @@ async def test_TC_WebRTCR_2_2(self):
)

if self.is_pics_sdk_ci_only:
# TODO: send command to DUT via websocket
resp = 'Y'
self.th_server.set_output_match("NOT_FOUND")
self.th_server.event.clear()

try:
await self.send_command("webrtc establish-session 1")
# Wait up to 90s until the provider logs that the data‑channel opened
if not self.th_server.event.wait(90):
raise TimeoutError("PeerConnection is not connected within 90s")
resp = 'Y'
except TimeoutError:
resp = 'N'
else:
resp = self.wait_for_user_input(prompt_msg)

Expand Down
20 changes: 3 additions & 17 deletions src/python_testing/TC_WEBRTCR_2_3.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,14 @@
import os
import tempfile

import websockets
from mobly import asserts
from TC_WEBRTCRTestBase import WEBRTCRTestBase

from matter.testing.apps import AppServerSubprocess
from matter.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
from matter.testing.matter_testing import TestStep, async_test_body, default_matter_test_main

SERVER_URI = "ws://localhost:9002"


class TC_WebRTCR_2_3(MatterBaseTest):
class TC_WebRTCR_2_3(WEBRTCRTestBase):
def setup_class(self):
super().setup_class()

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

async def send_command(self, command):
async with websockets.connect(SERVER_URI) as websocket:
logging.info(f"Connected to {SERVER_URI}")

# Send command
logging.info(f"Sending command: {command}")
await websocket.send(command)

# Receive response
await websocket.recv()
logging.info("Received command response")

@async_test_body
async def test_TC_WebRTCR_2_3(self):
"""
Expand Down
20 changes: 3 additions & 17 deletions src/python_testing/TC_WEBRTCR_2_4.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,14 @@
import os
import tempfile

import websockets
from mobly import asserts
from TC_WEBRTCRTestBase import WEBRTCRTestBase

from matter.testing.apps import AppServerSubprocess
from matter.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
from matter.testing.matter_testing import TestStep, async_test_body, default_matter_test_main

SERVER_URI = "ws://localhost:9002"


class TC_WebRTCR_2_4(MatterBaseTest):
class TC_WebRTCR_2_4(WEBRTCRTestBase):
def setup_class(self):
super().setup_class()

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

async def send_command(self, command):
async with websockets.connect(SERVER_URI) as websocket:
logging.info(f"Connected to {SERVER_URI}")

# Send command
logging.info(f"Sending command: {command}")
await websocket.send(command)

# Receive response
await websocket.recv()
logging.info("Received command response")

@async_test_body
async def test_TC_WebRTCR_2_4(self):
"""
Expand Down
22 changes: 17 additions & 5 deletions src/python_testing/TC_WEBRTCR_2_5.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
# === BEGIN CI TEST ARGUMENTS ===
# test-runner-runs:
# run1:
# app: ${CAMERA_CONTROLLER_APP}
# app-args: interactive server
# script-args: >
# --PICS src/app/tests/suites/certification/ci-pics-values
# --storage-path admin_storage.json
Expand All @@ -38,13 +40,14 @@
from time import sleep

from mobly import asserts
from TC_WEBRTCRTestBase import WEBRTCRTestBase

from matter import ChipDeviceCtrl
from matter.testing.apps import AppServerSubprocess
from matter.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
from matter.testing.matter_testing import TestStep, async_test_body, default_matter_test_main


class TC_WebRTCR_2_5(MatterBaseTest):
class TC_WebRTCR_2_5(WEBRTCRTestBase):
def setup_class(self):
super().setup_class()

Expand Down Expand Up @@ -156,7 +159,7 @@ async def test_TC_WebRTCR_2_5(self):
)

if self.is_pics_sdk_ci_only:
# TODO: send command to DUT via websocket
await self.send_command(f"pairing onnetwork 1 {passcode}")
resp = 'Y'
else:
resp = self.wait_for_user_input(prompt_msg)
Expand Down Expand Up @@ -204,8 +207,17 @@ async def test_TC_WebRTCR_2_5(self):
)

if self.is_pics_sdk_ci_only:
# TODO: establish session via websocket
resp = 'Y'
self.th_server.set_output_match("PeerConnection State: Connected")
self.th_server.event.clear()

try:
await self.send_command("webrtc establish-session 1")
# Wait up to 90s until the provider logs that the data‑channel opened
if not self.th_server.event.wait(90):
raise TimeoutError("PeerConnection is not connected within 90s")
resp = 'Y'
except TimeoutError:
resp = 'N'
else:
resp = self.wait_for_user_input(prompt_msg)

Expand Down
22 changes: 17 additions & 5 deletions src/python_testing/TC_WEBRTCR_2_6.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
# === BEGIN CI TEST ARGUMENTS ===
# test-runner-runs:
# run1:
# app: ${CAMERA_CONTROLLER_APP}
# app-args: interactive server
# script-args: >
# --PICS src/app/tests/suites/certification/ci-pics-values
# --storage-path admin_storage.json
Expand All @@ -38,14 +40,15 @@
from time import sleep

from mobly import asserts
from TC_WEBRTCRTestBase import WEBRTCRTestBase

import matter.clusters as Clusters
from matter import ChipDeviceCtrl
from matter.testing.apps import AppServerSubprocess
from matter.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
from matter.testing.matter_testing import TestStep, async_test_body, default_matter_test_main


class TC_WebRTCR_2_6(MatterBaseTest):
class TC_WebRTCR_2_6(WEBRTCRTestBase):
def setup_class(self):
super().setup_class()

Expand Down Expand Up @@ -153,7 +156,7 @@ async def test_TC_WebRTCR_2_6(self):
)

if self.is_pics_sdk_ci_only:
# TODO: send command to DUT via websocket
await self.send_command(f"pairing onnetwork 1 {passcode}")
resp = 'Y'
else:
resp = self.wait_for_user_input(prompt_msg)
Expand Down Expand Up @@ -203,8 +206,17 @@ async def test_TC_WebRTCR_2_6(self):
)

if self.is_pics_sdk_ci_only:
# TODO: send command to DUT via websocket
resp = 'Y'
self.th_server.set_output_match("NOT_FOUND")
self.th_server.event.clear()

try:
await self.send_command("webrtc establish-session 1")
# Wait up to 90s until the provider logs that the data‑channel opened
if not self.th_server.event.wait(90):
raise TimeoutError("PeerConnection is not connected within 90s")
resp = 'Y'
except TimeoutError:
resp = 'N'
else:
resp = self.wait_for_user_input(prompt_msg)

Expand Down
Loading
Loading