diff --git a/src/app/tests/TestCommandInteraction.cpp b/src/app/tests/TestCommandInteraction.cpp index df42d3fdb8c70d..8c94259d5fe489 100644 --- a/src/app/tests/TestCommandInteraction.cpp +++ b/src/app/tests/TestCommandInteraction.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -178,6 +179,8 @@ class TestCommandInteraction static void TestCommandHandlerWithProcessReceivedNotExistCommand(nlTestSuite * apSuite, void * apContext); static void TestCommandHandlerWithSendSimpleCommandData(nlTestSuite * apSuite, void * apContext); static void TestCommandHandlerCommandDataEncoding(nlTestSuite * apSuite, void * apContext); + static void TestCommandHandlerCommandEncodeFailure(nlTestSuite * apSuite, void * apContext); + static void TestCommandHandlerCommandEncodeExternalFailure(nlTestSuite * apSuite, void * apContext); static void TestCommandHandlerWithSendSimpleStatusCode(nlTestSuite * apSuite, void * apContext); static void TestCommandHandlerWithSendEmptyResponse(nlTestSuite * apSuite, void * apContext); static void TestCommandHandlerWithProcessReceivedMsg(nlTestSuite * apSuite, void * apContext); @@ -514,6 +517,23 @@ struct Fields } }; +struct BadFields +{ + static constexpr chip::CommandId GetCommandId() { return 4; } + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const + { + TLV::TLVType outerContainerType; + uint8_t data[36] = { 0 }; + ReturnErrorOnFailure(aWriter.StartContainer(aTag, TLV::kTLVType_Structure, outerContainerType)); + // Just encode something bad to return a failure state here. + for (uint8_t i = 1; i < UINT8_MAX; i++) + { + ReturnErrorOnFailure(app::DataModel::Encode(aWriter, TLV::ContextTag(i), ByteSpan(data))); + } + return aWriter.EndContainer(outerContainerType); + } +}; + void TestCommandInteraction::TestCommandHandlerCommandDataEncoding(nlTestSuite * apSuite, void * apContext) { TestContext & ctx = *static_cast(apContext); @@ -542,6 +562,66 @@ void TestCommandInteraction::TestCommandHandlerCommandDataEncoding(nlTestSuite * #endif } +void TestCommandInteraction::TestCommandHandlerCommandEncodeFailure(nlTestSuite * apSuite, void * apContext) +{ + TestContext & ctx = *static_cast(apContext); + CHIP_ERROR err = CHIP_NO_ERROR; + app::CommandHandler commandHandler(nullptr); + System::PacketBufferHandle commandPacket; + + TestExchangeDelegate delegate; + commandHandler.mpExchangeCtx = ctx.NewExchangeToAlice(&delegate); + + auto path = MakeTestCommandPath(); + + err = commandHandler.AddResponseDataOrFailureStatus(ConcreteCommandPath(path.mEndpointId, path.mClusterId, path.mCommandId), + BadFields()); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = commandHandler.Finalize(commandPacket); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + +#if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK + chip::System::PacketBufferTLVReader reader; + InvokeResponseMessage::Parser invokeResponseMessageParser; + reader.Init(std::move(commandPacket)); + err = invokeResponseMessageParser.Init(reader); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = invokeResponseMessageParser.CheckSchemaValidity(); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); +#endif +} + +void TestCommandInteraction::TestCommandHandlerCommandEncodeExternalFailure(nlTestSuite * apSuite, void * apContext) +{ + TestContext & ctx = *static_cast(apContext); + CHIP_ERROR err = CHIP_NO_ERROR; + app::CommandHandler commandHandler(nullptr); + System::PacketBufferHandle commandPacket; + + TestExchangeDelegate delegate; + commandHandler.mpExchangeCtx = ctx.NewExchangeToAlice(&delegate); + + auto path = MakeTestCommandPath(); + + err = commandHandler.AddResponseData(ConcreteCommandPath(path.mEndpointId, path.mClusterId, path.mCommandId), BadFields()); + NL_TEST_ASSERT(apSuite, err != CHIP_NO_ERROR); + err = commandHandler.AddStatus(ConcreteCommandPath(path.mEndpointId, path.mClusterId, path.mCommandId), + Protocols::InteractionModel::Status::Failure); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = commandHandler.Finalize(commandPacket); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + +#if CHIP_CONFIG_IM_ENABLE_SCHEMA_CHECK + chip::System::PacketBufferTLVReader reader; + InvokeResponseMessage::Parser invokeResponseMessageParser; + reader.Init(std::move(commandPacket)); + err = invokeResponseMessageParser.Init(reader); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + err = invokeResponseMessageParser.CheckSchemaValidity(); + NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); +#endif +} + void TestCommandInteraction::TestCommandHandlerWithSendSimpleStatusCode(nlTestSuite * apSuite, void * apContext) { // Send response which has simple status code and command path @@ -768,6 +848,8 @@ const nlTest sTests[] = NL_TEST_DEF("TestCommandSenderWithProcessReceivedMsg", chip::app::TestCommandInteraction::TestCommandSenderWithProcessReceivedMsg), NL_TEST_DEF("TestCommandHandlerWithSendSimpleCommandData", chip::app::TestCommandInteraction::TestCommandHandlerWithSendSimpleCommandData), NL_TEST_DEF("TestCommandHandlerCommandDataEncoding", chip::app::TestCommandInteraction::TestCommandHandlerCommandDataEncoding), + NL_TEST_DEF("TestCommandHandlerCommandEncodeFailure", chip::app::TestCommandInteraction::TestCommandHandlerCommandEncodeFailure), + NL_TEST_DEF("TestCommandHandlerCommandEncodeExternalFailure", chip::app::TestCommandInteraction::TestCommandHandlerCommandEncodeExternalFailure), NL_TEST_DEF("TestCommandHandlerWithSendSimpleStatusCode", chip::app::TestCommandInteraction::TestCommandHandlerWithSendSimpleStatusCode), NL_TEST_DEF("TestCommandHandlerWithProcessReceivedMsg", chip::app::TestCommandInteraction::TestCommandHandlerWithProcessReceivedMsg), NL_TEST_DEF("TestCommandHandlerWithProcessReceivedNotExistCommand", chip::app::TestCommandInteraction::TestCommandHandlerWithProcessReceivedNotExistCommand),