Skip to content
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

extract matter testing utilities to separate module #37309

Merged
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
998c3cc
extract utilities to separate module and mark them in original module…
asirko-soft Jan 29, 2025
54bbb3c
update build file to include utilities
asirko-soft Jan 29, 2025
5e486da
Use UserWarning instead of DeprecationWarning; Add type hint decorato…
asirko-soft Jan 29, 2025
ffb910b
lint code
asirko-soft Jan 29, 2025
95ffa2b
Merge branch 'master' into osirko_api_cleanup_extract-utilities
asirko-soft Jan 30, 2025
7b9c6a6
Merge branch 'master' into osirko_api_cleanup_extract-utilities
asirko-soft Jan 30, 2025
bf7f0db
fix incorrect signatures and return values
asirko-soft Jan 30, 2025
5276e70
adding missing alias and docstrings to utility methods
asirko-soft Jan 30, 2025
39cf68e
fix alias issue
asirko-soft Jan 30, 2025
1bd9b00
just update all the places where moved functiones are used
asirko-soft Jan 31, 2025
12e836b
remove commented out code
asirko-soft Jan 31, 2025
5a1a4fe
using direct aliases as requested in review
asirko-soft Feb 3, 2025
a816491
solit utilities to less general modules
asirko-soft Feb 6, 2025
86a464a
isort
asirko-soft Feb 6, 2025
1480b6e
rename types.py to matchers.py
asirko-soft Feb 6, 2025
7505489
rename type_matches to is_type
asirko-soft Feb 6, 2025
e093a0b
added docstrings and copyright to packages
asirko-soft Feb 6, 2025
5fdbc21
style fix
asirko-soft Feb 6, 2025
bbb911a
isort
asirko-soft Feb 6, 2025
6384035
point test_testing imports to original module for now
asirko-soft Feb 7, 2025
025cc48
add doctest for new modules
asirko-soft Feb 7, 2025
d8fb318
Merge branch 'master' into osirko_api_cleanup_extract-utilities
asirko-soft Feb 7, 2025
e258cde
Merge branch 'master' into osirko_api_cleanup_extract-utilities
asirko-soft Feb 7, 2025
b29c46a
this should fix build error, doctests will run when the module is imp…
asirko-soft Feb 7, 2025
c4c38e5
Merge remote-tracking branch 'upstream/master' into osirko_api_cleanu…
asirko-soft Feb 10, 2025
3b9525d
import modules as modules only; add ToDo to remove aliases in future
asirko-soft Feb 12, 2025
957957a
fix imports
asirko-soft Feb 12, 2025
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
4 changes: 2 additions & 2 deletions src/python_testing/TC_DA_1_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
import chip.clusters as Clusters
from chip.interaction_model import InteractionModelError, Status
from chip.testing.basic_composition import BasicCompositionTests
from chip.testing.matter_testing import (MatterBaseTest, TestStep, async_test_body, default_matter_test_main, hex_from_bytes,
type_matches)
from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
from chip.testing.utilities import hex_from_bytes, type_matches
from chip.tlv import TLVReader
from cryptography import x509
from cryptography.exceptions import InvalidSignature
Expand Down
3 changes: 2 additions & 1 deletion src/python_testing/TC_DA_1_5.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
import chip.clusters as Clusters
from chip import ChipDeviceCtrl
from chip.interaction_model import InteractionModelError, Status
from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main, hex_from_bytes, type_matches
from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main
from chip.testing.utilities import hex_from_bytes, type_matches
from chip.tlv import TLVReader
from cryptography import x509
from cryptography.hazmat.primitives import hashes
Expand Down
4 changes: 2 additions & 2 deletions src/python_testing/TC_DA_1_7.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
from typing import List, Optional

import chip.clusters as Clusters
from chip.testing.matter_testing import (MatterBaseTest, TestStep, async_test_body, bytes_from_hex, default_matter_test_main,
hex_from_bytes)
from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
from chip.testing.utilities import bytes_from_hex, hex_from_bytes
from cryptography.exceptions import InvalidSignature
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives.asymmetric import ec
Expand Down
2 changes: 1 addition & 1 deletion src/python_testing/TC_DEMTestBase.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import chip.clusters as Clusters
from chip.interaction_model import InteractionModelError, Status
from chip.testing.matter_testing import utc_time_in_matter_epoch
from chip.testing.utilities import utc_time_in_matter_epoch
from mobly import asserts

