Skip to content

Commit

Permalink
Fix issue 13075 (#15683)
Browse files Browse the repository at this point in the history
--When mQueueLength >= mQueueSize happens in CHIPCircularTLVBuffer::GetNewBuffer, if mProcessEvictedElement is set with AlwaysFail, EvictHead would fail when logging Event. We should let EvictHead and Init succeed, then later EnsureSpaceInCircularBuffer
would help get enough space for new event in LogEventPrivate.

add event overflow testing
  • Loading branch information
yunhanw-google authored and pull[bot] committed Jan 24, 2024
1 parent 9a6347f commit 2527024
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 7 deletions.
11 changes: 4 additions & 7 deletions src/app/EventManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ void EventManagement::Init(Messaging::ExchangeManager * apExchangeManager, uint3

prev = current;

current->mProcessEvictedElement = AlwaysFail;
current->mProcessEvictedElement = nullptr;
current->mAppData = nullptr;
}

Expand Down Expand Up @@ -272,8 +272,7 @@ CHIP_ERROR EventManagement::EnsureSpaceInCircularBuffer(size_t aRequiredSpace)
}
}

// On exit, configure the top-level s.t. it will always fail to evict an element
mpEventBuffer->mProcessEvictedElement = AlwaysFail;
mpEventBuffer->mProcessEvictedElement = nullptr;
mpEventBuffer->mAppData = nullptr;

