From 272d6fd063bcf56da102dcbe3a34e81042a38207 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas <vnicolas@apple.com> Date: Tue, 25 Jul 2023 09:35:39 +0200 Subject: [PATCH] [chiptool.py] Ensure async report that came in before the test got a chance to listen for a report are dispatched properly --- .../interactive/InteractiveCommands.cpp | 45 +++++++++++++++++-- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/examples/chip-tool/commands/interactive/InteractiveCommands.cpp b/examples/chip-tool/commands/interactive/InteractiveCommands.cpp index 6dae09ce392206..d2752a3fffac5a 100644 --- a/examples/chip-tool/commands/interactive/InteractiveCommands.cpp +++ b/examples/chip-tool/commands/interactive/InteractiveCommands.cpp @@ -67,6 +67,7 @@ struct InteractiveServerResult bool mIsAsyncReport = false; uint16_t mTimeout = 0; int mStatus = EXIT_SUCCESS; + std::vector<std::string> mPendingResults; std::vector<std::string> mResults; std::vector<InteractiveServerResultLog> mLogs; @@ -100,9 +101,20 @@ struct InteractiveServerResult mIsAsyncReport = isAsyncReport; mTimeout = timeout; - if (mIsAsyncReport && mTimeout) + if (mIsAsyncReport) { - chip::DeviceLayer::PlatformMgr().ScheduleWork(StartAsyncTimeout, reinterpret_cast<intptr_t>(this)); + if (mTimeout) + { + chip::DeviceLayer::PlatformMgr().ScheduleWork(StartAsyncTimeout, reinterpret_cast<intptr_t>(this)); + } + + if (!mPendingResults.empty()) + { + mResults = std::move(mPendingResults); + } + + // Reset the pending results. + mPendingResults.clear(); } } @@ -119,6 +131,7 @@ struct InteractiveServerResult mIsAsyncReport = false; mTimeout = 0; mStatus = EXIT_SUCCESS; + mPendingResults.clear(); mResults.clear(); mLogs.clear(); } @@ -158,11 +171,26 @@ struct InteractiveServerResult void MaybeAddResult(const char * result) { auto lock = ScopedLock(mMutex); - VerifyOrReturn(mEnabled); + // If we are not waiting for a result it could be that a report came in *before* the command to wait for + // it has happened. The result is stored until the next command. If the next command is an async + // command the pending result would be promote to a valid result so it could be dispatched properly. + if (!mEnabled) + { + mPendingResults.push_back(result); + return; + } mResults.push_back(result); } + bool HasResults() + { + auto lock = ScopedLock(mMutex); + VerifyOrReturnValue(mEnabled, false); + + return !mResults.empty(); + } + std::string AsJsonString() { auto lock = ScopedLock(mMutex); @@ -308,7 +336,16 @@ bool InteractiveServerCommand::OnWebSocketMessageReceived(char * msg) } gInteractiveServerResult.Setup(isAsyncReport, timeout); - VerifyOrReturnValue(!isAsyncReport, true); + + if (isAsyncReport) + { + if (gInteractiveServerResult.HasResults()) + { + mWebSocketServer.Send(gInteractiveServerResult.AsJsonString().c_str()); + gInteractiveServerResult.Reset(); + } + return true; + } auto shouldStop = ParseCommand(msg, &gInteractiveServerResult.mStatus); mWebSocketServer.Send(gInteractiveServerResult.AsJsonString().c_str());