logger = logging.getLogger(__name__)
Expand Down
7 changes: 3 additions & 4 deletions src/python_testing/TC_DGGEN_2_4.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,8 @@
import chip.clusters as Clusters
from chip.clusters.Types import NullValue
from chip.interaction_model import InteractionModelError
from chip.testing.matter_testing import (MatterBaseTest, async_test_body, default_matter_test_main,
matter_epoch_us_from_utc_datetime, utc_datetime_from_matter_epoch_us,
utc_datetime_from_posix_time_ms)
from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main
from chip.testing.utilities import utc_datetime_from_matter_epoch_us, utc_datetime_from_posix_time_ms, utc_time_in_matter_epoch
from mobly import asserts

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -104,7 +103,7 @@ async def test_TC_DGGEN_2_4(self):

self.print_step("1b", "Write current time to DUT")
# Get current time in the correct format to set via command.
th_utc = matter_epoch_us_from_utc_datetime(desired_datetime=None)
th_utc = utc_time_in_matter_epoch(desired_datetime=None)

await self.set_time_in_timesync(th_utc)

Expand Down
3 changes: 2 additions & 1 deletion src/python_testing/TC_TIMESYNC_2_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@
import chip.clusters as Clusters
from chip.clusters.Types import NullValue
from chip.testing.matter_testing import (MatterBaseTest, default_matter_test_main, has_attribute, has_cluster,
run_if_endpoint_matches, utc_time_in_matter_epoch)
run_if_endpoint_matches)
from chip.testing.utilities import utc_time_in_matter_epoch
from mobly import asserts


Expand Down
9 changes: 2 additions & 7 deletions src/python_testing/TC_TIMESYNC_2_10.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,12 @@
import chip.clusters as Clusters
from chip.clusters.Types import NullValue
from chip.interaction_model import InteractionModelError
from chip.testing.matter_testing import (MatterBaseTest, SimpleEventCallback, async_test_body, default_matter_test_main,
utc_time_in_matter_epoch)
from chip.testing.matter_testing import MatterBaseTest, SimpleEventCallback, async_test_body, default_matter_test_main
from chip.testing.utilities import get_wait_seconds_from_set_time, utc_time_in_matter_epoch
from chip.tlv import uint
from mobly import asserts


def get_wait_seconds_from_set_time(set_time_matter_us: int, wait_seconds: int):
seconds_passed = int((utc_time_in_matter_epoch() - set_time_matter_us)/1000000)
return wait_seconds - seconds_passed


class TC_TIMESYNC_2_10(MatterBaseTest):
async def send_set_time_zone_cmd(self, tz: typing.List[Clusters.Objects.TimeSynchronization.Structs.TimeZoneStruct]) -> Clusters.Objects.TimeSynchronization.Commands.SetTimeZoneResponse:
ret = await self.send_single_cmd(cmd=Clusters.Objects.TimeSynchronization.Commands.SetTimeZone(timeZone=tz), endpoint=self.endpoint)
Expand Down
4 changes: 2 additions & 2 deletions src/python_testing/TC_TIMESYNC_2_11.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
import chip.clusters as Clusters
from chip.clusters.Types import NullValue
from chip.interaction_model import InteractionModelError
from chip.testing.matter_testing import (MatterBaseTest, SimpleEventCallback, async_test_body, default_matter_test_main,
get_wait_seconds_from_set_time, type_matches, utc_time_in_matter_epoch)
from chip.testing.matter_testing import MatterBaseTest, SimpleEventCallback, async_test_body, default_matter_test_main
from chip.testing.utilities import get_wait_seconds_from_set_time, type_matches, utc_time_in_matter_epoch
from chip.tlv import uint
from mobly import asserts

