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

New unit testing cluster commands to support testing batch commands corner cases #31138

Merged
Merged
Show file tree
Hide file tree
Changes from 3 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
Original file line number Diff line number Diff line change
Expand Up @@ -6176,6 +6176,10 @@ internal cluster UnitTesting = 4294048773 {
NestedStructList arg1[] = 0;
}

response struct TestBatchHelperResponse = 12 {
octet_string<800> buffer = 0;
}

request struct TestListInt8UReverseRequestRequest {
int8u arg1[] = 0;
}
Expand Down Expand Up @@ -6222,6 +6226,18 @@ internal cluster UnitTesting = 4294048773 {
int8u arg1 = 0;
}

request struct TestBatchHelperRequestRequest {
int16u sleepBeforeResponseTimeMs = 0;
int16u sizeOfResponseBuffer = 1;
int8u fillCharacter = 2;
}

request struct TestSecondBatchHelperRequestRequest {
int16u sleepBeforeResponseTimeMs = 0;
int16u sizeOfResponseBuffer = 1;
int8u fillCharacter = 2;
}

/** Simple command without any parameters and without a specific response */
command Test(): DefaultSuccess = 0;
/** Simple command without any parameters and without a specific response not handled by the server */
Expand Down Expand Up @@ -6287,6 +6303,10 @@ internal cluster UnitTesting = 4294048773 {
command TestEmitTestEventRequest(TestEmitTestEventRequestRequest): TestEmitTestEventResponse = 20;
/** Command that takes identical arguments to the fields of the TestFabricScopedEvent and logs the TestFabricScopedEvent to the buffer. Command returns an event ID as the response. */
command TestEmitTestFabricScopedEventRequest(TestEmitTestFabricScopedEventRequestRequest): TestEmitTestFabricScopedEventResponse = 21;
/** Command that responds after sleepBeforeResponseTimeMs with an octet_string the size requested with fillCharacter. */
command TestBatchHelperRequest(TestBatchHelperRequestRequest): TestBatchHelperResponse = 22;
/** Second command that responds after sleepBeforeResponseTimeMs with an octet_string the size requested with fillCharacter. */
command TestSecondBatchHelperRequest(TestSecondBatchHelperRequestRequest): TestBatchHelperResponse = 23;
}

