From 126872923d432e72f72310029bd74ea8b972e458 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Thu, 16 Dec 2021 22:32:17 -0500 Subject: [PATCH] Switch TestReliableMessageProtocol to async message delivery (#13099) * Convert TestReliableMessageProtocol to using LoopbackMessagingContext. * Use async message delivery in TestReliableMessageProtocol. --- src/app/tests/AppTestContext.h | 4 +- src/messaging/tests/MessagingContext.cpp | 15 +++ src/messaging/tests/MessagingContext.h | 13 +- src/messaging/tests/TestExchangeMgr.cpp | 2 +- .../tests/TestReliableMessageProtocol.cpp | 117 +++++++++--------- 5 files changed, 89 insertions(+), 62 deletions(-) diff --git a/src/app/tests/AppTestContext.h b/src/app/tests/AppTestContext.h index 96ce8769a53201..d43ffb067f9ac5 100644 --- a/src/app/tests/AppTestContext.h +++ b/src/app/tests/AppTestContext.h @@ -25,9 +25,9 @@ namespace Test { * @brief The context of test cases for messaging layer. It wil initialize network layer and system layer, and create * two secure sessions, connected with each other. Exchanges can be created for each secure session. */ -class AppContext : public LoopbackMessagingContext +class AppContext : public LoopbackMessagingContext<> { - typedef LoopbackMessagingContext Super; + typedef LoopbackMessagingContext<> Super; public: /// Initialize the underlying layers. diff --git a/src/messaging/tests/MessagingContext.cpp b/src/messaging/tests/MessagingContext.cpp index e891147e52ab77..82b5b491176739 100644 --- a/src/messaging/tests/MessagingContext.cpp +++ b/src/messaging/tests/MessagingContext.cpp @@ -29,6 +29,7 @@ CHIP_ERROR MessagingContext::Init(TransportMgrBase * transport, IOContext * ioCo mInitialized = true; mIOContext = ioContext; + mTransport = transport; ReturnErrorOnFailure(mSessionManager.Init(&GetSystemLayer(), transport, &mMessageCounterManager)); @@ -56,6 +57,20 @@ CHIP_ERROR MessagingContext::Shutdown() return CHIP_NO_ERROR; } +CHIP_ERROR MessagingContext::InitFromExisting(const MessagingContext & existing) +{ + return Init(existing.mTransport, existing.mIOContext); +} + +CHIP_ERROR MessagingContext::ShutdownAndRestoreExisting(MessagingContext & existing) +{ + CHIP_ERROR err = Shutdown(); + // Point the transport back to the original session manager, since we had + // pointed it to ours. + existing.mTransport->SetSessionManager(&existing.GetSecureSessionManager()); + return err; +} + SessionHandle MessagingContext::GetSessionBobToAlice() { return mSessionBobToAlice.Get(); diff --git a/src/messaging/tests/MessagingContext.h b/src/messaging/tests/MessagingContext.h index 5ade386fde2134..ef3a261b47a067 100644 --- a/src/messaging/tests/MessagingContext.h +++ b/src/messaging/tests/MessagingContext.h @@ -50,6 +50,14 @@ class MessagingContext // Shutdown all layers, finalize operations CHIP_ERROR Shutdown(); + // Initialize from an existing messaging context. Useful if we want to + // share some state (like the transport). + CHIP_ERROR InitFromExisting(const MessagingContext & existing); + + // The shutdown method to use if using InitFromExisting. Must pass in the + // same existing context as was passed to InitFromExisting. + CHIP_ERROR ShutdownAndRestoreExisting(MessagingContext & existing); + static Inet::IPAddress GetAddress() { Inet::IPAddress addr; @@ -98,6 +106,7 @@ class MessagingContext Messaging::ExchangeManager mExchangeManager; secure_channel::MessageCounterManager mMessageCounterManager; IOContext * mIOContext; + TransportMgrBase * mTransport; // Only needed for InitFromExisting. NodeId mBobNodeId = 123654; NodeId mAliceNodeId = 111222333; @@ -115,7 +124,7 @@ class MessagingContext FabricIndex mDestFabricIndex = 0; }; -template +template class LoopbackMessagingContext : public MessagingContext { public: @@ -166,6 +175,8 @@ class LoopbackMessagingContext : public MessagingContext Transport & GetLoopback() { return mTransportManager.GetTransport().template GetImplAtIndex<0>(); } + TransportMgrBase & GetTransportMgr() { return mTransportManager; } + /* * For unit-tests that simulate end-to-end transmission and reception of messages in loopback mode, * this mode better replicates a real-functioning stack that correctly handles the processing diff --git a/src/messaging/tests/TestExchangeMgr.cpp b/src/messaging/tests/TestExchangeMgr.cpp index 1ac634be96353b..965cd8fbd15073 100644 --- a/src/messaging/tests/TestExchangeMgr.cpp +++ b/src/messaging/tests/TestExchangeMgr.cpp @@ -49,7 +49,7 @@ using namespace chip::Inet; using namespace chip::Transport; using namespace chip::Messaging; -using TestContext = chip::Test::LoopbackMessagingContext; +using TestContext = Test::LoopbackMessagingContext<>; enum : uint8_t { diff --git a/src/messaging/tests/TestReliableMessageProtocol.cpp b/src/messaging/tests/TestReliableMessageProtocol.cpp index 279be96b67b3ac..524a5f97ea0993 100644 --- a/src/messaging/tests/TestReliableMessageProtocol.cpp +++ b/src/messaging/tests/TestReliableMessageProtocol.cpp @@ -55,15 +55,13 @@ using namespace chip::Messaging; using namespace chip::Protocols; using namespace chip::System::Clock::Literals; -using TestContext = chip::Test::MessagingContext; +using TestContext = Test::LoopbackMessagingContext<>; TestContext sContext; const char PAYLOAD[] = "Hello!"; -TransportMgrBase gTransportMgr; -Test::LoopbackTransport gLoopback; -chip::Test::IOContext gIOContext; +auto & gLoopback = sContext.GetLoopback(); class MockAppDelegate : public ExchangeDelegate { @@ -226,6 +224,7 @@ void CheckResendApplicationMessage(nlTestSuite * inSuite, void * inContext) // expect a response. err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendMessageFlags::kExpectResponse); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the message was dropped, and was added to retransmit table NL_TEST_ASSERT(inSuite, gLoopback.mNumMessagesToDrop == 1); @@ -235,6 +234,7 @@ void CheckResendApplicationMessage(nlTestSuite * inSuite, void * inContext) // sleep 65 ms to trigger first re-transmit chip::test_utils::SleepMillis(65); ReliableMessageMgr::Timeout(&ctx.GetSystemLayer(), rm); + ctx.DrainAndServiceIO(); // Ensure the retransmit message was dropped, and is still there in the retransmit table NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 2); @@ -245,6 +245,7 @@ void CheckResendApplicationMessage(nlTestSuite * inSuite, void * inContext) // sleep another 65 ms to trigger second re-transmit chip::test_utils::SleepMillis(65); ReliableMessageMgr::Timeout(&ctx.GetSystemLayer(), rm); + ctx.DrainAndServiceIO(); // Ensure the retransmit message was NOT dropped, and the retransmit table is empty, as we should have gotten an ack NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount >= 3); @@ -287,6 +288,7 @@ void CheckCloseExchangeAndResendApplicationMessage(nlTestSuite * inSuite, void * err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the message was dropped, and was added to retransmit table NL_TEST_ASSERT(inSuite, gLoopback.mNumMessagesToDrop == 1); @@ -296,6 +298,7 @@ void CheckCloseExchangeAndResendApplicationMessage(nlTestSuite * inSuite, void * // sleep 65 ms to trigger first re-transmit chip::test_utils::SleepMillis(65); ReliableMessageMgr::Timeout(&ctx.GetSystemLayer(), rm); + ctx.DrainAndServiceIO(); // Ensure the retransmit message was dropped, and is still there in the retransmit table NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 2); @@ -306,6 +309,7 @@ void CheckCloseExchangeAndResendApplicationMessage(nlTestSuite * inSuite, void * // sleep another 65 ms to trigger second re-transmit chip::test_utils::SleepMillis(65); ReliableMessageMgr::Timeout(&ctx.GetSystemLayer(), rm); + ctx.DrainAndServiceIO(); // Ensure the retransmit message was NOT dropped, and the retransmit table is empty, as we should have gotten an ack NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount >= 3); @@ -349,6 +353,7 @@ void CheckFailedMessageRetainOnSend(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the message was dropped NL_TEST_ASSERT(inSuite, gLoopback.mDroppedMessageCount == 1); @@ -356,6 +361,7 @@ void CheckFailedMessageRetainOnSend(nlTestSuite * inSuite, void * inContext) // sleep 65 ms to trigger first re-transmit chip::test_utils::SleepMillis(65); ReliableMessageMgr::Timeout(&ctx.GetSystemLayer(), rm); + ctx.DrainAndServiceIO(); // Ensure the retransmit table is empty, as we did not provide a message to retain NL_TEST_ASSERT(inSuite, rm->TestGetCountRetransTable() == 0); @@ -395,6 +401,8 @@ void CheckUnencryptedMessageReceiveFailure(nlTestSuite * inSuite, void * inConte // We are sending a malicious packet, doesn't expect an ack err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kNoAutoRequestAck)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); + // Test that the message was actually sent (and not dropped) NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 1); NL_TEST_ASSERT(inSuite, gLoopback.mDroppedMessageCount == 0); @@ -441,6 +449,7 @@ void CheckResendApplicationMessageWithPeerExchange(nlTestSuite * inSuite, void * err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the message was dropped, and was added to retransmit table NL_TEST_ASSERT(inSuite, gLoopback.mNumMessagesToDrop == 0); @@ -451,6 +460,7 @@ void CheckResendApplicationMessageWithPeerExchange(nlTestSuite * inSuite, void * // sleep 65 ms to trigger first re-transmit chip::test_utils::SleepMillis(65); ReliableMessageMgr::Timeout(&ctx.GetSystemLayer(), rm); + ctx.DrainAndServiceIO(); // Ensure the retransmit message was not dropped, and is no longer in the retransmit table NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount >= 2); @@ -506,6 +516,7 @@ void CheckDuplicateMessageClosedExchange(nlTestSuite * inSuite, void * inContext err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the message was sent // The ack was dropped, and message was added to the retransmit table @@ -522,6 +533,7 @@ void CheckDuplicateMessageClosedExchange(nlTestSuite * inSuite, void * inContext // sleep 65 ms to trigger first re-transmit chip::test_utils::SleepMillis(65); ReliableMessageMgr::Timeout(&ctx.GetSystemLayer(), rm); + ctx.DrainAndServiceIO(); // Ensure the retransmit message was sent and the ack was sent // and retransmit table was cleared @@ -533,9 +545,11 @@ void CheckDuplicateMessageClosedExchange(nlTestSuite * inSuite, void * inContext void CheckResendSessionEstablishmentMessageWithPeerExchange(nlTestSuite * inSuite, void * inContext) { // Making this static to reduce stack usage, as some platforms have limits on stack size. - static TestContext ctx; + static Test::MessagingContext ctx; + + TestContext & inctx = *static_cast(inContext); - CHIP_ERROR err = ctx.Init(&gTransportMgr, &gIOContext); + CHIP_ERROR err = ctx.InitFromExisting(inctx); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); chip::System::PacketBufferHandle buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); @@ -576,6 +590,7 @@ void CheckResendSessionEstablishmentMessageWithPeerExchange(nlTestSuite * inSuit err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + inctx.DrainAndServiceIO(); // Ensure the message was dropped, and was added to retransmit table NL_TEST_ASSERT(inSuite, gLoopback.mNumMessagesToDrop == 0); @@ -586,6 +601,7 @@ void CheckResendSessionEstablishmentMessageWithPeerExchange(nlTestSuite * inSuit // sleep 65 ms to trigger first re-transmit chip::test_utils::SleepMillis(65); ReliableMessageMgr::Timeout(&ctx.GetSystemLayer(), rm); + inctx.DrainAndServiceIO(); // Ensure the retransmit message was not dropped, and is no longer in the retransmit table NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount >= 2); @@ -598,16 +614,7 @@ void CheckResendSessionEstablishmentMessageWithPeerExchange(nlTestSuite * inSuit err = ctx.GetExchangeManager().UnregisterUnsolicitedMessageHandlerForType(Echo::MsgType::EchoRequest); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); - ctx.Shutdown(); - - // This test didn't use the global test context because the session establishment messages - // do not carry encryption key IDs (as the messages are not encrypted), or node IDs (as these - // are not assigned yet). A temporary context is created with default values for these - // parameters. - // Let's reset the state of transport manager so that other tests are not impacted - // as those could be using the global test context. - TestContext & inctx = *static_cast(inContext); - gTransportMgr.SetSessionManager(&inctx.GetSecureSessionManager()); + ctx.ShutdownAndRestoreExisting(inctx); } void CheckDuplicateMessage(nlTestSuite * inSuite, void * inContext) @@ -652,6 +659,7 @@ void CheckDuplicateMessage(nlTestSuite * inSuite, void * inContext) err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the message was sent // The ack was dropped, and message was added to the retransmit table @@ -669,6 +677,7 @@ void CheckDuplicateMessage(nlTestSuite * inSuite, void * inContext) // sleep 65 ms to trigger first re-transmit chip::test_utils::SleepMillis(65); ReliableMessageMgr::Timeout(&ctx.GetSystemLayer(), rm); + ctx.DrainAndServiceIO(); // Ensure the retransmit message was sent and the ack was sent // and retransmit table was cleared @@ -718,6 +727,7 @@ void CheckReceiveAfterStandaloneAck(nlTestSuite * inSuite, void * inContext) err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the message was sent. NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 1); @@ -734,6 +744,7 @@ void CheckReceiveAfterStandaloneAck(nlTestSuite * inSuite, void * inContext) // Send the standalone ack. receiverRc->SendStandaloneAckMessage(); + ctx.DrainAndServiceIO(); // Ensure the ack was sent. NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 2); @@ -749,7 +760,9 @@ void CheckReceiveAfterStandaloneAck(nlTestSuite * inSuite, void * inContext) buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); NL_TEST_ASSERT(inSuite, !buffer.IsNull()); - mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer)); + err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer)); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the response and its ack was sent. NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 4); @@ -805,6 +818,7 @@ void CheckPiggybackAfterPiggyback(nlTestSuite * inSuite, void * inContext) err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the message was sent. NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 1); @@ -828,8 +842,11 @@ void CheckPiggybackAfterPiggyback(nlTestSuite * inSuite, void * inContext) buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); NL_TEST_ASSERT(inSuite, !buffer.IsNull()); - mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer), - SendFlags(SendMessageFlags::kExpectResponse).Set(SendMessageFlags::kNoAutoRequestAck)); + err = + mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer), + SendFlags(SendMessageFlags::kExpectResponse).Set(SendMessageFlags::kNoAutoRequestAck)); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the response was sent. NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 2); @@ -852,6 +869,7 @@ void CheckPiggybackAfterPiggyback(nlTestSuite * inSuite, void * inContext) err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse).Set(SendMessageFlags::kNoAutoRequestAck)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the message was sent. NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 3); @@ -873,6 +891,7 @@ void CheckPiggybackAfterPiggyback(nlTestSuite * inSuite, void * inContext) err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the response and its ack was sent. NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 5); @@ -928,6 +947,7 @@ void CheckSendUnsolicitedStandaloneAckMessage(nlTestSuite * inSuite, void * inCo NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); // Needs a manual close, because SendMessage does not close for standalone acks. exchange->Close(); + ctx.DrainAndServiceIO(); // Ensure the message and its ack were sent. NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 2); @@ -951,6 +971,7 @@ void CheckSendStandaloneAckMessage(nlTestSuite * inSuite, void * inContext) NL_TEST_ASSERT(inSuite, rc != nullptr); NL_TEST_ASSERT(inSuite, rc->SendStandaloneAckMessage() == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Need manual close because standalone acks don't close exchanges. exchange->Close(); @@ -1009,6 +1030,7 @@ void CheckMessageAfterClosed(nlTestSuite * inSuite, void * inContext) err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the message was sent. NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 1); @@ -1033,7 +1055,9 @@ void CheckMessageAfterClosed(nlTestSuite * inSuite, void * inContext) buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); NL_TEST_ASSERT(inSuite, !buffer.IsNull()); - mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer)); + err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer)); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the response was sent. NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 2); @@ -1057,6 +1081,7 @@ void CheckMessageAfterClosed(nlTestSuite * inSuite, void * inContext) err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the message was sent (and the ack for it was also sent). NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 4); @@ -1132,6 +1157,7 @@ void CheckLostResponseWithPiggyback(nlTestSuite * inSuite, void * inContext) err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the message was sent. NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 1); @@ -1165,7 +1191,9 @@ void CheckLostResponseWithPiggyback(nlTestSuite * inSuite, void * inContext) // Stop keeping receiver exchange alive. mockReceiver.mRetainExchange = true; - mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer)); + err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer)); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the response was sent but dropped. NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 2); @@ -1188,6 +1216,7 @@ void CheckLostResponseWithPiggyback(nlTestSuite * inSuite, void * inContext) // sleep 65 ms to trigger re-transmit from sender chip::test_utils::SleepMillis(65); ReliableMessageMgr::Timeout(&ctx.GetSystemLayer(), rm); + ctx.DrainAndServiceIO(); // We resent our first message, which did not make it to the app-level // listener on the receiver (because it's a duplicate) but did trigger a @@ -1217,6 +1246,7 @@ void CheckLostResponseWithPiggyback(nlTestSuite * inSuite, void * inContext) // sleep 65*3 ms to trigger re-transmit from receiver chip::test_utils::SleepMillis(65 * 3); ReliableMessageMgr::Timeout(&ctx.GetSystemLayer(), rm); + ctx.DrainAndServiceIO(); // And now we've definitely resent our response message, which should show // up as an app-level message and trigger a standalone ack. @@ -1281,6 +1311,7 @@ void CheckLostStandaloneAck(nlTestSuite * inSuite, void * inContext) err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer), SendFlags(SendMessageFlags::kExpectResponse)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the message was sent. NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 1); @@ -1304,8 +1335,10 @@ void CheckLostStandaloneAck(nlTestSuite * inSuite, void * inContext) buffer = chip::MessagePacketBuffer::NewWithData(PAYLOAD, sizeof(PAYLOAD)); NL_TEST_ASSERT(inSuite, !buffer.IsNull()); - mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer), - SendFlags(SendMessageFlags::kExpectResponse)); + err = mockReceiver.mExchange->SendMessage(Echo::MsgType::EchoResponse, std::move(buffer), + SendFlags(SendMessageFlags::kExpectResponse)); + NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the response was sent. NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 2); @@ -1332,6 +1365,7 @@ void CheckLostStandaloneAck(nlTestSuite * inSuite, void * inContext) err = exchange->SendMessage(Echo::MsgType::EchoRequest, std::move(buffer)); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); // Ensure the message and the standalone ack to it were sent. NL_TEST_ASSERT(inSuite, gLoopback.mSentMessageCount == 4); @@ -1390,49 +1424,16 @@ const nlTest sTests[] = NL_TEST_SENTINEL() }; -// clang-format on -int Initialize(void * aContext); -int Finalize(void * aContext); - -// clang-format off nlTestSuite sSuite = { "Test-CHIP-ReliableMessageProtocol", &sTests[0], - Initialize, - Finalize + TestContext::InitializeAsync, + TestContext::Finalize }; // clang-format on -/** - * Initialize the test suite. - */ -int Initialize(void * aContext) -{ - // Initialize System memory and resources - VerifyOrReturnError(chip::Platform::MemoryInit() == CHIP_NO_ERROR, FAILURE); - VerifyOrReturnError(gIOContext.Init() == CHIP_NO_ERROR, FAILURE); - VerifyOrReturnError(gTransportMgr.Init(&gLoopback) == CHIP_NO_ERROR, FAILURE); - - auto * ctx = static_cast(aContext); - VerifyOrReturnError(ctx->Init(&gTransportMgr, &gIOContext) == CHIP_NO_ERROR, FAILURE); - - gTransportMgr.SetSessionManager(&ctx->GetSecureSessionManager()); - return SUCCESS; -} - -/** - * Finalize the test suite. - */ -int Finalize(void * aContext) -{ - CHIP_ERROR err = reinterpret_cast(aContext)->Shutdown(); - gIOContext.Shutdown(); - chip::Platform::MemoryShutdown(); - return (err == CHIP_NO_ERROR) ? SUCCESS : FAILURE; -} - } // namespace /**