Expand Down
4 changes: 2 additions & 2 deletions src/python_testing/TC_TIMESYNC_2_12.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@
import chip.clusters as Clusters
from chip.clusters.Types import NullValue
from chip.interaction_model import InteractionModelError
from chip.testing.matter_testing import (MatterBaseTest, SimpleEventCallback, async_test_body, default_matter_test_main,
get_wait_seconds_from_set_time, type_matches, utc_time_in_matter_epoch)
from chip.testing.matter_testing import MatterBaseTest, SimpleEventCallback, async_test_body, default_matter_test_main
from chip.testing.utilities import get_wait_seconds_from_set_time, type_matches, utc_time_in_matter_epoch
from chip.tlv import uint
from mobly import asserts

Expand Down
4 changes: 2 additions & 2 deletions src/python_testing/TC_TIMESYNC_2_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@
import chip.clusters as Clusters
from chip.clusters.Types import NullValue
from chip.interaction_model import InteractionModelError
from chip.testing.matter_testing import (MatterBaseTest, async_test_body, compare_time, default_matter_test_main,
utc_time_in_matter_epoch)
from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main
from chip.testing.utilities import compare_time, utc_time_in_matter_epoch
from mobly import asserts


Expand Down
4 changes: 2 additions & 2 deletions src/python_testing/TC_TIMESYNC_2_4.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@

import chip.clusters as Clusters
from chip.interaction_model import InteractionModelError, Status
from chip.testing.matter_testing import (MatterBaseTest, async_test_body, default_matter_test_main, type_matches,
utc_time_in_matter_epoch)
from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main
from chip.testing.utilities import type_matches, utc_time_in_matter_epoch
from mobly import asserts


Expand Down
3 changes: 2 additions & 1 deletion src/python_testing/TC_TIMESYNC_2_5.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
import chip.clusters as Clusters
from chip.clusters.Types import NullValue
from chip.interaction_model import InteractionModelError, Status
from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main, utc_time_in_matter_epoch
from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main
from chip.testing.utilities import utc_time_in_matter_epoch
from mobly import asserts


Expand Down
4 changes: 2 additions & 2 deletions src/python_testing/TC_TIMESYNC_2_7.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
import chip.clusters as Clusters
from chip.clusters.Types import NullValue
from chip.interaction_model import InteractionModelError
from chip.testing.matter_testing import (MatterBaseTest, async_test_body, compare_time, default_matter_test_main, type_matches,
utc_time_in_matter_epoch)
from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main
from chip.testing.utilities import compare_time, type_matches, utc_time_in_matter_epoch
from chip.tlv import uint
from mobly import asserts

Expand Down
4 changes: 2 additions & 2 deletions src/python_testing/TC_TIMESYNC_2_8.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@
import chip.clusters as Clusters
from chip.clusters.Types import NullValue
from chip.interaction_model import InteractionModelError
from chip.testing.matter_testing import (MatterBaseTest, async_test_body, compare_time, default_matter_test_main, type_matches,
utc_time_in_matter_epoch)
from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main
from chip.testing.utilities import compare_time, type_matches, utc_time_in_matter_epoch
from chip.tlv import uint
from mobly import asserts

Expand Down
4 changes: 2 additions & 2 deletions src/python_testing/TC_TIMESYNC_2_9.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,8 @@
import chip.clusters as Clusters
from chip.clusters.Types import NullValue
from chip.interaction_model import InteractionModelError
from chip.testing.matter_testing import (MatterBaseTest, async_test_body, compare_time, default_matter_test_main, type_matches,
utc_time_in_matter_epoch)
from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main
from chip.testing.utilities import compare_time, type_matches, utc_time_in_matter_epoch
from chip.tlv import uint
from mobly import asserts

Expand Down
4 changes: 2 additions & 2 deletions src/python_testing/TC_VALCC_4_4.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
import chip.clusters as Clusters
from chip.clusters.Types import NullValue
from chip.interaction_model import InteractionModelError, Status
from chip.testing.matter_testing import (MatterBaseTest, TestStep, async_test_body, default_matter_test_main,
utc_time_in_matter_epoch)
from chip.testing.matter_testing import MatterBaseTest, TestStep, async_test_body, default_matter_test_main
from chip.testing.utilities import utc_time_in_matter_epoch
from mobly import asserts


Expand Down
3 changes: 2 additions & 1 deletion src/python_testing/TestCommissioningTimeSync.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
from chip import ChipDeviceCtrl
from chip.clusters.Types import NullValue
from chip.interaction_model import InteractionModelError, Status
from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main, utc_time_in_matter_epoch
from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main
from chip.testing.utilities import utc_time_in_matter_epoch
from mobly import asserts

