From 3873661a6005a640809ba5734aeef96ced779e59 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 9 Nov 2021 12:46:24 -0500 Subject: [PATCH] Fix YAML checking of return values handle lists and structs correctly (#11570) * Turn on checking of list contents for YAML tests. The change to CheckValue is to make it clearer which value is the actual value and which value is the expected value. The change to TestAttrAccess::ReadListInt8uAttribute is to make the actual value it produces match the expected value, in a way that keeps the values different from the indices. * Turn on checking of struct fields for YAML tests The CheckValueAsString change is just to show what the actual value was that does not match the expected value. The CheckValue (enum version) change is to make it compile, now that it's actually being used. --- .../chip-tool/commands/tests/TestCommand.cpp | 14 +- .../chip-tool/commands/tests/TestCommand.h | 91 ++++---- .../partials/test_cluster_value_equals.zapt | 32 ++- .../test-cluster-server.cpp | 6 +- .../tests/suites/TV_AudioOutputCluster.yaml | 6 +- .../tests/suites/TV_MediaInputCluster.yaml | 14 +- .../suites/TV_TargetNavigatorCluster.yaml | 6 +- src/app/tests/suites/TV_TvChannelCluster.yaml | 12 +- .../tests/suites/TestDescriptorCluster.yaml | 23 ++- .../suites/certification/Test_TC_DM_2_2.yaml | 4 +- .../common/ClusterTestGeneration.js | 79 +++---- .../chip-tool/zap-generated/test/Commands.h | 195 ++++++++++++++++-- 12 files changed, 336 insertions(+), 146 deletions(-) diff --git a/examples/chip-tool/commands/tests/TestCommand.cpp b/examples/chip-tool/commands/tests/TestCommand.cpp index 48d031bfac1af4..094e5e505db943 100644 --- a/examples/chip-tool/commands/tests/TestCommand.cpp +++ b/examples/chip-tool/commands/tests/TestCommand.cpp @@ -109,17 +109,6 @@ bool TestCommand::CheckConstraintMaxLength(const char * itemName, uint64_t curre return true; } -bool TestCommand::CheckValueAsList(const char * itemName, uint64_t current, uint64_t expected) -{ - if (current != expected) - { - Exit(std::string(itemName) + " count mismatch: " + std::to_string(current) + " != " + std::to_string(expected)); - return false; - } - - return true; -} - bool TestCommand::CheckValueAsString(const char * itemName, const chip::ByteSpan current, const char * expected) { const chip::ByteSpan expectedArgument = chip::ByteSpan(chip::Uint8::from_const_char(expected), strlen(expected)); @@ -138,7 +127,8 @@ bool TestCommand::CheckValueAsString(const char * itemName, const chip::CharSpan const chip::CharSpan expectedArgument(expected, strlen(expected)); if (!current.data_equal(expectedArgument)) { - Exit(std::string(itemName) + " value mismatch, expecting " + std::string(expected)); + Exit(std::string(itemName) + " value mismatch, expected '" + expected + "' but got '" + + std::string(current.data(), current.size()) + "'"); return false; } diff --git a/examples/chip-tool/commands/tests/TestCommand.h b/examples/chip-tool/commands/tests/TestCommand.h index 0e1c8ea9eb9b93..0cf358d260a559 100644 --- a/examples/chip-tool/commands/tests/TestCommand.h +++ b/examples/chip-tool/commands/tests/TestCommand.h @@ -106,7 +106,8 @@ class TestCommand : public CHIPCommand { if (current != expected) { - Exit(std::string(itemName) + " value mismatch: " + std::to_string(current) + " != " + std::to_string(expected)); + Exit(std::string(itemName) + " value mismatch: expected " + std::to_string(expected) + " but got " + + std::to_string(current)); return false; } @@ -116,78 +117,58 @@ class TestCommand : public CHIPCommand template ::value, int> = 0> bool CheckValue(const char * itemName, T current, U expected) { - return CheckValue(itemName, to_underlying(current), expected); + return CheckValue(itemName, chip::to_underlying(current), expected); } - bool CheckValueAsList(const char * itemName, uint64_t current, uint64_t expected); - - template - bool CheckValueAsListHelper(const char * itemName, typename chip::app::DataModel::DecodableList::Iterator iter) + /** + * Check that the next list item, which is at index "index", exists and + * decodes properly. + */ + template + bool CheckNextListItemDecodes(const char * listName, typename std::remove_reference_t::Iterator & iter, size_t index) { - if (iter.Next()) - { - Exit(std::string(itemName) + " value mismatch: expected no more items but found " + std::to_string(iter.GetValue())); - return false; - } + bool hasValue = iter.Next(); if (iter.GetStatus() != CHIP_NO_ERROR) { - Exit(std::string(itemName) + - " value mismatch: expected no more items but got an error: " + iter.GetStatus().AsString()); + Exit(std::string(listName) + " value mismatch: error '" + iter.GetStatus().AsString() + "'decoding item at index " + + std::to_string(index)); return false; } - return true; - } - template - bool CheckValueAsListHelper(const char * itemName, typename chip::app::DataModel::DecodableList::Iterator & iter, - const U & firstItem, ValueTypes &&... otherItems) - { - bool haveValue = iter.Next(); - if (iter.GetStatus() != CHIP_NO_ERROR) - { - Exit(std::string(itemName) + " value mismatch: expected " + std::to_string(firstItem) + - " but got error: " + iter.GetStatus().AsString()); - return false; - } - if (!haveValue) - { - Exit(std::string(itemName) + " value mismatch: expected " + std::to_string(firstItem) + - " but found nothing or an error"); - return false; - } - if (iter.GetValue() != firstItem) + if (hasValue) { - Exit(std::string(itemName) + " value mismatch: expected " + std::to_string(firstItem) + " but found " + - std::to_string(iter.GetValue())); - return false; + return true; } - return CheckValueAsListHelper(itemName, iter, std::forward(otherItems)...); - } - template - bool CheckValueAsList(const char * itemName, chip::app::DataModel::DecodableList list, ValueTypes &&... items) - { - auto iter = list.begin(); - return CheckValueAsListHelper(itemName, iter, std::forward(items)...); + Exit(std::string(listName) + " value mismatch: should have value at index " + std::to_string(index) + + " but doesn't (actual value too short)"); + return false; } - template - bool CheckValueAsListLength(const char * itemName, chip::app::DataModel::DecodableList list, uint64_t expectedLength) + /** + * Check that there are no more list items now that we have seen + * "expectedCount" of them. + */ + template + bool CheckNoMoreListItems(const char * listName, typename std::remove_reference_t::Iterator & iter, + size_t expectedCount) { - // We don't just use list.ComputeSize(), because we want to check that - // all the values in the list correctly decode to our type too. - auto iter = list.begin(); - uint64_t count = 0; - while (iter.Next()) - { - ++count; - } + bool hasValue = iter.Next(); if (iter.GetStatus() != CHIP_NO_ERROR) { - Exit(std::string(itemName) + " list length mismatch: expected " + std::to_string(expectedLength) + " but got an error"); + Exit(std::string(listName) + " value mismatch: error '" + iter.GetStatus().AsString() + + "'decoding item after we have seen " + std::to_string(expectedCount) + " items"); return false; } - return CheckValueAsList(itemName, count, expectedLength); + + if (!hasValue) + { + return true; + } + + Exit(std::string(listName) + " value mismatch: expected only " + std::to_string(expectedCount) + + " items, but have more than that (actual value too long)"); + return false; } bool CheckValueAsString(const char * itemName, chip::ByteSpan current, const char * expected); diff --git a/examples/chip-tool/templates/partials/test_cluster_value_equals.zapt b/examples/chip-tool/templates/partials/test_cluster_value_equals.zapt index d39aa60c2799e9..9fe0a9af1faf41 100644 --- a/examples/chip-tool/templates/partials/test_cluster_value_equals.zapt +++ b/examples/chip-tool/templates/partials/test_cluster_value_equals.zapt @@ -8,12 +8,30 @@ VerifyOrReturn(CheckValueNonNull("{{label}}", {{actual}})); {{>valueEquals label=(concat label ".Value()") actual=(concat actual ".Value()") expected=expected isNullable=false}} {{/if}} +{{else if isArray}} + auto iter = {{actual}}.begin(); + {{#each expected}} + VerifyOrReturn(CheckNextListItemDecodes("{{../label}}", iter, {{@index}})); + {{>valueEquals label=(concat ../label "[" @index "]") actual="iter.GetValue()" expected=this isArray=false type=../type chipType=../chipType}} + {{/each}} + VerifyOrReturn(CheckNoMoreListItems("{{label}}", iter, {{expected.length}})); {{else}} - VerifyOrReturn(CheckValue - {{~#if isList}}AsListLength("{{label}}", {{actual}}, {{expected.length}}) - {{else if isArray}}AsList("{{label}}", {{actual}}{{#if expected.length}}, {{expected}}{{/if}}) - {{else if (isString type)}}AsString("{{label}}", {{actual}}, "{{expected}}") - {{else}}<{{chipType}}>("{{label}}", {{actual}}, {{expected}}{{asTypeLiteralSuffix type}}) - {{/if}} - ); + {{#if_is_struct type}} + {{! Iterate over the actual types in the struct, so we pick up the right + type/optionality/nullability information for them for our recursive + call. }} + {{#zcl_struct_items_by_struct_name type}} + {{#if (expectedValueHasProp ../expected (asLowerCamelCase label))}} + {{>valueEquals label=(concat ../label "." (asLowerCamelCase label)) actual=(concat ../actual "." (asLowerCamelCase label)) expected=(lookup ../expected (asLowerCamelCase label))}} + {{/if}} + {{/zcl_struct_items_by_struct_name}} + {{! Maybe we should add a check for properties in the expected object (other + than "global") that are not present in the struct ? }} + {{else}} + VerifyOrReturn(CheckValue + {{~#if (isString type)}}AsString("{{label}}", {{actual}}, "{{expected}}") + {{else}}<{{chipType}}>("{{label}}", {{actual}}, {{expected}}{{asTypeLiteralSuffix type}}) + {{/if}} + ); + {{/if_is_struct}} {{/if}} diff --git a/src/app/clusters/test-cluster-server/test-cluster-server.cpp b/src/app/clusters/test-cluster-server/test-cluster-server.cpp index 689969833e948d..19c60d03ac2e65 100644 --- a/src/app/clusters/test-cluster-server/test-cluster-server.cpp +++ b/src/app/clusters/test-cluster-server/test-cluster-server.cpp @@ -129,10 +129,10 @@ EmberAfStatus writeTestListInt8uAttribute(EndpointId endpoint) CHIP_ERROR TestAttrAccess::ReadListInt8uAttribute(AttributeValueEncoder & aEncoder) { return aEncoder.EncodeList([](const TagBoundEncoder & encoder) -> CHIP_ERROR { - constexpr uint16_t attributeCount = 4; - for (uint8_t index = 0; index < attributeCount; index++) + constexpr uint8_t maxValue = 4; + for (uint8_t value = 1; value <= maxValue; value++) { - ReturnErrorOnFailure(encoder.Encode(index)); + ReturnErrorOnFailure(encoder.Encode(value)); } return CHIP_NO_ERROR; }); diff --git a/src/app/tests/suites/TV_AudioOutputCluster.yaml b/src/app/tests/suites/TV_AudioOutputCluster.yaml index f6116a67fa399f..642f02b61485b8 100644 --- a/src/app/tests/suites/TV_AudioOutputCluster.yaml +++ b/src/app/tests/suites/TV_AudioOutputCluster.yaml @@ -25,9 +25,9 @@ tests: response: value: [ - { index: 1, outputType: 0, name: 12 }, - { index: 2, outputType: 0, name: 12 }, - { index: 3, outputType: 0, name: 12 }, + { index: 1, outputType: 0, name: "exampleName" }, + { index: 2, outputType: 0, name: "exampleName" }, + { index: 3, outputType: 0, name: "exampleName" }, ] - label: "Select Output Command" diff --git a/src/app/tests/suites/TV_MediaInputCluster.yaml b/src/app/tests/suites/TV_MediaInputCluster.yaml index b07076486f99ff..fe7fe12e9a44ce 100644 --- a/src/app/tests/suites/TV_MediaInputCluster.yaml +++ b/src/app/tests/suites/TV_MediaInputCluster.yaml @@ -25,8 +25,18 @@ tests: response: value: [ - { index: 1, inputType: 4, name: 12, description: 19 }, - { index: 2, inputType: 4, name: 12, description: 19 }, + { + index: 1, + inputType: 4, + name: "exampleName", + description: "exampleDescription", + }, + { + index: 2, + inputType: 4, + name: "exampleName", + description: "exampleDescription", + }, ] - label: "Select Input Command" diff --git a/src/app/tests/suites/TV_TargetNavigatorCluster.yaml b/src/app/tests/suites/TV_TargetNavigatorCluster.yaml index 807f3e8010270d..83d85cdfd3723f 100644 --- a/src/app/tests/suites/TV_TargetNavigatorCluster.yaml +++ b/src/app/tests/suites/TV_TargetNavigatorCluster.yaml @@ -23,7 +23,11 @@ tests: command: "readAttribute" attribute: "Target Navigator List" response: - value: [{ identifier: 1, name: 12 }, { identifier: 2, name: 12 }] + value: + [ + { identifier: 1, name: "exampleName" }, + { identifier: 2, name: "exampleName" }, + ] - label: "Navigate Target Command" command: "NavigateTarget" diff --git a/src/app/tests/suites/TV_TvChannelCluster.yaml b/src/app/tests/suites/TV_TvChannelCluster.yaml index 31d92d203696c0..289fb04de607d7 100644 --- a/src/app/tests/suites/TV_TvChannelCluster.yaml +++ b/src/app/tests/suites/TV_TvChannelCluster.yaml @@ -28,16 +28,16 @@ tests: { majorNumber: 1, minorNumber: 2, - name: 12, - callSign: 13, - affiliateCallSign: 13, + name: "exampleName", + callSign: "exampleCSign", + affiliateCallSign: "exampleASign", }, { majorNumber: 2, minorNumber: 3, - name: 12, - callSign: 13, - affiliateCallSign: 13, + name: "exampleName", + callSign: "exampleCSign", + affiliateCallSign: "exampleASign", }, ] # TODO: Enable the test once struct response is supported diff --git a/src/app/tests/suites/TestDescriptorCluster.yaml b/src/app/tests/suites/TestDescriptorCluster.yaml index 2189baf294f3e9..25d05b0a9f0c88 100644 --- a/src/app/tests/suites/TestDescriptorCluster.yaml +++ b/src/app/tests/suites/TestDescriptorCluster.yaml @@ -29,9 +29,26 @@ tests: command: "readAttribute" attribute: "Server List" response: - value: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] - # CLUSTER_ID value is dummy 0 since yaml compares only the length of the List. - # right now + value: [ + 0x0003, # Identify + 0x001D, # Descriptor + 0x0028, # Basic Information + 0x0029, # OTA Software Update Provider + 0x002A, # OTA Software Update Requestor + 0x0030, # General Commissioning + 0x0031, # Network Commissioning + 0x0032, # Diagnostic Logs + 0x0033, # General Diagnostics + 0x0034, # Software Diagnostics + 0x0035, # Thread Network Diagnostiscs + 0x0036, # WiFi Network Diagnostics + 0x0037, # Ethernet Network Diagnostics + 0x003C, # Administrator Commissioning + 0x003E, # Operational Credentials + 0x0405, # Relative Humidity Measurement (why on EP0?) + 0xF000, # Binding + 0xF004, # Group Key Management + ] - label: "Read attribute Client list" command: "readAttribute" diff --git a/src/app/tests/suites/certification/Test_TC_DM_2_2.yaml b/src/app/tests/suites/certification/Test_TC_DM_2_2.yaml index 93febad7e71237..2260a43bee3ae2 100644 --- a/src/app/tests/suites/certification/Test_TC_DM_2_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_DM_2_2.yaml @@ -80,6 +80,8 @@ tests: command: "readAttribute" attribute: "TrustedRootCertificates" response: - value: [237] + # Can't check for the expected value here, since we don't know it. + # TODO: Check the length, at least? + # value: [237] constraints: type: list diff --git a/src/app/zap-templates/common/ClusterTestGeneration.js b/src/app/zap-templates/common/ClusterTestGeneration.js index 326cec63461e0b..f67e4c42ff4147 100644 --- a/src/app/zap-templates/common/ClusterTestGeneration.js +++ b/src/app/zap-templates/common/ClusterTestGeneration.js @@ -467,6 +467,42 @@ function chip_tests_item_response_type(options) return asPromise.call(this, promise, options); } +// test_cluster_command_value and test_cluster_value-equals are recursive partials using #each. At some point the |global| +// context is lost and it fails. Make sure to attach the global context as a property of the | value | +// that is evaluated. +function attachGlobal(global, value) +{ + if (Array.isArray(value)) { + value = value.map(v => attachGlobal(global, v)); + } else if (value instanceof Object) { + for (key in value) { + if (key == "global") { + continue; + } + value[key] = attachGlobal(global, value[key]); + } + } else if (value === null) { + value = new NullObject(); + } else { + switch (typeof value) { + case 'number': + value = new Number(value); + break; + case 'string': + value = new String(value); + break; + case 'boolean': + value = new Boolean(value); + break; + default: + throw new Error('Unsupported value: ' + JSON.stringify(value)); + } + } + + value.global = global; + return value; +} + function chip_tests_item_parameters(options) { const commandValues = this.arguments.values; @@ -494,41 +530,6 @@ function chip_tests_item_parameters(options) 'Missing "' + commandArg.name + '" in arguments list: \n\t* ' + commandValues.map(command => command.name).join('\n\t* ')); } - // test_cluster_command_value is a recursive partial using #each. At some point the |global| - // context is lost and it fails. Make sure to attach the global context as a property of the | value | - // that is evaluated. - function attachGlobal(global, value) - { - if (Array.isArray(value)) { - value = value.map(v => attachGlobal(global, v)); - } else if (value instanceof Object) { - for (key in value) { - if (key == "global") { - continue; - } - value[key] = attachGlobal(global, value[key]); - } - } else if (value === null) { - value = new NullObject(); - } else { - switch (typeof value) { - case 'number': - value = new Number(value); - break; - case 'string': - value = new String(value); - break; - case 'boolean': - value = new Boolean(value); - break; - default: - throw new Error('Unsupported value: ' + JSON.stringify(value)); - } - } - - value.global = global; - return value; - } commandArg.definedValue = attachGlobal(this.global, expected.value); return commandArg; @@ -558,7 +559,7 @@ function chip_tests_item_response_parameters(options) const expected = responseValues.splice(expectedIndex, 1)[0]; if ('value' in expected) { responseArg.hasExpectedValue = true; - responseArg.expectedValue = expected.value; + responseArg.expectedValue = attachGlobal(this.global, expected.value); } if ('constraints' in expected) { @@ -590,6 +591,11 @@ function isLiteralNull(value, options) return (value === null) || (value instanceof NullObject); } +function expectedValueHasProp(value, name) +{ + return name in value; +} + // // Module exports // @@ -601,3 +607,4 @@ exports.chip_tests_item_response_parameters = chip_tests_item_response_parameter exports.chip_tests_pics = chip_tests_pics; exports.isTestOnlyCluster = isTestOnlyCluster; exports.isLiteralNull = isLiteralNull; +exports.expectedValueHasProp = expectedValueHasProp; diff --git a/zzz_generated/chip-tool/zap-generated/test/Commands.h b/zzz_generated/chip-tool/zap-generated/test/Commands.h index 6a2ef2baa4ec1c..e97915bca48643 100644 --- a/zzz_generated/chip-tool/zap-generated/test/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/test/Commands.h @@ -13212,7 +13212,9 @@ class Test_TC_DM_2_2 : public TestCommand void OnSuccessResponse_0(const chip::app::DataModel::DecodableList< chip::app::Clusters::OperationalCredentials::Structs::FabricDescriptor::DecodableType> & fabricsList) { - VerifyOrReturn(CheckValueAsListLength("fabricsList", fabricsList, 1)); + auto iter = fabricsList.begin(); + VerifyOrReturn(CheckNextListItemDecodes("fabricsList", iter, 0)); + VerifyOrReturn(CheckNoMoreListItems("fabricsList", iter, 1)); NextTest(); } @@ -13260,7 +13262,7 @@ class Test_TC_DM_2_2 : public TestCommand void OnSuccessResponse_3(const chip::app::DataModel::DecodableList & trustedRootCertificates) { - VerifyOrReturn(CheckValueAsListLength("trustedRootCertificates", trustedRootCertificates, 1)); + VerifyOrReturn(CheckConstraintType("trustedRootCertificates", "", "list")); NextTest(); } }; @@ -23201,7 +23203,14 @@ class TV_TargetNavigatorCluster : public TestCommand const chip::app::DataModel::DecodableList< chip::app::Clusters::TargetNavigator::Structs::NavigateTargetTargetInfo::DecodableType> & targetNavigatorList) { - VerifyOrReturn(CheckValueAsListLength("targetNavigatorList", targetNavigatorList, 2)); + auto iter = targetNavigatorList.begin(); + VerifyOrReturn(CheckNextListItemDecodes("targetNavigatorList", iter, 0)); + VerifyOrReturn(CheckValue<>("targetNavigatorList[0].identifier", iter.GetValue().identifier, 1)); + VerifyOrReturn(CheckValueAsString("targetNavigatorList[0].name", iter.GetValue().name, "exampleName")); + VerifyOrReturn(CheckNextListItemDecodes("targetNavigatorList", iter, 1)); + VerifyOrReturn(CheckValue<>("targetNavigatorList[1].identifier", iter.GetValue().identifier, 2)); + VerifyOrReturn(CheckValueAsString("targetNavigatorList[1].name", iter.GetValue().name, "exampleName")); + VerifyOrReturn(CheckNoMoreListItems("targetNavigatorList", iter, 2)); NextTest(); } @@ -23325,7 +23334,20 @@ class TV_AudioOutputCluster : public TestCommand const chip::app::DataModel::DecodableList & audioOutputList) { - VerifyOrReturn(CheckValueAsListLength("audioOutputList", audioOutputList, 3)); + auto iter = audioOutputList.begin(); + VerifyOrReturn(CheckNextListItemDecodes("audioOutputList", iter, 0)); + VerifyOrReturn(CheckValue<>("audioOutputList[0].index", iter.GetValue().index, 1)); + VerifyOrReturn(CheckValue<>("audioOutputList[0].outputType", iter.GetValue().outputType, 0)); + VerifyOrReturn(CheckValueAsString("audioOutputList[0].name", iter.GetValue().name, "exampleName")); + VerifyOrReturn(CheckNextListItemDecodes("audioOutputList", iter, 1)); + VerifyOrReturn(CheckValue<>("audioOutputList[1].index", iter.GetValue().index, 2)); + VerifyOrReturn(CheckValue<>("audioOutputList[1].outputType", iter.GetValue().outputType, 0)); + VerifyOrReturn(CheckValueAsString("audioOutputList[1].name", iter.GetValue().name, "exampleName")); + VerifyOrReturn(CheckNextListItemDecodes("audioOutputList", iter, 2)); + VerifyOrReturn(CheckValue<>("audioOutputList[2].index", iter.GetValue().index, 3)); + VerifyOrReturn(CheckValue<>("audioOutputList[2].outputType", iter.GetValue().outputType, 0)); + VerifyOrReturn(CheckValueAsString("audioOutputList[2].name", iter.GetValue().name, "exampleName")); + VerifyOrReturn(CheckNoMoreListItems("audioOutputList", iter, 3)); NextTest(); } @@ -23495,7 +23517,12 @@ class TV_ApplicationLauncherCluster : public TestCommand void OnSuccessResponse_0(const chip::app::DataModel::DecodableList & applicationLauncherList) { - VerifyOrReturn(CheckValueAsListLength("applicationLauncherList", applicationLauncherList, 2)); + auto iter = applicationLauncherList.begin(); + VerifyOrReturn(CheckNextListItemDecodes("applicationLauncherList", iter, 0)); + VerifyOrReturn(CheckValue("applicationLauncherList[0]", iter.GetValue(), 123U)); + VerifyOrReturn(CheckNextListItemDecodes("applicationLauncherList", iter, 1)); + VerifyOrReturn(CheckValue("applicationLauncherList[1]", iter.GetValue(), 456U)); + VerifyOrReturn(CheckNoMoreListItems("applicationLauncherList", iter, 2)); NextTest(); } @@ -24499,7 +24526,20 @@ class TV_TvChannelCluster : public TestCommand const chip::app::DataModel::DecodableList & tvChannelList) { - VerifyOrReturn(CheckValueAsListLength("tvChannelList", tvChannelList, 2)); + auto iter = tvChannelList.begin(); + VerifyOrReturn(CheckNextListItemDecodes("tvChannelList", iter, 0)); + VerifyOrReturn(CheckValue<>("tvChannelList[0].majorNumber", iter.GetValue().majorNumber, 1U)); + VerifyOrReturn(CheckValue<>("tvChannelList[0].minorNumber", iter.GetValue().minorNumber, 2U)); + VerifyOrReturn(CheckValueAsString("tvChannelList[0].name", iter.GetValue().name, "exampleName")); + VerifyOrReturn(CheckValueAsString("tvChannelList[0].callSign", iter.GetValue().callSign, "exampleCSign")); + VerifyOrReturn(CheckValueAsString("tvChannelList[0].affiliateCallSign", iter.GetValue().affiliateCallSign, "exampleASign")); + VerifyOrReturn(CheckNextListItemDecodes("tvChannelList", iter, 1)); + VerifyOrReturn(CheckValue<>("tvChannelList[1].majorNumber", iter.GetValue().majorNumber, 2U)); + VerifyOrReturn(CheckValue<>("tvChannelList[1].minorNumber", iter.GetValue().minorNumber, 3U)); + VerifyOrReturn(CheckValueAsString("tvChannelList[1].name", iter.GetValue().name, "exampleName")); + VerifyOrReturn(CheckValueAsString("tvChannelList[1].callSign", iter.GetValue().callSign, "exampleCSign")); + VerifyOrReturn(CheckValueAsString("tvChannelList[1].affiliateCallSign", iter.GetValue().affiliateCallSign, "exampleASign")); + VerifyOrReturn(CheckNoMoreListItems("tvChannelList", iter, 2)); NextTest(); } @@ -24748,7 +24788,18 @@ class TV_MediaInputCluster : public TestCommand const chip::app::DataModel::DecodableList & mediaInputList) { - VerifyOrReturn(CheckValueAsListLength("mediaInputList", mediaInputList, 2)); + auto iter = mediaInputList.begin(); + VerifyOrReturn(CheckNextListItemDecodes("mediaInputList", iter, 0)); + VerifyOrReturn(CheckValue<>("mediaInputList[0].index", iter.GetValue().index, 1)); + VerifyOrReturn(CheckValue<>("mediaInputList[0].inputType", iter.GetValue().inputType, 4)); + VerifyOrReturn(CheckValueAsString("mediaInputList[0].name", iter.GetValue().name, "exampleName")); + VerifyOrReturn(CheckValueAsString("mediaInputList[0].description", iter.GetValue().description, "exampleDescription")); + VerifyOrReturn(CheckNextListItemDecodes("mediaInputList", iter, 1)); + VerifyOrReturn(CheckValue<>("mediaInputList[1].index", iter.GetValue().index, 2)); + VerifyOrReturn(CheckValue<>("mediaInputList[1].inputType", iter.GetValue().inputType, 4)); + VerifyOrReturn(CheckValueAsString("mediaInputList[1].name", iter.GetValue().name, "exampleName")); + VerifyOrReturn(CheckValueAsString("mediaInputList[1].description", iter.GetValue().description, "exampleDescription")); + VerifyOrReturn(CheckNoMoreListItems("mediaInputList", iter, 2)); NextTest(); } @@ -28410,7 +28461,16 @@ class TestCluster : public TestCommand void OnSuccessResponse_106(const chip::app::DataModel::DecodableList & listInt8u) { - VerifyOrReturn(CheckValueAsListLength("listInt8u", listInt8u, 4)); + auto iter = listInt8u.begin(); + VerifyOrReturn(CheckNextListItemDecodes("listInt8u", iter, 0)); + VerifyOrReturn(CheckValue("listInt8u[0]", iter.GetValue(), 1)); + VerifyOrReturn(CheckNextListItemDecodes("listInt8u", iter, 1)); + VerifyOrReturn(CheckValue("listInt8u[1]", iter.GetValue(), 2)); + VerifyOrReturn(CheckNextListItemDecodes("listInt8u", iter, 2)); + VerifyOrReturn(CheckValue("listInt8u[2]", iter.GetValue(), 3)); + VerifyOrReturn(CheckNextListItemDecodes("listInt8u", iter, 3)); + VerifyOrReturn(CheckValue("listInt8u[3]", iter.GetValue(), 4)); + VerifyOrReturn(CheckNoMoreListItems("listInt8u", iter, 4)); NextTest(); } @@ -28426,7 +28486,16 @@ class TestCluster : public TestCommand void OnSuccessResponse_107(const chip::app::DataModel::DecodableList & listOctetString) { - VerifyOrReturn(CheckValueAsListLength("listOctetString", listOctetString, 4)); + auto iter = listOctetString.begin(); + VerifyOrReturn(CheckNextListItemDecodes("listOctetString", iter, 0)); + VerifyOrReturn(CheckValueAsString("listOctetString[0]", iter.GetValue(), "Test0")); + VerifyOrReturn(CheckNextListItemDecodes("listOctetString", iter, 1)); + VerifyOrReturn(CheckValueAsString("listOctetString[1]", iter.GetValue(), "Test1")); + VerifyOrReturn(CheckNextListItemDecodes("listOctetString", iter, 2)); + VerifyOrReturn(CheckValueAsString("listOctetString[2]", iter.GetValue(), "Test2")); + VerifyOrReturn(CheckNextListItemDecodes("listOctetString", iter, 3)); + VerifyOrReturn(CheckValueAsString("listOctetString[3]", iter.GetValue(), "Test3")); + VerifyOrReturn(CheckNoMoreListItems("listOctetString", iter, 4)); NextTest(); } @@ -28444,7 +28513,20 @@ class TestCluster : public TestCommand const chip::app::DataModel::DecodableList & listStructOctetString) { - VerifyOrReturn(CheckValueAsListLength("listStructOctetString", listStructOctetString, 4)); + auto iter = listStructOctetString.begin(); + VerifyOrReturn(CheckNextListItemDecodes("listStructOctetString", iter, 0)); + VerifyOrReturn(CheckValue<>("listStructOctetString[0].fabricIndex", iter.GetValue().fabricIndex, 0ULL)); + VerifyOrReturn(CheckValueAsString("listStructOctetString[0].operationalCert", iter.GetValue().operationalCert, "Test0")); + VerifyOrReturn(CheckNextListItemDecodes("listStructOctetString", iter, 1)); + VerifyOrReturn(CheckValue<>("listStructOctetString[1].fabricIndex", iter.GetValue().fabricIndex, 1ULL)); + VerifyOrReturn(CheckValueAsString("listStructOctetString[1].operationalCert", iter.GetValue().operationalCert, "Test1")); + VerifyOrReturn(CheckNextListItemDecodes("listStructOctetString", iter, 2)); + VerifyOrReturn(CheckValue<>("listStructOctetString[2].fabricIndex", iter.GetValue().fabricIndex, 2ULL)); + VerifyOrReturn(CheckValueAsString("listStructOctetString[2].operationalCert", iter.GetValue().operationalCert, "Test2")); + VerifyOrReturn(CheckNextListItemDecodes("listStructOctetString", iter, 3)); + VerifyOrReturn(CheckValue<>("listStructOctetString[3].fabricIndex", iter.GetValue().fabricIndex, 3ULL)); + VerifyOrReturn(CheckValueAsString("listStructOctetString[3].operationalCert", iter.GetValue().operationalCert, "Test3")); + VerifyOrReturn(CheckNoMoreListItems("listStructOctetString", iter, 4)); NextTest(); } @@ -29049,7 +29131,26 @@ class TestClusterComplexTypes : public TestCommand void OnSuccessResponse_4(const chip::app::DataModel::DecodableList & arg1) { - VerifyOrReturn(CheckValueAsList("arg1", arg1, 9, 8, 7, 6, 5, 4, 3, 2, 1)); + auto iter = arg1.begin(); + VerifyOrReturn(CheckNextListItemDecodes("arg1", iter, 0)); + VerifyOrReturn(CheckValue("arg1[0]", iter.GetValue(), 9)); + VerifyOrReturn(CheckNextListItemDecodes("arg1", iter, 1)); + VerifyOrReturn(CheckValue("arg1[1]", iter.GetValue(), 8)); + VerifyOrReturn(CheckNextListItemDecodes("arg1", iter, 2)); + VerifyOrReturn(CheckValue("arg1[2]", iter.GetValue(), 7)); + VerifyOrReturn(CheckNextListItemDecodes("arg1", iter, 3)); + VerifyOrReturn(CheckValue("arg1[3]", iter.GetValue(), 6)); + VerifyOrReturn(CheckNextListItemDecodes("arg1", iter, 4)); + VerifyOrReturn(CheckValue("arg1[4]", iter.GetValue(), 5)); + VerifyOrReturn(CheckNextListItemDecodes("arg1", iter, 5)); + VerifyOrReturn(CheckValue("arg1[5]", iter.GetValue(), 4)); + VerifyOrReturn(CheckNextListItemDecodes("arg1", iter, 6)); + VerifyOrReturn(CheckValue("arg1[6]", iter.GetValue(), 3)); + VerifyOrReturn(CheckNextListItemDecodes("arg1", iter, 7)); + VerifyOrReturn(CheckValue("arg1[7]", iter.GetValue(), 2)); + VerifyOrReturn(CheckNextListItemDecodes("arg1", iter, 8)); + VerifyOrReturn(CheckValue("arg1[8]", iter.GetValue(), 1)); + VerifyOrReturn(CheckNoMoreListItems("arg1", iter, 9)); NextTest(); } @@ -29079,7 +29180,8 @@ class TestClusterComplexTypes : public TestCommand void OnSuccessResponse_5(const chip::app::DataModel::DecodableList & arg1) { - VerifyOrReturn(CheckValueAsList("arg1", arg1)); + auto iter = arg1.begin(); + VerifyOrReturn(CheckNoMoreListItems("arg1", iter, 0)); NextTest(); } @@ -29698,7 +29800,10 @@ class TestDescriptorCluster : public TestCommand void OnSuccessResponse_0( const chip::app::DataModel::DecodableList & deviceList) { - VerifyOrReturn(CheckValueAsListLength("deviceList", deviceList, 1)); + auto iter = deviceList.begin(); + VerifyOrReturn(CheckNextListItemDecodes("deviceList", iter, 0)); + VerifyOrReturn(CheckValue<>("deviceList[0].revision", iter.GetValue().revision, 1U)); + VerifyOrReturn(CheckNoMoreListItems("deviceList", iter, 1)); NextTest(); } @@ -29714,7 +29819,44 @@ class TestDescriptorCluster : public TestCommand void OnSuccessResponse_1(const chip::app::DataModel::DecodableList & serverList) { - VerifyOrReturn(CheckValueAsListLength("serverList", serverList, 18)); + auto iter = serverList.begin(); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 0)); + VerifyOrReturn(CheckValue("serverList[0]", iter.GetValue(), 3UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 1)); + VerifyOrReturn(CheckValue("serverList[1]", iter.GetValue(), 29UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 2)); + VerifyOrReturn(CheckValue("serverList[2]", iter.GetValue(), 40UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 3)); + VerifyOrReturn(CheckValue("serverList[3]", iter.GetValue(), 41UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 4)); + VerifyOrReturn(CheckValue("serverList[4]", iter.GetValue(), 42UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 5)); + VerifyOrReturn(CheckValue("serverList[5]", iter.GetValue(), 48UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 6)); + VerifyOrReturn(CheckValue("serverList[6]", iter.GetValue(), 49UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 7)); + VerifyOrReturn(CheckValue("serverList[7]", iter.GetValue(), 50UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 8)); + VerifyOrReturn(CheckValue("serverList[8]", iter.GetValue(), 51UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 9)); + VerifyOrReturn(CheckValue("serverList[9]", iter.GetValue(), 52UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 10)); + VerifyOrReturn(CheckValue("serverList[10]", iter.GetValue(), 53UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 11)); + VerifyOrReturn(CheckValue("serverList[11]", iter.GetValue(), 54UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 12)); + VerifyOrReturn(CheckValue("serverList[12]", iter.GetValue(), 55UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 13)); + VerifyOrReturn(CheckValue("serverList[13]", iter.GetValue(), 60UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 14)); + VerifyOrReturn(CheckValue("serverList[14]", iter.GetValue(), 62UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 15)); + VerifyOrReturn(CheckValue("serverList[15]", iter.GetValue(), 1029UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 16)); + VerifyOrReturn(CheckValue("serverList[16]", iter.GetValue(), 61440UL)); + VerifyOrReturn(CheckNextListItemDecodes("serverList", iter, 17)); + VerifyOrReturn(CheckValue("serverList[17]", iter.GetValue(), 61444UL)); + VerifyOrReturn(CheckNoMoreListItems("serverList", iter, 18)); NextTest(); } @@ -29730,7 +29872,8 @@ class TestDescriptorCluster : public TestCommand void OnSuccessResponse_2(const chip::app::DataModel::DecodableList & clientList) { - VerifyOrReturn(CheckValueAsListLength("clientList", clientList, 0)); + auto iter = clientList.begin(); + VerifyOrReturn(CheckNoMoreListItems("clientList", iter, 0)); NextTest(); } @@ -29746,7 +29889,12 @@ class TestDescriptorCluster : public TestCommand void OnSuccessResponse_3(const chip::app::DataModel::DecodableList & partsList) { - VerifyOrReturn(CheckValueAsListLength("partsList", partsList, 2)); + auto iter = partsList.begin(); + VerifyOrReturn(CheckNextListItemDecodes("partsList", iter, 0)); + VerifyOrReturn(CheckValue("partsList[0]", iter.GetValue(), 1U)); + VerifyOrReturn(CheckNextListItemDecodes("partsList", iter, 1)); + VerifyOrReturn(CheckValue("partsList[1]", iter.GetValue(), 2U)); + VerifyOrReturn(CheckNoMoreListItems("partsList", iter, 2)); NextTest(); } }; @@ -30384,7 +30532,20 @@ class TestModeSelectCluster : public TestCommand const chip::app::DataModel::DecodableList & supportedModes) { - VerifyOrReturn(CheckValueAsListLength("supportedModes", supportedModes, 3)); + auto iter = supportedModes.begin(); + VerifyOrReturn(CheckNextListItemDecodes("supportedModes", iter, 0)); + VerifyOrReturn(CheckValueAsString("supportedModes[0].label", iter.GetValue().label, "Black")); + VerifyOrReturn(CheckValue<>("supportedModes[0].mode", iter.GetValue().mode, 0)); + VerifyOrReturn(CheckValue<>("supportedModes[0].semanticTag", iter.GetValue().semanticTag, 0UL)); + VerifyOrReturn(CheckNextListItemDecodes("supportedModes", iter, 1)); + VerifyOrReturn(CheckValueAsString("supportedModes[1].label", iter.GetValue().label, "Cappuccino")); + VerifyOrReturn(CheckValue<>("supportedModes[1].mode", iter.GetValue().mode, 4)); + VerifyOrReturn(CheckValue<>("supportedModes[1].semanticTag", iter.GetValue().semanticTag, 0UL)); + VerifyOrReturn(CheckNextListItemDecodes("supportedModes", iter, 2)); + VerifyOrReturn(CheckValueAsString("supportedModes[2].label", iter.GetValue().label, "Espresso")); + VerifyOrReturn(CheckValue<>("supportedModes[2].mode", iter.GetValue().mode, 7)); + VerifyOrReturn(CheckValue<>("supportedModes[2].semanticTag", iter.GetValue().semanticTag, 0UL)); + VerifyOrReturn(CheckNoMoreListItems("supportedModes", iter, 3)); NextTest(); }