Skip to content

Commit

Permalink
[Fix] Proposed resolution of issue project-chip#230: remove PICS from…
Browse files Browse the repository at this point in the history
… timesync tests (project-chip#33953)

* Created proposed resolution of Github issue project-chip#230:
* Removed PICS from TC_TIMESYNC_2_1 and TC_TIMESYNC_2_2 in python_testing folder
* Added using the wait_for_user_input() to allow user to inform if certain features are present on DUT

* Updated TC_TIMESYNC_2_1 test:
* Now utilizes Clusters.TimeSynchronization.Bitmaps.Feature to check supported features on DUT in place of PICS or waiting for user input.

* Restyled by autopep8

* Applied stylization fix to TC_TIMESYNC_2_2 test
module as mentioned in restyled.io check.

* Restyled by autopep8

* Removed unnecessary pics_TC_TIMESYNC_2_1()
from TC_TIMESYNC_2_1 class as no longer needed with recent changes implemented.

* Updates to TC_TIMESYNC_2_1 and 2_2 test modules:
- Restored pics_TC_TIMESYNC_2_1 and pics_TC_TIMESYNC_2_2 functions
- Added if check for timesource attribute ID for test step 3 in TC_TIMESYNC_2_1 test module
- Updated endpoint variable to statically be set to 0

* Restyled by autopep8

* Updated TC_TIMESYNC_2_1 and TC_TIMESYNC_2_2:
- Changed method for getting attribute_list
-- now using get_single_attribute_expect_success() from matter_testing_support module
- Updated time source test step 5 to include if check in TC_TIMESYNC_2_2 test module to match with TC_TIMESYNC_2_1

* Restyled by autopep8

* Updated TC_TIMESYNC_2_2 with suggestions from Cecille

- Changed class name value assigned to time_cluster variable
- Updated timesync_attr_list and timesource_attr_id variables to contain time_cluster in value in place of Clusters.TimeSynchronization

* Apply suggestions from code review from Cecille

Adding these suggestions from Cecille after testing in local dev env

Co-authored-by: C Freeman <[email protected]>

---------

Co-authored-by: Restyled.io <[email protected]>
Co-authored-by: C Freeman <[email protected]>
  • Loading branch information
3 people authored Jul 6, 2024
1 parent bd2fef3 commit 6e31453
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 55 deletions.
92 changes: 39 additions & 53 deletions src/python_testing/TC_TIMESYNC_2_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,40 +41,47 @@ def pics_TC_TIMESYNC_2_1(self) -> list[str]:

@async_test_body
async def test_TC_TIMESYNC_2_1(self):
endpoint = 0

endpoint = self.user_params.get("endpoint", 0)
features = await self.read_single_attribute(dev_ctrl=self.default_controller, node_id=self.dut_node_id,
endpoint=endpoint, attribute=Clusters.TimeSynchronization.Attributes.FeatureMap)

self.supports_time_zone = bool(features & Clusters.TimeSynchronization.Bitmaps.Feature.kTimeZone)
self.supports_ntpc = bool(features & Clusters.TimeSynchronization.Bitmaps.Feature.kNTPClient)
self.supports_ntps = bool(features & Clusters.TimeSynchronization.Bitmaps.Feature.kNTPServer)
self.supports_trusted_time_source = bool(features & Clusters.TimeSynchronization.Bitmaps.Feature.kTimeSyncClient)

time_cluster = Clusters.TimeSynchronization
timesync_attr_list = time_cluster.Attributes.AttributeList
attribute_list = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=time_cluster, attribute=timesync_attr_list)
timesource_attr_id = time_cluster.Attributes.TimeSource.attribute_id

self.print_step(1, "Commissioning, already done")
attributes = Clusters.TimeSynchronization.Attributes

self.print_step(2, "Read Granularity attribute")
if self.check_pics("TIMESYNC.S.A0001"):
granularity_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.Granularity)
asserts.assert_less(granularity_dut, Clusters.TimeSynchronization.Enums.GranularityEnum.kUnknownEnumValue,
"Granularity is not in valid range")
else:
asserts.assert_true(False, "Granularity is a mandatory attribute and must be present in the PICS file")
granularity_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.Granularity)
asserts.assert_less(granularity_dut, Clusters.TimeSynchronization.Enums.GranularityEnum.kUnknownEnumValue,
"Granularity is not in valid range")

self.print_step(3, "Read TimeSource")
if self.check_pics("TIMESYNC.S.A0002"):
if timesource_attr_id in attribute_list:
time_source = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.TimeSource)
asserts.assert_less(time_source, Clusters.TimeSynchronization.Enums.TimeSourceEnum.kUnknownEnumValue,
"TimeSource is not in valid range")

