Skip to content

Commit

Permalink
Make it possible for apps into the placeholder directory to have cust…
Browse files Browse the repository at this point in the history
…om tests (#11332)
  • Loading branch information
vivien-apple authored and pull[bot] committed Dec 12, 2022
1 parent 85ae4f5 commit 2333624
Show file tree
Hide file tree
Showing 13 changed files with 386 additions and 2 deletions.
14 changes: 14 additions & 0 deletions examples/chip-tool/templates/partials/test_cluster.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,18 @@ class {{filename}}: public TestCommand

{{#chip_tests_items}}
{{#unless (isTestOnlyCluster cluster)}}
{{#unless isWait}}
{{#unless isCommand}}
chip::Callback::Callback<void (*) ({{>failureArguments}})> {{>failureCallback}} { {{>failureResponse}}, this };
chip::Callback::Callback<void (*) ({{>successArguments}})> {{>successCallback}} { {{>successResponse}}, this };
{{/unless}}
{{/unless}}
{{/unless}}
{{/chip_tests_items}}

{{#chip_tests_items}}
{{#unless (isTestOnlyCluster cluster)}}
{{#unless isWait}}
{{#unless isCommand}}
static void {{>failureResponse}}({{> failureArguments}})
{
Expand All @@ -83,6 +86,7 @@ class {{filename}}: public TestCommand
bool mReceivedReport_{{index}} = false;
{{/if}}

{{/unless}}
{{/unless}}
{{/unless}}
{{/chip_tests_items}}
Expand All @@ -98,6 +102,16 @@ class {{filename}}: public 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}}
Expand Down
9 changes: 9 additions & 0 deletions examples/placeholder/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ chip_data_model("configuration") {
is_server = true
}

config("includes") {
include_dirs = [
".",
"include",
]
}

executable("chip-${chip_tests_zap_config}") {
sources = [ "main.cpp" ]

Expand All @@ -37,6 +44,8 @@ executable("chip-${chip_tests_zap_config}") {
"${chip_root}/src/lib",
]

include_dirs = [ "include" ]

cflags = [ "-Wconversion" ]

output_dir = root_out_dir
Expand Down
28 changes: 28 additions & 0 deletions examples/placeholder/linux/apps/app1/tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
*
* 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.
*/

function getTests()
{
const tests = [];

return tests.join(', ');
}

//
// Module exports
//
exports.getTests = getTests;
78 changes: 78 additions & 0 deletions examples/placeholder/linux/include/MatterCallbacks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
*
* Copyright (c) 2021 Project CHIP Authors
* All rights reserved.
*
* 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.
*/

#pragma once

#include <app/ConcreteAttributePath.h>
#include <app/ConcreteCommandPath.h>
#include <lib/support/CodeUtils.h>
#include <platform/CHIPDeviceLayer.h>

#include <zap-generated/test/Commands.h>

TestCommand * gTestCommand = nullptr;

void OnPlatformEvent(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg)
{
switch (event->Type)
{
case chip::DeviceLayer::DeviceEventType::kCommissioningComplete:
ChipLogError(Zcl, "Commissioning complete");

TestCommand * command = reinterpret_cast<TestCommand *>(arg);
if (command == nullptr)
{
ChipLogError(Zcl, "No tests.");
return;
}

gTestCommand = command;
gTestCommand->NextTest();
break;
}
}

void MatterPostCommandReceivedCallback(const chip::app::ConcreteCommandPath & commandPath)
{
VerifyOrReturn(gTestCommand != nullptr);

ChipLogError(Zcl, "Receive command: Endpoint: %u, Cluster: " ChipLogFormatMEI ", Command: " ChipLogFormatMEI,
commandPath.mEndpointId, ChipLogValueMEI(commandPath.mClusterId), ChipLogValueMEI(commandPath.mCommandId));

gTestCommand->CheckCommandPath(commandPath);
}

void MatterPostAttributeReadCallback(const chip::app::ConcreteAttributePath & attributePath)
{
VerifyOrReturn(gTestCommand != nullptr);

ChipLogError(Zcl, "Receive READ attribute command: Endpoint: %u, Cluster: " ChipLogFormatMEI ", Attribute: " ChipLogFormatMEI,
attributePath.mEndpointId, ChipLogValueMEI(attributePath.mClusterId), ChipLogValueMEI(attributePath.mAttributeId));

gTestCommand->CheckAttributePath(attributePath);
}

void MatterPostAttributeWriteCallback(const chip::app::ConcreteAttributePath & attributePath)
{
VerifyOrReturn(gTestCommand != nullptr);

ChipLogError(Zcl, "Receive WRITE attribute command: Endpoint: %u, Cluster: " ChipLogFormatMEI ", Attribute: " ChipLogFormatMEI,
attributePath.mEndpointId, ChipLogValueMEI(attributePath.mClusterId), ChipLogValueMEI(attributePath.mAttributeId));

gTestCommand->CheckAttributePath(attributePath);
}
82 changes: 82 additions & 0 deletions examples/placeholder/linux/include/TestCommand.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/*
*
* Copyright (c) 2021 Project CHIP Authors
* All rights reserved.
*
* 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.
*/

#pragma once

#include <app/ConcreteAttributePath.h>
#include <app/ConcreteCommandPath.h>

#include <app-common/zap-generated/ids/Attributes.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app-common/zap-generated/ids/Commands.h>

class TestCommand
{
public:
TestCommand(const char * commandName) : mCommandPath(0, 0, 0), mAttributePath(0, 0, 0) {}
virtual ~TestCommand() {}

virtual void NextTest() = 0;
void Wait() {}
void SetCommandExitStatus(CHIP_ERROR status)
{
chip::DeviceLayer::PlatformMgr().StopEventLoopTask();
exit(CHIP_NO_ERROR == status ? EXIT_SUCCESS : EXIT_FAILURE);
}

CHIP_ERROR Log(const char * message)
{
ChipLogProgress(chipTool, "%s", message);
NextTest();
return CHIP_NO_ERROR;
}

void CheckCommandPath(const chip::app::ConcreteCommandPath & commandPath)
{
if (commandPath == mCommandPath)
{
NextTest();
return;
}

ChipLogError(chipTool, "CommandPath does not match");
SetCommandExitStatus(CHIP_ERROR_INTERNAL);
}

void CheckAttributePath(const chip::app::ConcreteAttributePath & attributePath)
{
if (attributePath == mAttributePath)
{
NextTest();
return;
}

ChipLogError(chipTool, "AttributePath does not match");
return SetCommandExitStatus(CHIP_ERROR_INTERNAL);
}

void ClearAttributeAndCommandPaths()
{
mCommandPath = chip::app::ConcreteCommandPath(0, 0, 0);
mAttributePath = chip::app::ConcreteAttributePath(0, 0, 0);
}

protected:
chip::app::ConcreteCommandPath mCommandPath;
chip::app::ConcreteAttributePath mAttributePath;
};
23 changes: 22 additions & 1 deletion examples/placeholder/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,34 @@
*/

#include "AppMain.h"
#include "Options.h"

#include <cassert>
#include <lib/support/CodeUtils.h>

#include "MatterCallbacks.h"

void RunTestCommand()
{
const char * command = LinuxDeviceOptions::GetInstance().command;
if (command == nullptr)
{
return;
}

auto test = GetTestCommand(command);
if (test.get() == nullptr)
{
ChipLogError(chipTool, "Specified test command does not exists: %s", command);
return;
}

chip::DeviceLayer::PlatformMgr().AddEventHandler(OnPlatformEvent, reinterpret_cast<intptr_t>(test.get()));
}

int main(int argc, char * argv[])
{
VerifyOrDie(ChipLinuxAppInit(argc, argv) == 0);
RunTestCommand();
ChipLinuxAppMainLoop();
return 0;
}
32 changes: 32 additions & 0 deletions examples/placeholder/templates/helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
*
* 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.
*/

function getTests()
{
try {
const appTest = require('../linux/apps/' + process.env.TARGET_APP + '/tests.js');
return appTest.getTests();
} catch (e) {
console.info("No tests configuration has been found.");
return '';
}
}

//
// Module exports
//
exports.getTests = getTests;
42 changes: 42 additions & 0 deletions examples/placeholder/templates/templates.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"name": "Placeholder templates",
"version": "chip-v1",
"helpers": [
"../../../src/app/zap-templates/partials/helper.js",
"../../../src/app/zap-templates/common/StringHelper.js",
"../../../src/app/zap-templates/templates/app/helper.js",
"../../../src/app/zap-templates/templates/chip/helper.js",
"../../../src/app/zap-templates/common/ClusterTestGeneration.js",
"helper.js"
],
"override": "../../../src/app/zap-templates/common/override.js",
"partials": [
{
"name": "header",
"path": "../../../src/app/zap-templates/partials/header.zapt"
},
{
"name": "clusters_header",
"path": "../../../src/app/zap-templates/partials/clusters_header.zapt"
},
{
"name": "cluster_header",
"path": "../../../src/app/zap-templates/partials/cluster_header.zapt"
},
{
"name": "test_cluster",
"path": "../../../examples/chip-tool/templates/partials/test_cluster.zapt"
},
{
"name": "commandValue",
"path": "../../../examples/chip-tool/templates/partials/test_cluster_command_value.zapt"
}
],
"templates": [
{
"path": "tests-commands.zapt",
"name": "Tests Commands header",
"output": "test/Commands.h"
}
]
}
23 changes: 23 additions & 0 deletions examples/placeholder/templates/tests-commands.zapt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{{> header}}

#pragma once

#include "TestCommand.h"

{{#if (getTests)}}
{{>test_cluster tests=(getTests)}}
{{/if}}

std::unique_ptr<TestCommand>GetTestCommand(std::string testName)
{
{{#if (getTests)}}
{{#chip_tests (getTests)}}
if (testName == "{{filename}}")
{
return std::unique_ptr<{{filename}}>(new {{filename}}());
}
{{/chip_tests}}
{{/if}}

return nullptr;
}
Loading

0 comments on commit 2333624

Please sign in to comment.