Skip to content

Commit

Permalink
[YAML] Add 'saveAs' support for CHAR_STRING and OCTET_STRING (#13541)
Browse files Browse the repository at this point in the history
  • Loading branch information
vivien-apple authored and pull[bot] committed Jan 22, 2024
1 parent 6d9e916 commit 3336402
Show file tree
Hide file tree
Showing 13 changed files with 1,475 additions and 26 deletions.
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

# 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
6 changes: 6 additions & 0 deletions src/darwin/Framework/CHIP/templates/partials/test_value.zapt
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

0 comments on commit 3336402

Please sign in to comment.