Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[YAML] Add 'saveAs' support for CHAR_STRING and OCTET_STRING #13541

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions examples/chip-tool/templates/partials/test_cluster.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,23 @@ class {{filename}}: public TestCommand
{{/chip_tests_config}}
}

~{{filename}}()
{
{{#chip_tests_items}}
{{#chip_tests_item_response_parameters}}
{{#if saveAs}}
{{#if (isString type)}}
if ({{saveAs}}Buffer != nullptr)
{
chip::Platform::MemoryFree({{saveAs}}Buffer);
{{saveAs}}Buffer = nullptr;
}
{{/if}}
{{/if}}
{{/chip_tests_item_response_parameters}}
{{/chip_tests_items}}
}

/////////// TestCommand Interface /////////
void NextTest() override
{
Expand Down Expand Up @@ -75,6 +92,7 @@ class {{filename}}: public TestCommand
{{#chip_tests_items}}
{{#chip_tests_item_response_parameters}}
{{#if saveAs}}
{{~#if (isString type)}}{{#if (isOctetString type)}}uint8_t{{else}}char{{/if}} * {{saveAs}}Buffer = nullptr;{{/if~}}
{{chipType}} {{saveAs}};
{{/if}}
{{/chip_tests_item_response_parameters}}
Expand Down Expand Up @@ -357,8 +375,18 @@ class {{filename}}: public TestCommand
{{/if}}

{{#if saveAs}}
{{#if (isString type)}}
if ({{saveAs}}Buffer != nullptr)
{
chip::Platform::MemoryFree({{saveAs}}Buffer);
}
{{saveAs}}Buffer = static_cast<{{#if (isOctetString type)}}uint8_t{{else}}char{{/if}} *>(chip::Platform::MemoryAlloc({{>item}}.size()));
memcpy({{saveAs}}Buffer, {{>item}}.data(), {{>item}}.size());
{{saveAs}} = {{chipType}}({{saveAs}}Buffer, {{>item}}.size());
{{else}}
{{saveAs}} = {{>item}};
{{/if}}
{{/if}}
{{/chip_tests_item_response_parameters}}
{{#unless async}}NextTest();{{/unless}}
{{/if}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@

{{else}}
{{container}} =
{{#if_chip_enum type}}
{{~#if (chip_tests_variables_has definedValue)~}}
{{definedValue}};
{{else~}}
{{~#if_chip_enum type~}}
static_cast<{{zapTypeToEncodableClusterObjectType type ns=ns}}>({{definedValue}});
{{else if (isCharString type)}}
chip::Span<const char>("{{definedValue}}garbage: not in length on purpose", {{utf8StringLength definedValue}});
Expand All @@ -49,6 +52,8 @@
{{else}}
{{asTypedLiteral definedValue type}};
{{/if_is_bitmap}}
{{/if_chip_enum}}
{{/if_chip_enum~}}
{{~/if~}}

{{/if_is_struct}}
{{/if}}
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@
than "global") that are not present in the struct ? }}
{{else}}
VerifyOrReturn(CheckValue{{#if (isString type)}}AsString{{/if}}("{{label}}", {{actual}},
{{~#if (isOctetString type)}}chip::ByteSpan(chip::Uint8::from_const_char("{{octetStringEscapedForCLiteral expected}}"), {{expected.length}})
{{~#if (chip_tests_variables_has expected)}}{{expected}}
{{else if (isOctetString type)}}chip::ByteSpan(chip::Uint8::from_const_char("{{octetStringEscapedForCLiteral expected}}"), {{expected.length}})
{{else if (isCharString type)}}chip::CharSpan("{{expected}}", {{utf8StringLength expected}})
{{else if (chip_tests_config_has expected)}}m{{asUpperCamelCase expected}}.HasValue() ? m{{asUpperCamelCase expected}}.Value() : {{asTypedLiteral (chip_tests_config_get_default_value expected) (chip_tests_config_get_type expected)}}
{{else}}{{asTypedLiteral expected type}}
Expand Down
122 changes: 122 additions & 0 deletions src/app/tests/suites/TestSaveAs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -675,3 +675,125 @@ tests:
attribute: "vendor_id"
response:
value: readAttributeVendorIdDefaultValue

vivien-apple marked this conversation as resolved.
Show resolved Hide resolved
# Tests for CHAR_STRING

- label: "Read attribute char_string Default Value"
command: "readAttribute"
attribute: "char_string"
response:
saveAs: readAttributeCharStringDefaultValue
value: ""

- label:
"Read attribute char_string Default Value and compare to saved value"
command: "readAttribute"
attribute: "char_string"
response:
value: readAttributeCharStringDefaultValue

- label: "Write attribute char_string Not Default Value"
command: "writeAttribute"
attribute: "char_string"
arguments:
value: "NotDefault"

- label: "Read attribute char_string Not Default Value"
command: "readAttribute"
attribute: "char_string"
response:
saveAs: readAttributeCharStringNotDefaultValue
value: "NotDefault"
constraints:
notValue: readAttributeCharStringDefaultValue

- label:
"Read attribute char_string Not Default Value and compare to saved
value"
command: "readAttribute"
attribute: "char_string"
response:
value: readAttributeCharStringNotDefaultValue
constraints:
notValue: readAttributeCharStringDefaultValue

- label: "Write attribute char_string Not Default Value from saved value"
command: "writeAttribute"
attribute: "char_string"
arguments:
value: readAttributeCharStringNotDefaultValue

- label:
"Read attribute char_string Not Default Value and compare to expected
value"
command: "readAttribute"
attribute: "char_string"
response:
value: "NotDefault"

- label: "Write attribute char_string Default Value"
command: "writeAttribute"
attribute: "char_string"
arguments:
value: readAttributeCharStringDefaultValue

# Tests for OCTET_STRING

- label: "Read attribute octet_string Default Value"
command: "readAttribute"
attribute: "octet_string"
response:
saveAs: readAttributeOctetStringDefaultValue
value: ""

- label:
"Read attribute octet_string Default Value and compare to saved value"
command: "readAttribute"
attribute: "octet_string"
response:
value: readAttributeOctetStringDefaultValue

- label: "Write attribute octet_string Not Default Value"
command: "writeAttribute"
attribute: "octet_string"
arguments:
value: "NotDefault"

- label: "Read attribute octet_string Not Default Value"
command: "readAttribute"
attribute: "octet_string"
response:
saveAs: readAttributeOctetStringNotDefaultValue
value: "NotDefault"
constraints:
notValue: readAttributeOctetStringDefaultValue

- label:
"Read attribute octet_string Not Default Value and compare to saved
value"
command: "readAttribute"
attribute: "octet_string"
response:
value: readAttributeOctetStringNotDefaultValue
constraints:
notValue: readAttributeOctetStringDefaultValue

- label: "Write attribute octet_string Not Default Value from saved value"
command: "writeAttribute"
attribute: "octet_string"
arguments:
value: readAttributeOctetStringNotDefaultValue

- label:
"Read attribute octet_string Not Default Value and compare to expected
value"
command: "readAttribute"
attribute: "octet_string"
response:
value: "NotDefault"

- label: "Write attribute octet_string Default Value"
command: "writeAttribute"
attribute: "octet_string"
arguments:
value: readAttributeOctetStringDefaultValue
57 changes: 41 additions & 16 deletions src/app/zap-templates/common/ClusterTestGeneration.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,14 +288,19 @@ function setDefaultResponse(test)
throwError(test, errorStr);
}

const name = test.isAttribute ? test.attribute : test.event;
const name = test.isAttribute ? test.attribute : test.event;
const response = test[kResponseName];
if (hasResponseValue) {
test[kResponseName].values.push({ name : name, value : test[kResponseName].value, saveAs : test[kResponseName].saveAs });
const value = { name, value : response.value, saveAs : response.saveAs };
response.values.push(value);
}

if (hasResponseConstraints) {
test[kResponseName].values.push(
{ name : name, constraints : test[kResponseName].constraints, saveAs : test[kResponseName].saveAs });
let constraints = { name : name, constraints : response.constraints };
if ('saveAs' in response && !hasResponseValue) {
constraints.saveAs = response.saveAs;
}
response.values.push(constraints);
}

delete test[kResponseName].value;
Expand Down Expand Up @@ -503,12 +508,7 @@ function chip_tests_items(options)
return templateUtil.collectBlocks(this.tests, options, this);
}

function chip_tests_config(options)
{
return templateUtil.collectBlocks(this.variables.config, options, this);
}

function getConfigVariable(context, name)
function getVariable(context, key, name)
{
while (!('variables' in context) && context.parent) {
context = context.parent;
Expand All @@ -518,33 +518,55 @@ function getConfigVariable(context, name)
return null;
}

return context.variables.config.find(variable => variable.name == name);
return context.variables[key].find(variable => variable.name == name);
}

function getConfigVariableOrThrow(context, name)
function getVariableOrThrow(context, key, name)
{
const variable = getConfigVariable(context, name);
const variable = getVariable(context, key, name);
if (variable == null) {
throw new Error(`Variable ${name} can not be found`);
}
return variable;
}

function chip_tests_variables(options)
{
return templateUtil.collectBlocks(this.variables.tests, options, this);
}

function chip_tests_variables_has(name, options)
{
const variable = getVariable(this, 'tests', name);
return !!variable;
}

function chip_tests_variables_get_type(name, options)
{
const variable = getVariableOrThrow(this, 'tests', name);
return variable.type;
}

function chip_tests_config(options)
{
return templateUtil.collectBlocks(this.variables.config, options, this);
}

function chip_tests_config_has(name, options)
{
const variable = getConfigVariable(this, name);
const variable = getVariable(this, 'config', name);
return !!variable;
}

function chip_tests_config_get_default_value(name, options)
{
const variable = getConfigVariableOrThrow(this, name);
const variable = getVariableOrThrow(this, 'config', name);
return variable.defaultValue;
}

function chip_tests_config_get_type(name, options)
{
const variable = getConfigVariableOrThrow(this, name);
const variable = getVariableOrThrow(this, 'config', name);
return variable.type;
}

Expand Down Expand Up @@ -717,6 +739,9 @@ exports.chip_tests_config = chip_tests_config;
exports.chip_tests_config_has = chip_tests_config_has;
exports.chip_tests_config_get_default_value = chip_tests_config_get_default_value;
exports.chip_tests_config_get_type = chip_tests_config_get_type;
exports.chip_tests_variables = chip_tests_variables;
exports.chip_tests_variables_has = chip_tests_variables_has;
exports.chip_tests_variables_get_type = chip_tests_variables_get_type;
exports.isTestOnlyCluster = isTestOnlyCluster;
exports.isLiteralNull = isLiteralNull;
exports.octetStringEscapedForCLiteral = octetStringEscapedForCLiteral;
Expand Down
6 changes: 3 additions & 3 deletions src/darwin/Framework/CHIP/templates/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ function asTestValue()
}
}

function asObjectiveCBasicType(type)
function asObjectiveCBasicType(type, options)
{
if (StringHelper.isOctetString(type)) {
return 'NSData *';
return options.hash.is_mutable ? 'NSMutableData *' : 'NSData *';
} else if (StringHelper.isCharString(type)) {
return 'NSString *';
return options.hash.is_mutable ? 'NSMutableString *' : 'NSString *';
} else {
return ChipTypesHelper.asBasicType(this.chipType);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,13 @@
{{! Maybe we should add a check for properties in the expected object (other
than "global") that are not present in the struct ? }}
{{else}}
{{#if (isOctetString type)}}
{{#if (chip_tests_variables_has expected)}}
{{#if (isString type)}}
XCTAssertEqualObjects({{actual}}, {{expected}});
{{else}}
XCTAssertEqual([{{actual}} {{asObjectiveCNumberType "" type true}}Value], {{expected}});
{{/if}}
{{else if (isOctetString type)}}
XCTAssertTrue([{{actual}} isEqualToData:[[NSData alloc] initWithBytes:"{{octetStringEscapedForCLiteral expected}}" length:{{expected.length}}]]);
{{else if (isCharString type)}}
XCTAssertTrue([{{actual}} isEqualToString:@"{{expected}}"]);
Expand Down
12 changes: 11 additions & 1 deletion src/darwin/Framework/CHIP/templates/partials/test_cluster.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ bool testSendCluster{{parent.filename}}_{{asTestIndex index}}_{{asUpperCamelCase
{{/if}}
{{#chip_tests_item_response_parameters}}
{{#if saveAs}}
{{asBasicType chipType}} {{saveAs}};
{{asObjectiveCBasicType type is_mutable=true}} {{saveAs}};
{{/if}}
{{/chip_tests_item_response_parameters}}

Expand Down Expand Up @@ -103,8 +103,14 @@ ResponseHandler {{> subscribeDataCallback}} = nil;
{{> actualValue}}
{{>check_test_value actual="actualValue" expected=expectedValue cluster=../cluster}}
{{#if saveAs}}
{{#if (isOctetString type)}}
{{saveAs}} = [NSMutableData dataWithData:actualValue];
{{else if (isCharString type)}}
{{saveAs}} = [NSMutableString stringWithString:actualValue];
{{else}}
{{saveAs}} = [actualValue {{asObjectiveCNumberType "" type true}}Value];
{{/if}}
{{/if}}
}
{{/if}}
{{#if hasExpectedConstraints}}
Expand Down Expand Up @@ -177,7 +183,11 @@ ResponseHandler {{> subscribeDataCallback}} = nil;
XCTAssertFalse(actualValue == nil);
{{else}}
if (actualValue != nil) {
{{#if (isString type)}}
XCTAssertNotEqualObjects(actualValue, {{expectedConstraints.notValue}});
{{else}}
XCTAssertNotEqual([actualValue {{asObjectiveCNumberType "" type true}}Value], {{asTypedLiteral expectedConstraints.notValue type}});
{{/if}}
}
{{/if}}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@
{{/if_include_struct_item_value}}
{{/zcl_struct_items_by_struct_name}}

{{else if (chip_tests_variables_has definedValue)}}
{{#if (isString type)}}
{{target}} = [{{definedValue}} copy];
{{else}}
{{target}} = [NSNumber numberWith{{asObjectiveCNumberType definedValue type false}}:{{definedValue}}];
{{/if}}
{{else if (isCharString type)}}
{{target}} = @"{{definedValue}}";
{{else if (isOctetString type)}}
Expand Down
Loading