| {{#chip_tests tests}} |
| class {{filename}}: public TestCommand |
| { |
| public: |
| {{filename}}(): TestCommand("{{filename}}"), mTestIndex(0) {} |
| |
| /////////// TestCommand Interface ///////// |
| void NextTest() override |
| { |
| CHIP_ERROR err = CHIP_NO_ERROR; |
| |
| if (0 == mTestIndex) |
| { |
| ChipLogProgress(chipTool, " **** Test Start: {{filename}}\n"); |
| } |
| |
| if (mTestCount == mTestIndex) |
| { |
| ChipLogProgress(chipTool, " **** Test Complete: {{filename}}\n"); |
| SetCommandExitStatus(CHIP_NO_ERROR); |
| return; |
| } |
| |
| Wait(); |
| |
| // Ensure we increment mTestIndex before we start running the relevant |
| // command. That way if we lose the timeslice after we send the message |
| // but before our function call returns, we won't end up with an |
| // incorrect mTestIndex value observed when we get the response. |
| switch (mTestIndex++) |
| { |
| {{#chip_tests_items}} |
| case {{index}}: |
| ChipLogProgress(chipTool, " ***** Test Step {{index}} : {{label}}\n"); |
| err = Test{{asUpperCamelCase label}}_{{index}}(); |
| break; |
| {{/chip_tests_items}} |
| } |
| |
| if (CHIP_NO_ERROR != err) |
| { |
| ChipLogError(chipTool, " ***** Test Failure: %s\n", chip::ErrorStr(err)); |
| SetCommandExitStatus(err); |
| } |
| } |
| |
| |
| private: |
| std::atomic_uint16_t mTestIndex; |
| const uint16_t mTestCount = {{totalTests}}; |
| |
| {{#*inline "failureCallback"}}mOnFailureCallback_{{index}}{{/inline}} |
| {{#*inline "successCallback"}}mOnSuccessCallback_{{index}}{{/inline}} |
| {{#*inline "failureResponse"}}OnFailureCallback_{{index}}{{/inline}} |
| {{#*inline "successResponse"}}OnSuccessCallback_{{index}}{{/inline}} |
| {{#*inline "successArguments"}}void * context{{#chip_tests_item_response_parameters}}, {{zapTypeToDecodableClusterObjectType type ns=parent.cluster isArgument=true}} {{asLowerCamelCase name}}{{/chip_tests_item_response_parameters}}{{/inline}} |
| {{#*inline "failureArguments"}}void * context, uint8_t status{{/inline}} |
| |
| {{#chip_tests_items}} |
| {{#unless (isTestOnlyCluster cluster)}} |
| {{#unless isWait}} |
| {{#unless isCommand}} |
| {{#unless isWriteAttribute}} |
| chip::Callback::Callback<void (*) ({{>failureArguments}})> {{>failureCallback}} { {{>failureResponse}}, this }; |
| chip::Callback::Callback<void (*) ({{>successArguments}})> {{>successCallback}} { {{>successResponse}}, this }; |
| {{/unless}} |
| {{/unless}} |
| {{/unless}} |
| {{/unless}} |
| {{/chip_tests_items}} |
| |
| {{#chip_tests_items}} |
| {{#unless (isTestOnlyCluster cluster)}} |
| {{#unless isWait}} |
| {{#unless isCommand}} |
| {{#if isWriteAttribute}} |
| static void {{>failureResponse}}(void * context, EmberAfStatus status) |
| { |
| (static_cast<{{filename}} *>(context))->OnFailureResponse_{{index}}(chip::to_underlying(status)); |
| } |
| {{else}} |
| static void {{>failureResponse}}({{> failureArguments}}) |
| { |
| (static_cast<{{filename}} *>(context))->OnFailureResponse_{{index}}(status); |
| } |
| {{/if}} |
| |
| |
| static void {{>successResponse}}({{> successArguments}}) |
| { |
| (static_cast<{{filename}} *>(context))->OnSuccessResponse_{{index}}({{#chip_tests_item_response_parameters}}{{#not_first}}, {{/not_first}}{{asLowerCamelCase name}}{{/chip_tests_item_response_parameters}}); |
| } |
| |
| {{! "isWaitForReport" can be replaced by "async" if there is a mechanism to remove the report handler}} |
| {{#if isWaitForReport}} |
| bool mReceivedReport_{{index}} = false; |
| {{/if}} |
| |
| {{/unless}} |
| {{/unless}} |
| {{/unless}} |
| {{/chip_tests_items}} |
| |
| // |
| // Tests methods |
| // |
| |
| {{#chip_tests_items}} |
| {{#*inline "testCommand"}}Test{{asUpperCamelCase label}}_{{index}}{{/inline}} |
| {{#if (isTestOnlyCluster cluster)}} |
| CHIP_ERROR {{>testCommand}}() |
| { |
| return {{command}}({{#chip_tests_item_parameters}}{{#not_first}}, {{/not_first}}{{#if (isString type)}}"{{/if}}{{definedValue}}{{#if (isString type)}}"{{/if}}{{/chip_tests_item_parameters}}); |
| } |
| {{else if isWait}} |
| CHIP_ERROR {{>testCommand}}() |
| { |
| ChipLogError(chipTool, "[Endpoint: {{endpoint}} Cluster: {{cluster}} {{#if isAttribute}}Attribute: {{attribute}}{{else}}Command: {{wait}}{{/if}}] {{label}}"); |
| {{#*inline "waitForTypeName"}}{{#if isAttribute}}Attribute{{else}}Command{{/if}}{{/inline}} |
| {{#*inline "waitForTypeId"}}chip::app::Clusters::{{asUpperCamelCase cluster}}::{{#if isAttribute}}Attributes::{{attribute}}{{else}}Commands::{{wait}}{{/if}}::Id{{/inline}} |
| ClearAttributeAndCommandPaths(); |
| m{{>waitForTypeName}}Path = chip::app::Concrete{{>waitForTypeName}}Path({{endpoint}}, chip::app::Clusters::{{asUpperCamelCase cluster}}::Id, {{>waitForTypeId}}); |
| return CHIP_NO_ERROR; |
| } |
| {{else}} |
| {{#*inline "failureResponse"}}OnFailureResponse_{{index}}{{/inline}} |
| {{#*inline "successResponse"}}OnSuccessResponse_{{index}}{{/inline}} |
| {{#*inline "failureArguments"}}uint8_t status{{/inline}} |
| {{#*inline "successArguments"}}{{#chip_tests_item_response_parameters}}{{#not_first}}, {{/not_first}}{{zapTypeToDecodableClusterObjectType type ns=parent.cluster isArgument=true}} {{asLowerCamelCase name}}{{/chip_tests_item_response_parameters}}{{/inline}} |
| |
| CHIP_ERROR {{>testCommand}}() |
| { |
| chip::Controller::{{asUpperCamelCase cluster}}ClusterTest cluster; |
| cluster.Associate(mDevice, {{endpoint}}); |
| |
| {{#if isCommand}} |
| using requestType = chip::app::Clusters::{{asUpperCamelCase cluster}}::Commands::{{asUpperCamelCase command}}::Type; |
| using responseType = chip::app::{{chip_tests_item_response_type}}; |
| |
| chip::app::Clusters::{{asUpperCamelCase cluster}}::Commands::{{asUpperCamelCase command}}::Type request; |
| {{#chip_tests_item_parameters}} |
| {{>commandValue ns=parent.cluster container=(concat "request." (asLowerCamelCase label)) definedValue=definedValue}} |
| {{/chip_tests_item_parameters}} |
| |
| auto success = [](void * context, const responseType & data) { |
| (static_cast<{{filename}} *>(context))->OnSuccessResponse_{{index}}({{#chip_tests_item_response_parameters}}{{#not_first}}, {{/not_first}}data.{{asLowerCamelCase name}}{{/chip_tests_item_response_parameters}}); |
| }; |
| |
| auto failure = [](void * context, EmberAfStatus status) { |
| (static_cast<{{filename}} *>(context))->OnFailureResponse_{{index}}(status); |
| }; |
| {{#if async}}ReturnErrorOnFailure({{else}}return {{/if}}cluster.InvokeCommand<requestType, responseType>(request, this, success, failure){{#if async}}){{/if}}; |
| {{else}} |
| {{#chip_tests_item_parameters}} |
| {{zapTypeToEncodableClusterObjectType type ns=parent.cluster}} {{asLowerCamelCase name}}Argument; |
| {{>commandValue ns=parent.cluster container=(concat (asLowerCamelCase name) "Argument") definedValue=definedValue}} |
| {{/chip_tests_item_parameters}} |
| |
| {{#if isWriteAttribute}} |
| {{#*inline "failureResponse"}}OnFailureCallback_{{index}}{{/inline}} |
| {{#*inline "successResponse"}}OnSuccessCallback_{{index}}{{/inline}} |
| {{#if async}}ReturnErrorOnFailure({{else}}return {{/if}}cluster.WriteAttribute<chip::app::Clusters::{{asUpperCamelCase cluster}}::Attributes::{{asUpperCamelCase attribute}}::TypeInfo>({{#chip_tests_item_parameters}}{{asLowerCamelCase name}}Argument, {{/chip_tests_item_parameters}}this, {{>successResponse}}, {{>failureResponse}}){{#if async}}){{/if}}; |
| {{else}} |
| {{~#*inline "commandName"}}{{asUpperCamelCase commandName}}{{#if isAttribute}}Attribute{{asUpperCamelCase attribute}}{{/if}}{{/inline}} |
| {{#if async}}ReturnErrorOnFailure({{else}}return {{/if}}cluster.{{>commandName}}({{>successCallback}}.Cancel(){{#unless isWaitForReport}}, {{>failureCallback}}.Cancel(){{/unless}}{{#chip_tests_item_parameters}}, {{asLowerCamelCase name}}Argument{{/chip_tests_item_parameters}}){{#if async}}){{/if}}; |
| {{/if}} |
| |
| {{/if}} |
| {{#if async}}return WaitForMs(0);{{/if}} |
| } |
| |
| void {{>failureResponse}}({{>failureArguments}}) |
| { |
| {{~#unless response.error}} |
| {{#if optional}}(status == EMBER_ZCL_STATUS_UNSUPPORTED_ATTRIBUTE) ? NextTest() : {{/if}}ThrowFailureResponse(); |
| {{else}} |
| {{#unless async}}NextTest();{{/unless}} |
| {{/unless}} |
| } |
| |
| void {{>successResponse}}({{>successArguments}}) |
| { |
| {{~#if response.error}} |
| ThrowSuccessResponse(); |
| {{else}} |
| {{! This block can be removed if there is a mechanism to remove the report handler}} |
| {{#if isWaitForReport}} |
| VerifyOrReturn(mReceivedReport_{{index}} == false, ChipLogError(chipTool, "Not Fatal: on report called more than once.")); |
| mReceivedReport_{{index}} = true; |
| {{/if}} |
| {{#if hasWaitForReport}} |
| VerifyOrReturn(mReceivedReport_{{waitForReport.index}}, Exit("Initial report not received!")); |
| {{/if}} |
| {{#chip_tests_item_response_parameters}} |
| {{~#*inline "item"}}{{asLowerCamelCase name}}{{#if isOptional}}.Value(){{/if}}{{/inline}} |
| {{~#*inline "itemValue"}}{{>item}}{{#if isNullable}}.Value(){{/if}}{{/inline}} |
| {{#if hasExpectedValue}} |
| {{#if isOptional}} |
| {{~#*inline "item"}}{{asLowerCamelCase name}}{{/inline}} |
| VerifyOrReturn(CheckValuePresent("{{> item}}", {{> item}})); |
| {{/if}} |
| {{#if (isLiteralNull expectedValue)}} |
| VerifyOrReturn(CheckValueNull("{{> item}}", {{> item}})); |
| {{else}} |
| {{#if isNullable}} |
| VerifyOrReturn(CheckValueNonNull("{{> item}}", {{> item}})); |
| {{/if}} |
| VerifyOrReturn(CheckValue |
| {{~#if isList}}AsListLength("{{>itemValue}}", {{>itemValue}}, {{expectedValue.length}}) |
| {{else if isArray}}AsList("{{>itemValue}}", {{>itemValue}}{{#if expectedValue.length}}, {{expectedValue}}{{/if}}) |
| {{else if (isString type)}}AsString("{{>itemValue}}", {{>itemValue}}, "{{expectedValue}}") |
| {{else}}<{{chipType}}>("{{>itemValue}}", {{>itemValue}}, {{expectedValue}}{{asTypeLiteralSuffix type}}) |
| {{/if}} |
| ); |
| {{/if}} |
| {{/if}} |
| {{#if hasExpectedConstraints}} |
| {{#if isOptional}} |
| {{~#*inline "item"}}{{asLowerCamelCase name}}{{/inline}} |
| VerifyOrReturn(CheckValuePresent("{{> item}}", {{> item}})); |
| {{/if}} |
| {{#if expectedConstraints.type}}VerifyOrReturn(CheckConstraintType("{{>item}}", "", "{{expectedConstraints.type}}"));{{/if}} |
| {{~#if expectedConstraints.format}}VerifyOrReturn(CheckConstraintFormat("{{>item}}", "", "{{expectedConstraints.format}}"));{{/if}} |
| {{~#if expectedConstraints.minLength}}VerifyOrReturn(CheckConstraintMinLength("{{>item}}", {{>item}}.size(), {{expectedConstraints.minLength}}));{{/if}} |
| {{~#if expectedConstraints.maxLength}}VerifyOrReturn(CheckConstraintMaxLength("{{>item}}", {{>item}}.size(), {{expectedConstraints.maxLength}}));{{/if}} |
| {{~#if expectedConstraints.minValue}}VerifyOrReturn(CheckConstraintMinValue<{{chipType}}>("{{>item}}", {{>item}}, {{expectedConstraints.minValue}}));{{/if}} |
| {{~#if expectedConstraints.maxValue}}VerifyOrReturn(CheckConstraintMaxValue<{{chipType}}>("{{>item}}", {{>item}}, {{expectedConstraints.maxValue}}));{{/if}} |
| {{~#if expectedConstraints.notValue}}VerifyOrReturn(CheckConstraintNotValue<{{chipType}}>("{{>item}}", {{>item}}, {{expectedConstraints.notValue}}));{{/if}} |
| {{/if}} |
| {{/chip_tests_item_response_parameters}} |
| {{#unless async}}NextTest();{{/unless}} |
| {{/if}} |
| } |
| |
| {{/if}} |
| {{/chip_tests_items}} |
| }; |
| |
| {{/chip_tests}} |