From a73c4c2070fe5d7b7b37e1bb964e7146a77384c4 Mon Sep 17 00:00:00 2001 From: Jake Ororke Date: Fri, 14 Jun 2024 15:31:16 -0700 Subject: [PATCH 01/12] Created proposed resolution of Github issue #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 --- src/python_testing/TC_TIMESYNC_2_1.py | 104 ++++++++++---------------- src/python_testing/TC_TIMESYNC_2_2.py | 12 +-- 2 files changed, 44 insertions(+), 72 deletions(-) diff --git a/src/python_testing/TC_TIMESYNC_2_1.py b/src/python_testing/TC_TIMESYNC_2_1.py index 12e588b0424e11..df3f0e02216ecf 100644 --- a/src/python_testing/TC_TIMESYNC_2_1.py +++ b/src/python_testing/TC_TIMESYNC_2_1.py @@ -34,40 +34,40 @@ def pics_TC_TIMESYNC_2_1(self) -> list[str]: @async_test_body async def test_TC_TIMESYNC_2_1(self): + # Establishing features support + TSCfeat = self.wait_for_user_input(prompt_msg="Is TSC feature supported? (y or n)\n", input_msg="Is TSC feature supported? (y or n)\n", prompt_msg_placeholder="y or n") + NTPCfeat = self.wait_for_user_input(prompt_msg="Is NTPC feature supported? (y or n)\n", input_msg="Is NTPC feature supported? (y or n)\n", prompt_msg_placeholder="y or n", default_value='n') + NTPSfeat = self.wait_for_user_input(prompt_msg="Is NTPS feature supported? (y or n)\n", input_msg="Is NTPS feature supported? (y or n)\n", prompt_msg_placeholder="y or n", default_value='n') + TZfeat = self.wait_for_user_input(prompt_msg="Is TZ feature supported? (y or n)\n", input_msg="Is TZ feature supported? (y or n)\n", prompt_msg_placeholder="y or n") endpoint = self.user_params.get("endpoint", 0) 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"): - 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") + 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 TSCfeat == 'y': trusted_time_source = await self.read_ts_attribute_expect_success(endpoint=endpoint, - attribute=attributes.TrustedTimeSource) + 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") + "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") + "FabricIndex for the TrustedTimeSource is out of range") + self.print_step(5, "Read DefaultNTP") - if self.check_pics("TIMESYNC.S.A0004"): + if NTPCfeat == 'y': 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") @@ -80,11 +80,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 TZfeat == 'y': 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") @@ -97,45 +95,38 @@ 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 TZfeat == 'y': dst_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.DSTOffset) last_valid_until = -1 last_valid_starting = -1 for dst in dst_dut: asserts.assert_greater(dst.validStarting, last_valid_starting, - "DSTOffset list must be sorted by ValidStarting time") + "DSTOffset list must be sorted by ValidStarting time") last_valid_starting = dst.validStarting asserts.assert_greater_equal(dst.validStarting, last_valid_until, - "DSTOffset list must have every ValidStarting > ValidUntil of the previous entry") + "DSTOffset list must have every ValidStarting > ValidUntil of the previous entry") 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 TZfeat == 'y': 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: @@ -148,46 +139,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 TZfeat == 'y': 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 NTPSfeat == 'y': # 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 TZfeat == 'y': 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 TZfeat == 'y': 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 NTPCfeat == 'y': 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__": default_matter_test_main() diff --git a/src/python_testing/TC_TIMESYNC_2_2.py b/src/python_testing/TC_TIMESYNC_2_2.py index e80dcab0738181..dd4b549dba8707 100644 --- a/src/python_testing/TC_TIMESYNC_2_2.py +++ b/src/python_testing/TC_TIMESYNC_2_2.py @@ -23,15 +23,11 @@ from matter_testing_support import MatterBaseTest, async_test_body, compare_time, default_matter_test_main, utc_time_in_matter_epoch from mobly import asserts - class TC_TIMESYNC_2_2(MatterBaseTest): async def read_ts_attribute_expect_success(self, endpoint, attribute): cluster = Clusters.Objects.TimeSynchronization return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) - def pics_TC_TIMESYNC_2_2(self) -> list[str]: - return ["TIMESYNC.S"] - @async_test_body async def test_TC_TIMESYNC_2_2(self): @@ -78,11 +74,9 @@ 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"): - 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) - + 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) if __name__ == "__main__": default_matter_test_main() From c3d9b06584a0448c6d4e6977b848d915fc729cd4 Mon Sep 17 00:00:00 2001 From: Jake Ororke Date: Wed, 19 Jun 2024 10:48:14 -0700 Subject: [PATCH 02/12] 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. --- src/python_testing/TC_TIMESYNC_2_1.py | 33 ++++++++++++++------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/python_testing/TC_TIMESYNC_2_1.py b/src/python_testing/TC_TIMESYNC_2_1.py index df3f0e02216ecf..b796a68d850570 100644 --- a/src/python_testing/TC_TIMESYNC_2_1.py +++ b/src/python_testing/TC_TIMESYNC_2_1.py @@ -34,14 +34,15 @@ def pics_TC_TIMESYNC_2_1(self) -> list[str]: @async_test_body async def test_TC_TIMESYNC_2_1(self): - # Establishing features support - TSCfeat = self.wait_for_user_input(prompt_msg="Is TSC feature supported? (y or n)\n", input_msg="Is TSC feature supported? (y or n)\n", prompt_msg_placeholder="y or n") - NTPCfeat = self.wait_for_user_input(prompt_msg="Is NTPC feature supported? (y or n)\n", input_msg="Is NTPC feature supported? (y or n)\n", prompt_msg_placeholder="y or n", default_value='n') - NTPSfeat = self.wait_for_user_input(prompt_msg="Is NTPS feature supported? (y or n)\n", input_msg="Is NTPS feature supported? (y or n)\n", prompt_msg_placeholder="y or n", default_value='n') - TZfeat = self.wait_for_user_input(prompt_msg="Is TZ feature supported? (y or n)\n", input_msg="Is TZ feature supported? (y or n)\n", prompt_msg_placeholder="y or n") - 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) + self.print_step(1, "Commissioning, already done") attributes = Clusters.TimeSynchronization.Attributes @@ -56,7 +57,7 @@ async def test_TC_TIMESYNC_2_1(self): "TimeSource is not in valid range") self.print_step(4, "Read TrustedTimeSource") - if TSCfeat == 'y': + 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: @@ -67,7 +68,7 @@ async def test_TC_TIMESYNC_2_1(self): self.print_step(5, "Read DefaultNTP") - if NTPCfeat == 'y': + 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") @@ -82,7 +83,7 @@ async def test_TC_TIMESYNC_2_1(self): asserts.assert_true(is_web_addr or is_ip_addr, "Returned DefaultNTP value is not a IP address or web address") self.print_step(6, "Read TimeZone") - if TZfeat == 'y': + 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") @@ -97,7 +98,7 @@ async def test_TC_TIMESYNC_2_1(self): asserts.assert_not_equal(tz_dut[1].validAt, 0, "TimeZone list second entry must have a non-zero ValidAt time") self.print_step(7, "Read DSTOffset") - if TZfeat == 'y': + 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 @@ -126,7 +127,7 @@ async def test_TC_TIMESYNC_2_1(self): asserts.assert_less_equal(delta, toleranace, "UTC time is not within tolerance of TH") self.print_step(9, "Read LocalTime") - if TZfeat == 'y': + 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: @@ -141,30 +142,30 @@ async def test_TC_TIMESYNC_2_1(self): asserts.assert_less_equal(delta, toleranace, "Local time caluclation is not within tolerance of calculated value") self.print_step(10, "Read TimeZoneDatabase") - if TZfeat == 'y': + 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") self.print_step(11, "Read NTPServerAvailable") - if NTPSfeat == 'y': + 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) self.print_step(12, "Read TimeZoneListMaxSize") - if TZfeat == 'y': + 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") self.print_step(13, "Read DSTOffsetListMaxSize") - if TZfeat == 'y': + 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") self.print_step(14, "Read SupportsDNSResolve") # bool typechecking happens in the test read functions, so all we need to do here is do the read - if NTPCfeat == 'y': + if self.supports_ntpc: await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.SupportsDNSResolve) if __name__ == "__main__": From 7a1c96870474b87bf675a4d1b99cdf479f9ebff0 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Wed, 19 Jun 2024 17:51:36 +0000 Subject: [PATCH 03/12] Restyled by autopep8 --- src/python_testing/TC_TIMESYNC_2_1.py | 16 ++++++++-------- src/python_testing/TC_TIMESYNC_2_2.py | 2 ++ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/python_testing/TC_TIMESYNC_2_1.py b/src/python_testing/TC_TIMESYNC_2_1.py index b796a68d850570..4e20834f3b25e0 100644 --- a/src/python_testing/TC_TIMESYNC_2_1.py +++ b/src/python_testing/TC_TIMESYNC_2_1.py @@ -45,7 +45,7 @@ async def test_TC_TIMESYNC_2_1(self): self.print_step(1, "Commissioning, already done") attributes = Clusters.TimeSynchronization.Attributes - + self.print_step(2, "Read Granularity attribute") granularity_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.Granularity) asserts.assert_less(granularity_dut, Clusters.TimeSynchronization.Enums.GranularityEnum.kUnknownEnumValue, @@ -59,14 +59,13 @@ async def test_TC_TIMESYNC_2_1(self): self.print_step(4, "Read TrustedTimeSource") if self.supports_trusted_time_source: trusted_time_source = await self.read_ts_attribute_expect_success(endpoint=endpoint, - attribute=attributes.TrustedTimeSource) + 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") + "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") + "FabricIndex for the TrustedTimeSource is out of range") - self.print_step(5, "Read DefaultNTP") if self.supports_ntpc: default_ntp = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.DefaultNTP) @@ -104,10 +103,10 @@ async def test_TC_TIMESYNC_2_1(self): last_valid_starting = -1 for dst in dst_dut: asserts.assert_greater(dst.validStarting, last_valid_starting, - "DSTOffset list must be sorted by ValidStarting time") + "DSTOffset list must be sorted by ValidStarting time") last_valid_starting = dst.validStarting asserts.assert_greater_equal(dst.validStarting, last_valid_until, - "DSTOffset list must have every ValidStarting > ValidUntil of the previous entry") + "DSTOffset list must have every ValidStarting > ValidUntil of the previous entry") 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") @@ -151,7 +150,7 @@ async def test_TC_TIMESYNC_2_1(self): 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) - + self.print_step(12, "Read TimeZoneListMaxSize") if self.supports_time_zone: size = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.TimeZoneListMaxSize) @@ -168,5 +167,6 @@ async def test_TC_TIMESYNC_2_1(self): if self.supports_ntpc: await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.SupportsDNSResolve) + if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/TC_TIMESYNC_2_2.py b/src/python_testing/TC_TIMESYNC_2_2.py index dd4b549dba8707..d76f67409de2df 100644 --- a/src/python_testing/TC_TIMESYNC_2_2.py +++ b/src/python_testing/TC_TIMESYNC_2_2.py @@ -23,6 +23,7 @@ from matter_testing_support import MatterBaseTest, async_test_body, compare_time, default_matter_test_main, utc_time_in_matter_epoch from mobly import asserts + class TC_TIMESYNC_2_2(MatterBaseTest): async def read_ts_attribute_expect_success(self, endpoint, attribute): cluster = Clusters.Objects.TimeSynchronization @@ -78,5 +79,6 @@ async def test_TC_TIMESYNC_2_2(self): if utc_dut_initial is NullValue: asserts.assert_equal(source, Clusters.Objects.TimeSynchronization.Enums.TimeSourceEnum.kAdmin) + if __name__ == "__main__": default_matter_test_main() From beef977037ce5151e6248fa59cbbbe6711b43148 Mon Sep 17 00:00:00 2001 From: Jake Ororke Date: Wed, 19 Jun 2024 16:40:42 -0700 Subject: [PATCH 04/12] Applied stylization fix to TC_TIMESYNC_2_2 test module as mentioned in restyled.io check. --- src/python_testing/TC_TIMESYNC_2_2.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/python_testing/TC_TIMESYNC_2_2.py b/src/python_testing/TC_TIMESYNC_2_2.py index d76f67409de2df..dd4b549dba8707 100644 --- a/src/python_testing/TC_TIMESYNC_2_2.py +++ b/src/python_testing/TC_TIMESYNC_2_2.py @@ -23,7 +23,6 @@ from matter_testing_support import MatterBaseTest, async_test_body, compare_time, default_matter_test_main, utc_time_in_matter_epoch from mobly import asserts - class TC_TIMESYNC_2_2(MatterBaseTest): async def read_ts_attribute_expect_success(self, endpoint, attribute): cluster = Clusters.Objects.TimeSynchronization @@ -79,6 +78,5 @@ async def test_TC_TIMESYNC_2_2(self): if utc_dut_initial is NullValue: asserts.assert_equal(source, Clusters.Objects.TimeSynchronization.Enums.TimeSourceEnum.kAdmin) - if __name__ == "__main__": default_matter_test_main() From 3d8fd154809ac143e3a3c5b069cff3503a2096b6 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Wed, 19 Jun 2024 23:43:34 +0000 Subject: [PATCH 05/12] Restyled by autopep8 --- src/python_testing/TC_TIMESYNC_2_2.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/python_testing/TC_TIMESYNC_2_2.py b/src/python_testing/TC_TIMESYNC_2_2.py index dd4b549dba8707..d76f67409de2df 100644 --- a/src/python_testing/TC_TIMESYNC_2_2.py +++ b/src/python_testing/TC_TIMESYNC_2_2.py @@ -23,6 +23,7 @@ from matter_testing_support import MatterBaseTest, async_test_body, compare_time, default_matter_test_main, utc_time_in_matter_epoch from mobly import asserts + class TC_TIMESYNC_2_2(MatterBaseTest): async def read_ts_attribute_expect_success(self, endpoint, attribute): cluster = Clusters.Objects.TimeSynchronization @@ -78,5 +79,6 @@ async def test_TC_TIMESYNC_2_2(self): if utc_dut_initial is NullValue: asserts.assert_equal(source, Clusters.Objects.TimeSynchronization.Enums.TimeSourceEnum.kAdmin) + if __name__ == "__main__": default_matter_test_main() From 9c6aeaf3ad73f6f9f623b14b67171ab9fb23c847 Mon Sep 17 00:00:00 2001 From: Jake Ororke Date: Mon, 24 Jun 2024 14:44:54 -0700 Subject: [PATCH 06/12] Removed unnecessary pics_TC_TIMESYNC_2_1() from TC_TIMESYNC_2_1 class as no longer needed with recent changes implemented. --- src/python_testing/TC_TIMESYNC_2_1.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/python_testing/TC_TIMESYNC_2_1.py b/src/python_testing/TC_TIMESYNC_2_1.py index 4e20834f3b25e0..65ac90f7e25b37 100644 --- a/src/python_testing/TC_TIMESYNC_2_1.py +++ b/src/python_testing/TC_TIMESYNC_2_1.py @@ -29,9 +29,6 @@ async def read_ts_attribute_expect_success(self, endpoint, attribute): cluster = Clusters.Objects.TimeSynchronization return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) - def pics_TC_TIMESYNC_2_1(self) -> list[str]: - return ["TIMESYNC.S"] - @async_test_body async def test_TC_TIMESYNC_2_1(self): endpoint = self.user_params.get("endpoint", 0) From 91d13505e52af341ad8b0ddea3ad50934234e5cf Mon Sep 17 00:00:00 2001 From: Jake Ororke Date: Tue, 25 Jun 2024 13:26:31 -0700 Subject: [PATCH 07/12] 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 --- src/python_testing/TC_TIMESYNC_2_1.py | 24 +++++++++++++++++++----- src/python_testing/TC_TIMESYNC_2_2.py | 3 +++ 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/python_testing/TC_TIMESYNC_2_1.py b/src/python_testing/TC_TIMESYNC_2_1.py index 65ac90f7e25b37..1e891aa1b38702 100644 --- a/src/python_testing/TC_TIMESYNC_2_1.py +++ b/src/python_testing/TC_TIMESYNC_2_1.py @@ -29,29 +29,43 @@ async def read_ts_attribute_expect_success(self, endpoint, attribute): cluster = Clusters.Objects.TimeSynchronization return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + def pics_TC_TIMESYNC_2_1(self) -> list[str]: + return ["TIMESYNC.S"] + @async_test_body async def test_TC_TIMESYNC_2_1(self): - endpoint = self.user_params.get("endpoint", 0) + 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) + timesource_attr_id = Clusters.Objects.TimeSynchronization.Attributes.TimeSource.attribute_id + + # Reading attributes from DUT + timesync_attr_list = Clusters.Objects.TimeSynchronization.Attributes.AttributeList + read_request = await self.default_controller.ReadAttribute(self.dut_node_id, [timesync_attr_list]) + attributes_list = read_request[0] + + # Extracting gathered attributes dictionary values into a list containing only supported attribute ids + attribute_list_confined = list([values for values in attributes_list[list(attributes_list.keys())[0]].values()])[1] self.print_step(1, "Commissioning, already done") attributes = Clusters.TimeSynchronization.Attributes - + self.print_step(2, "Read Granularity attribute") 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") - 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") + if timesource_attr_id in attribute_list_confined: + 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.supports_trusted_time_source: diff --git a/src/python_testing/TC_TIMESYNC_2_2.py b/src/python_testing/TC_TIMESYNC_2_2.py index d76f67409de2df..a16168ddd532a8 100644 --- a/src/python_testing/TC_TIMESYNC_2_2.py +++ b/src/python_testing/TC_TIMESYNC_2_2.py @@ -29,6 +29,9 @@ async def read_ts_attribute_expect_success(self, endpoint, attribute): cluster = Clusters.Objects.TimeSynchronization return await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=attribute) + def pics_TC_TIMESYNC_2_2(self) -> list[str]: + return ["TIMESYNC.S"] + @async_test_body async def test_TC_TIMESYNC_2_2(self): From a2f059eca88e0ca53acdba55dc9c966dac8904b9 Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Tue, 25 Jun 2024 20:49:54 +0000 Subject: [PATCH 08/12] Restyled by autopep8 --- src/python_testing/TC_TIMESYNC_2_1.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/python_testing/TC_TIMESYNC_2_1.py b/src/python_testing/TC_TIMESYNC_2_1.py index 1e891aa1b38702..4ba14d5ba94372 100644 --- a/src/python_testing/TC_TIMESYNC_2_1.py +++ b/src/python_testing/TC_TIMESYNC_2_1.py @@ -38,13 +38,13 @@ async def test_TC_TIMESYNC_2_1(self): 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) - timesource_attr_id = Clusters.Objects.TimeSynchronization.Attributes.TimeSource.attribute_id - + timesource_attr_id = Clusters.Objects.TimeSynchronization.Attributes.TimeSource.attribute_id + # Reading attributes from DUT timesync_attr_list = Clusters.Objects.TimeSynchronization.Attributes.AttributeList read_request = await self.default_controller.ReadAttribute(self.dut_node_id, [timesync_attr_list]) @@ -55,7 +55,7 @@ async def test_TC_TIMESYNC_2_1(self): self.print_step(1, "Commissioning, already done") attributes = Clusters.TimeSynchronization.Attributes - + self.print_step(2, "Read Granularity attribute") granularity_dut = await self.read_ts_attribute_expect_success(endpoint=endpoint, attribute=attributes.Granularity) asserts.assert_less(granularity_dut, Clusters.TimeSynchronization.Enums.GranularityEnum.kUnknownEnumValue, From 3bfc575071045fbabb9a6471e584cfb06c1cca02 Mon Sep 17 00:00:00 2001 From: Jake Ororke Date: Wed, 26 Jun 2024 10:40:18 -0700 Subject: [PATCH 09/12] 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 --- src/python_testing/TC_TIMESYNC_2_1.py | 12 ++++-------- src/python_testing/TC_TIMESYNC_2_2.py | 10 +++++++--- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/python_testing/TC_TIMESYNC_2_1.py b/src/python_testing/TC_TIMESYNC_2_1.py index 4ba14d5ba94372..92d14faa7434f6 100644 --- a/src/python_testing/TC_TIMESYNC_2_1.py +++ b/src/python_testing/TC_TIMESYNC_2_1.py @@ -43,15 +43,11 @@ async def test_TC_TIMESYNC_2_1(self): 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) - timesource_attr_id = Clusters.Objects.TimeSynchronization.Attributes.TimeSource.attribute_id - # Reading attributes from DUT + time_cluster = Clusters.Objects.TimeSynchronization timesync_attr_list = Clusters.Objects.TimeSynchronization.Attributes.AttributeList - read_request = await self.default_controller.ReadAttribute(self.dut_node_id, [timesync_attr_list]) - attributes_list = read_request[0] - - # Extracting gathered attributes dictionary values into a list containing only supported attribute ids - attribute_list_confined = list([values for values in attributes_list[list(attributes_list.keys())[0]].values()])[1] + attribute_list = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=time_cluster, attribute=timesync_attr_list) + timesource_attr_id = Clusters.Objects.TimeSynchronization.Attributes.TimeSource.attribute_id self.print_step(1, "Commissioning, already done") attributes = Clusters.TimeSynchronization.Attributes @@ -62,7 +58,7 @@ async def test_TC_TIMESYNC_2_1(self): "Granularity is not in valid range") self.print_step(3, "Read TimeSource") - if timesource_attr_id in attribute_list_confined: + 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") diff --git a/src/python_testing/TC_TIMESYNC_2_2.py b/src/python_testing/TC_TIMESYNC_2_2.py index a16168ddd532a8..44ea2036bd8909 100644 --- a/src/python_testing/TC_TIMESYNC_2_2.py +++ b/src/python_testing/TC_TIMESYNC_2_2.py @@ -39,6 +39,9 @@ async def test_TC_TIMESYNC_2_2(self): endpoint = 0 time_cluster = Clusters.Objects.TimeSynchronization + timesync_attr_list = Clusters.Objects.TimeSynchronization.Attributes.AttributeList + attribute_list = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=time_cluster, attribute=timesync_attr_list) + timesource_attr_id = Clusters.Objects.TimeSynchronization.Attributes.TimeSource.attribute_id self.print_step(1, "Commissioning, already done") attributes = Clusters.TimeSynchronization.Attributes @@ -78,9 +81,10 @@ 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") - 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) + 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) if __name__ == "__main__": From 27a0140351950c61cfee82789db2cdc622e0542b Mon Sep 17 00:00:00 2001 From: "Restyled.io" Date: Wed, 26 Jun 2024 17:47:25 +0000 Subject: [PATCH 10/12] Restyled by autopep8 --- src/python_testing/TC_TIMESYNC_2_2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/TC_TIMESYNC_2_2.py b/src/python_testing/TC_TIMESYNC_2_2.py index 44ea2036bd8909..1d1453437fffd9 100644 --- a/src/python_testing/TC_TIMESYNC_2_2.py +++ b/src/python_testing/TC_TIMESYNC_2_2.py @@ -81,7 +81,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 timesource_attr_id in attribute_list: + 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) From 115de1953ac4c5cf91b06b607ec51d247a1f1095 Mon Sep 17 00:00:00 2001 From: Jake Ororke Date: Thu, 27 Jun 2024 09:32:37 -0700 Subject: [PATCH 11/12] 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 --- src/python_testing/TC_TIMESYNC_2_2.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/python_testing/TC_TIMESYNC_2_2.py b/src/python_testing/TC_TIMESYNC_2_2.py index c885f99baf28c4..949fac75f2f4f7 100644 --- a/src/python_testing/TC_TIMESYNC_2_2.py +++ b/src/python_testing/TC_TIMESYNC_2_2.py @@ -45,10 +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 - timesync_attr_list = Clusters.Objects.TimeSynchronization.Attributes.AttributeList + 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 = Clusters.Objects.TimeSynchronization.Attributes.TimeSource.attribute_id + timesource_attr_id = time_cluster.Attributes.TimeSource.attribute_id self.print_step(1, "Commissioning, already done") attributes = Clusters.TimeSynchronization.Attributes From 3ec7bbc585f36301db135c797c849f2fecf59f11 Mon Sep 17 00:00:00 2001 From: Jake Ororke Date: Thu, 27 Jun 2024 09:36:09 -0700 Subject: [PATCH 12/12] Apply suggestions from code review from Cecille Adding these suggestions from Cecille after testing in local dev env Co-authored-by: C Freeman --- src/python_testing/TC_TIMESYNC_2_1.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/python_testing/TC_TIMESYNC_2_1.py b/src/python_testing/TC_TIMESYNC_2_1.py index f2c0235f58662a..febaea6f1e9d49 100644 --- a/src/python_testing/TC_TIMESYNC_2_1.py +++ b/src/python_testing/TC_TIMESYNC_2_1.py @@ -51,10 +51,10 @@ async def test_TC_TIMESYNC_2_1(self): 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.Objects.TimeSynchronization - timesync_attr_list = Clusters.Objects.TimeSynchronization.Attributes.AttributeList + 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 = Clusters.Objects.TimeSynchronization.Attributes.TimeSource.attribute_id + timesource_attr_id = time_cluster.Attributes.TimeSource.attribute_id self.print_step(1, "Commissioning, already done") attributes = Clusters.TimeSynchronization.Attributes