Fix urgent event support (#15884)

Add python event urgency test support
diff --git a/src/app/ClusterInfo.h b/src/app/ClusterInfo.h
index e8fdc95..2e3e0dd 100644
--- a/src/app/ClusterInfo.h
+++ b/src/app/ClusterInfo.h
@@ -103,6 +103,7 @@
     ListIndex mListIndex     = kInvalidListIndex;   // uint16
     EndpointId mEndpointId   = kInvalidEndpointId;  // uint16
     Optional<DataVersion> mDataVersion;             // uint32
+    bool mIsUrgentEvent = false;                    // uint8
 };
 } // namespace app
 } // namespace chip
diff --git a/src/app/EventLogging.h b/src/app/EventLogging.h
index 9580dcb..9d5d56d 100644
--- a/src/app/EventLogging.h
+++ b/src/app/EventLogging.h
@@ -57,21 +57,18 @@
  * LogEvent has 2 variant, one for fabric-scoped events and one for non-fabric-scoped events.
  * @param[in] aEventData  The event cluster object
  * @param[in] aEndpoint    The current cluster's Endpoint Id
- * @param[in] aUrgent    The EventOption Type, kUrgent or kNotUrgent
  * @param[out] aEventNumber The event Number if the event was written to the
  *                         log, 0 otherwise. The Event number is expected to monotonically increase.
  *
  * @return CHIP_ERROR  CHIP Error Code
  */
 template <typename T, std::enable_if_t<DataModel::IsFabricScoped<T>::value, bool> = true>
-CHIP_ERROR LogEvent(const T & aEventData, EndpointId aEndpoint, EventNumber & aEventNumber,
-                    EventOptions::Type aUrgent = EventOptions::Type::kNotUrgent)
+CHIP_ERROR LogEvent(const T & aEventData, EndpointId aEndpoint, EventNumber & aEventNumber)
 {
     EventLogger<T> eventData(aEventData);
     ConcreteEventPath path(aEndpoint, aEventData.GetClusterId(), aEventData.GetEventId());
     EventManagement & logMgmt = chip::app::EventManagement::GetInstance();
     EventOptions eventOptions;
-    eventOptions.mUrgent      = aUrgent;
     eventOptions.mPath        = path;
     eventOptions.mPriority    = aEventData.GetPriorityLevel();
     eventOptions.mFabricIndex = aEventData.GetFabricIndex();
@@ -88,14 +85,12 @@
 }
 
 template <typename T, std::enable_if_t<!DataModel::IsFabricScoped<T>::value, bool> = true>