exit:
Expand Down Expand Up @@ -311,9 +310,7 @@ CHIP_ERROR EventManagement::ConstructEvent(EventLoadOutContext * apContext, Even
VerifyOrReturnError(apOptions != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

EventReportIB::Builder eventReportBuilder;
eventReportBuilder.Init(&(apContext->mWriter));
// TODO: Update IsUrgent, issue 11386
// TODO: Update statusIB, issue 11388
ReturnErrorOnFailure(eventReportBuilder.Init(&(apContext->mWriter)));
EventDataIB::Builder & eventDataIBBuilder = eventReportBuilder.CreateEventData();
ReturnErrorOnFailure(eventReportBuilder.GetError());
EventPathIB::Builder & eventPathBuilder = eventDataIBBuilder.CreatePath();
Expand All @@ -322,7 +319,7 @@ CHIP_ERROR EventManagement::ConstructEvent(EventLoadOutContext * apContext, Even
eventPathBuilder.Endpoint(apOptions->mPath.mEndpointId)
.Cluster(apOptions->mPath.mClusterId)
.Event(apOptions->mPath.mEventId)
.IsUrgent(false)
.IsUrgent(apOptions->mUrgent == EventOptions::Type::kUrgent)
.EndOfEventPathIB();
ReturnErrorOnFailure(eventPathBuilder.GetError());
eventDataIBBuilder.EventNumber(apContext->mCurrentEventNumber).Priority(chip::to_underlying(apContext->mPriority));
Expand Down
1 change: 1 addition & 0 deletions src/app/tests/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ chip_test_suite("tests") {
"TestCommandPathParams.cpp",
"TestDataModelSerialization.cpp",
"TestEventLogging.cpp",
"TestEventOverflow.cpp",
"TestEventPathParams.cpp",
"TestInteractionModelEngine.cpp",
"TestMessageDef.cpp",
Expand Down
185 changes: 185 additions & 0 deletions src/app/tests/TestEventOverflow.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
/*
*
* Copyright (c) 2022 Project CHIP Authors
* All rights reserved.
*
* 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.
*/

/**
* @file
* This file implements a test for CHIP Interaction Model Event logging
*
*/

#include <app/ClusterInfo.h>
#include <app/EventLoggingDelegate.h>
#include <app/EventLoggingTypes.h>
#include <app/EventManagement.h>
#include <app/InteractionModelEngine.h>
#include <app/tests/AppTestContext.h>
#include <lib/core/CHIPCore.h>
#include <lib/core/CHIPTLV.h>
#include <lib/core/CHIPTLVDebug.hpp>
#include <lib/core/CHIPTLVUtilities.hpp>
#include <lib/support/EnforceFormat.h>
#include <lib/support/ErrorStr.h>
#include <lib/support/UnitTestRegistration.h>
#include <lib/support/logging/Constants.h>
#include <messaging/ExchangeContext.h>
#include <messaging/Flags.h>
#include <platform/CHIPDeviceLayer.h>
#include <system/TLVPacketBufferBackingStore.h>

#include <nlunit-test.h>

namespace {

static uint8_t gDebugEventBuffer[2048];
static uint8_t gInfoEventBuffer[2048];
static uint8_t gCritEventBuffer[2048];
static chip::app::CircularEventBuffer gCircularEventBuffer[3];

class TestContext : public chip::Test::AppContext
{
public:
static int InitializeAsync(void * context)
{
if (AppContext::InitializeAsync(context) != SUCCESS)
return FAILURE;

auto * ctx = static_cast<TestContext *>(context);

chip::app::LogStorageResources logStorageResources[] = {
{ &gDebugEventBuffer[0], sizeof(gDebugEventBuffer), chip::app::PriorityLevel::Debug },
{ &gInfoEventBuffer[0], sizeof(gInfoEventBuffer), chip::app::PriorityLevel::Info },
{ &gCritEventBuffer[0], sizeof(gCritEventBuffer), chip::app::PriorityLevel::Critical },
};

chip::app::EventManagement::CreateEventManagement(&ctx->GetExchangeManager(),
sizeof(logStorageResources) / sizeof(logStorageResources[0]),
gCircularEventBuffer, logStorageResources, nullptr, 0, nullptr);

return SUCCESS;
}

static int Finalize(void * context)
{
chip::app::EventManagement::DestroyEventManagement();

if (AppContext::Finalize(context) != SUCCESS)
return FAILURE;

return SUCCESS;
}
};

class TestEventGenerator : public chip::app::EventLoggingDelegate
{
public:
CHIP_ERROR WriteEvent(chip::TLV::TLVWriter & aWriter)
{
chip::TLV::TLVType dataContainerType;
ReturnErrorOnFailure(aWriter.StartContainer(chip::TLV::ContextTag(chip::to_underlying(chip::app::EventDataIB::Tag::kData)),
chip::TLV::kTLVType_Structure, dataContainerType));
ReturnErrorOnFailure(aWriter.Put(chip::TLV::ContextTag(1), 1));
ReturnErrorOnFailure(aWriter.Put(chip::TLV::ContextTag(2), 2));
return aWriter.EndContainer(dataContainerType);
}
};

static void CheckLogEventOverFlow(nlTestSuite * apSuite, void * apContext)
{
CHIP_ERROR err = CHIP_NO_ERROR;
chip::EventNumber oldEid = 0;
chip::EventNumber eid = 0;
chip::app::EventOptions options;
TestEventGenerator testEventGenerator;

chip::EndpointId testEndpointId = 1;
chip::ClusterId testClusterId = 0x00000006;
chip::EventId testEvent = 1;
options.mPath = { testEndpointId, testClusterId, testEvent };
options.mPriority = chip::app::PriorityLevel::Debug;

chip::app::EventManagement & logMgmt = chip::app::EventManagement::GetInstance();
int alternate = 0;
for (int i = 0; i < 500; i++)
{
switch (alternate)
{
case 0:
options.mPriority = chip::app::PriorityLevel::Critical;
break;
case 1:
options.mPriority = chip::app::PriorityLevel::Debug;
break;
case 2:
options.mPriority = chip::app::PriorityLevel::Critical;
break;
case 3:
options.mPriority = chip::app::PriorityLevel::Debug;
break;
case 4:
options.mPriority = chip::app::PriorityLevel::Critical;
break;
case 5:
options.mPriority = chip::app::PriorityLevel::Debug;
break;
case 6:
options.mPriority = chip::app::PriorityLevel::Critical;
break;
case 7:
options.mPriority = chip::app::PriorityLevel::Debug;
break;
case 8:
options.mPriority = chip::app::PriorityLevel::Critical;
break;
case 9:
options.mPriority = chip::app::PriorityLevel::Debug;
break;
}
alternate = i % 10;

err = logMgmt.LogEvent(&testEventGenerator, options, eid);
NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR);
if (eid > 0)
{
NL_TEST_ASSERT(apSuite, eid == oldEid + 1);
oldEid = eid;
}
}
}

const nlTest sTests[] = { NL_TEST_DEF("CheckLogEventOverFlow", CheckLogEventOverFlow), NL_TEST_SENTINEL() };

// clang-format off
nlTestSuite sSuite =
{
"TestEventOverflow",
&sTests[0],
TestContext::InitializeAsync,
TestContext::Finalize
};
// clang-format on

} // namespace

int TestEventOverflow()
{
TestContext gContext;
nlTestRunner(&sSuite, &gContext);
return (nlTestRunnerStats(&sSuite));
}

CHIP_REGISTER_TEST_SUITE(TestEventOverflow)

0 comments on commit 2527024

Please sign in to comment.