# We don't have a good pipe between the c++ enums in CommissioningDelegate and python
Expand Down
5 changes: 2 additions & 3 deletions src/python_testing/TestMatterTestingSupport.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,12 @@

import chip.clusters as Clusters
from chip.clusters.Types import Nullable, NullValue
from chip.testing.matter_testing import (MatterBaseTest, async_test_body, compare_time, default_matter_test_main,
get_wait_seconds_from_set_time, parse_matter_test_args, type_matches,
utc_time_in_matter_epoch)
from chip.testing.matter_testing import MatterBaseTest, async_test_body, default_matter_test_main, parse_matter_test_args
from chip.testing.pics import parse_pics, parse_pics_xml
from chip.testing.taglist_and_topology_test import (TagProblem, create_device_type_list_for_root, create_device_type_lists,
find_tag_list_problems, find_tree_roots, flat_list_ok, get_all_children,
get_direct_children_of_root, parts_list_cycles, separate_endpoint_types)
from chip.testing.utilities import compare_time, get_wait_seconds_from_set_time, type_matches, utc_time_in_matter_epoch
from chip.tlv import uint
from mobly import asserts, signals

Expand Down
1 change: 1 addition & 0 deletions src/python_testing/matter_testing_infrastructure/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ pw_python_package("chip-testing-module") {
"chip/testing/spec_parsing.py",
"chip/testing/taglist_and_topology_test.py",
"chip/testing/tasks.py",
"chip/testing/utilities.py",
]
tests = [
"chip/testing/test_metadata.py",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import time
import typing
import uuid
from binascii import hexlify, unhexlify
from binascii import unhexlify
from dataclasses import asdict as dataclass_asdict
from dataclasses import dataclass, field
from datetime import datetime, timedelta, timezone
Expand All @@ -41,7 +41,17 @@
from itertools import chain
from typing import Any, Iterable, List, Optional, Tuple

from chip.tlv import float32, uint
from chip.testing.utilities import bytes_from_hex as bytes_from_hex
from chip.testing.utilities import cluster_id_str as cluster_id_str
from chip.testing.utilities import compare_time as compare_time
from chip.testing.utilities import get_wait_seconds_from_set_time as get_wait_seconds_from_set_time
from chip.testing.utilities import hex_from_bytes as hex_from_bytes
from chip.testing.utilities import id_str as id_str
from chip.testing.utilities import type_matches as type_matches
from chip.testing.utilities import utc_datetime_from_matter_epoch_us as utc_datetime_from_matter_epoch_us
from chip.testing.utilities import utc_datetime_from_posix_time_ms as utc_datetime_from_posix_time_ms
from chip.testing.utilities import utc_time_in_matter_epoch as utc_time_in_matter_epoch
from chip.tlv import uint

# isort: off

Expand Down Expand Up @@ -149,78 +159,6 @@ def get_default_paa_trust_store(root_path: pathlib.Path) -> pathlib.Path:
return pathlib.Path.cwd()


def type_matches(received_value, desired_type):
""" Checks if the value received matches the expected type.

Handles unpacking Nullable and Optional types and
compares list value types for non-empty lists.
"""
if typing.get_origin(desired_type) == typing.Union:
return any(type_matches(received_value, t) for t in typing.get_args(desired_type))
elif typing.get_origin(desired_type) == list:
if isinstance(received_value, list):
# Assume an empty list is of the correct type
return True if received_value == [] else any(type_matches(received_value[0], t) for t in typing.get_args(desired_type))
else:
return False
elif desired_type == uint:
return isinstance(received_value, int) and received_value >= 0
elif desired_type == float32:
return isinstance(received_value, float)
else:
return isinstance(received_value, desired_type)

# TODO(#31177): Need to add unit tests for all time conversion methods.


def utc_time_in_matter_epoch(desired_datetime: Optional[datetime] = None):
""" Returns the time in matter epoch in us.

If desired_datetime is None, it will return the current time.
"""
if desired_datetime is None:
utc_native = datetime.now(tz=timezone.utc)
else:
utc_native = desired_datetime
# Matter epoch is 0 hours, 0 minutes, 0 seconds on Jan 1, 2000 UTC
utc_th_delta = utc_native - datetime(2000, 1, 1, 0, 0, 0, 0, timezone.utc)
utc_th_us = int(utc_th_delta.total_seconds() * 1000000)
return utc_th_us


matter_epoch_us_from_utc_datetime = utc_time_in_matter_epoch


def utc_datetime_from_matter_epoch_us(matter_epoch_us: int) -> datetime:
"""Returns the given Matter epoch time as a usable Python datetime in UTC."""
delta_from_epoch = timedelta(microseconds=matter_epoch_us)
matter_epoch = datetime(2000, 1, 1, 0, 0, 0, 0, timezone.utc)

return matter_epoch + delta_from_epoch


def utc_datetime_from_posix_time_ms(posix_time_ms: int) -> datetime:
millis = posix_time_ms % 1000
seconds = posix_time_ms // 1000
return datetime.fromtimestamp(seconds, timezone.utc) + timedelta(milliseconds=millis)


def compare_time(received: int, offset: timedelta = timedelta(), utc: Optional[int] = None, tolerance: timedelta = timedelta(seconds=5)) -> None:
if utc is None:
utc = utc_time_in_matter_epoch()

# total seconds includes fractional for microseconds
expected = utc + offset.total_seconds() * 1000000
delta_us = abs(expected - received)
delta = timedelta(microseconds=delta_us)
asserts.assert_less_equal(delta, tolerance, "Received time is out of tolerance")


def get_wait_seconds_from_set_time(set_time_matter_us: int, wait_seconds: int):
seconds_passed = (utc_time_in_matter_epoch() - set_time_matter_us) // 1000000
return wait_seconds - seconds_passed


class SimpleEventCallback:
def __init__(self, name: str, expected_cluster_id: int, expected_event_id: int, output_queue: queue.SimpleQueue):
self._name = name
Expand Down Expand Up @@ -708,21 +646,6 @@ def get_attribute_string(self, cluster_id: int, attribute_id) -> str:
return f"Attribute {attribute_name} ({attribute_id}, 0x{attribute_id:04X})"


def id_str(id):
return f'{id} (0x{id:02x})'


def cluster_id_str(id):
if id in Clusters.ClusterObjects.ALL_CLUSTERS.keys():
s = Clusters.ClusterObjects.ALL_CLUSTERS[id].__name__
else:
s = "Unknown cluster"
try:
return f'{id_str(id)} {s}'
except TypeError:
return 'HERE IS THE PROBLEM'


@dataclass
class CustomCommissioningParameters:
commissioningParameters: CommissioningParameters
Expand Down Expand Up @@ -930,19 +853,6 @@ def stack(self) -> ChipStack:
return builtins.chipStack


def bytes_from_hex(hex: str) -> bytes:
"""Converts any `hex` string representation including `01:ab:cd` to bytes

Handles any whitespace including newlines, which are all stripped.
"""
return unhexlify("".join(hex.replace(":", "").replace(" ", "").split()))


def hex_from_bytes(b: bytes) -> str:
"""Converts a bytes object `b` into a hex string (reverse of bytes_from_hex)"""
return hexlify(b).decode("utf-8")


@dataclass
class TestStep:
test_plan_number: typing.Union[int, str]
Expand Down Expand Up @@ -2578,3 +2488,15 @@ def run_tests(test_class: MatterBaseTest, matter_test_config: MatterTestConfig,
if not run_tests_no_exit(test_class, matter_test_config, runner.get_loop(),
hooks, default_controller, external_stack):
sys.exit(1)


type_matches = type_matches
utc_time_in_matter_epoch = utc_time_in_matter_epoch
utc_datetime_from_matter_epoch_us = utc_datetime_from_matter_epoch_us
utc_datetime_from_posix_time_ms = utc_datetime_from_posix_time_ms
compare_time = compare_time
get_wait_seconds_from_set_time = get_wait_seconds_from_set_time
bytes_from_hex = bytes_from_hex
hex_from_bytes = hex_from_bytes
id_str = id_str
cluster_id_str = cluster_id_str
Loading
Loading