-CHIP_ERROR LogEvent(const T & aEventData, EndpointId aEndpoint, EventNumber & aEventNumber,
-                    EventOptions::Type aUrgent = EventOptions::Type::kNotUrgent)
+CHIP_ERROR LogEvent(const T & aEventData, EndpointId aEndpoint, EventNumber & aEventNumber)
 {
     EventLogger<T> eventData(aEventData);
     ConcreteEventPath path(aEndpoint, aEventData.GetClusterId(), aEventData.GetEventId());
     EventManagement & logMgmt = chip::app::EventManagement::GetInstance();
     EventOptions eventOptions;
-    eventOptions.mUrgent   = aUrgent;
     eventOptions.mPath     = path;
     eventOptions.mPriority = aEventData.GetPriorityLevel();
     return logMgmt.LogEvent(&eventData, eventOptions, aEventNumber);
diff --git a/src/app/EventLoggingTypes.h b/src/app/EventLoggingTypes.h
index d685113..28a891a 100644
--- a/src/app/EventLoggingTypes.h
+++ b/src/app/EventLoggingTypes.h
@@ -127,21 +127,11 @@
 class EventOptions
 {
 public:
-    enum class Type
-    {
-        kUrgent = 0,
-        kNotUrgent,
-    };
-    EventOptions() : mPriority(PriorityLevel::Invalid), mUrgent(Type::kNotUrgent) {}
-    EventOptions(Timestamp aTimestamp) : mTimestamp(aTimestamp), mPriority(PriorityLevel::Invalid), mUrgent(Type::kNotUrgent) {}
-
-    EventOptions(Timestamp aTimestamp, Type aUrgent) : mTimestamp(aTimestamp), mPriority(PriorityLevel::Invalid), mUrgent(aUrgent)
-    {}
+    EventOptions() : mPriority(PriorityLevel::Invalid) {}
+    EventOptions(Timestamp aTimestamp) : mTimestamp(aTimestamp), mPriority(PriorityLevel::Invalid) {}
     ConcreteEventPath mPath;
     Timestamp mTimestamp;
     PriorityLevel mPriority = PriorityLevel::Invalid;
-    Type mUrgent            = Type::kNotUrgent; /**< A flag denoting if the event is time sensitive.  When kUrgent is set, it causes
-                                                       the event log to be flushed. */
     // kUndefinedFabricIndex 0 means not fabric associated at all
     FabricIndex mFabricIndex = kUndefinedFabricIndex;
 };
diff --git a/src/app/EventManagement.cpp b/src/app/EventManagement.cpp
index dd5ecea..a48d790 100644
--- a/src/app/EventManagement.cpp
+++ b/src/app/EventManagement.cpp
@@ -319,7 +319,6 @@
     eventPathBuilder.Endpoint(apOptions->mPath.mEndpointId)
         .Cluster(apOptions->mPath.mClusterId)
         .Event(apOptions->mPath.mEventId)
-        .IsUrgent(apOptions->mUrgent == EventOptions::Type::kUrgent)
         .EndOfEventPathIB();
     ReturnErrorOnFailure(eventPathBuilder.GetError());
     eventDataIBBuilder.EventNumber(apContext->mCurrentEventNumber).Priority(chip::to_underlying(apContext->mPriority));
@@ -476,7 +475,6 @@
     // Create all event specific data
     // Timestamp; encoded as a delta time
 
-    opts.mUrgent      = aEventOptions.mUrgent;
     opts.mPath        = aEventOptions.mPath;
     opts.mFabricIndex = aEventOptions.mFabricIndex;
 
@@ -533,8 +531,7 @@
                       opts.mTimestamp.mType == Timestamp::Type::kSystem ? "Sys" : "Epoch", ChipLogValueX64(opts.mTimestamp.mValue));
 #endif // CHIP_CONFIG_EVENT_LOGGING_VERBOSE_DEBUG_LOGS
 
-        err = InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleEventDelivery(opts.mPath, opts.mUrgent,
-                                                                                                mBytesWritten);
+        err = InteractionModelEngine::GetInstance()->GetReportingEngine().ScheduleEventDelivery(opts.mPath, mBytesWritten);
     }
 
     return err;
diff --git a/src/app/EventPathParams.h b/src/app/EventPathParams.h
index 7a3675a..0516874 100644
--- a/src/app/EventPathParams.h
+++ b/src/app/EventPathParams.h
@@ -26,8 +26,8 @@
 namespace app {
 struct EventPathParams
 {
-    EventPathParams(EndpointId aEndpointId, ClusterId aClusterId, EventId aEventId) :
-        mEndpointId(aEndpointId), mClusterId(aClusterId), mEventId(aEventId)
+    EventPathParams(EndpointId aEndpointId, ClusterId aClusterId, EventId aEventId, bool aUrgentEvent = false) :
+        mEndpointId(aEndpointId), mClusterId(aClusterId), mEventId(aEventId), mIsUrgentEvent(aUrgentEvent)
     {}
     EventPathParams() {}
     bool IsSamePath(const EventPathParams & other) const
@@ -47,6 +47,7 @@
     EndpointId mEndpointId = kInvalidEndpointId;
     ClusterId mClusterId   = kInvalidClusterId;
     EventId mEventId       = kInvalidEventId;
+    bool mIsUrgentEvent    = false;
 };
 } // namespace app
 } // namespace chip
diff --git a/src/app/MessageDef/EventPathIB.cpp b/src/app/MessageDef/EventPathIB.cpp
index 486c9ce..ca15101 100644
--- a/src/app/MessageDef/EventPathIB.cpp
+++ b/src/app/MessageDef/EventPathIB.cpp
@@ -242,6 +242,10 @@
         Event(aEventPathParams.mEventId);
     }
 
+    if (aEventPathParams.mIsUrgentEvent)
+    {
+        IsUrgent(aEventPathParams.mIsUrgentEvent);
+    }
     EndOfEventPathIB();
     return GetError();
 }
