Skip to content

Commit

Permalink
Add some cluster tests to iOS ChipTool (#6402)
Browse files Browse the repository at this point in the history
  • Loading branch information
vivien-apple authored Apr 30, 2021
1 parent e78324e commit 6df63b4
Show file tree
Hide file tree
Showing 7 changed files with 3,611 additions and 1 deletion.
9 changes: 8 additions & 1 deletion .github/workflows/darwin.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,13 @@ jobs:
- name: Clean Build
run: xcodebuild clean
working-directory: src/darwin/Framework
- name: Bootstrap
run: scripts/build/gn_bootstrap.sh
- name: Run Build Test Server
run: |
scripts/examples/gn_build_example.sh examples/all-clusters-app/linux out/debug chip_config_network_layer_ble=false
- name: Run Tests
run: xcodebuild test -target "CHIP" -scheme "CHIP Framework Tests" -sdk macosx
run: |
../../../out/debug/chip-all-clusters-app &
xcodebuild test -target "CHIP" -scheme "CHIP Framework Tests" -sdk macosx
working-directory: src/darwin/Framework
1 change: 1 addition & 0 deletions scripts/tools/zap_regen_all.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def getSpecificTemplatesTargets():
targets = []
targets.append(['examples/chip-tool/chip-tool.zap', '-t', 'examples/chip-tool/templates/templates.json'])
targets.append(['src/controller/controller-clusters.zap', '-t', 'src/app/zap-templates/chip-templates.json'])
targets.append(['src/darwin/Framework/CHIP/chip-tool.zap', '-t', 'src/darwin/Framework/CHIP/templates/templates.json'])
return targets

def getTargets():
Expand Down
4 changes: 4 additions & 0 deletions src/darwin/Framework/CHIP.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
1E1F24982636F84000FA0EA9 /* CHIPClusters.h in Headers */ = {isa = PBXBuildFile; fileRef = 1E1F24962636F84000FA0EA9 /* CHIPClusters.h */; };
1E1F24992636F84000FA0EA9 /* CHIPClusters.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E1F24972636F84000FA0EA9 /* CHIPClusters.cpp */; };
1E9BD1C72621AFF100FC3246 /* attribute-size.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1E9BD1C62621AFF100FC3246 /* attribute-size.cpp */; };
1EB41B7B263C4CC60048E4C1 /* CHIPClustersTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 1EB41B7A263C4CC60048E4C1 /* CHIPClustersTests.m */; };
1EC4CE3A25CC263E00D7304F /* reporting.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1EC4CE3825CC263E00D7304F /* reporting.cpp */; };
1EC4CE3B25CC263E00D7304F /* reporting-default-configuration.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1EC4CE3925CC263E00D7304F /* reporting-default-configuration.cpp */; };
1EC4CE3D25CC265200D7304F /* DataModelHandler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1EC4CE3C25CC265200D7304F /* DataModelHandler.cpp */; };
Expand Down Expand Up @@ -72,6 +73,7 @@
1E1F24962636F84000FA0EA9 /* CHIPClusters.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CHIPClusters.h; path = gen/CHIPClusters.h; sourceTree = "<group>"; };
1E1F24972636F84000FA0EA9 /* CHIPClusters.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CHIPClusters.cpp; path = gen/CHIPClusters.cpp; sourceTree = "<group>"; };
1E9BD1C62621AFF100FC3246 /* attribute-size.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "attribute-size.cpp"; path = "gen/attribute-size.cpp"; sourceTree = "<group>"; };
1EB41B7A263C4CC60048E4C1 /* CHIPClustersTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CHIPClustersTests.m; sourceTree = "<group>"; };
1EC4CE3825CC263E00D7304F /* reporting.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = reporting.cpp; path = ../../../app/reporting/reporting.cpp; sourceTree = "<group>"; };
1EC4CE3925CC263E00D7304F /* reporting-default-configuration.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = "reporting-default-configuration.cpp"; path = "../../../app/reporting/reporting-default-configuration.cpp"; sourceTree = "<group>"; };
1EC4CE3C25CC265200D7304F /* DataModelHandler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DataModelHandler.cpp; path = ../../../app/util/DataModelHandler.cpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -238,6 +240,7 @@
B202529A2459E34F00F97062 /* CHIPTests */ = {
isa = PBXGroup;
children = (
1EB41B7A263C4CC60048E4C1 /* CHIPClustersTests.m */,
B2F53AF1245B0DCF0010745E /* CHIPSetupPayloadParserTests.m */,
B202529D2459E34F00F97062 /* Info.plist */,
);
Expand Down Expand Up @@ -435,6 +438,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
1EB41B7B263C4CC60048E4C1 /* CHIPClustersTests.m in Sources */,
B2F53AF2245B0DCF0010745E /* CHIPSetupPayloadParserTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
186 changes: 186 additions & 0 deletions src/darwin/Framework/CHIP/templates/clusters-tests.zapt
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
//
// CHIPClustersTests.m
// CHIPClustersTests
/**
*
* 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.
*/

// module headers
#import <CHIP/CHIP.h>

// additional includes
#import "CHIPError.h"

// system dependencies
#import <XCTest/XCTest.h>

const uint16_t kTimeoutInMs = 10;
const uint64_t kDeviceId = 1;
const uint16_t kDiscriminator = 3840;
const uint32_t kSetupPINCode = 20202021;
const uint16_t kRemotePort = 11097;
const uint16_t kLocalPort = 11098;
NSString * kAddress = @"::1";

CHIPDevice * GetPairedDevice(uint64_t deviceId)
{
CHIPDeviceController * controller = [CHIPDeviceController sharedController];
XCTAssertNotNil(controller);

NSError * pairingError;
CHIPDevice * device = [controller getPairedDevice:deviceId error:&pairingError];
XCTAssertEqual(pairingError.code, 0);
XCTAssertNotNil(device);

return device;
}

@interface CHIPToolPairingDelegate : NSObject <CHIPDevicePairingDelegate>
@property (nonatomic, strong) XCTestExpectation * expectation;
@end

@implementation CHIPToolPairingDelegate
- (id)initWithExpectation:(XCTestExpectation *)expectation
{
self = [super init];
if (self) {
_expectation = expectation;
}
return self;
}

- (void)onPairingComplete:(NSError *)error
{
XCTAssertEqual(error.code, 0);
[_expectation fulfill];
_expectation = nil;
}
@end

@interface CHIPClustersTests : XCTestCase
@end

@implementation CHIPClustersTests

- (void)testInitStack
{
XCTestExpectation * expectation = [self expectationWithDescription:@"Pairing Complete"];

CHIPDeviceController * controller = [CHIPDeviceController sharedController];
XCTAssertNotNil(controller);

CHIPToolPairingDelegate * pairing = [[CHIPToolPairingDelegate alloc] initWithExpectation:expectation];
dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.pairing", DISPATCH_QUEUE_SERIAL);

[controller setListenPort:kLocalPort];
[controller setPairingDelegate:pairing queue:callbackQueue];

BOOL started = [controller startup:nil queue:nil];
XCTAssertTrue(started);

NSError * error;
[controller pairDevice:kDeviceId
address:kAddress
port:kRemotePort
discriminator:kDiscriminator
setupPINCode:kSetupPINCode
error:&error];
XCTAssertEqual(error.code, 0);

[self waitForExpectationsWithTimeout:kTimeoutInMs handler:nil];
}

- (void)testShutdownStack
{
CHIPDeviceController * controller = [CHIPDeviceController sharedController];
XCTAssertNotNil(controller);

NSError * error;
[controller unpairDevice:kDeviceId error:&error];
XCTAssertEqual(error.code, 0);

BOOL stopped = [controller shutdown];
XCTAssertTrue(stopped);
}

{{#chip_client_clusters}}
{{#chip_server_cluster_commands}}
{{#unless (zcl_command_arguments_count this.id)}}
- (void)testSendCluster{{asCamelCased parent.name false}}{{asCamelCased name false}}Command
{
XCTestExpectation * expectation = [self expectationWithDescription:@"{{asCamelCased parent.name false}}{{asCamelCased name false}}"];

CHIPDevice * device = GetPairedDevice(kDeviceId);
dispatch_queue_t queue = dispatch_get_main_queue();
CHIP{{asCamelCased parent.name false}} * cluster = [[CHIP{{asCamelCased parent.name false}} alloc] initWithDevice:device endpoint:{{asExpectedEndpointForCluster (asCamelCased parent.name false)}} queue:queue];
XCTAssertNotNil(cluster);

[cluster {{asCamelCased name}}:^(NSError * err, NSDictionary * values) {
NSLog(@"{{asCamelCased parent.name false}} {{asCamelCased name false}} Error: %@", err);
XCTAssertEqual(err.code, {{asExpectedReturnValueForCommand (asCamelCased parent.name false) (asCamelCased name false)}});
[expectation fulfill];
}];

[self waitForExpectationsWithTimeout:kTimeoutInMs handler:nil];
}
{{/unless}}
{{/chip_server_cluster_commands}}
{{/chip_client_clusters}}

{{#chip_client_clusters}}
{{#chip_server_cluster_attributes}}
- (void)testSendCluster{{asCamelCased parent.name false}}ReadAttribute{{asCamelCased name false}}
{
XCTestExpectation * expectation = [self expectationWithDescription:@"{{asCamelCased parent.name false}}ReadAttribute{{asCamelCased name false}}"];

CHIPDevice * device = GetPairedDevice(kDeviceId);
dispatch_queue_t queue = dispatch_get_main_queue();
CHIP{{asCamelCased parent.name false}} * cluster = [[CHIP{{asCamelCased parent.name false}} alloc] initWithDevice:device endpoint:{{asExpectedEndpointForCluster (asCamelCased parent.name false)}} queue:queue];
XCTAssertNotNil(cluster);

[cluster readAttribute{{asCamelCased name false}}:^(NSError * err, NSDictionary * values) {
NSLog(@"{{asCamelCased parent.name false}} {{asCamelCased name false}} Error: %@", err);
XCTAssertEqual(err.code, 0);
[expectation fulfill];
}];

[self waitForExpectationsWithTimeout:kTimeoutInMs handler:nil];
}

{{#if (isWritableAttribute)}}
- (void)testSendCluster{{asCamelCased parent.name false}}WriteAttribute{{asCamelCased name false}}
{
XCTestExpectation * expectation = [self expectationWithDescription:@"{{asCamelCased parent.name false}}WriteAttribute{{asCamelCased name false}}"];

CHIPDevice * device = GetPairedDevice(kDeviceId);
dispatch_queue_t queue = dispatch_get_main_queue();
CHIP{{asCamelCased parent.name false}} * cluster = [[CHIP{{asCamelCased parent.name false}} alloc] initWithDevice:device endpoint:{{asExpectedEndpointForCluster (asCamelCased parent.name false)}} queue:queue];
XCTAssertNotNil(cluster);

{{asObjectiveCBasicType type}} value = {{asTestValue}};
[cluster writeAttribute{{asCamelCased name false}}:value completionHandler:^(NSError * err, NSDictionary * values) {
NSLog(@"{{asCamelCased parent.name false}} {{asCamelCased name false}} Error: %@", err);
XCTAssertEqual(err.code, 0);
[expectation fulfill];
}];

[self waitForExpectationsWithTimeout:kTimeoutInMs handler:nil];
}
{{/if}}
{{/chip_server_cluster_attributes}}
{{/chip_client_clusters}}

@end
94 changes: 94 additions & 0 deletions src/darwin/Framework/CHIP/templates/helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
*
* 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.
*/

// Import helpers from zap core
const zapPath = '../../../../../third_party/zap/repo/src-electron/';
const templateUtil = require(zapPath + 'generator/template-util.js')
const zclHelper = require(zapPath + 'generator/helper-zcl.js')

const ChipTypesHelper = require('../../../../../src/app/zap-templates/common/ChipTypesHelper.js');
const StringHelper = require('../../../../../src/app/zap-templates/common/StringHelper.js');

// Ideally those clusters clusters endpoints should be retrieved from the
// descriptor cluster.
function asExpectedEndpointForCluster(clusterName)
{
switch (clusterName) {
case 'Basic':
case 'Descriptor':
case 'GeneralCommissioning':
case 'GroupKeyManagement':
case 'NetworkCommissioning':
case 'OperationalCredentials':
return 0;
}

return 1;
}

function asExpectedReturnValueForCommand(clusterName, commandName)
{
switch (clusterName) {
case 'GeneralCommissioning':
switch (commandName) {
// All methods are not implemented and returns `EMBER_ZCL_STATUS_FAILURE`
default:
return 1;
}
break;

case 'OperationalCredentials':
switch (commandName) {
// All methods are not implemented and returns `EMBER_ZCL_STATUS_FAILURE`
default:
return 1;
}
break;

case 'Thermostat':
switch (commandName) {
// All those methods are not implemented and directly returns false. So the stack returns
// `EMBER_ZCL_STATUS_UNSUP_CLUSTER_COMMAND`
case 'GetRelayStatusLog':
case 'ClearWeeklySchedule':
case 'SetWeeklySchedule':
case 'GetWeeklySchedule':
return 1;
}
break;
}

return 0;
}

function asTestValue()
{
if (StringHelper.isOctetString(this.type)) {
return '[@"Test" dataUsingEncoding:NSUTF8StringEncoding]';
} else if (StringHelper.isCharString(this.type)) {
return '@"Test"';
} else {
return this.min || this.max || 0;
}
}

//
// Module exports
//
exports.asExpectedEndpointForCluster = asExpectedEndpointForCluster;
exports.asExpectedReturnValueForCommand = asExpectedReturnValueForCommand;
exports.asTestValue = asTestValue;
20 changes: 20 additions & 0 deletions src/darwin/Framework/CHIP/templates/templates.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"name": "Framework 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",
"helper.js"
],
"override": "../../../../../src/app/zap-templates/common/override.js",
"partials": [],
"templates": [
{
"path": "clusters-tests.zapt",
"name": "Cluster Tests",
"output": "src/darwin/Framework/CHIPTests/CHIPClustersTests.m"
}
]
}
Loading

0 comments on commit 6df63b4

Please sign in to comment.