/** The Fault Injection Cluster provide a means for a test harness to configure faults(for example triggering a fault in the system). */
Expand Down
28 changes: 22 additions & 6 deletions examples/all-clusters-app/all-clusters-common/all-clusters-app.zap
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,19 @@
}
],
"package": [
{
"pathRelativity": "relativeToZap",
"path": "../../../src/app/zap-templates/app-templates.json",
"type": "gen-templates-json",
"version": "chip-v1"
},
{
"pathRelativity": "relativeToZap",
"path": "../../../src/app/zap-templates/zcl/zcl-with-test-extensions.json",
"type": "zcl-properties",
"category": "matter",
"version": 1,
"description": "Matter SDK ZCL data with some extensions"
},
{
"pathRelativity": "relativeToZap",
"path": "../../../src/app/zap-templates/app-templates.json",
"type": "gen-templates-json",
"version": "chip-v1"
}
],
"endpointTypes": [
Expand Down Expand Up @@ -19114,6 +19114,22 @@
"source": "client",
"isIncoming": 1,
"isEnabled": 1
},
{
"name": "TestBatchHelperRequest",
"code": 22,
"mfgCode": null,
"source": "client",
"isIncoming": 1,
"isEnabled": 1
},
{
"name": "TestSecondBatchHelperRequest",
"code": 23,
"mfgCode": null,
"source": "client",
"isIncoming": 1,
"isEnabled": 1
}
],
"attributes": [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5601,6 +5601,10 @@ internal cluster UnitTesting = 4294048773 {
NestedStructList arg1[] = 0;
}

response struct TestBatchHelperResponse = 12 {
octet_string<800> buffer = 0;
}

request struct TestListInt8UReverseRequestRequest {
int8u arg1[] = 0;
}
Expand Down Expand Up @@ -5647,6 +5651,18 @@ internal cluster UnitTesting = 4294048773 {
int8u arg1 = 0;
}

request struct TestBatchHelperRequestRequest {
int16u sleepBeforeResponseTimeMs = 0;
int16u sizeOfResponseBuffer = 1;
int8u fillCharacter = 2;
}

request struct TestSecondBatchHelperRequestRequest {
int16u sleepBeforeResponseTimeMs = 0;
int16u sizeOfResponseBuffer = 1;
int8u fillCharacter = 2;
}

/** Simple command without any parameters and without a specific response */
command Test(): DefaultSuccess = 0;
/** Simple command without any parameters and without a specific response not handled by the server */
Expand Down Expand Up @@ -5712,6 +5728,10 @@ internal cluster UnitTesting = 4294048773 {
command TestEmitTestEventRequest(TestEmitTestEventRequestRequest): TestEmitTestEventResponse = 20;
/** Command that takes identical arguments to the fields of the TestFabricScopedEvent and logs the TestFabricScopedEvent to the buffer. Command returns an event ID as the response. */
command TestEmitTestFabricScopedEventRequest(TestEmitTestFabricScopedEventRequestRequest): TestEmitTestFabricScopedEventResponse = 21;
/** Command that responds after sleepBeforeResponseTimeMs with an octet_string the size requested with fillCharacter. */
command TestBatchHelperRequest(TestBatchHelperRequestRequest): TestBatchHelperResponse = 22;
/** Second command that responds after sleepBeforeResponseTimeMs with an octet_string the size requested with fillCharacter. */
command TestSecondBatchHelperRequest(TestSecondBatchHelperRequestRequest): TestBatchHelperResponse = 23;
}

endpoint 0 {
Expand Down
85 changes: 85 additions & 0 deletions src/app/clusters/test-cluster-server/test-cluster-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,14 @@ class TestAttrAccess : public AttributeAccessInterface
CHIP_ERROR WriteListFabricScopedAttribute(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder);
};

struct AsyncBatchCommandsWorkData
{
CommandHandler::Handle asyncCommandHandle;
ConcreteCommandPath commandPath = ConcreteCommandPath(0, 0, 0);
uint16_t sizeOfResponseBuffer;
uint8_t fillCharacter;
};

TestAttrAccess gAttrAccess;
uint8_t gListUint8Data[kAttributeListLength];
size_t gListUint8DataLen = kAttributeListLength;
Expand Down Expand Up @@ -137,6 +145,36 @@ SimpleEnum gSimpleEnums[kAttributeListLength];
size_t gSimpleEnumCount = 0;
Structs::NullablesAndOptionalsStruct::Type gNullablesAndOptionalsStruct;

void emberAfUnitTestingClusterTestBatchWork(AsyncBatchCommandsWorkData * asyncWorkData)
tehampson marked this conversation as resolved.
Show resolved Hide resolved
{
auto commandHandleRef = std::move(asyncWorkData->asyncCommandHandle);
auto commandHandle = commandHandleRef.Get();
if (commandHandle == nullptr)
{
// Very weird that we are even in here, what set this to nullptr?
Platform::Delete(asyncWorkData);
return;
}

uint8_t buffer[800];
tehampson marked this conversation as resolved.
Show resolved Hide resolved
memset(buffer, asyncWorkData->fillCharacter, asyncWorkData->sizeOfResponseBuffer);
Commands::TestBatchHelperResponse::Type response;
response.buffer = ByteSpan(buffer, asyncWorkData->sizeOfResponseBuffer);
commandHandle->AddResponse(asyncWorkData->commandPath, response);
Platform::Delete(asyncWorkData);
}

static void timerCallback(System::Layer *, void * callbackContext)
{
emberAfUnitTestingClusterTestBatchWork(reinterpret_cast<AsyncBatchCommandsWorkData *>(callbackContext));
}

static void scheduleTimerCallbackMs(AsyncBatchCommandsWorkData * asyncWorkData, uint32_t delayMs)
{
DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Milliseconds32(delayMs), timerCallback,
reinterpret_cast<void *>(asyncWorkData));
}

CHIP_ERROR TestAttrAccess::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder)
{
switch (aPath.mAttributeId)
Expand Down Expand Up @@ -994,6 +1032,53 @@ bool emberAfUnitTestingClusterTestSimpleOptionalArgumentRequestCallback(
return true;
}

// TestBatchHelperRequest and TestSecondBatchHelperRequest do the same thing.
// The reason there are two identical commands is because batch command requires
// command paths in the same batch to be unique. These command allow for
// client to control order of the response and control size of CommandDataIB
// being sent back to help test some corner cases.
bool emberAfUnitTestingClusterTestBatchHelperCommon(CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
const uint16_t sleepTimeMs, const uint16_t sizeOfResponseBuffer,
const uint8_t fillCharacter)
{
if (sizeOfResponseBuffer > 800)
tehampson marked this conversation as resolved.
Show resolved Hide resolved
{
commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::ConstraintError);
return true;
}

AsyncBatchCommandsWorkData * asyncWorkData = Platform::New<AsyncBatchCommandsWorkData>();
if (asyncWorkData == nullptr)
{
commandObj->AddStatus(commandPath, Protocols::InteractionModel::Status::Busy);
return true;
}

asyncWorkData->asyncCommandHandle = commandObj;
asyncWorkData->commandPath = commandPath;
asyncWorkData->sizeOfResponseBuffer = sizeOfResponseBuffer;
asyncWorkData->fillCharacter = fillCharacter;

scheduleTimerCallbackMs(asyncWorkData, sleepTimeMs);

return true;
}

bool emberAfUnitTestingClusterTestBatchHelperRequestCallback(CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
const Commands::TestBatchHelperRequest::DecodableType & commandData)
{
return emberAfUnitTestingClusterTestBatchHelperCommon(commandObj, commandPath, commandData.sleepBeforeResponseTimeMs,
commandData.sizeOfResponseBuffer, commandData.fillCharacter);
}