diff --git a/src/app/ReadHandler.cpp b/src/app/ReadHandler.cpp
index 0b116af..952d360 100644
--- a/src/app/ReadHandler.cpp
+++ b/src/app/ReadHandler.cpp
@@ -515,6 +515,13 @@
         }
         ReturnErrorOnFailure(err);
 
+        err = path.GetIsUrgent(&(clusterInfo.mIsUrgentEvent));
+        if (CHIP_END_OF_TLV == err)
+        {
+            err = CHIP_NO_ERROR;
+        }
+        ReturnErrorOnFailure(err);
+
         ReturnErrorOnFailure(InteractionModelEngine::GetInstance()->PushFront(mpEventClusterInfoList, clusterInfo));
     }
 
diff --git a/src/app/clusters/basic/basic.cpp b/src/app/clusters/basic/basic.cpp
index 77633b4..130a144 100644
--- a/src/app/clusters/basic/basic.cpp
+++ b/src/app/clusters/basic/basic.cpp
@@ -340,7 +340,7 @@
             Events::StartUp::Type event{ softwareVersion };
             EventNumber eventNumber;
 
-            CHIP_ERROR err = LogEvent(event, endpoint, eventNumber, EventOptions::Type::kUrgent);
+            CHIP_ERROR err = LogEvent(event, endpoint, eventNumber);
             if (CHIP_NO_ERROR != err)
             {
                 ChipLogError(Zcl, "PlatformMgrDelegate: Failed to record StartUp event: %" CHIP_ERROR_FORMAT, err.Format());
@@ -359,7 +359,7 @@
             Events::ShutDown::Type event;
             EventNumber eventNumber;
 
-            CHIP_ERROR err = LogEvent(event, endpoint, eventNumber, EventOptions::Type::kUrgent);
+            CHIP_ERROR err = LogEvent(event, endpoint, eventNumber);
             if (CHIP_NO_ERROR != err)
             {
                 ChipLogError(Zcl, "PlatformMgrDelegate: Failed to record ShutDown event: %" CHIP_ERROR_FORMAT, err.Format());
diff --git a/src/app/clusters/general-diagnostics-server/general-diagnostics-server.cpp b/src/app/clusters/general-diagnostics-server/general-diagnostics-server.cpp
index 0a14cbf..834f855 100644
--- a/src/app/clusters/general-diagnostics-server/general-diagnostics-server.cpp
+++ b/src/app/clusters/general-diagnostics-server/general-diagnostics-server.cpp
@@ -206,7 +206,7 @@
         Events::BootReason::Type event{ static_cast<EmberAfBootReasonType>(bootReason) };
         EventNumber eventNumber;
 
-        CHIP_ERROR err = LogEvent(event, 0, eventNumber, EventOptions::Type::kUrgent);
+        CHIP_ERROR err = LogEvent(event, 0, eventNumber);
         if (CHIP_NO_ERROR != err)
         {
             ChipLogError(Zcl, "GeneralDiagnosticsDelegate: Failed to record BootReason event: %" CHIP_ERROR_FORMAT, err.Format());
@@ -233,7 +233,7 @@
                 reinterpret_cast<const HardwareFaultType *>(previous.data()), previous.size());
             Events::HardwareFaultChange::Type event{ currentList, previousList };
 
-            if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber, EventOptions::Type::kUrgent))
+            if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber))
             {
                 ChipLogError(Zcl, "GeneralDiagnosticsDelegate: Failed to record HardwareFault event");
             }
@@ -259,7 +259,7 @@
                 DataModel::List<const RadioFaultType>(reinterpret_cast<const RadioFaultType *>(previous.data()), previous.size());
             Events::RadioFaultChange::Type event{ currentList, previousList };
 
-            if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber, EventOptions::Type::kUrgent))
+            if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber))
             {
                 ChipLogError(Zcl, "GeneralDiagnosticsDelegate: Failed to record RadioFault event");
             }
@@ -285,7 +285,7 @@
                 reinterpret_cast<const NetworkFaultType *>(previous.data()), previous.size());
             Events::NetworkFaultChange::Type event{ currentList, previousList };
 
