blob: 8838a59c23f04595aa4689144ed4f950771ac9ba [file] [log] [blame]
{{#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 isCommand}}
chip::Callback::Callback<void (*) ({{>failureArguments}})> {{>failureCallback}} { {{>failureResponse}}, this };
chip::Callback::Callback<void (*) ({{>successArguments}})> {{>successCallback}} { {{>successResponse}}, this };
{{/unless}}
{{/unless}}
{{/chip_tests_items}}
{{#chip_tests_items}}
{{#unless (isTestOnlyCluster cluster)}}
{{#unless isCommand}}
static void {{>failureResponse}}({{> failureArguments}})
{
(static_cast<{{filename}} *>(context))->OnFailureResponse_{{index}}(status);
}
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}}
{{/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}}
{{#*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="request" 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}}
{{chipType}} {{asLowerCamelCase name}}Argument =
{{#if (isOctetString type)}}
chip::ByteSpan(chip::Uint8::from_const_char("{{definedValue}}"), strlen("{{definedValue}}"))
{{else if (isCharString type)}}
chip::CharSpan("{{definedValue}}", strlen("{{definedValue}}"))
{{else}}
{{definedValue}}{{asTypeLiteralSuffix type}}
{{/if}};
{{/chip_tests_item_parameters}}
{{~#*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 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}}{{/inline}}
{{#if hasExpectedValue}}
VerifyOrReturn(CheckValue
{{~#if isList}}AsListLength("{{>item}}", {{>item}}, {{expectedValue.length}})
{{else if isArray}}AsList("{{>item}}", {{>item}}, {{expectedValue}})
{{else if (isString type)}}AsString("{{>item}}", {{>item}}, "{{expectedValue}}")
{{else}}<{{chipType}}>("{{>item}}", {{>item}}, {{expectedValue}}{{asTypeLiteralSuffix type}})
{{/if}}
);
{{/if}}
{{#if hasExpectedConstraints}}
{{#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}}