self.print_step(4, "Read TrustedTimeSource")
if self.check_pics("TIMESYNC.S.A0003"):
if self.supports_trusted_time_source:
trusted_time_source = await self.read_ts_attribute_expect_success(endpoint=endpoint,
attribute=attributes.TrustedTimeSource)
if trusted_time_source is not NullValue:
asserts.assert_less_equal(trusted_time_source.fabricIndex, 0xFE,
"FabricIndex for the TrustedTimeSource is out of range")
asserts.assert_greater_equal(trusted_time_source.fabricIndex, 1,
"FabricIndex for the TrustedTimeSource is out of range")
elif self.check_pics("TIMESYNC.S.F03"):
asserts.assert_true(False, "TrustedTimeSource is mandatory if the TSC feature (TIMESYNC.S.F03) is supported")

self.print_step(5, "Read DefaultNTP")
if self.check_pics("TIMESYNC.S.A0004"):
if self.supports_ntpc:
default_ntp = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.DefaultNTP)
if default_ntp is not NullValue:
asserts.assert_less_equal(len(default_ntp), 128, "DefaultNTP length must be less than 128")
Expand All @@ -87,11 +94,9 @@ async def test_TC_TIMESYNC_2_1(self):
is_ip_addr = False
pass
asserts.assert_true(is_web_addr or is_ip_addr, "Returned DefaultNTP value is not a IP address or web address")
elif self.check_pics("TIMESYNC.S.F01"):
asserts.assert_true(False, "DefaultNTP is mandatory if the NTPC (TIMESYNC.S.F01) feature is supported")

self.print_step(6, "Read TimeZone")
if self.check_pics("TIMESYNC.S.A0005"):
if self.supports_time_zone:
tz_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.TimeZone)
asserts.assert_greater_equal(len(tz_dut), 1, "TimeZone must have at least one entry in the list")
asserts.assert_less_equal(len(tz_dut), 2, "TimeZone may have a maximum of two entries in the list")
Expand All @@ -104,11 +109,9 @@ async def test_TC_TIMESYNC_2_1(self):
asserts.assert_equal(tz_dut[0].validAt, 0, "TimeZone list first entry must have a 0 ValidAt time")
if len(tz_dut) > 1:
asserts.assert_not_equal(tz_dut[1].validAt, 0, "TimeZone list second entry must have a non-zero ValidAt time")
elif self.check_pics("TIMESYNC.S.F00"):
asserts.assert_true(False, "TimeZone is mandatory if the TZ (TIMESYNC.S.F00) feature is supported")

self.print_step(7, "Read DSTOffset")
if self.check_pics("TIMESYNC.S.A0006"):
if self.supports_time_zone:
dst_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.DSTOffset)
last_valid_until = -1
last_valid_starting = -1
Expand All @@ -121,28 +124,23 @@ async def test_TC_TIMESYNC_2_1(self):
last_valid_until = dst.validUntil
if dst.validUntil is NullValue or dst.validUntil is None:
asserts.assert_equal(dst, dst_dut[-1], "DSTOffset list must have Null ValidUntil at the end")
elif self.check_pics("TIMESYNC.S.F00"):
asserts.assert_true(False, "DSTOffset is mandatory if the TZ (TIMESYNC.S.F00) feature is supported")

self.print_step(8, "Read UTCTime")
if self.check_pics("TIMESYNC.S.A0000"):
utc_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.UTCTime)
if utc_dut is NullValue:
asserts.assert_equal(granularity_dut, Clusters.TimeSynchronization.Enums.GranularityEnum.kNoTimeGranularity)
else:
asserts.assert_not_equal(granularity_dut, Clusters.TimeSynchronization.Enums.GranularityEnum.kNoTimeGranularity)
if granularity_dut is Clusters.TimeSynchronization.Enums.GranularityEnum.kMinutesGranularity:
toleranace = timedelta(minutes=10)
else:
toleranace = timedelta(minutes=1)
delta_us = abs(utc_dut - utc_time_in_matter_epoch())
delta = timedelta(microseconds=delta_us)
asserts.assert_less_equal(delta, toleranace, "UTC time is not within tolerance of TH")
utc_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.UTCTime)
if utc_dut is NullValue:
asserts.assert_equal(granularity_dut, Clusters.TimeSynchronization.Enums.GranularityEnum.kNoTimeGranularity)
else:
asserts.assert_true(False, "UTCTime is a mandatory attribute and must be present in the PICS file")
asserts.assert_not_equal(granularity_dut, Clusters.TimeSynchronization.Enums.GranularityEnum.kNoTimeGranularity)
if granularity_dut is Clusters.TimeSynchronization.Enums.GranularityEnum.kMinutesGranularity:
toleranace = timedelta(minutes=10)
else:
toleranace = timedelta(minutes=1)
delta_us = abs(utc_dut - utc_time_in_matter_epoch())
delta = timedelta(microseconds=delta_us)
asserts.assert_less_equal(delta, toleranace, "UTC time is not within tolerance of TH")