bool emberAfUnitTestingClusterTestSecondBatchHelperRequestCallback(
CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
const Commands::TestSecondBatchHelperRequest::DecodableType & commandData)
{
return emberAfUnitTestingClusterTestBatchHelperCommon(commandObj, commandPath, commandData.sleepBeforeResponseTimeMs,
commandData.sizeOfResponseBuffer, commandData.fillCharacter);
}

// -----------------------------------------------------------------------------
// Plugin initialization

Expand Down
27 changes: 27 additions & 0 deletions src/app/zap-templates/zcl/data-model/chip/test-cluster.xml
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,26 @@ limitations under the License.
<arg name="arg1" type="int8u"/>
</command>

<command source="client" code="0x16" name="TestBatchHelperRequest"
optional="true" response="TestBatchHelperResponse" apiMaturity="provisional">
<description>
Command that responds after sleepBeforeResponseTimeMs with an octet_string the size requested with fillCharacter.
</description>
<arg name="sleepBeforeResponseTimeMs" type="int16u"/>
<arg name="sizeOfResponseBuffer" type="int16u"/>
tehampson marked this conversation as resolved.
Show resolved Hide resolved
<arg name="fillCharacter" type="int8u"/>
</command>

<command source="client" code="0x17" name="TestSecondBatchHelperRequest"
optional="true" response="TestBatchHelperResponse" apiMaturity="provisional">
<description>
Second command that responds after sleepBeforeResponseTimeMs with an octet_string the size requested with fillCharacter.
</description>
<arg name="sleepBeforeResponseTimeMs" type="int16u"/>
<arg name="sizeOfResponseBuffer" type="int16u"/>
<arg name="fillCharacter" type="int8u"/>
</command>

<command source="server" code="0x00" name="TestSpecificResponse" optional="true" disableDefaultResponse="true">
<description>
Simple response for TestWithResponse with a simple return value
Expand Down Expand Up @@ -566,6 +586,13 @@ limitations under the License.
<arg name="value" type="int64u"/>
</command>

<command source="server" code="0x0C" name="TestBatchHelperResponse" optional="true" disableDefaultResponse="true" apiMaturity="provisional">
<description>
Delivers the ID of an event in response to test command emitting fabric scoped events.
tehampson marked this conversation as resolved.
Show resolved Hide resolved
</description>
<arg name="buffer" type="octet_string" length="800"/>
tehampson marked this conversation as resolved.
Show resolved Hide resolved
</command>

<event code="0x0001" name="TestEvent" priority="info" side="server">
<description>Example test event</description>
<field id="1" name="arg1" type="int8u"/>
Expand Down
20 changes: 20 additions & 0 deletions src/controller/data_model/controller-clusters.matter
Original file line number Diff line number Diff line change
Expand Up @@ -8647,6 +8647,10 @@ internal cluster UnitTesting = 4294048773 {
NestedStructList arg1[] = 0;
}

response struct TestBatchHelperResponse = 12 {
octet_string<800> buffer = 0;
}

request struct TestListInt8UReverseRequestRequest {
int8u arg1[] = 0;
}
Expand Down Expand Up @@ -8693,6 +8697,18 @@ internal cluster UnitTesting = 4294048773 {
int8u arg1 = 0;
}

request struct TestBatchHelperRequestRequest {
int16u sleepBeforeResponseTimeMs = 0;
int16u sizeOfResponseBuffer = 1;
int8u fillCharacter = 2;
}

request struct TestSecondBatchHelperRequestRequest {
int16u sleepBeforeResponseTimeMs = 0;
int16u sizeOfResponseBuffer = 1;
int8u fillCharacter = 2;
}

/** Simple command without any parameters and without a specific response */
command Test(): DefaultSuccess = 0;
/** Simple command without any parameters and without a specific response not handled by the server */
Expand Down Expand Up @@ -8758,6 +8774,10 @@ internal cluster UnitTesting = 4294048773 {
command TestEmitTestEventRequest(TestEmitTestEventRequestRequest): TestEmitTestEventResponse = 20;
/** Command that takes identical arguments to the fields of the TestFabricScopedEvent and logs the TestFabricScopedEvent to the buffer. Command returns an event ID as the response. */
command TestEmitTestFabricScopedEventRequest(TestEmitTestFabricScopedEventRequestRequest): TestEmitTestFabricScopedEventResponse = 21;
/** Command that responds after sleepBeforeResponseTimeMs with an octet_string the size requested with fillCharacter. */
command TestBatchHelperRequest(TestBatchHelperRequestRequest): TestBatchHelperResponse = 22;
/** Second command that responds after sleepBeforeResponseTimeMs with an octet_string the size requested with fillCharacter. */
command TestSecondBatchHelperRequest(TestSecondBatchHelperRequestRequest): TestBatchHelperResponse = 23;
}

/** The Fault Injection Cluster provide a means for a test harness to configure faults(for example triggering a fault in the system). */
Expand Down
Loading
Loading