From 5d924c29c43e7104906e22c3098a2767533ad55f Mon Sep 17 00:00:00 2001 From: Zang MingJie Date: Fri, 22 Apr 2022 21:22:42 +0800 Subject: [PATCH] Use async loopback transport for all tests (#17622) * Use async loopback transport for all tests * Resolve comments * Add comment about cleaning loopback queue --- src/app/tests/AppTestContext.h | 8 +- src/app/tests/TestBufferedReadCallback.cpp | 2 +- src/app/tests/TestClusterStateCache.cpp | 2 +- src/app/tests/TestCommandInteraction.cpp | 2 +- src/app/tests/TestEventLogging.cpp | 6 +- src/app/tests/TestEventOverflow.cpp | 6 +- src/app/tests/TestInteractionModelEngine.cpp | 2 +- src/app/tests/TestReadInteraction.cpp | 9 +- src/app/tests/TestReportingEngine.cpp | 2 +- src/app/tests/TestTimedHandler.cpp | 2 +- src/app/tests/TestWriteInteraction.cpp | 21 +--- src/controller/tests/TestEventCaching.cpp | 6 +- src/controller/tests/TestEventChunking.cpp | 6 +- src/controller/tests/TestReadChunking.cpp | 2 +- .../tests/TestServerCommandDispatch.cpp | 4 +- src/controller/tests/TestWriteChunking.cpp | 2 +- .../tests/data_model/TestCommands.cpp | 2 +- src/controller/tests/data_model/TestRead.cpp | 2 +- src/controller/tests/data_model/TestWrite.cpp | 2 +- src/messaging/ExchangeContext.cpp | 15 --- src/messaging/ReliableMessageContext.h | 7 +- src/messaging/tests/BUILD.gn | 2 +- src/messaging/tests/MessagingContext.h | 113 ++---------------- src/messaging/tests/TestExchangeMgr.cpp | 5 +- .../tests/TestReliableMessageProtocol.cpp | 5 +- .../secure_channel/tests/TestCASESession.cpp | 4 +- .../tests/TestMessageCounterManager.cpp | 16 +-- .../secure_channel/tests/TestPASESession.cpp | 20 ++-- src/transport/raw/tests/NetworkTestHelpers.h | 69 +++++------ src/transport/tests/BUILD.gn | 12 +- .../tests/LoopbackTransportManager.h | 107 +++++++++++++++++ src/transport/tests/TestSessionManager.cpp | 86 ++++++------- 32 files changed, 247 insertions(+), 302 deletions(-) create mode 100644 src/transport/tests/LoopbackTransportManager.h diff --git a/src/app/tests/AppTestContext.h b/src/app/tests/AppTestContext.h index 19401c634b81b7..fa7d76f03e5d3d 100644 --- a/src/app/tests/AppTestContext.h +++ b/src/app/tests/AppTestContext.h @@ -16,7 +16,6 @@ #pragma once #include -#include namespace chip { namespace Test { @@ -25,14 +24,11 @@ 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: - // Disallow initialization as a sync loopback context. - static void Initialize(void *) = delete; - /// Initialize the underlying layers. CHIP_ERROR Init() override; diff --git a/src/app/tests/TestBufferedReadCallback.cpp b/src/app/tests/TestBufferedReadCallback.cpp index 0434fefd4fed92..82f45c6ca7bad9 100644 --- a/src/app/tests/TestBufferedReadCallback.cpp +++ b/src/app/tests/TestBufferedReadCallback.cpp @@ -609,7 +609,7 @@ nlTestSuite theSuite = { "TestBufferedReadCallback", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; diff --git a/src/app/tests/TestClusterStateCache.cpp b/src/app/tests/TestClusterStateCache.cpp index 0bca99063716d4..de447223f7512e 100644 --- a/src/app/tests/TestClusterStateCache.cpp +++ b/src/app/tests/TestClusterStateCache.cpp @@ -625,7 +625,7 @@ nlTestSuite theSuite = { "TestClusterStateCache", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; diff --git a/src/app/tests/TestCommandInteraction.cpp b/src/app/tests/TestCommandInteraction.cpp index cb7b7ff1022bb8..298896ac3d69ff 100644 --- a/src/app/tests/TestCommandInteraction.cpp +++ b/src/app/tests/TestCommandInteraction.cpp @@ -924,7 +924,7 @@ nlTestSuite sSuite = { "TestCommandInteraction", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; // clang-format on diff --git a/src/app/tests/TestEventLogging.cpp b/src/app/tests/TestEventLogging.cpp index d3671d63ce866d..a9d70c28d4de82 100644 --- a/src/app/tests/TestEventLogging.cpp +++ b/src/app/tests/TestEventLogging.cpp @@ -61,9 +61,9 @@ static chip::app::CircularEventBuffer gCircularEventBuffer[3]; class TestContext : public chip::Test::AppContext { public: - static int InitializeAsync(void * context) + static int Initialize(void * context) { - if (AppContext::InitializeAsync(context) != SUCCESS) + if (AppContext::Initialize(context) != SUCCESS) return FAILURE; auto * ctx = static_cast(context); @@ -302,7 +302,7 @@ nlTestSuite sSuite = { "EventLogging", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; // clang-format on diff --git a/src/app/tests/TestEventOverflow.cpp b/src/app/tests/TestEventOverflow.cpp index 4039ddddef9662..66e13176b53f0b 100644 --- a/src/app/tests/TestEventOverflow.cpp +++ b/src/app/tests/TestEventOverflow.cpp @@ -53,9 +53,9 @@ static chip::app::CircularEventBuffer gCircularEventBuffer[3]; class TestContext : public chip::Test::AppContext { public: - static int InitializeAsync(void * context) + static int Initialize(void * context) { - if (AppContext::InitializeAsync(context) != SUCCESS) + if (AppContext::Initialize(context) != SUCCESS) return FAILURE; auto * ctx = static_cast(context); @@ -176,7 +176,7 @@ nlTestSuite sSuite = { "TestEventOverflow", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; // clang-format on diff --git a/src/app/tests/TestInteractionModelEngine.cpp b/src/app/tests/TestInteractionModelEngine.cpp index fe5814d6511df0..ce461f8d8b09ac 100644 --- a/src/app/tests/TestInteractionModelEngine.cpp +++ b/src/app/tests/TestInteractionModelEngine.cpp @@ -113,7 +113,7 @@ nlTestSuite sSuite = { "TestInteractionModelEngine", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; // clang-format on diff --git a/src/app/tests/TestReadInteraction.cpp b/src/app/tests/TestReadInteraction.cpp index 1e0c9fc7008470..5dcd67daa98511 100644 --- a/src/app/tests/TestReadInteraction.cpp +++ b/src/app/tests/TestReadInteraction.cpp @@ -64,11 +64,9 @@ chip::DataVersion kTestDataVersion2 = 5; class TestContext : public chip::Test::AppContext { public: - static int Initialize(void * context) = delete; - - static int InitializeAsync(void * context) + static int Initialize(void * context) { - if (AppContext::InitializeAsync(context) != SUCCESS) + if (AppContext::Initialize(context) != SUCCESS) return FAILURE; auto * ctx = static_cast(context); @@ -105,7 +103,6 @@ class TestContext : public chip::Test::AppContext }; TestContext sContext; -auto & sLoopback = sContext.GetLoopback(); class TestEventGenerator : public chip::app::EventLoggingDelegate { @@ -2609,7 +2606,7 @@ nlTestSuite sSuite = { "TestReadInteraction", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; // clang-format on diff --git a/src/app/tests/TestReportingEngine.cpp b/src/app/tests/TestReportingEngine.cpp index 3b5213de5d3334..7efee4292f2d7e 100644 --- a/src/app/tests/TestReportingEngine.cpp +++ b/src/app/tests/TestReportingEngine.cpp @@ -195,7 +195,7 @@ nlTestSuite sSuite = { "TestReportingEngine", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; // clang-format on diff --git a/src/app/tests/TestTimedHandler.cpp b/src/app/tests/TestTimedHandler.cpp index 2af7563b2c3141..0fb1a35a31ba8a 100644 --- a/src/app/tests/TestTimedHandler.cpp +++ b/src/app/tests/TestTimedHandler.cpp @@ -258,7 +258,7 @@ nlTestSuite sSuite = { "TestTimedHandler", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; // clang-format on diff --git a/src/app/tests/TestWriteInteraction.cpp b/src/app/tests/TestWriteInteraction.cpp index 822e89d81f1716..6c286786990617 100644 --- a/src/app/tests/TestWriteInteraction.cpp +++ b/src/app/tests/TestWriteInteraction.cpp @@ -276,22 +276,6 @@ void TestWriteInteraction::TestWriteHandler(nlTestSuite * apSuite, void * apCont TestContext & ctx = *static_cast(apContext); - // - // We have to enable async dispatch here to ensure that the exchange - // gets correctly closed out in the test below. Otherwise, the following happens: - // - // 1. WriteHandler generates a response upon OnWriteRequest being called. - // 2. Since there is no matching active client-side exchange for that request, the IM engine - // handles it incorrectly and treats it like an unsolicited message. - // 3. It is invalid to receive a WriteResponse as an unsolicited message so it correctly sends back - // a StatusResponse containing an error to that message. - // 4. Without unwinding the existing call stack, a response is received on the same exchange that the handler - // generated a WriteResponse on. This exchange should have been closed in a normal execution model, but in - // a synchronous model, the exchange is still open, and the status response is sent to the WriteHandler. - // 5. WriteHandler::OnMessageReceived is invoked, and it correctly asserts. - // - ctx.EnableAsyncDispatch(); - constexpr bool allBooleans[] = { true, false }; for (auto messageIsTimed : allBooleans) { @@ -328,15 +312,12 @@ void TestWriteInteraction::TestWriteHandler(nlTestSuite * apSuite, void * apCont NL_TEST_ASSERT(apSuite, status == Status::UnsupportedAccess); } - ctx.DrainAndServiceIO(); ctx.DrainAndServiceIO(); Messaging::ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr(); NL_TEST_ASSERT(apSuite, rm->TestGetCountRetransTable() == 0); } } - - ctx.DisableAsyncDispatch(); } const EmberAfAttributeMetadata * GetAttributeMetadata(const ConcreteAttributePath & aConcreteClusterPath) @@ -490,7 +471,7 @@ int Test_Setup(void * inContext) { VerifyOrReturnError(CHIP_NO_ERROR == chip::Platform::MemoryInit(), FAILURE); - VerifyOrReturnError(TestContext::InitializeAsync(inContext) == SUCCESS, FAILURE); + VerifyOrReturnError(TestContext::Initialize(inContext) == SUCCESS, FAILURE); TestContext & ctx = *static_cast(inContext); gTestStorage.ClearStorage(); diff --git a/src/controller/tests/TestEventCaching.cpp b/src/controller/tests/TestEventCaching.cpp index c7aae2f1ab8604..cc00ea81bec51d 100644 --- a/src/controller/tests/TestEventCaching.cpp +++ b/src/controller/tests/TestEventCaching.cpp @@ -54,9 +54,9 @@ static chip::app::CircularEventBuffer gCircularEventBuffer[3]; class TestContext : public chip::Test::AppContext { public: - static int InitializeAsync(void * context) + static int Initialize(void * context) { - if (AppContext::InitializeAsync(context) != SUCCESS) + if (AppContext::Initialize(context) != SUCCESS) return FAILURE; auto * ctx = static_cast(context); @@ -454,7 +454,7 @@ nlTestSuite sSuite = { "TestEventCaching", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; // clang-format on diff --git a/src/controller/tests/TestEventChunking.cpp b/src/controller/tests/TestEventChunking.cpp index 05549597b08172..98c431426c34c4 100644 --- a/src/controller/tests/TestEventChunking.cpp +++ b/src/controller/tests/TestEventChunking.cpp @@ -54,9 +54,9 @@ static chip::app::CircularEventBuffer gCircularEventBuffer[3]; class TestContext : public chip::Test::AppContext { public: - static int InitializeAsync(void * context) + static int Initialize(void * context) { - if (AppContext::InitializeAsync(context) != SUCCESS) + if (AppContext::Initialize(context) != SUCCESS) return FAILURE; auto * ctx = static_cast(context); @@ -534,7 +534,7 @@ nlTestSuite sSuite = { "TestEventChunking", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; // clang-format on diff --git a/src/controller/tests/TestReadChunking.cpp b/src/controller/tests/TestReadChunking.cpp index 585c09f882753e..572990d1ca70cf 100644 --- a/src/controller/tests/TestReadChunking.cpp +++ b/src/controller/tests/TestReadChunking.cpp @@ -908,7 +908,7 @@ nlTestSuite sSuite = { "TestReadChunking", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; // clang-format on diff --git a/src/controller/tests/TestServerCommandDispatch.cpp b/src/controller/tests/TestServerCommandDispatch.cpp index 51f9bc3cfa615c..a6812b1d2ad7df 100644 --- a/src/controller/tests/TestServerCommandDispatch.cpp +++ b/src/controller/tests/TestServerCommandDispatch.cpp @@ -184,8 +184,6 @@ void TestCommandInteraction::TestNoHandler(nlTestSuite * apSuite, void * apConte responseDirective = kSendDataResponse; - ctx.EnableAsyncDispatch(); - chip::Controller::InvokeCommandRequest(&ctx.GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, onFailureCb); @@ -402,7 +400,7 @@ nlTestSuite sSuite = { "TestCommands", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; // clang-format on diff --git a/src/controller/tests/TestWriteChunking.cpp b/src/controller/tests/TestWriteChunking.cpp index f008fa934b5afd..6917aa0d17a38e 100644 --- a/src/controller/tests/TestWriteChunking.cpp +++ b/src/controller/tests/TestWriteChunking.cpp @@ -727,7 +727,7 @@ nlTestSuite sSuite = { "TestWriteChunking", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; // clang-format on diff --git a/src/controller/tests/data_model/TestCommands.cpp b/src/controller/tests/data_model/TestCommands.cpp index 3de71240658ac0..49a88f295015d3 100644 --- a/src/controller/tests/data_model/TestCommands.cpp +++ b/src/controller/tests/data_model/TestCommands.cpp @@ -450,7 +450,7 @@ nlTestSuite sSuite = { "TestCommands", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; // clang-format on diff --git a/src/controller/tests/data_model/TestRead.cpp b/src/controller/tests/data_model/TestRead.cpp index 295ad9355f5f3d..348b3d43284251 100644 --- a/src/controller/tests/data_model/TestRead.cpp +++ b/src/controller/tests/data_model/TestRead.cpp @@ -1490,7 +1490,7 @@ nlTestSuite sSuite = { "TestRead", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; // clang-format on diff --git a/src/controller/tests/data_model/TestWrite.cpp b/src/controller/tests/data_model/TestWrite.cpp index 8a873f09d63c92..78167c4895830e 100644 --- a/src/controller/tests/data_model/TestWrite.cpp +++ b/src/controller/tests/data_model/TestWrite.cpp @@ -384,7 +384,7 @@ nlTestSuite sSuite = { "TestWrite", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; // clang-format on diff --git a/src/messaging/ExchangeContext.cpp b/src/messaging/ExchangeContext.cpp index 3af9f00450ded1..64d8868c837efc 100644 --- a/src/messaging/ExchangeContext.cpp +++ b/src/messaging/ExchangeContext.cpp @@ -424,25 +424,10 @@ CHIP_ERROR ExchangeContext::HandleMessage(uint32_t messageCounter, const Payload // layer has completed its work on the ExchangeContext. ExchangeHandle ref(*this); - // Keep track of whether we're nested under an outer HandleMessage - // invocation. - bool alreadyHandlingMessage = mFlags.Has(Flags::kFlagHandlingMessage); - mFlags.Set(Flags::kFlagHandlingMessage); - bool isStandaloneAck = payloadHeader.HasMessageType(Protocols::SecureChannel::MsgType::StandaloneAck); bool isDuplicate = msgFlags.Has(MessageFlagValues::kDuplicateMessage); auto deferred = MakeDefer([&]() { - // The alreadyHandlingMessage check is effectively a workaround for the fact that SendMessage() is not calling - // MessageHandled() yet and will go away when we fix that. - if (alreadyHandlingMessage) - { - // Don't close if there's an outer HandleMessage invocation. It'll deal with the closing. - return; - } - // We are the outermost HandleMessage invocation. We're not handling a message anymore. - mFlags.Clear(Flags::kFlagHandlingMessage); - // Duplicates and standalone acks are not application-level messages, so they should generally not lead to any state // changes. The one exception to that is that if we have a null mDelegate then our lifetime is not application-defined, // since we don't interact with the application at that point. That can happen when we are already closed (in which case diff --git a/src/messaging/ReliableMessageContext.h b/src/messaging/ReliableMessageContext.h index 19bfeca4e993c3..d60c057f61086f 100644 --- a/src/messaging/ReliableMessageContext.h +++ b/src/messaging/ReliableMessageContext.h @@ -198,14 +198,11 @@ class ReliableMessageContext /// When set, signifies that this exchange is waiting for a call to SendMessage. kFlagWillSendMessage = (1u << 8), - /// When set, signifies that we are currently in the middle of HandleMessage. - kFlagHandlingMessage = (1u << 9), - /// When set, we have had Close() or Abort() called on us already. - kFlagClosed = (1u << 10), + kFlagClosed = (1u << 9), /// When set, signifies that the exchange is requesting Sleepy End Device fast-polling mode. - kFlagFastPollingMode = (1u << 11), + kFlagFastPollingMode = (1u << 10), }; BitFlags mFlags; // Internal state flags diff --git a/src/messaging/tests/BUILD.gn b/src/messaging/tests/BUILD.gn index 5caa64a50579ea..10f34fca6d2f45 100644 --- a/src/messaging/tests/BUILD.gn +++ b/src/messaging/tests/BUILD.gn @@ -35,7 +35,7 @@ static_library("helpers") { "${chip_root}/src/messaging", "${chip_root}/src/protocols", "${chip_root}/src/transport", - "${chip_root}/src/transport/raw/tests:helpers", + "${chip_root}/src/transport/tests:helpers", "${nlio_root}:nlio", ] } diff --git a/src/messaging/tests/MessagingContext.h b/src/messaging/tests/MessagingContext.h index 18f3a479ca1f34..e7bad99dd533cb 100644 --- a/src/messaging/tests/MessagingContext.h +++ b/src/messaging/tests/MessagingContext.h @@ -24,7 +24,7 @@ #include #include #include -#include +#include #include @@ -158,8 +158,8 @@ class MessagingContext : public PlatformMemoryUser Optional mSessionBobToFriends; }; -template -class LoopbackMessagingContext : public MessagingContext +// LoopbackMessagingContext enriches MessagingContext with an async loopback transport +class LoopbackMessagingContext : public LoopbackTransportManager, public MessagingContext { public: virtual ~LoopbackMessagingContext() {} @@ -168,9 +168,8 @@ class LoopbackMessagingContext : public MessagingContext virtual CHIP_ERROR Init() { ReturnErrorOnFailure(chip::Platform::MemoryInit()); - ReturnErrorOnFailure(mIOContext.Init()); - ReturnErrorOnFailure(mTransportManager.Init("LOOPBACK")); - ReturnErrorOnFailure(MessagingContext::Init(&mTransportManager, &mIOContext)); + ReturnErrorOnFailure(LoopbackTransportManager::Init()); + ReturnErrorOnFailure(MessagingContext::Init(&GetTransportMgr(), &GetIOContext())); return CHIP_NO_ERROR; } @@ -178,7 +177,7 @@ class LoopbackMessagingContext : public MessagingContext virtual CHIP_ERROR Shutdown() { ReturnErrorOnFailure(MessagingContext::Shutdown()); - ReturnErrorOnFailure(mIOContext.Shutdown()); + ReturnErrorOnFailure(LoopbackTransportManager::Shutdown()); chip::Platform::MemoryShutdown(); return CHIP_NO_ERROR; } @@ -191,111 +190,13 @@ class LoopbackMessagingContext : public MessagingContext return ctx->Init() == CHIP_NO_ERROR ? SUCCESS : FAILURE; } - static int InitializeAsync(void * context) - { - auto * ctx = static_cast(context); - - VerifyOrReturnError(ctx->Init() == CHIP_NO_ERROR, FAILURE); - ctx->EnableAsyncDispatch(); - - return SUCCESS; - } - static int Finalize(void * context) { auto * ctx = static_cast(context); return ctx->Shutdown() == CHIP_NO_ERROR ? SUCCESS : FAILURE; } - Transport & GetLoopback() { return mTransportManager.GetTransport().template GetImplAtIndex<0>(); } - - TransportMgrBase & GetTransportMgr() { return mTransportManager; } - - IOContext & GetIOContext() { return mIOContext; } - - /* - * 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 - * of a transmitted message as an asynchronous, bottom half handler dispatched after the current execution context has - completed. - * This is achieved using SystemLayer::ScheduleWork. - - * This should be used in conjunction with the DrainAndServiceIO function below to correctly service and drain the event queue. - * - */ - void EnableAsyncDispatch() - { - auto & impl = GetLoopback(); - impl.EnableAsyncDispatch(&mIOContext.GetSystemLayer()); - } - - /* - * Reset the dispatch back to a model that synchronously dispatches received messages up the stack. - * - * NOTE: This results in highly atypical/complex call stacks that are not representative of what happens on real - * devices and can cause subtle and complex bugs to either appear or get masked in the system. Where possible, please - * use this sparingly! - * - */ - void DisableAsyncDispatch() - { - auto & impl = GetLoopback(); - impl.DisableAsyncDispatch(); - } - - /* - * This drives the servicing of events using the embedded IOContext while there are pending - * messages in the loopback transport's pending message queue. This should run to completion - * in well-behaved logic (i.e there isn't an indefinite ping-pong of messages transmitted back - * and forth). - * - * Consequently, this is guarded with a user-provided timeout to ensure we don't have unit-tests that stall - * in CI due to bugs in the code that is being tested. - * - * This DOES NOT ensure that all pending events are serviced to completion - * (i.e timers, any ScheduleWork calls), but does: - * - * 1) Guarantee that every call will make some progress on ready-to-run - * things, by calling DriveIO at least once. - * 2) Try to ensure that any ScheduleWork calls that happend directly as a - * result of message reception, and any messages those async tasks send, - * get handled before DrainAndServiceIO returns. - */ - void DrainAndServiceIO(System::Clock::Timeout maxWait = chip::System::Clock::Seconds16(5)) - { - auto & impl = GetLoopback(); - System::Clock::Timestamp startTime = System::SystemClock().GetMonotonicTimestamp(); - - while (true) - { - bool hadPendingMessages = impl.HasPendingMessages(); - while (impl.HasPendingMessages()) - { - mIOContext.DriveIO(); - if ((System::SystemClock().GetMonotonicTimestamp() - startTime) >= maxWait) - { - return; - } - } - // Processing those messages might have queued some run-ASAP async - // work. Make sure to process that too, in case it generates - // response messages. - mIOContext.DriveIO(); - if (!hadPendingMessages && !impl.HasPendingMessages()) - { - // We're not making any progress on messages. Just stop. - break; - } - // No need to check our timer here: either impl.HasPendingMessages() - // is true and we will check it next iteration, or it's false and we - // will either stop on the next iteration or it will become true and - // we will check the timer then. - } - } - -private: - TransportMgr mTransportManager; - Test::IOContext mIOContext; + using LoopbackTransportManager::GetSystemLayer; }; } // namespace Test diff --git a/src/messaging/tests/TestExchangeMgr.cpp b/src/messaging/tests/TestExchangeMgr.cpp index 9a6025eabb7afb..5b63eff590a19e 100644 --- a/src/messaging/tests/TestExchangeMgr.cpp +++ b/src/messaging/tests/TestExchangeMgr.cpp @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -49,7 +48,7 @@ using namespace chip::Inet; using namespace chip::Transport; using namespace chip::Messaging; -using TestContext = Test::LoopbackMessagingContext<>; +using TestContext = Test::LoopbackMessagingContext; enum : uint8_t { @@ -251,7 +250,7 @@ nlTestSuite sSuite = { "Test-CHIP-ExchangeManager", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize }; // clang-format on diff --git a/src/messaging/tests/TestReliableMessageProtocol.cpp b/src/messaging/tests/TestReliableMessageProtocol.cpp index 1698fc0dbe824b..406a8cb1896f32 100644 --- a/src/messaging/tests/TestReliableMessageProtocol.cpp +++ b/src/messaging/tests/TestReliableMessageProtocol.cpp @@ -44,7 +44,6 @@ #include #include #include -#include namespace { @@ -55,7 +54,7 @@ using namespace chip::Messaging; using namespace chip::Protocols; using namespace chip::System::Clock::Literals; -using TestContext = Test::LoopbackMessagingContext<>; +using TestContext = Test::LoopbackMessagingContext; TestContext sContext; @@ -1587,7 +1586,7 @@ nlTestSuite sSuite = { "Test-CHIP-ReliableMessageProtocol", &sTests[0], - TestContext::InitializeAsync, + TestContext::Initialize, TestContext::Finalize, InitializeTestCase, }; diff --git a/src/protocols/secure_channel/tests/TestCASESession.cpp b/src/protocols/secure_channel/tests/TestCASESession.cpp index b714b52e203e6e..665d84df47021d 100644 --- a/src/protocols/secure_channel/tests/TestCASESession.cpp +++ b/src/protocols/secure_channel/tests/TestCASESession.cpp @@ -37,7 +37,6 @@ #include #include #include -#include #include "credentials/tests/CHIPCert_test_vectors.h" @@ -51,7 +50,7 @@ using namespace chip::Transport; using namespace chip::Messaging; using namespace chip::Protocols; -using TestContext = Test::LoopbackMessagingContext<>; +using TestContext = Test::LoopbackMessagingContext; namespace { TestContext sContext; @@ -654,7 +653,6 @@ CHIP_ERROR CASETestSecurePairingSetup(void * inContext) ctx.ConfigInitializeNodes(false); ReturnErrorOnFailure(ctx.Init()); - ctx.EnableAsyncDispatch(); gCommissionerFabrics.Init(&gCommissionerStorageDelegate); gDeviceFabrics.Init(&gDeviceStorageDelegate); diff --git a/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp b/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp index 2a9528436b098c..28206c1136193f 100644 --- a/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp +++ b/src/protocols/secure_channel/tests/TestMessageCounterManager.cpp @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -48,13 +47,9 @@ using namespace chip::Transport; using namespace chip::Messaging; using namespace chip::Protocols; -using TestContext = chip::Test::MessagingContext; - +using TestContext = chip::Test::LoopbackMessagingContext; TestContext sContext; -TransportMgr gTransportMgr; -chip::Test::IOContext gIOContext; - const char PAYLOAD[] = "Hello!"; class MockAppDelegate : public ExchangeDelegate @@ -152,13 +147,8 @@ nlTestSuite sSuite = */ int Initialize(void * aContext) { - // Initialize System memory and resources - VerifyOrReturnError(chip::Platform::MemoryInit() == CHIP_NO_ERROR, FAILURE); - VerifyOrReturnError(gIOContext.Init(&sSuite) == CHIP_NO_ERROR, FAILURE); - VerifyOrReturnError(gTransportMgr.Init("LOOPBACK") == CHIP_NO_ERROR, FAILURE); - auto * ctx = static_cast(aContext); - VerifyOrReturnError(ctx->Init(&sSuite, &gTransportMgr, &gIOContext) == CHIP_NO_ERROR, FAILURE); + VerifyOrReturnError(ctx->Init(&sSuite) == CHIP_NO_ERROR, FAILURE); return SUCCESS; } @@ -169,8 +159,6 @@ int Initialize(void * aContext) int Finalize(void * aContext) { CHIP_ERROR err = reinterpret_cast(aContext)->Shutdown(); - gIOContext.Shutdown(); - chip::Platform::MemoryShutdown(); return (err == CHIP_NO_ERROR) ? SUCCESS : FAILURE; } diff --git a/src/protocols/secure_channel/tests/TestPASESession.cpp b/src/protocols/secure_channel/tests/TestPASESession.cpp index 598dee3c53dd5d..b9eaf37f25a084 100644 --- a/src/protocols/secure_channel/tests/TestPASESession.cpp +++ b/src/protocols/secure_channel/tests/TestPASESession.cpp @@ -33,7 +33,6 @@ #include #include #include -#include // This test suite pushes multiple PASESession objects onto the stack for the // purposes of testing device-to-device communication. However, in the real @@ -73,17 +72,14 @@ constexpr Spake2pVerifierSerialized sTestSpake2p01_SerializedVerifier = { 0xB7, 0xC0, 0x7F, 0xCC, 0x06, 0x27, 0xA1, 0xB8, 0x57, 0x3A, 0x14, 0x9F, 0xCD, 0x1F, 0xA4, 0x66, 0xCF }; -class PASETestLoopbackTransport : public Test::LoopbackTransport +class PASETestLoopbackTransportDelegate : public Test::LoopbackTransportDelegate { - void MessageDropped() override { mMessageDropped = true; } - public: - bool CanSendToPeer(const PeerAddress & address) override { return true; } - + void OnMessageDropped() override { mMessageDropped = true; } bool mMessageDropped = false; }; -using TestContext = chip::Test::LoopbackMessagingContext; +using TestContext = chip::Test::LoopbackMessagingContext; TestContext sContext; auto & gLoopback = sContext.GetLoopback(); @@ -208,6 +204,8 @@ void SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inContext, P PASESession pairingAccessory; SessionManager sessionManager; + PASETestLoopbackTransportDelegate delegate; + gLoopback.SetLoopbackTransportDelegate(&delegate); gLoopback.mSentMessageCount = 0; ExchangeContext * contextCommissioner = ctx.NewUnauthenticatedExchangeToBob(&pairingCommissioner); @@ -240,10 +238,10 @@ void SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inContext, P &delegateCommissioner) == CHIP_NO_ERROR); ctx.DrainAndServiceIO(); - while (gLoopback.mMessageDropped) + while (delegate.mMessageDropped) { chip::test_utils::SleepMillis(85); - gLoopback.mMessageDropped = false; + delegate.mMessageDropped = false; ReliableMessageMgr::Timeout(&ctx.GetSystemLayer(), ctx.GetExchangeManager().GetReliableMessageMgr()); ctx.DrainAndServiceIO(); }; @@ -275,6 +273,8 @@ void SecurePairingHandshakeTestCommon(nlTestSuite * inSuite, void * inContext, P pairingCommissioner.GetRemoteMRPConfig().mActiveRetransTimeout == mrpAccessoryConfig.Value().mActiveRetransTimeout); } + + gLoopback.SetLoopbackTransportDelegate(nullptr); } void SecurePairingHandshakeTest(nlTestSuite * inSuite, void * inContext) @@ -444,7 +444,7 @@ int TestSecurePairing_Setup(void * inContext) // Initialize System memory and resources ctx.ConfigInitializeNodes(false); - VerifyOrReturnError(TestContext::InitializeAsync(inContext) == SUCCESS, FAILURE); + VerifyOrReturnError(TestContext::Initialize(inContext) == SUCCESS, FAILURE); return SUCCESS; } diff --git a/src/transport/raw/tests/NetworkTestHelpers.h b/src/transport/raw/tests/NetworkTestHelpers.h index 987c81a895c984..61779bdc497f45 100644 --- a/src/transport/raw/tests/NetworkTestHelpers.h +++ b/src/transport/raw/tests/NetworkTestHelpers.h @@ -36,8 +36,6 @@ namespace Test { class IOContext { public: - IOContext() {} - /// Initialize the underlying layers and test suite pointer CHIP_ERROR Init(); @@ -61,35 +59,34 @@ class IOContext Inet::EndPointManager * mUDPEndPointManager = nullptr; }; -class LoopbackTransport : public Transport::Base +class LoopbackTransportDelegate { public: - /// Transports are required to have a constructor that takes exactly one argument - CHIP_ERROR Init(const char *) { return CHIP_NO_ERROR; } + virtual ~LoopbackTransportDelegate() {} - /* - * 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 - * of a transmitted message as an asynchronous, bottom half handler dispatched after the current execution context has - * completed. This is achieved using SystemLayer::ScheduleWork. - */ - void EnableAsyncDispatch(System::Layer * aSystemLayer) + // Called by the loopback transport when it drops a message due to a nonzero mNumMessagesToDrop. + virtual void OnMessageDropped() {} +}; + +class LoopbackTransport : public Transport::Base +{ +public: + void InitLoopbackTransport(System::Layer * systemLayer) { mSystemLayer = systemLayer; } + void ShutdownLoopbackTransport() { - mSystemLayer = aSystemLayer; - mAsyncMessageDispatch = true; + // TODO: remove these after #17624 (Ensure tests drain all message in loopback transport) being fixed + // Packets are allocated from platform memory, we should release them before Platform::MemoryShutdown + while (!mPendingMessageQueue.empty()) + mPendingMessageQueue.pop(); } - /* - * Reset the dispatch back to a model that synchronously dispatches received messages up the stack. - * - * NOTE: This results in highly atypical/complex call stacks that are not representative of what happens on real - * devices and can cause subtle and complex bugs to either appear or get masked in the system. Where possible, please - * use this sparingly! - */ - void DisableAsyncDispatch() { mAsyncMessageDispatch = false; } + /// Transports are required to have a constructor that takes exactly one argument + CHIP_ERROR Init(const char *) { return CHIP_NO_ERROR; } bool HasPendingMessages() { return !mPendingMessageQueue.empty(); } + void SetLoopbackTransportDelegate(LoopbackTransportDelegate * delegate) { mDelegate = delegate; } + static void OnMessageReceived(System::Layer * aSystemLayer, void * aAppState) { LoopbackTransport * _this = static_cast(aAppState); @@ -110,22 +107,15 @@ class LoopbackTransport : public Transport::Base if (mNumMessagesToDrop == 0) { System::PacketBufferHandle receivedMessage = msgBuf.CloneData(); - - if (mAsyncMessageDispatch) - { - mPendingMessageQueue.push(PendingMessageItem(address, std::move(receivedMessage))); - mSystemLayer->ScheduleWork(OnMessageReceived, this); - } - else - { - HandleMessageReceived(address, std::move(receivedMessage)); - } + mPendingMessageQueue.push(PendingMessageItem(address, std::move(receivedMessage))); + mSystemLayer->ScheduleWork(OnMessageReceived, this); } else { mNumMessagesToDrop--; mDroppedMessageCount++; - MessageDropped(); + if (mDelegate != nullptr) + mDelegate->OnMessageDropped(); } return CHIP_NO_ERROR; @@ -151,17 +141,14 @@ class LoopbackTransport : public Transport::Base System::PacketBufferHandle mPendingMessage; }; - // Hook for subclasses to perform custom logic on message drops. - virtual void MessageDropped() {} - System::Layer * mSystemLayer = nullptr; - bool mAsyncMessageDispatch = false; std::queue mPendingMessageQueue; Transport::PeerAddress mTxAddress; - uint32_t mNumMessagesToDrop = 0; - uint32_t mDroppedMessageCount = 0; - uint32_t mSentMessageCount = 0; - CHIP_ERROR mMessageSendError = CHIP_NO_ERROR; + uint32_t mNumMessagesToDrop = 0; + uint32_t mDroppedMessageCount = 0; + uint32_t mSentMessageCount = 0; + CHIP_ERROR mMessageSendError = CHIP_NO_ERROR; + LoopbackTransportDelegate * mDelegate = nullptr; }; } // namespace Test diff --git a/src/transport/tests/BUILD.gn b/src/transport/tests/BUILD.gn index 104f4b03ea9da8..ad14819c67145d 100644 --- a/src/transport/tests/BUILD.gn +++ b/src/transport/tests/BUILD.gn @@ -19,6 +19,16 @@ import("//build_overrides/nlunit_test.gni") import("${chip_root}/build/chip/chip_test_suite.gni") +source_set("helpers") { + sources = [ "LoopbackTransportManager.h" ] + + public_deps = [ + "${chip_root}/src/transport:transport", + "${chip_root}/src/transport/raw", + "${chip_root}/src/transport/raw/tests:helpers", + ] +} + chip_test_suite("tests") { output_name = "libTransportLayerTests" @@ -41,7 +51,7 @@ chip_test_suite("tests") { "${chip_root}/src/lib/support", "${chip_root}/src/protocols", "${chip_root}/src/transport", - "${chip_root}/src/transport/raw/tests:helpers", + "${chip_root}/src/transport/tests:helpers", "${nlio_root}:nlio", "${nlunit_test_root}:nlunit-test", ] diff --git a/src/transport/tests/LoopbackTransportManager.h b/src/transport/tests/LoopbackTransportManager.h new file mode 100644 index 00000000000000..df44e5d46f94a1 --- /dev/null +++ b/src/transport/tests/LoopbackTransportManager.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2022 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. + */ +#pragma once + +#include +#include +#include +#include + +namespace chip { +namespace Test { + +class LoopbackTransportManager +{ +public: + /// Initialize the underlying layers. + CHIP_ERROR Init() + { + ReturnErrorOnFailure(mIOContext.Init()); + GetLoopback().InitLoopbackTransport(&mIOContext.GetSystemLayer()); + ReturnErrorOnFailure(mTransportManager.Init("LOOPBACK")); + return CHIP_NO_ERROR; + } + + // Shutdown all layers, finalize operations + CHIP_ERROR Shutdown() + { + GetLoopback().ShutdownLoopbackTransport(); + ReturnErrorOnFailure(mIOContext.Shutdown()); + return CHIP_NO_ERROR; + } + + System::Layer & GetSystemLayer() { return mIOContext.GetSystemLayer(); } + LoopbackTransport & GetLoopback() { return mTransportManager.GetTransport().template GetImplAtIndex<0>(); } + TransportMgrBase & GetTransportMgr() { return mTransportManager; } + IOContext & GetIOContext() { return mIOContext; } + + /* + * This drives the servicing of events using the embedded IOContext while there are pending + * messages in the loopback transport's pending message queue. This should run to completion + * in well-behaved logic (i.e there isn't an indefinite ping-pong of messages transmitted back + * and forth). + * + * Consequently, this is guarded with a user-provided timeout to ensure we don't have unit-tests that stall + * in CI due to bugs in the code that is being tested. + * + * This DOES NOT ensure that all pending events are serviced to completion + * (i.e timers, any ScheduleWork calls), but does: + * + * 1) Guarantee that every call will make some progress on ready-to-run + * things, by calling DriveIO at least once. + * 2) Try to ensure that any ScheduleWork calls that happend directly as a + * result of message reception, and any messages those async tasks send, + * get handled before DrainAndServiceIO returns. + */ + void DrainAndServiceIO(System::Clock::Timeout maxWait = chip::System::Clock::Seconds16(5)) + { + auto & impl = GetLoopback(); + System::Clock::Timestamp startTime = System::SystemClock().GetMonotonicTimestamp(); + + while (true) + { + bool hadPendingMessages = impl.HasPendingMessages(); + while (impl.HasPendingMessages()) + { + mIOContext.DriveIO(); + if ((System::SystemClock().GetMonotonicTimestamp() - startTime) >= maxWait) + { + return; + } + } + // Processing those messages might have queued some run-ASAP async + // work. Make sure to process that too, in case it generates + // response messages. + mIOContext.DriveIO(); + if (!hadPendingMessages && !impl.HasPendingMessages()) + { + // We're not making any progress on messages. Just stop. + break; + } + // No need to check our timer here: either impl.HasPendingMessages() + // is true and we will check it next iteration, or it's false and we + // will either stop on the next iteration or it will become true and + // we will check the timer then. + } + } + +private: + Test::IOContext mIOContext; + TransportMgr mTransportManager; +}; + +} // namespace Test +} // namespace chip diff --git a/src/transport/tests/TestSessionManager.cpp b/src/transport/tests/TestSessionManager.cpp index eeb73c75aa70bd..25090b7a547876 100644 --- a/src/transport/tests/TestSessionManager.cpp +++ b/src/transport/tests/TestSessionManager.cpp @@ -35,7 +35,7 @@ #include #include #include -#include +#include #include #include @@ -51,7 +51,7 @@ using namespace chip::Inet; using namespace chip::Transport; using namespace chip::Test; -using TestContext = chip::Test::IOContext; +using TestContext = chip::Test::LoopbackTransportManager; TestContext sContext; @@ -97,18 +97,16 @@ void CheckSimpleInitTest(nlTestSuite * inSuite, void * inContext) { TestContext & ctx = *reinterpret_cast(inContext); - TransportMgr transportMgr; FabricTable fabricTable; SessionManager sessionManager; secure_channel::MessageCounterManager gMessageCounterManager; chip::TestPersistentStorageDelegate deviceStorage; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == transportMgr.Init("LOOPBACK")); NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == fabricTable.Init(&deviceStorage)); - NL_TEST_ASSERT( - inSuite, - CHIP_NO_ERROR == - sessionManager.Init(&ctx.GetSystemLayer(), &transportMgr, &gMessageCounterManager, &deviceStorage, &fabricTable)); + NL_TEST_ASSERT(inSuite, + CHIP_NO_ERROR == + sessionManager.Init(&ctx.GetSystemLayer(), &ctx.GetTransportMgr(), &gMessageCounterManager, &deviceStorage, + &fabricTable)); } void CheckMessageTest(nlTestSuite * inSuite, void * inContext) @@ -127,18 +125,16 @@ void CheckMessageTest(nlTestSuite * inSuite, void * inContext) IPAddress::FromString("::1", addr); CHIP_ERROR err = CHIP_NO_ERROR; - TransportMgr transportMgr; FabricTable fabricTable; SessionManager sessionManager; secure_channel::MessageCounterManager gMessageCounterManager; chip::TestPersistentStorageDelegate deviceStorage; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == transportMgr.Init("LOOPBACK")); NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == fabricTable.Init(&deviceStorage)); - NL_TEST_ASSERT( - inSuite, - CHIP_NO_ERROR == - sessionManager.Init(&ctx.GetSystemLayer(), &transportMgr, &gMessageCounterManager, &deviceStorage, &fabricTable)); + NL_TEST_ASSERT(inSuite, + CHIP_NO_ERROR == + sessionManager.Init(&ctx.GetSystemLayer(), &ctx.GetTransportMgr(), &gMessageCounterManager, &deviceStorage, + &fabricTable)); callback.mSuite = inSuite; @@ -196,6 +192,7 @@ void CheckMessageTest(nlTestSuite * inSuite, void * inContext) err = sessionManager.SendPreparedMessage(aliceToBobSession.Get(), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 1); // Let's send the max sized message and make sure it is received @@ -210,6 +207,7 @@ void CheckMessageTest(nlTestSuite * inSuite, void * inContext) err = sessionManager.SendPreparedMessage(aliceToBobSession.Get(), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 2); uint16_t large_payload_len = sizeof(LARGE_PAYLOAD); @@ -242,18 +240,16 @@ void SendEncryptedPacketTest(nlTestSuite * inSuite, void * inContext) IPAddress::FromString("::1", addr); CHIP_ERROR err = CHIP_NO_ERROR; - TransportMgr transportMgr; FabricTable fabricTable; SessionManager sessionManager; secure_channel::MessageCounterManager gMessageCounterManager; chip::TestPersistentStorageDelegate deviceStorage; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == transportMgr.Init("LOOPBACK")); NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == fabricTable.Init(&deviceStorage)); - NL_TEST_ASSERT( - inSuite, - CHIP_NO_ERROR == - sessionManager.Init(&ctx.GetSystemLayer(), &transportMgr, &gMessageCounterManager, &deviceStorage, &fabricTable)); + NL_TEST_ASSERT(inSuite, + CHIP_NO_ERROR == + sessionManager.Init(&ctx.GetSystemLayer(), &ctx.GetTransportMgr(), &gMessageCounterManager, &deviceStorage, + &fabricTable)); callback.mSuite = inSuite; @@ -313,15 +309,17 @@ void SendEncryptedPacketTest(nlTestSuite * inSuite, void * inContext) err = sessionManager.SendPreparedMessage(aliceToBobSession.Get(), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); + NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 1); + // Reset receive side message counter, or duplicated message will be denied. Transport::SecureSession * session = bobToAliceSession.Get()->AsSecureSession(); session->GetSessionMessageCounter().GetPeerMessageCounter().SetCounter(1); - NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 1); - err = sessionManager.SendPreparedMessage(aliceToBobSession.Get(), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 2); sessionManager.Shutdown(); @@ -343,18 +341,16 @@ void SendBadEncryptedPacketTest(nlTestSuite * inSuite, void * inContext) IPAddress::FromString("::1", addr); CHIP_ERROR err = CHIP_NO_ERROR; - TransportMgr transportMgr; FabricTable fabricTable; SessionManager sessionManager; secure_channel::MessageCounterManager gMessageCounterManager; chip::TestPersistentStorageDelegate deviceStorage; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == transportMgr.Init("LOOPBACK")); NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == fabricTable.Init(&deviceStorage)); - NL_TEST_ASSERT( - inSuite, - CHIP_NO_ERROR == - sessionManager.Init(&ctx.GetSystemLayer(), &transportMgr, &gMessageCounterManager, &deviceStorage, &fabricTable)); + NL_TEST_ASSERT(inSuite, + CHIP_NO_ERROR == + sessionManager.Init(&ctx.GetSystemLayer(), &ctx.GetTransportMgr(), &gMessageCounterManager, &deviceStorage, + &fabricTable)); callback.mSuite = inSuite; @@ -414,6 +410,7 @@ void SendBadEncryptedPacketTest(nlTestSuite * inSuite, void * inContext) err = sessionManager.SendPreparedMessage(aliceToBobSession.Get(), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 1); /* -------------------------------------------------------------------------------------------*/ @@ -434,6 +431,7 @@ void SendBadEncryptedPacketTest(nlTestSuite * inSuite, void * inContext) err = sessionManager.SendPreparedMessage(aliceToBobSession.Get(), badMessageCounterMsg); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 1); /* -------------------------------------------------------------------------------------------*/ @@ -450,15 +448,17 @@ void SendBadEncryptedPacketTest(nlTestSuite * inSuite, void * inContext) err = sessionManager.SendPreparedMessage(aliceToBobSession.Get(), badKeyIdMsg); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); + NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 1); + /* -------------------------------------------------------------------------------------------*/ session->GetSessionMessageCounter().GetPeerMessageCounter().SetCounter(1); - NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 1); - // Send the correct encrypted msg err = sessionManager.SendPreparedMessage(aliceToBobSession.Get(), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 2); sessionManager.Shutdown(); @@ -480,18 +480,16 @@ void SendPacketWithOldCounterTest(nlTestSuite * inSuite, void * inContext) IPAddress::FromString("::1", addr); CHIP_ERROR err = CHIP_NO_ERROR; - TransportMgr transportMgr; FabricTable fabricTable; SessionManager sessionManager; secure_channel::MessageCounterManager gMessageCounterManager; chip::TestPersistentStorageDelegate deviceStorage; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == transportMgr.Init("LOOPBACK")); NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == fabricTable.Init(&deviceStorage)); - NL_TEST_ASSERT( - inSuite, - CHIP_NO_ERROR == - sessionManager.Init(&ctx.GetSystemLayer(), &transportMgr, &gMessageCounterManager, &deviceStorage, &fabricTable)); + NL_TEST_ASSERT(inSuite, + CHIP_NO_ERROR == + sessionManager.Init(&ctx.GetSystemLayer(), &ctx.GetTransportMgr(), &gMessageCounterManager, &deviceStorage, + &fabricTable)); callback.mSuite = inSuite; @@ -550,6 +548,7 @@ void SendPacketWithOldCounterTest(nlTestSuite * inSuite, void * inContext) err = sessionManager.SendPreparedMessage(aliceToBobSession.Get(), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 1); // Now advance our message counter by 5. @@ -566,6 +565,7 @@ void SendPacketWithOldCounterTest(nlTestSuite * inSuite, void * inContext) err = sessionManager.SendPreparedMessage(aliceToBobSession.Get(), newMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 2); // Now resend our original message. It should be rejected as a duplicate. @@ -573,6 +573,7 @@ void SendPacketWithOldCounterTest(nlTestSuite * inSuite, void * inContext) err = sessionManager.SendPreparedMessage(aliceToBobSession.Get(), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 2); sessionManager.Shutdown(); @@ -594,18 +595,16 @@ void SendPacketWithTooOldCounterTest(nlTestSuite * inSuite, void * inContext) IPAddress::FromString("::1", addr); CHIP_ERROR err = CHIP_NO_ERROR; - TransportMgr transportMgr; FabricTable fabricTable; SessionManager sessionManager; secure_channel::MessageCounterManager gMessageCounterManager; chip::TestPersistentStorageDelegate deviceStorage; - NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == transportMgr.Init("LOOPBACK")); NL_TEST_ASSERT(inSuite, CHIP_NO_ERROR == fabricTable.Init(&deviceStorage)); - NL_TEST_ASSERT( - inSuite, - CHIP_NO_ERROR == - sessionManager.Init(&ctx.GetSystemLayer(), &transportMgr, &gMessageCounterManager, &deviceStorage, &fabricTable)); + NL_TEST_ASSERT(inSuite, + CHIP_NO_ERROR == + sessionManager.Init(&ctx.GetSystemLayer(), &ctx.GetTransportMgr(), &gMessageCounterManager, &deviceStorage, + &fabricTable)); callback.mSuite = inSuite; @@ -664,6 +663,7 @@ void SendPacketWithTooOldCounterTest(nlTestSuite * inSuite, void * inContext) err = sessionManager.SendPreparedMessage(aliceToBobSession.Get(), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 1); // Now advance our message counter by at least @@ -682,6 +682,7 @@ void SendPacketWithTooOldCounterTest(nlTestSuite * inSuite, void * inContext) err = sessionManager.SendPreparedMessage(aliceToBobSession.Get(), newMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 2); // Now resend our original message. It should be rejected as a duplicate. @@ -689,6 +690,7 @@ void SendPacketWithTooOldCounterTest(nlTestSuite * inSuite, void * inContext) err = sessionManager.SendPreparedMessage(aliceToBobSession.Get(), preparedMessage); NL_TEST_ASSERT(inSuite, err == CHIP_NO_ERROR); + ctx.DrainAndServiceIO(); NL_TEST_ASSERT(inSuite, callback.ReceiveHandlerCallCount == 2); sessionManager.Shutdown();