self.print_step(9, "Read LocalTime")
if self.check_pics("TIMESYNC.S.A0007"):
if self.supports_time_zone:
utc_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.UTCTime)
local_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.LocalTime)
if utc_dut is NullValue:
Expand All @@ -155,45 +153,33 @@ async def test_TC_TIMESYNC_2_1(self):
delta = timedelta(microseconds=delta_us)
toleranace = timedelta(minutes=1)
asserts.assert_less_equal(delta, toleranace, "Local time caluclation is not within tolerance of calculated value")
elif self.check_pics("TIMESYNC.S.F00"):
asserts.assert_true(False, "LocalTime is mandatory if the TZ (TIMESYNC.S.F00) feature is supported")

self.print_step(10, "Read TimeZoneDatabase")
if self.check_pics("TIMESYNC.S.A0008"):
if self.supports_time_zone:
tz_db_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.TimeZoneDatabase)
asserts.assert_less(tz_db_dut, Clusters.TimeSynchronization.Enums.TimeZoneDatabaseEnum.kUnknownEnumValue,
"TimeZoneDatabase is not in valid range")
elif self.check_pics("TIMESYNC.S.F00"):
asserts.assert_true(False, "TimeZoneDatabase is mandatory if the TZ (TIMESYNC.S.F00) feature is supported")

self.print_step(11, "Read NTPServerAvailable")
if self.check_pics("TIMESYNC.S.A0009"):
if self.supports_ntps:
# bool typechecking happens in the test read functions, so all we need to do here is do the read
await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.NTPServerAvailable)
elif self.check_pics("TIMESYNC.S.F02"):
asserts.assert_true(False, "NTPServerAvailable is mandatory if the NTPS (TIMESYNC.S.F02) feature is supported")

self.print_step(12, "Read TimeZoneListMaxSize")
if self.check_pics("TIMESYNC.S.A000a"):
if self.supports_time_zone:
size = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.TimeZoneListMaxSize)
asserts.assert_greater_equal(size, 1, "TimeZoneListMaxSize must be at least 1")
asserts.assert_less_equal(size, 2, "TimeZoneListMaxSize must be max 2")
elif self.check_pics("TIMESYNC.S.F00"):
asserts.assert_true(False, "TimeZoneListMaxSize is mandatory if the TZ (TIMESYNC.S.F00) feature is supported")

self.print_step(13, "Read DSTOffsetListMaxSize")
if self.check_pics("TIMESYNC.S.A000b"):
if self.supports_time_zone:
size = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.DSTOffsetListMaxSize)
asserts.assert_greater_equal(size, 1, "DSTOffsetListMaxSize must be at least 1")
elif self.check_pics("TIMESYNC.S.F00"):
asserts.assert_true(False, "DSTOffsetListMaxSize is mandatory if the TZ (TIMESYNC.S.F00) feature is supported")

self.print_step(14, "Read SupportsDNSResolve")
if self.check_pics("TIMESYNC.S.A0004"):
# bool typechecking happens in the test read functions, so all we need to do here is do the read
# bool typechecking happens in the test read functions, so all we need to do here is do the read
if self.supports_ntpc:
await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.SupportsDNSResolve)
elif self.check_pics("TIMESYNC.S.F01"):
asserts.assert_true(False, "SupportsDNSResolve is mandatory if the NTPC (TIMESYNC.S.F01) feature is supported")


if __name__ == "__main__":
Expand Down
7 changes: 5 additions & 2 deletions src/python_testing/TC_TIMESYNC_2_2.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ async def test_TC_TIMESYNC_2_2(self):
# Time sync is required to be on endpoint 0 if it is present
endpoint = 0

time_cluster = Clusters.Objects.TimeSynchronization
time_cluster = Clusters.TimeSynchronization
timesync_attr_list = time_cluster.Attributes.AttributeList
attribute_list = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=time_cluster, attribute=timesync_attr_list)
timesource_attr_id = time_cluster.Attributes.TimeSource.attribute_id

self.print_step(1, "Commissioning, already done")
attributes = Clusters.TimeSynchronization.Attributes
Expand Down Expand Up @@ -85,7 +88,7 @@ async def test_TC_TIMESYNC_2_2(self):
compare_time(received=utc_dut, utc=th_utc, tolerance=tolerance)

self.print_step(5, "Read time source")
if self.check_pics("TIMESYNC.S.A0002"):
if timesource_attr_id in attribute_list:
source = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.TimeSource)
if utc_dut_initial is NullValue:
asserts.assert_equal(source, Clusters.Objects.TimeSynchronization.Enums.TimeSourceEnum.kAdmin)
Expand Down

0 comments on commit 6e31453

Please sign in to comment.