-            if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber, EventOptions::Type::kUrgent))
+            if (CHIP_NO_ERROR != LogEvent(event, endpointId, eventNumber))
             {
                 ChipLogError(Zcl, "GeneralDiagnosticsDelegate: Failed to record NetworkFault event");
             }
diff --git a/src/app/reporting/Engine.cpp b/src/app/reporting/Engine.cpp
index ac35a88..1e4f7eb 100644
--- a/src/app/reporting/Engine.cpp
+++ b/src/app/reporting/Engine.cpp
@@ -735,18 +735,21 @@
     return CHIP_NO_ERROR;
 }
 
-CHIP_ERROR Engine::ScheduleUrgentEventDelivery(ConcreteEventPath & aPath)
+CHIP_ERROR Engine::ScheduleEventDelivery(ConcreteEventPath & aPath, uint32_t aBytesWritten)
 {
-    InteractionModelEngine::GetInstance()->mReadHandlers.ForEachActiveObject([&aPath](ReadHandler * handler) {
+    bool isUrgentEvent = false;
+    InteractionModelEngine::GetInstance()->mReadHandlers.ForEachActiveObject([&aPath, &isUrgentEvent](ReadHandler * handler) {
         if (handler->IsType(ReadHandler::InteractionType::Read))
         {
             return Loop::Continue;
         }
 
-        for (auto clusterInfo = handler->GetEventClusterInfolist(); clusterInfo != nullptr; clusterInfo = clusterInfo->mpNext)
+        for (auto * interestedPath = handler->GetEventClusterInfolist(); interestedPath != nullptr;
+             interestedPath        = interestedPath->mpNext)
         {
-            if (clusterInfo->IsEventPathSupersetOf(aPath))
+            if (interestedPath->IsEventPathSupersetOf(aPath) && interestedPath->mIsUrgentEvent)
             {
+                isUrgentEvent = true;
                 handler->UnblockUrgentEventDelivery();
                 break;
             }
@@ -755,18 +758,14 @@
         return Loop::Continue;
     });
 
-    return ScheduleRun();
-}
-
-CHIP_ERROR Engine::ScheduleEventDelivery(ConcreteEventPath & aPath, EventOptions::Type aUrgent, uint32_t aBytesWritten)
-{
-    if (aUrgent != EventOptions::Type::kUrgent)
+    if (isUrgentEvent)
     {
-        return ScheduleBufferPressureEventDelivery(aBytesWritten);
+        ChipLogDetail(DataManagement, "urgent event schedule run");
+        return ScheduleRun();
     }
     else
     {
-        return ScheduleUrgentEventDelivery(aPath);
+        return ScheduleBufferPressureEventDelivery(aBytesWritten);
     }
     return CHIP_NO_ERROR;
 }
diff --git a/src/app/reporting/Engine.h b/src/app/reporting/Engine.h
index c74cc26..c29f100 100644
--- a/src/app/reporting/Engine.h
+++ b/src/app/reporting/Engine.h
@@ -94,7 +94,7 @@
      *  Schedule the event delivery
      *
      */
-    CHIP_ERROR ScheduleEventDelivery(ConcreteEventPath & aPath, EventOptions::Type aUrgent, uint32_t aBytesWritten);
+    CHIP_ERROR ScheduleEventDelivery(ConcreteEventPath & aPath, uint32_t aBytesWritten);
 
     /*
      * Resets the tracker that tracks the currently serviced read handler.
@@ -164,7 +164,6 @@
      */
     static void Run(System::Layer * aSystemLayer, void * apAppState);
 
-    CHIP_ERROR ScheduleUrgentEventDelivery(ConcreteEventPath & aPath);
     CHIP_ERROR ScheduleBufferPressureEventDelivery(uint32_t aBytesWritten);
     void GetMinEventLogPosition(uint32_t & aMinLogPosition);
 
diff --git a/src/app/tests/TestReadInteraction.cpp b/src/app/tests/TestReadInteraction.cpp
index fc3ccd0..186fa25 100644
--- a/src/app/tests/TestReadInteraction.cpp
+++ b/src/app/tests/TestReadInteraction.cpp
@@ -116,7 +116,7 @@
     int32_t mStatus;
 };
 
-void GenerateEvents(nlTestSuite * apSuite, void * apContext, bool aIsUrgent = false)
+void GenerateEvents(nlTestSuite * apSuite, void * apContext)
 {
     CHIP_ERROR err = CHIP_NO_ERROR;
     chip::EventNumber eid1, eid2;
@@ -128,11 +128,9 @@
     options2.mPath     = { kTestEndpointId, kTestClusterId, kTestEventIdCritical };
     options2.mPriority = chip::app::PriorityLevel::Critical;
     TestEventGenerator testEventGenerator;
-    if (aIsUrgent)
-    {
-        options2.mUrgent = chip::app::EventOptions::Type::kUrgent;
-    }
     chip::app::EventManagement & logMgmt = chip::app::EventManagement::GetInstance();
+
+    ChipLogDetail(DataManagement, "Generating Events");
     testEventGenerator.SetStatus(0);
     err = logMgmt.LogEvent(&testEventGenerator, options1, eid1);
     NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
@@ -294,6 +292,7 @@
     static void TestReadChunking(nlTestSuite * apSuite, void * apContext);
     static void TestSetDirtyBetweenChunks(nlTestSuite * apSuite, void * apContext);
     static void TestSubscribeRoundtrip(nlTestSuite * apSuite, void * apContext);
+    static void TestSubscribeUrgentWildcardEvent(nlTestSuite * apSuite, void * apContext);
     static void TestSubscribeWildcard(nlTestSuite * apSuite, void * apContext);
     static void TestSubscribeEarlyShutdown(nlTestSuite * apSuite, void * apContext);
     static void TestSubscribeInvalidAttributePathRoundtrip(nlTestSuite * apSuite, void * apContext);
@@ -1506,9 +1505,9 @@
     {
         app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &ctx.GetExchangeManager(), delegate,
                                    chip::app::ReadClient::InteractionType::Subscribe);
-
-        delegate.mGotReport = false;
-        err                 = readClient.SendRequest(readPrepareParams);
+        readPrepareParams.mpEventPathParamsList[0].mIsUrgentEvent = true;
+        delegate.mGotReport                                       = false;
+        err                                                       = readClient.SendRequest(readPrepareParams);
         NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
 
         ctx.DrainAndServiceIO();
@@ -1522,7 +1521,7 @@
         NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 2);
         NL_TEST_ASSERT(apSuite, engine->GetNumActiveReadHandlers(ReadHandler::InteractionType::Subscribe) == 1);
 
-        GenerateEvents(apSuite, apContext, true /*aIsUrgent*/);
+        GenerateEvents(apSuite, apContext);
         NL_TEST_ASSERT(apSuite, delegate.mpReadHandler->mHoldReport == false);
         NL_TEST_ASSERT(apSuite, delegate.mpReadHandler->mDirty == true);
         chip::app::ClusterInfo dirtyPath1;
@@ -1636,6 +1635,89 @@
     NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
 }
 
+void TestReadInteraction::TestSubscribeUrgentWildcardEvent(nlTestSuite * apSuite, void * apContext)
+{
+    TestContext & ctx = *static_cast<TestContext *>(apContext);
+    CHIP_ERROR err    = CHIP_NO_ERROR;
+
+    Messaging::ReliableMessageMgr * rm = ctx.GetExchangeManager().GetReliableMessageMgr();
+    // Shouldn't have anything in the retransmit table when starting the test.
+    NL_TEST_ASSERT(apSuite, rm->TestGetCountRetransTable() == 0);
+
+    MockInteractionModelApp delegate;
+    auto * engine = chip::app::InteractionModelEngine::GetInstance();
+    err           = engine->Init(&ctx.GetExchangeManager());
+    NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+    NL_TEST_ASSERT(apSuite, !delegate.mGotEventResponse);
+
+    ReadPrepareParams readPrepareParams(ctx.GetSessionBobToAlice());
+    chip::app::EventPathParams eventPathParams[2];
+    readPrepareParams.mpEventPathParamsList                = eventPathParams;
+    readPrepareParams.mpEventPathParamsList[0].mEndpointId = kTestEndpointId;
+    readPrepareParams.mpEventPathParamsList[0].mClusterId  = kTestClusterId;
+
+    readPrepareParams.mpEventPathParamsList[1].mEndpointId = kTestEndpointId;
+    readPrepareParams.mpEventPathParamsList[1].mClusterId  = kTestClusterId;
+    readPrepareParams.mpEventPathParamsList[1].mEventId    = kTestEventIdCritical;
+
+    readPrepareParams.mEventPathParamsListSize = 2;
+
+    chip::app::AttributePathParams attributePathParams[2];
+    readPrepareParams.mpAttributePathParamsList                 = attributePathParams;
+    readPrepareParams.mpAttributePathParamsList[0].mEndpointId  = kTestEndpointId;
+    readPrepareParams.mpAttributePathParamsList[0].mClusterId   = kTestClusterId;
+    readPrepareParams.mpAttributePathParamsList[0].mAttributeId = 1;
+
+    readPrepareParams.mpAttributePathParamsList[1].mEndpointId  = kTestEndpointId;
+    readPrepareParams.mpAttributePathParamsList[1].mClusterId   = kTestClusterId;
+    readPrepareParams.mpAttributePathParamsList[1].mAttributeId = 2;
+
+    readPrepareParams.mAttributePathParamsListSize = 2;
+
+    readPrepareParams.mMinIntervalFloorSeconds   = 2;
+    readPrepareParams.mMaxIntervalCeilingSeconds = 5;
+    printf("\nSend first subscribe request message with wildcard urgent event to Node: %" PRIu64 "\n", chip::kTestDeviceNodeId);
+
+    delegate.mNumAttributeResponse       = 0;
+    readPrepareParams.mKeepSubscriptions = false;
+
+    {
+        app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &ctx.GetExchangeManager(), delegate,
+                                   chip::app::ReadClient::InteractionType::Subscribe);
+        readPrepareParams.mpEventPathParamsList[0].mIsUrgentEvent = true;
+        delegate.mGotReport                                       = false;
+        err                                                       = readClient.SendRequest(readPrepareParams);
+        NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
+
+        ctx.DrainAndServiceIO();
+
+        NL_TEST_ASSERT(apSuite, engine->GetNumActiveReadHandlers() == 1);
+        NL_TEST_ASSERT(apSuite, engine->ActiveHandlerAt(0) != nullptr);
+        delegate.mpReadHandler = engine->ActiveHandlerAt(0);
+
+        NL_TEST_ASSERT(apSuite, delegate.mGotEventResponse);
+        NL_TEST_ASSERT(apSuite, delegate.mGotReport);
+        NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 2);
+        NL_TEST_ASSERT(apSuite, engine->GetNumActiveReadHandlers(ReadHandler::InteractionType::Subscribe) == 1);
+
+        GenerateEvents(apSuite, apContext);
+        NL_TEST_ASSERT(apSuite, delegate.mpReadHandler->mHoldReport == false);
+        NL_TEST_ASSERT(apSuite, delegate.mpReadHandler->mDirty == true);
+        delegate.mGotEventResponse = false;
+        delegate.mGotReport        = false;
+        ctx.DrainAndServiceIO();
+        NL_TEST_ASSERT(apSuite, delegate.mGotEventResponse);
+    }
+
+    // By now we should have closed all exchanges and sent all pending acks, so
+    // there should be no queued-up things in the retransmit table.
+    NL_TEST_ASSERT(apSuite, rm->TestGetCountRetransTable() == 0);
+
+    NL_TEST_ASSERT(apSuite, engine->GetNumActiveReadClients() == 0);
+    engine->Shutdown();
+    NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0);
+}
+
 void TestReadInteraction::TestSubscribeWildcard(nlTestSuite * apSuite, void * apContext)
 {
     TestContext & ctx = *static_cast<TestContext *>(apContext);
@@ -1982,6 +2064,7 @@
     {
         app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &ctx.GetExchangeManager(), delegate,
                                    chip::app::ReadClient::InteractionType::Subscribe);
+        readPrepareParams.mpEventPathParamsList[0].mIsUrgentEvent = true;
         printf("\nSend first subscribe request message to Node: %" PRIu64 "\n", chip::kTestDeviceNodeId);
         delegate.mGotReport = false;
         err                 = readClient.SendRequest(readPrepareParams);
@@ -1998,7 +2081,7 @@
         NL_TEST_ASSERT(apSuite, delegate.mNumAttributeResponse == 2);
         NL_TEST_ASSERT(apSuite, engine->GetNumActiveReadHandlers(ReadHandler::InteractionType::Subscribe) == 1);
 
-        GenerateEvents(apSuite, apContext, true /*aIsUrgent*/);
+        GenerateEvents(apSuite, apContext);
         NL_TEST_ASSERT(apSuite, delegate.mpReadHandler->mHoldReport == false);
         NL_TEST_ASSERT(apSuite, delegate.mpReadHandler->mDirty == true);
         chip::app::ClusterInfo dirtyPath1;
@@ -2301,6 +2384,7 @@
     {
         app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &ctx.GetExchangeManager(), delegate,
                                    chip::app::ReadClient::InteractionType::Subscribe);
+        readPrepareParams.mpEventPathParamsList[0].mIsUrgentEvent = true;
         printf("\nSend first subscribe request message to Node: %" PRIu64 "\n", chip::kTestDeviceNodeId);
         delegate.mGotReport = false;
         err                 = readClient.SendRequest(readPrepareParams);
@@ -2316,7 +2400,7 @@
         NL_TEST_ASSERT(apSuite, delegate.mGotReport);
         NL_TEST_ASSERT(apSuite, engine->GetNumActiveReadHandlers(ReadHandler::InteractionType::Subscribe) == 1);
 
-        GenerateEvents(apSuite, apContext, true /*aIsUrgent*/);
+        GenerateEvents(apSuite, apContext);
         NL_TEST_ASSERT(apSuite, delegate.mpReadHandler->mHoldReport == false);
         NL_TEST_ASSERT(apSuite, delegate.mpReadHandler->mDirty == true);
         chip::app::ClusterInfo dirtyPath1;
@@ -2397,6 +2481,7 @@
     {
         app::ReadClient readClient(chip::app::InteractionModelEngine::GetInstance(), &ctx.GetExchangeManager(), delegate,
                                    chip::app::ReadClient::InteractionType::Subscribe);
+        readPrepareParams.mpEventPathParamsList[0].mIsUrgentEvent = true;
         printf("\nSend first subscribe request message to Node: %" PRIu64 "\n", chip::kTestDeviceNodeId);
         delegate.mGotReport = false;
         err                 = readClient.SendRequest(readPrepareParams);
@@ -2412,7 +2497,7 @@
         NL_TEST_ASSERT(apSuite, delegate.mGotReport);
         NL_TEST_ASSERT(apSuite, engine->GetNumActiveReadHandlers(ReadHandler::InteractionType::Subscribe) == 1);
 
-        GenerateEvents(apSuite, apContext, true /*aIsUrgent*/);
+        GenerateEvents(apSuite, apContext);
         NL_TEST_ASSERT(apSuite, delegate.mpReadHandler->mHoldReport == false);
         NL_TEST_ASSERT(apSuite, delegate.mpReadHandler->mDirty == true);
         chip::app::ClusterInfo dirtyPath1;
@@ -2479,6 +2564,7 @@
     NL_TEST_DEF("TestReadHandlerInvalidAttributePath", chip::app::TestReadInteraction::TestReadHandlerInvalidAttributePath),
     NL_TEST_DEF("TestProcessSubscribeRequest", chip::app::TestReadInteraction::TestProcessSubscribeRequest),
     NL_TEST_DEF("TestSubscribeRoundtrip", chip::app::TestReadInteraction::TestSubscribeRoundtrip),
+    NL_TEST_DEF("TestSubscribeUrgentWildcardEvent", chip::app::TestReadInteraction::TestSubscribeUrgentWildcardEvent),
     NL_TEST_DEF("TestSubscribeWildcard", chip::app::TestReadInteraction::TestSubscribeWildcard),
     NL_TEST_DEF("TestSubscribeEarlyShutdown", chip::app::TestReadInteraction::TestSubscribeEarlyShutdown),
     NL_TEST_DEF("TestSubscribeInvalidAttributePathRoundtrip", chip::app::TestReadInteraction::TestSubscribeInvalidAttributePathRoundtrip),