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

Add Darwin chip tool tests #15823

Merged
merged 2 commits into from
Mar 8, 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
1 change: 1 addition & 0 deletions examples/chip-tool-darwin/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ assert(chip_build_tools)

executable("chip-tool-darwin") {
sources = [
"${chip_root}/zzz_generated/chip-tool-darwin/zap-generated/cluster/CHIPTestClustersObjc.mm",
"commands/clusters/ModelCommandBridge.mm",
"commands/common/CHIPCommandBridge.mm",
"commands/common/CHIPCommandStorageDelegate.mm",
Expand Down
262 changes: 262 additions & 0 deletions examples/chip-tool-darwin/commands/tests/TestCommandBridge.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,262 @@
/*
* Copyright (c) 2022 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 "../common/CHIPCommandBridge.h"
#include <app/tests/suites/include/ConstraintsChecker.h>
#include <app/tests/suites/include/PICSChecker.h>
#include <app/tests/suites/include/ValueChecker.h>
#include <lib/support/UnitTestUtils.h>
#include <zap-generated/cluster/CHIPTestClustersObjc.h>

#import <CHIP/CHIPError.h>

constexpr uint16_t kTimeoutInSeconds = 90;

class TestCommandBridge : public CHIPCommandBridge, public ValueChecker, public ConstraintsChecker, public PICSChecker {
public:
TestCommandBridge(const char * _Nonnull commandName)
: CHIPCommandBridge(commandName)
{
AddArgument("node-id", 0, UINT64_MAX, &mNodeId);
AddArgument("delayInMs", 0, UINT64_MAX, &mDelayInMs);
AddArgument("PICS", &mPICSFilePath);
}

~TestCommandBridge() {};

/////////// CHIPCommand Interface /////////
CHIP_ERROR RunCommand() override
{
if (mPICSFilePath.HasValue()) {
PICS.SetValue(PICSBooleanReader::Read(mPICSFilePath.Value()));
}

mCallbackQueue = dispatch_queue_create("com.chip-tool.command", DISPATCH_QUEUE_SERIAL);

NextTest();
return CHIP_NO_ERROR;
}

chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(kTimeoutInSeconds); }

virtual void NextTest() = 0;

void Exit(std::string message) override
{
ChipLogError(chipTool, " ***** Test Failure: %s\n", message.c_str());
SetCommandExitStatus(CHIP_ERROR_INTERNAL);
}

/////////// GlobalCommands Interface /////////
void Log(NSString * _Nonnull message)
{
NSLog(@"%@", message);
NextTest();
}

void WaitForMs(unsigned int ms)
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, ms * NSEC_PER_MSEC), mCallbackQueue, ^{
NextTest();
});
}

void UserPrompt(NSString * _Nonnull message) { NextTest(); }

void WaitForCommissionee(chip::NodeId nodeId)
{
CHIPDeviceController * controller = [CHIPDeviceController sharedController];
VerifyOrReturn(controller != nil, SetCommandExitStatus(CHIP_ERROR_INCORRECT_STATE));

[controller getConnectedDevice:nodeId
queue:mCallbackQueue
completionHandler:^(CHIPDevice * _Nullable device, NSError * _Nullable error) {
CHIP_ERROR err = [CHIPError errorToCHIPErrorCode:error];
VerifyOrReturn(CHIP_NO_ERROR == err, SetCommandExitStatus(err));

mConnectedDevice = device;
NextTest();
}];
}

CHIPDevice * _Nullable GetConnectedDevice(void) { return mConnectedDevice; }

protected:
dispatch_queue_t _Nullable mCallbackQueue;
CHIPDevice * _Nullable mConnectedDevice;
chip::NodeId mNodeId;

void Wait()
{
if (mDelayInMs.HasValue()) {
chip::test_utils::SleepMillis(mDelayInMs.Value());
}
};

chip::Optional<uint64_t> mDelayInMs;
chip::Optional<char *> mPICSFilePath;
chip::Optional<chip::EndpointId> mEndpointId;
chip::Optional<uint16_t> mTimeout;

bool CheckConstraintStartsWith(
const char * _Nonnull itemName, const NSString * _Nonnull current, const char * _Nonnull expected)
{
const chip::CharSpan value([current UTF8String], [current lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
return ConstraintsChecker::CheckConstraintStartsWith(itemName, value, expected);
}

bool CheckConstraintEndsWith(const char * _Nonnull itemName, const NSString * _Nonnull current, const char * _Nonnull expected)
{
const chip::CharSpan value([current UTF8String], [current lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
return ConstraintsChecker::CheckConstraintEndsWith(itemName, value, expected);
}

bool CheckConstraintIsUpperCase(const char * _Nonnull itemName, const NSString * _Nonnull current, bool expectUpperCase)
{
const chip::CharSpan value([current UTF8String], [current lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
return ConstraintsChecker::CheckConstraintIsUpperCase(itemName, value, expectUpperCase);
}

bool CheckConstraintIsLowerCase(const char * _Nonnull itemName, const NSString * _Nonnull current, bool expectLowerCase)
{
const chip::CharSpan value([current UTF8String], [current lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
return ConstraintsChecker::CheckConstraintIsLowerCase(itemName, value, expectLowerCase);
}

bool CheckConstraintIsHexString(const char * _Nonnull itemName, const NSString * _Nonnull current, bool expectHexString)
{
const chip::CharSpan value([current UTF8String], [current lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
return ConstraintsChecker::CheckConstraintIsHexString(itemName, value, expectHexString);
}

bool CheckConstraintNotValue(
const char * _Nonnull itemName, const NSString * _Nonnull current, const NSString * _Nonnull expected)
{
const chip::CharSpan currentValue([current UTF8String], [current lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
const chip::CharSpan expectedValue([expected UTF8String], [expected lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
return ConstraintsChecker::CheckConstraintNotValue(itemName, currentValue, expectedValue);
}

bool CheckConstraintNotValue(const char * _Nonnull itemName, const NSData * _Nonnull current, const NSData * _Nonnull expected)
{
const chip::ByteSpan currentValue(static_cast<const uint8_t *>([current bytes]), [current length]);
const chip::ByteSpan expectedValue(static_cast<const uint8_t *>([expected bytes]), [expected length]);
return ConstraintsChecker::CheckConstraintNotValue(itemName, currentValue, expectedValue);
}

bool CheckConstraintNotValue(const char * _Nonnull itemName, const NSNumber * _Nonnull current, NSNumber * _Nonnull expected)
{
if ([current isEqualToNumber:expected]) {
Exit(std::string(itemName) + " got unexpected value: " + std::string([[current stringValue] UTF8String]));
return false;
}

return true;
}

template <typename T>
bool CheckConstraintNotValue(const char * _Nonnull itemName, const NSNumber * _Nonnull current, T expected)
{
return CheckConstraintNotValue(itemName, current, @(expected));
}

template <typename T> bool CheckConstraintNotValue(const char * _Nonnull itemName, NSError * _Nullable current, T expected)
{
NSNumber * currentValue = @([CHIPError errorToCHIPErrorCode:current].AsInteger());
return CheckConstraintNotValue(itemName, currentValue, @(expected));
}

bool CheckValueAsString(const char * _Nonnull itemName, const id _Nonnull current, const NSString * _Nonnull expected)
{
NSString * data = current;
const chip::CharSpan currentValue([data UTF8String], [data lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
const chip::CharSpan expectedValue([expected UTF8String], [expected lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
return ValueChecker::CheckValueAsString(itemName, currentValue, expectedValue);
}

bool CheckValueAsString(const char * _Nonnull itemName, const id _Nonnull current, const NSData * _Nonnull expected)
{
NSData * data = current;
const chip::ByteSpan currentValue(static_cast<const uint8_t *>([data bytes]), [data length]);
const chip::ByteSpan expectedValue(static_cast<const uint8_t *>([expected bytes]), [expected length]);
return ValueChecker::CheckValueAsString(itemName, currentValue, expectedValue);
}

bool CheckValue(const char * _Nonnull itemName, NSNumber * _Nonnull current, NSNumber * _Nonnull expected)
{
if (![current isEqualToNumber:expected]) {
Exit(std::string(itemName) + " value mismatch: expected " + std::string([[expected stringValue] UTF8String])
+ " but got " + std::string([[current stringValue] UTF8String]));
return false;
}

return true;
}

bool CheckValue(const char * _Nonnull itemName, id _Nonnull current, NSNumber * _Nonnull expected)
{
NSNumber * currentValue = current;
return CheckValue(itemName, currentValue, expected);
}

template <typename T> bool CheckValue(const char * _Nonnull itemName, NSNumber * _Nonnull current, T expected)
{
return CheckValue(itemName, current, @(expected));
}

template <typename T> bool CheckValue(const char * _Nonnull itemName, id _Nonnull current, T expected)
{
NSNumber * currentValue = current;
return CheckValue(itemName, currentValue, @(expected));
}

template <typename T> bool CheckValue(const char * _Nonnull itemName, NSError * _Nullable current, T expected)
{

NSNumber * currentValue = @([CHIPError errorToCHIPErrorCode:current].AsInteger());
return CheckValue(itemName, currentValue, @(expected));
}

template <typename T, typename U> bool CheckValue(const char * _Nonnull itemName, T current, U expected)
{

return ValueChecker::CheckValue(itemName, current, expected);
}

bool CheckValueNonNull(const char * _Nonnull itemName, id _Nullable current)
{
if (current != nil) {
return true;
}

Exit(std::string(itemName) + " expected to not be null but is");
return false;
}

bool CheckValueNull(const char * _Nonnull itemName, id _Nullable current)
{
if (current == nil) {
return true;
}

Exit(std::string(itemName) + " expected to be null but isn't");
return false;
}
};
3 changes: 3 additions & 0 deletions examples/chip-tool-darwin/main.mm
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@
#include "commands/common/Commands.h"

#include "commands/pairing/Commands.h"

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

int main(int argc, const char * argv[])
{
Commands commands;
registerCommandsPairing(commands);
registerCommandsTests(commands);
registerClusters(commands);
return commands.Run(argc, (char **) argv);
}
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
{{#if (chip_has_client_clusters)}}
{{> header}}
#import <Foundation/Foundation.h>
#import <CHIP/CHIPError_Internal.h>

#import "CHIPCallbackBridge_internal.h"
#import "CHIP/zap-generated/CHIPCallbackBridge_internal.h"
#import "CHIPCluster_internal.h"
#import "CHIPDevice.h"
#import "CHIPDevice_Internal.h"
Expand Down
61 changes: 61 additions & 0 deletions examples/chip-tool-darwin/templates/helper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
*
* 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/dist/src-electron/';
const { asB_locks, ensureClusters } = require('../../../src/app/zap-templates/common/ClustersHelper.js');
const templateUtil = require(zapPath + 'generator/template-util.js');
const zclHelper = require(zapPath + 'generator/helper-zcl.js');
const zclQuery = require(zapPath + 'db/query-zcl.js');

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

function asHyphenatedLower(name)
{
name = name.replace(/\s+/g, '').replace(/\.?([A-Z])/g, function(x) {
return '-' + x
})
return name.substring(1).toLowerCase();
}

function toLowerCase(name)
{
return name.toLowerCase();
}

function getCommands()
{
return ensureClusters(this).getClientCommands(this.name);
}

function hasCommands()
{
return getCommands.call(this).then(commands => { return !!commands.length });
}

function hasArguments()
{
return !!this.arguments.length
}

//
// Module exports
//
exports.asHyphenatedLower = asHyphenatedLower;
exports.hasCommands = hasCommands;
exports.toLowerCase = toLowerCase
exports.hasArguments = hasArguments;
Loading