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 a mechanism to declare command line variables directly from YAML and support it inside chip-tool #13115

Merged
merged 2 commits into from
Jan 7, 2022
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
7 changes: 1 addition & 6 deletions examples/chip-tool/commands/tests/TestCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,17 +40,12 @@ class TestCommand : public CHIPCommand
{
AddArgument("node-id", 0, UINT64_MAX, &mNodeId);
AddArgument("delayInMs", 0, UINT64_MAX, &mDelayInMs);
AddArgument("timeout", 0, UINT16_MAX, &mTimeout);
vivien-apple marked this conversation as resolved.
Show resolved Hide resolved
AddArgument("endpoint-id", CHIP_ZCL_ENDPOINT_MIN, CHIP_ZCL_ENDPOINT_MAX, &mEndpointId);
AddArgument("PICS", &mPICSFilePath);
}

/////////// CHIPCommand Interface /////////
CHIP_ERROR RunCommand() override;
chip::System::Clock::Timeout GetWaitDuration() const override
{
return chip::System::Clock::Seconds16(mTimeout.HasValue() ? mTimeout.Value() : kTimeoutInSeconds);
}
chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(kTimeoutInSeconds); }

virtual void NextTest() = 0;

Expand Down
21 changes: 17 additions & 4 deletions examples/chip-tool/templates/partials/test_cluster.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@
class {{filename}}: public TestCommand
{
public:
{{filename}}(): TestCommand("{{filename}}"), mTestIndex(0) {}
{{filename}}(): TestCommand("{{filename}}"), mTestIndex(0)
{
{{#chip_tests_config}}
{{#if (isString type)}}
AddArgument("{{name}}", &m{{asUpperCamelCase name}});
{{else}}
AddArgument("{{name}}", {{asTypeMinValue type}}, {{asTypeMaxValue type}}, &m{{asUpperCamelCase name}});
{{/if}}
{{/chip_tests_config}}
}

/////////// TestCommand Interface /////////
void NextTest() override
Expand Down Expand Up @@ -45,13 +54,17 @@ class {{filename}}: public TestCommand
}

{{#if timeout}}
chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(mTimeout.HasValue() : mTimeout.Value() : {{timeout}}); }
chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(mTimeout.HasValue() ? mTimeout.Value() : {{timeout}}); }
{{/if}}

private:
std::atomic_uint16_t mTestIndex;
const uint16_t mTestCount = {{totalTests}};

{{#chip_tests_config}}
chip::Optional<{{chipType}}> m{{asUpperCamelCase name}};
{{/chip_tests_config}}

{{#chip_tests_items}}
{{#chip_tests_item_response_parameters}}
{{#if saveAs}}
Expand Down Expand Up @@ -156,7 +169,7 @@ class {{filename}}: public TestCommand
{{else if isWait}}
CHIP_ERROR {{>testCommand}}()
{
const chip::EndpointId endpoint = mEndpointId.HasValue() ? mEndpointId.Value() : {{endpoint}};
const chip::EndpointId endpoint = {{#if (chip_tests_config_has "endpoint")}}mEndpoint.HasValue() ? mEndpoint.Value() : {{/if}}{{endpoint}};
ChipLogError(chipTool, "[Endpoint: 0x%08x Cluster: {{cluster}} {{#if isAttribute}}Attribute: {{attribute}}{{else}}Command: {{wait}}{{/if}}] {{label}}", endpoint);
{{#*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}}
Expand All @@ -172,7 +185,7 @@ class {{filename}}: public TestCommand
{{#if isGroupCommand}}
const chip::GroupId groupId = {{groupId}};
{{else}}
const chip::EndpointId endpoint = mEndpointId.HasValue() ? mEndpointId.Value() : {{endpoint}};
const chip::EndpointId endpoint = {{#if (chip_tests_config_has "endpoint")}}mEndpoint.HasValue() ? mEndpoint.Value() : {{/if}}{{endpoint}};
{{/if}}

{{~#*inline "maybeTimedInteractionTimeout"}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@
{{else}}
{{#if_is_bitmap type}}
static_cast<{{zapTypeToEncodableClusterObjectType type ns=ns}}>({{definedValue}});
{{else if (chip_tests_config_has definedValue)}}
m{{asUpperCamelCase definedValue}}.HasValue() ? m{{asUpperCamelCase definedValue}}.Value() : {{asTypedLiteral (chip_tests_config_get_default_value definedValue) (chip_tests_config_get_type definedValue)}};
{{else}}
{{asTypedLiteral definedValue type}};
{{/if_is_bitmap}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,12 @@
{{! 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 (isOctetString type)}}AsString("{{label}}", {{actual}}, chip::ByteSpan(chip::Uint8::from_const_char("{{octetStringEscapedForCLiteral expected}}"), {{expected.length}}))
{{else if (isCharString type)}}AsString("{{label}}", {{actual}}, chip::CharSpan("{{expected}}", {{utf8StringLength expected}}))
{{else}}("{{label}}", {{actual}}, {{asTypedLiteral expected type}})
VerifyOrReturn(CheckValue{{#if (isString type)}}AsString{{/if}}("{{label}}", {{actual}},
{{~#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}}
{{/if}}
);
));
{{/if_is_struct}}
{{/if}}
1 change: 1 addition & 0 deletions examples/chip-tool/templates/tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@ function getTests()
'TestDelayCommands',
'TestLogCommands',
'TestSaveAs',
'TestConfigVariables',
'TestDescriptorCluster',
'TestBasicInformation',
'TestIdentifyCluster',
Expand Down
12 changes: 12 additions & 0 deletions examples/placeholder/linux/include/TestCommand.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,18 @@ class TestCommand
exit(CHIP_NO_ERROR == status ? EXIT_SUCCESS : EXIT_FAILURE);
}

template <typename T>
size_t AddArgument(const char * name, chip::Optional<T> * value)
{
return 0;
}

template <typename T>
size_t AddArgument(const char * name, int64_t min, uint64_t max, chip::Optional<T> * value)
{
return 0;
}

CHIP_ERROR Log(const char * message)
{
ChipLogProgress(chipTool, "%s", message);
Expand Down
1 change: 1 addition & 0 deletions examples/placeholder/templates/templates.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"../../../src/app/zap-templates/templates/app/helper.js",
"../../../src/app/zap-templates/templates/chip/helper.js",
"../../../src/app/zap-templates/common/ClusterTestGeneration.js",
"../../../examples/chip-tool/templates/helper.js",
"helper.js"
],
"override": "../../../src/app/zap-templates/common/override.js",
Expand Down
57 changes: 57 additions & 0 deletions src/app/tests/suites/TestConfigVariables.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright (c) 2021 Project CHIP Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

name: Test Cluster Config Variables Tests

config:
cluster: "Test Cluster"
endpoint: 1
arg1:
type: INT8U
defaultValue: 5
returnValueWithArg1:
type: INT8U
defaultValue: 25

tests:
- label: "Wait for the commissioned device to be retrieved"
cluster: "DelayCommands"
command: "WaitForCommissionee"

- label: "Send Test Add Arguments Command"
command: "testAddArguments"
arguments:
values:
- name: "arg1"
value: 3
- name: "arg2"
value: 17
response:
values:
- name: "returnValue"
saveAs: TestAddArgumentDefaultValue
value: 20

- label: "Send Test Add Arguments Command"
command: "testAddArguments"
arguments:
values:
- name: "arg1"
value: arg1
- name: "arg2"
value: TestAddArgumentDefaultValue
response:
values:
- name: "returnValue"
value: returnValueWithArg1
60 changes: 59 additions & 1 deletion src/app/zap-templates/common/ClusterTestGeneration.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ const templateUtil = require(zapPath + 'dist/src-electron/generator/template-uti

const { getClusters, getCommands, getAttributes, isTestOnlyCluster } = require('./simulated-clusters/SimulatedClusters.js');
const { asBlocks, ensureClusters } = require('./ClustersHelper.js');
const { Variables } = require('./variables/Variables.js');

const kIdentityName = 'identity';
const kClusterName = 'cluster';
Expand Down Expand Up @@ -440,7 +441,9 @@ async function chip_tests(list, options)
const items = Array.isArray(list) ? list : list.split(',');
const names = items.map(name => name.trim());
let tests = names.map(item => parse(item));
tests = await Promise.all(tests.map(async function(test) {

const context = this;
tests = await Promise.all(tests.map(async function(test) {
test.tests = await Promise.all(test.tests.map(async function(item) {
item.global = global;
if (item.isCommand) {
Expand All @@ -452,6 +455,12 @@ async function chip_tests(list, options)
}
return item;
}));

const variables = await Variables(context, test);
test.variables = {
config : variables.config,
tests : variables.tests,
};
return test;
}));
return templateUtil.collectBlocks(tests, options, this);
Expand All @@ -462,6 +471,51 @@ 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)
{
while (!('variables' in context) && context.parent) {
context = context.parent;
}

if (typeof context === 'undefined' || !('variables' in context)) {
return null;
}

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

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

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

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

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

// 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.
Expand Down Expand Up @@ -632,6 +686,10 @@ exports.chip_tests_items = chip_tests_items;
exports.chip_tests_item_parameters = chip_tests_item_parameters;
exports.chip_tests_item_response_parameters = chip_tests_item_response_parameters;
exports.chip_tests_pics = chip_tests_pics;
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.isTestOnlyCluster = isTestOnlyCluster;
exports.isLiteralNull = isLiteralNull;
exports.expectedValueHasProp = expectedValueHasProp;
Expand Down
Loading