From 8b10aadac5807c3b85697e2881dc33d7debc4817 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 13 Jan 2025 15:47:19 -0500 Subject: [PATCH] Add a test that exercises receiving an invalid WriteRequest message. --- src/app/tests/TestWriteInteraction.cpp | 70 ++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/src/app/tests/TestWriteInteraction.cpp b/src/app/tests/TestWriteInteraction.cpp index 6500b5fe0db6a8..e0560ddecbc173 100644 --- a/src/app/tests/TestWriteInteraction.cpp +++ b/src/app/tests/TestWriteInteraction.cpp @@ -19,10 +19,12 @@ #include #include +#include #include #include #include #include +#include #include #include #include @@ -85,6 +87,7 @@ class TestWriteInteraction : public chip::Test::AppContext void TestWriteClient(); void TestWriteClientGroup(); void TestWriteHandlerReceiveInvalidMessage(); + void TestWriteHandlerReceiveEmptyWriteRequest(); void TestWriteInvalidMessage1(); void TestWriteInvalidMessage2(); void TestWriteInvalidMessage3(); @@ -101,9 +104,30 @@ class TestWriteInteraction : public chip::Test::AppContext class TestExchangeDelegate : public Messaging::ExchangeDelegate { +public: + Protocols::InteractionModel::Status mLastStatus = Protocols::InteractionModel::Status::Success; + bool mLastStatusParsedSuccessfully = false; + +private: + CHIP_ERROR UpdateLastStatus(System::PacketBufferHandle && payload) + { + StatusResponseMessage::Parser response; + System::PacketBufferTLVReader reader; + reader.Init(std::move(payload)); + ReturnErrorOnFailure(response.Init(reader)); + StatusIB status; + ReturnErrorOnFailure(response.GetStatus(mLastStatus)); + return CHIP_NO_ERROR; + } + CHIP_ERROR OnMessageReceived(Messaging::ExchangeContext * ec, const PayloadHeader & payloadHeader, System::PacketBufferHandle && payload) override { + if (payloadHeader.HasMessageType(Protocols::InteractionModel::MsgType::StatusResponse)) + { + CHIP_ERROR err = UpdateLastStatus(std::move(payload)); + mLastStatusParsedSuccessfully = (err == CHIP_NO_ERROR); + } return CHIP_NO_ERROR; } @@ -628,6 +652,52 @@ TEST_F(TestWriteInteraction, TestWriteHandlerInvalidateFabric) #endif +// This test sends an invalid (because there is no application payload at all) +// Write Request message and makes sure that a correct Status Response is +// received. +TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteHandlerReceiveEmptyWriteRequest) +{ + Messaging::ReliableMessageMgr * rm = GetExchangeManager().GetReliableMessageMgr(); + // Shouldn't have anything in the retransmit table when starting the test. + EXPECT_EQ(rm->TestGetCountRetransTable(), 0); + + TestWriteClientCallback writeCallback; + auto * engine = chip::app::InteractionModelEngine::GetInstance(); + EXPECT_EQ(engine->Init(&GetExchangeManager(), &GetFabricTable(), app::reporting::GetDefaultReportScheduler()), CHIP_NO_ERROR); + + GetLoopback().mDroppedMessageCount = 0; + GetLoopback().mSentMessageCount = 0; + GetLoopback().mNumMessagesToDrop = 0; + + // Just send an empty message claiming to be a write request. + System::PacketBufferHandle emptyMessage = System::PacketBufferHandle::New(Crypto::CHIP_CRYPTO_AEAD_MIC_LENGTH_BYTES); + + TestExchangeDelegate delegate; + delegate.mLastStatusParsedSuccessfully = false; + + auto exchange = NewExchangeToAlice(&delegate); + EXPECT_NE(exchange, nullptr); + + EXPECT_EQ(exchange->SendMessage(Protocols::InteractionModel::MsgType::WriteRequest, std::move(emptyMessage), + Messaging::SendMessageFlags::kExpectResponse), + CHIP_NO_ERROR); + + DrainAndServiceIO(); + + EXPECT_EQ(InteractionModelEngine::GetInstance()->GetNumActiveWriteHandlers(), 0u); + EXPECT_EQ(GetLoopback().mSentMessageCount, 3u); // Request, response, ack + EXPECT_EQ(GetLoopback().mDroppedMessageCount, 0u); + + EXPECT_TRUE(delegate.mLastStatusParsedSuccessfully); + EXPECT_EQ(delegate.mLastStatus, Protocols::InteractionModel::Status::InvalidAction); + + engine->Shutdown(); + ExpireSessionAliceToBob(); + ExpireSessionBobToAlice(); + CreateSessionAliceToBob(); + CreateSessionBobToAlice(); +} + // Write Client sends a write request, receives an unexpected message type, sends a status response to that. TEST_F_FROM_FIXTURE(TestWriteInteraction, TestWriteInvalidMessage1) {