diff --git a/src/controller/tests/BUILD.gn b/src/controller/tests/BUILD.gn index 1d93c12c37053c..1e2b15d7778beb 100644 --- a/src/controller/tests/BUILD.gn +++ b/src/controller/tests/BUILD.gn @@ -14,11 +14,11 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") -import("//build_overrides/nlunit_test.gni") +import("//build_overrides/pigweed.gni") import("${chip_root}/build/chip/chip_test_suite.gni") -chip_test_suite_using_nltest("tests") { +chip_test_suite("tests") { output_name = "libControllerTests" test_sources = [ "TestCommissionableNodeController.cpp" ] @@ -40,10 +40,8 @@ chip_test_suite_using_nltest("tests") { "${chip_root}/src/app/tests:helpers", "${chip_root}/src/controller", "${chip_root}/src/lib/support:test_utils", - "${chip_root}/src/lib/support:testing_nlunit", "${chip_root}/src/messaging/tests:helpers", "${chip_root}/src/transport/raw/tests:helpers", - "${nlunit_test_root}:nlunit-test", ] if (chip_device_platform != "mbed") { diff --git a/src/controller/tests/TestCommissionableNodeController.cpp b/src/controller/tests/TestCommissionableNodeController.cpp index 5e866b4b25ea72..b68d0748d62c42 100644 --- a/src/controller/tests/TestCommissionableNodeController.cpp +++ b/src/controller/tests/TestCommissionableNodeController.cpp @@ -16,10 +16,10 @@ * limitations under the License. */ +#include + #include #include -#include -#include using namespace chip; using namespace chip::Dnssd; @@ -61,8 +61,15 @@ class MockResolver : public Resolver namespace { +class TestCommissionableNodeController : public ::testing::Test +{ +public: + static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } + static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } +}; + #if INET_CONFIG_ENABLE_IPV4 -void TestGetDiscoveredCommissioner_HappyCase(nlTestSuite * inSuite, void * inContext) +TEST_F(TestCommissionableNodeController, TestGetDiscoveredCommissioner_HappyCase) { MockResolver resolver; CommissionableNodeController controller(&resolver); @@ -76,14 +83,14 @@ void TestGetDiscoveredCommissioner_HappyCase(nlTestSuite * inSuite, void * inCon controller.OnNodeDiscovered(discNodeData); - NL_TEST_ASSERT(inSuite, controller.GetDiscoveredCommissioner(0) != nullptr); - NL_TEST_ASSERT(inSuite, strcmp(inNodeData.hostName, controller.GetDiscoveredCommissioner(0)->hostName) == 0); - NL_TEST_ASSERT(inSuite, inNodeData.ipAddress[0] == controller.GetDiscoveredCommissioner(0)->ipAddress[0]); - NL_TEST_ASSERT(inSuite, controller.GetDiscoveredCommissioner(0)->port == 5540); - NL_TEST_ASSERT(inSuite, controller.GetDiscoveredCommissioner(0)->numIPs == 1); + ASSERT_NE(controller.GetDiscoveredCommissioner(0), nullptr); + EXPECT_STREQ(inNodeData.hostName, controller.GetDiscoveredCommissioner(0)->hostName); + EXPECT_EQ(inNodeData.ipAddress[0], controller.GetDiscoveredCommissioner(0)->ipAddress[0]); + EXPECT_EQ(controller.GetDiscoveredCommissioner(0)->port, 5540); + EXPECT_EQ(controller.GetDiscoveredCommissioner(0)->numIPs, 1u); } -void TestGetDiscoveredCommissioner_InvalidNodeDiscovered_ReturnsNullptr(nlTestSuite * inSuite, void * inContext) +TEST_F(TestCommissionableNodeController, TestGetDiscoveredCommissioner_InvalidNodeDiscovered_ReturnsNullptr) { MockResolver resolver; CommissionableNodeController controller(&resolver); @@ -98,11 +105,11 @@ void TestGetDiscoveredCommissioner_InvalidNodeDiscovered_ReturnsNullptr(nlTestSu for (int i = 0; i < CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES; i++) { - NL_TEST_ASSERT(inSuite, controller.GetDiscoveredCommissioner(i) == nullptr); + EXPECT_EQ(controller.GetDiscoveredCommissioner(i), nullptr); } } -void TestGetDiscoveredCommissioner_HappyCase_OneValidOneInvalidNode(nlTestSuite * inSuite, void * inContext) +TEST_F(TestCommissionableNodeController, TestGetDiscoveredCommissioner_HappyCase_OneValidOneInvalidNode) { MockResolver resolver; CommissionableNodeController controller(&resolver); @@ -123,101 +130,56 @@ void TestGetDiscoveredCommissioner_HappyCase_OneValidOneInvalidNode(nlTestSuite controller.OnNodeDiscovered(validDiscNodeData); controller.OnNodeDiscovered(invalidDiscNodeData); - NL_TEST_ASSERT(inSuite, controller.GetDiscoveredCommissioner(0) != nullptr); - NL_TEST_ASSERT(inSuite, strcmp(validNodeData.hostName, controller.GetDiscoveredCommissioner(0)->hostName) == 0); - NL_TEST_ASSERT(inSuite, validNodeData.ipAddress[0] == controller.GetDiscoveredCommissioner(0)->ipAddress[0]); - NL_TEST_ASSERT(inSuite, controller.GetDiscoveredCommissioner(0)->port == 5540); - NL_TEST_ASSERT(inSuite, controller.GetDiscoveredCommissioner(0)->numIPs == 1); + ASSERT_NE(controller.GetDiscoveredCommissioner(0), nullptr); + EXPECT_STREQ(validNodeData.hostName, controller.GetDiscoveredCommissioner(0)->hostName); + EXPECT_EQ(validNodeData.ipAddress[0], controller.GetDiscoveredCommissioner(0)->ipAddress[0]); + EXPECT_EQ(controller.GetDiscoveredCommissioner(0)->port, 5540); + EXPECT_EQ(controller.GetDiscoveredCommissioner(0)->numIPs, 1u); - NL_TEST_ASSERT(inSuite, controller.GetDiscoveredCommissioner(1) == nullptr); + EXPECT_EQ(controller.GetDiscoveredCommissioner(1), nullptr); } #endif // INET_CONFIG_ENABLE_IPV4 -void TestGetDiscoveredCommissioner_NoNodesDiscovered_ReturnsNullptr(nlTestSuite * inSuite, void * inContext) +TEST_F(TestCommissionableNodeController, TestGetDiscoveredCommissioner_NoNodesDiscovered_ReturnsNullptr) { MockResolver resolver; CommissionableNodeController controller(&resolver); for (int i = 0; i < CHIP_DEVICE_CONFIG_MAX_DISCOVERED_NODES; i++) { - NL_TEST_ASSERT(inSuite, controller.GetDiscoveredCommissioner(i) == nullptr); + EXPECT_EQ(controller.GetDiscoveredCommissioner(i), nullptr); } } -void TestDiscoverCommissioners_HappyCase(nlTestSuite * inSuite, void * inContext) +TEST_F(TestCommissionableNodeController, TestDiscoverCommissioners_HappyCase) { MockResolver resolver; CommissionableNodeController controller(&resolver); - NL_TEST_ASSERT(inSuite, controller.DiscoverCommissioners() == CHIP_NO_ERROR); + EXPECT_EQ(controller.DiscoverCommissioners(), CHIP_NO_ERROR); } -void TestDiscoverCommissioners_HappyCaseWithDiscoveryFilter(nlTestSuite * inSuite, void * inContext) +TEST_F(TestCommissionableNodeController, TestDiscoverCommissioners_HappyCaseWithDiscoveryFilter) { MockResolver resolver; CommissionableNodeController controller(&resolver); - NL_TEST_ASSERT(inSuite, - controller.DiscoverCommissioners(Dnssd::DiscoveryFilter(Dnssd::DiscoveryFilterType::kDeviceType, 35)) == - CHIP_NO_ERROR); + EXPECT_EQ(controller.DiscoverCommissioners(Dnssd::DiscoveryFilter(Dnssd::DiscoveryFilterType::kDeviceType, 35)), CHIP_NO_ERROR); } -void TestDiscoverCommissioners_InitError_ReturnsError(nlTestSuite * inSuite, void * inContext) +TEST_F(TestCommissionableNodeController, TestDiscoverCommissioners_InitError_ReturnsError) { MockResolver resolver; resolver.InitStatus = CHIP_ERROR_INTERNAL; CommissionableNodeController controller(&resolver); - NL_TEST_ASSERT(inSuite, controller.DiscoverCommissioners() != CHIP_NO_ERROR); + EXPECT_NE(controller.DiscoverCommissioners(), CHIP_NO_ERROR); } -void TestDiscoverCommissioners_DiscoverCommissionersError_ReturnsError(nlTestSuite * inSuite, void * inContext) +TEST_F(TestCommissionableNodeController, TestDiscoverCommissioners_DiscoverCommissionersError_ReturnsError) { MockResolver resolver; resolver.DiscoverCommissionersStatus = CHIP_ERROR_INTERNAL; CommissionableNodeController controller(&resolver); - NL_TEST_ASSERT(inSuite, controller.DiscoverCommissioners() != CHIP_NO_ERROR); + EXPECT_NE(controller.DiscoverCommissioners(), CHIP_NO_ERROR); } -// clang-format off -const nlTest sTests[] = -{ -#if INET_CONFIG_ENABLE_IPV4 - NL_TEST_DEF("TestGetDiscoveredCommissioner_HappyCase", TestGetDiscoveredCommissioner_HappyCase), - NL_TEST_DEF("TestGetDiscoveredCommissioner_HappyCase_OneValidOneInvalidNode", TestGetDiscoveredCommissioner_HappyCase_OneValidOneInvalidNode), - NL_TEST_DEF("TestGetDiscoveredCommissioner_InvalidNodeDiscovered_ReturnsNullptr", TestGetDiscoveredCommissioner_InvalidNodeDiscovered_ReturnsNullptr), -#endif // INET_CONFIG_ENABLE_IPV4 - NL_TEST_DEF("TestGetDiscoveredCommissioner_NoNodesDiscovered_ReturnsNullptr", TestGetDiscoveredCommissioner_NoNodesDiscovered_ReturnsNullptr), - NL_TEST_DEF("TestDiscoverCommissioners_HappyCase", TestDiscoverCommissioners_HappyCase), - NL_TEST_DEF("TestDiscoverCommissioners_HappyCaseWithDiscoveryFilter", TestDiscoverCommissioners_HappyCaseWithDiscoveryFilter), - NL_TEST_DEF("TestDiscoverCommissioners_InitError_ReturnsError", TestDiscoverCommissioners_InitError_ReturnsError), - NL_TEST_DEF("TestDiscoverCommissioners_DiscoverCommissionersError_ReturnsError", TestDiscoverCommissioners_DiscoverCommissionersError_ReturnsError), - NL_TEST_SENTINEL() -}; -// clang-format on - } // namespace - -int TestCommissionableNodeController_Setup(void * inContext) -{ - if (CHIP_NO_ERROR != chip::Platform::MemoryInit()) - { - return FAILURE; - } - - return SUCCESS; -} - -int TestCommissionableNodeController_Teardown(void * inContext) -{ - chip::Platform::MemoryShutdown(); - return SUCCESS; -} - -int TestCommissionableNodeController() -{ - nlTestSuite theSuite = { "CommissionableNodeController", &sTests[0], TestCommissionableNodeController_Setup, - TestCommissionableNodeController_Teardown }; - nlTestRunner(&theSuite, nullptr); - return nlTestRunnerStats(&theSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestCommissionableNodeController) diff --git a/src/controller/tests/TestEventCaching.cpp b/src/controller/tests/TestEventCaching.cpp index 3ff85ebdf96cdc..b4c262725f74d3 100644 --- a/src/controller/tests/TestEventCaching.cpp +++ b/src/controller/tests/TestEventCaching.cpp @@ -16,6 +16,8 @@ * limitations under the License. */ +#include + #include "app-common/zap-generated/ids/Attributes.h" #include "app-common/zap-generated/ids/Clusters.h" #include "app/ClusterStateCache.h" @@ -33,12 +35,9 @@ #include #include #include -#include -#include #include #include #include -#include using namespace chip; using namespace chip::app; @@ -51,11 +50,43 @@ static uint8_t gInfoEventBuffer[4096]; static uint8_t gCritEventBuffer[4096]; static chip::app::CircularEventBuffer gCircularEventBuffer[3]; -class TestContext : public chip::Test::AppContext +using TestContext = chip::Test::AppContext; + +// +// The generated endpoint_config for the controller app has Endpoint 1 +// already used in the fixed endpoint set of size 1. Consequently, let's use the next +// number higher than that for our dynamic test endpoint. +// +constexpr EndpointId kTestEndpointId = 2; + +class TestEventCaching : public ::testing::Test { public: - // Performs setup for each individual test in the test suite - void SetUp() override + // Performs shared setup for all tests in the test suite + static void SetUpTestSuite() + { + if (mpContext == nullptr) + { + mpContext = new TestContext(); + ASSERT_NE(mpContext, nullptr); + } + mpContext->SetUpTestSuite(); + } + + // Performs shared teardown for all tests in the test suite + static void TearDownTestSuite() + { + mpContext->TearDownTestSuite(); + if (mpContext != nullptr) + { + delete mpContext; + mpContext = nullptr; + } + } + +protected: + // Performs setup for each test in the suite + void SetUp() { const chip::app::LogStorageResources logStorageResources[] = { { &gDebugEventBuffer[0], sizeof(gDebugEventBuffer), chip::app::PriorityLevel::Debug }, @@ -63,44 +94,29 @@ class TestContext : public chip::Test::AppContext { &gCritEventBuffer[0], sizeof(gCritEventBuffer), chip::app::PriorityLevel::Critical }, }; - chip::Test::AppContext::SetUp(); + mpContext->SetUp(); CHIP_ERROR err = CHIP_NO_ERROR; // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete VerifyOrDieWithMsg((err = mEventCounter.Init(0)) == CHIP_NO_ERROR, AppServer, "Init EventCounter failed: %" CHIP_ERROR_FORMAT, err.Format()); - chip::app::EventManagement::CreateEventManagement(&GetExchangeManager(), ArraySize(logStorageResources), + chip::app::EventManagement::CreateEventManagement(&mpContext->GetExchangeManager(), ArraySize(logStorageResources), gCircularEventBuffer, logStorageResources, &mEventCounter); } - // Performs teardown for each individual test in the test suite - void TearDown() override + // Performs teardown for each test in the suite + void TearDown() { chip::app::EventManagement::DestroyEventManagement(); - chip::Test::AppContext::TearDown(); + mpContext->TearDown(); } -private: - MonotonicallyIncreasingCounter mEventCounter; -}; - -nlTestSuite * gSuite = nullptr; - -// -// The generated endpoint_config for the controller app has Endpoint 1 -// already used in the fixed endpoint set of size 1. Consequently, let's use the next -// number higher than that for our dynamic test endpoint. -// -constexpr EndpointId kTestEndpointId = 2; - -class TestReadEvents -{ -public: - TestReadEvents() {} - static void TestBasicCaching(nlTestSuite * apSuite, void * apContext); + static TestContext * mpContext; private: + MonotonicallyIncreasingCounter mEventCounter; }; +TestContext * TestEventCaching::mpContext = nullptr; //clang-format off DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(testClusterAttrs) @@ -132,7 +148,7 @@ class TestReadCallback : public app::ClusterStateCache::Callback namespace { -void GenerateEvents(nlTestSuite * apSuite, chip::EventNumber & firstEventNumber, chip::EventNumber & lastEventNumber) +void GenerateEvents(chip::EventNumber & firstEventNumber, chip::EventNumber & lastEventNumber) { CHIP_ERROR err = CHIP_NO_ERROR; static uint8_t generationCount = 0; @@ -142,7 +158,7 @@ void GenerateEvents(nlTestSuite * apSuite, chip::EventNumber & firstEventNumber, for (int i = 0; i < 5; i++) { content.arg1 = static_cast(generationCount++); - NL_TEST_ASSERT(apSuite, (err = app::LogEvent(content, kTestEndpointId, lastEventNumber)) == CHIP_NO_ERROR); + EXPECT_EQ((err = app::LogEvent(content, kTestEndpointId, lastEventNumber)), CHIP_NO_ERROR); if (i == 0) { firstEventNumber = lastEventNumber; @@ -161,10 +177,9 @@ void GenerateEvents(nlTestSuite * apSuite, chip::EventNumber & firstEventNumber, * events are present in the cache. * */ -void TestReadEvents::TestBasicCaching(nlTestSuite * apSuite, void * apContext) +TEST_F(TestEventCaching, TestBasicCaching) { - TestContext & ctx = *static_cast(apContext); - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = mpContext->GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -177,8 +192,8 @@ void TestReadEvents::TestBasicCaching(nlTestSuite * apSuite, void * apContext) chip::EventNumber firstEventNumber; chip::EventNumber lastEventNumber; - GenerateEvents(apSuite, firstEventNumber, lastEventNumber); - NL_TEST_ASSERT(apSuite, lastEventNumber > firstEventNumber); + GenerateEvents(firstEventNumber, lastEventNumber); + EXPECT_GT(lastEventNumber, firstEventNumber); app::EventPathParams eventPath; eventPath.mEndpointId = kTestEndpointId; @@ -192,81 +207,81 @@ void TestReadEvents::TestBasicCaching(nlTestSuite * apSuite, void * apContext) TestReadCallback readCallback; { - app::ReadClient readClient(engine, &ctx.GetExchangeManager(), readCallback.mClusterCacheAdapter.GetBufferedCallback(), - app::ReadClient::InteractionType::Read); + app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), + readCallback.mClusterCacheAdapter.GetBufferedCallback(), app::ReadClient::InteractionType::Read); - NL_TEST_ASSERT(apSuite, readClient.SendRequest(readParams) == CHIP_NO_ERROR); + EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); uint8_t generationCount = 0; readCallback.mClusterCacheAdapter.ForEachEventData( - [&apSuite, &readCallback, &generationCount, firstEventNumber, lastEventNumber](const app::EventHeader & header) { - NL_TEST_ASSERT(apSuite, header.mPath.mClusterId == Clusters::UnitTesting::Id); - NL_TEST_ASSERT(apSuite, header.mPath.mEventId == Clusters::UnitTesting::Events::TestEvent::Id); - NL_TEST_ASSERT(apSuite, header.mPath.mEndpointId == kTestEndpointId); - NL_TEST_ASSERT(apSuite, header.mEventNumber >= firstEventNumber); - NL_TEST_ASSERT(apSuite, header.mEventNumber <= lastEventNumber); + [&readCallback, &generationCount, firstEventNumber, lastEventNumber](const app::EventHeader & header) { + EXPECT_EQ(header.mPath.mClusterId, Clusters::UnitTesting::Id); + EXPECT_EQ(header.mPath.mEventId, Clusters::UnitTesting::Events::TestEvent::Id); + EXPECT_EQ(header.mPath.mEndpointId, kTestEndpointId); + EXPECT_GE(header.mEventNumber, firstEventNumber); + EXPECT_LE(header.mEventNumber, lastEventNumber); Clusters::UnitTesting::Events::TestEvent::DecodableType eventData; - NL_TEST_ASSERT(apSuite, readCallback.mClusterCacheAdapter.Get(header.mEventNumber, eventData) == CHIP_NO_ERROR); + EXPECT_EQ(readCallback.mClusterCacheAdapter.Get(header.mEventNumber, eventData), CHIP_NO_ERROR); - NL_TEST_ASSERT(apSuite, eventData.arg1 == generationCount); + EXPECT_EQ(eventData.arg1, generationCount); generationCount++; return CHIP_NO_ERROR; }); - NL_TEST_ASSERT(apSuite, generationCount == lastEventNumber - firstEventNumber + 1); + EXPECT_EQ(generationCount, lastEventNumber - firstEventNumber + 1); Optional highestEventNumber; readCallback.mClusterCacheAdapter.GetHighestReceivedEventNumber(highestEventNumber); - NL_TEST_ASSERT(apSuite, highestEventNumber.HasValue() && highestEventNumber.Value() == lastEventNumber); + EXPECT_TRUE(highestEventNumber.HasValue() && highestEventNumber.Value() == lastEventNumber); // // Re-run the iterator but pass in a path filter: EP*/TestCluster/EID* // generationCount = 0; readCallback.mClusterCacheAdapter.ForEachEventData( - [&apSuite, &readCallback, &generationCount, firstEventNumber, lastEventNumber](const app::EventHeader & header) { - NL_TEST_ASSERT(apSuite, header.mPath.mClusterId == Clusters::UnitTesting::Id); - NL_TEST_ASSERT(apSuite, header.mPath.mEventId == Clusters::UnitTesting::Events::TestEvent::Id); - NL_TEST_ASSERT(apSuite, header.mPath.mEndpointId == kTestEndpointId); - NL_TEST_ASSERT(apSuite, header.mEventNumber >= firstEventNumber); - NL_TEST_ASSERT(apSuite, header.mEventNumber <= lastEventNumber); + [&readCallback, &generationCount, firstEventNumber, lastEventNumber](const app::EventHeader & header) { + EXPECT_EQ(header.mPath.mClusterId, Clusters::UnitTesting::Id); + EXPECT_EQ(header.mPath.mEventId, Clusters::UnitTesting::Events::TestEvent::Id); + EXPECT_EQ(header.mPath.mEndpointId, kTestEndpointId); + EXPECT_GE(header.mEventNumber, firstEventNumber); + EXPECT_LE(header.mEventNumber, lastEventNumber); Clusters::UnitTesting::Events::TestEvent::DecodableType eventData; - NL_TEST_ASSERT(apSuite, readCallback.mClusterCacheAdapter.Get(header.mEventNumber, eventData) == CHIP_NO_ERROR); + EXPECT_EQ(readCallback.mClusterCacheAdapter.Get(header.mEventNumber, eventData), CHIP_NO_ERROR); - NL_TEST_ASSERT(apSuite, eventData.arg1 == generationCount); + EXPECT_EQ(eventData.arg1, generationCount); generationCount++; return CHIP_NO_ERROR; }, app::EventPathParams(kInvalidEndpointId, Clusters::UnitTesting::Id, kInvalidEventId)); - NL_TEST_ASSERT(apSuite, generationCount == lastEventNumber - firstEventNumber + 1); + EXPECT_EQ(generationCount, lastEventNumber - firstEventNumber + 1); // // Re-run the iterator but pass in a path filter: EP*/TestCluster/TestEvent // generationCount = 0; readCallback.mClusterCacheAdapter.ForEachEventData( - [&apSuite, &readCallback, &generationCount, firstEventNumber, lastEventNumber](const app::EventHeader & header) { - NL_TEST_ASSERT(apSuite, header.mPath.mClusterId == Clusters::UnitTesting::Id); - NL_TEST_ASSERT(apSuite, header.mPath.mEventId == Clusters::UnitTesting::Events::TestEvent::Id); - NL_TEST_ASSERT(apSuite, header.mPath.mEndpointId == kTestEndpointId); - NL_TEST_ASSERT(apSuite, header.mEventNumber >= firstEventNumber); - NL_TEST_ASSERT(apSuite, header.mEventNumber <= lastEventNumber); + [&readCallback, &generationCount, firstEventNumber, lastEventNumber](const app::EventHeader & header) { + EXPECT_EQ(header.mPath.mClusterId, Clusters::UnitTesting::Id); + EXPECT_EQ(header.mPath.mEventId, Clusters::UnitTesting::Events::TestEvent::Id); + EXPECT_EQ(header.mPath.mEndpointId, kTestEndpointId); + EXPECT_GE(header.mEventNumber, firstEventNumber); + EXPECT_LE(header.mEventNumber, lastEventNumber); Clusters::UnitTesting::Events::TestEvent::DecodableType eventData; - NL_TEST_ASSERT(apSuite, readCallback.mClusterCacheAdapter.Get(header.mEventNumber, eventData) == CHIP_NO_ERROR); + EXPECT_EQ(readCallback.mClusterCacheAdapter.Get(header.mEventNumber, eventData), CHIP_NO_ERROR); - NL_TEST_ASSERT(apSuite, eventData.arg1 == generationCount); + EXPECT_EQ(eventData.arg1, generationCount); generationCount++; return CHIP_NO_ERROR; }, app::EventPathParams(kInvalidEndpointId, Clusters::UnitTesting::Id, Clusters::UnitTesting::Events::TestEvent::Id)); - NL_TEST_ASSERT(apSuite, generationCount == lastEventNumber - firstEventNumber + 1); + EXPECT_EQ(generationCount, lastEventNumber - firstEventNumber + 1); // // Re-run the iterator but pass in a min event number filter @@ -274,23 +289,23 @@ void TestReadEvents::TestBasicCaching(nlTestSuite * apSuite, void * apContext) // generationCount = 1; readCallback.mClusterCacheAdapter.ForEachEventData( - [&apSuite, &readCallback, &generationCount, firstEventNumber, lastEventNumber](const app::EventHeader & header) { - NL_TEST_ASSERT(apSuite, header.mPath.mClusterId == Clusters::UnitTesting::Id); - NL_TEST_ASSERT(apSuite, header.mPath.mEventId == Clusters::UnitTesting::Events::TestEvent::Id); - NL_TEST_ASSERT(apSuite, header.mPath.mEndpointId == kTestEndpointId); - NL_TEST_ASSERT(apSuite, header.mEventNumber >= firstEventNumber + 1); - NL_TEST_ASSERT(apSuite, header.mEventNumber <= lastEventNumber); + [&readCallback, &generationCount, firstEventNumber, lastEventNumber](const app::EventHeader & header) { + EXPECT_EQ(header.mPath.mClusterId, Clusters::UnitTesting::Id); + EXPECT_EQ(header.mPath.mEventId, Clusters::UnitTesting::Events::TestEvent::Id); + EXPECT_EQ(header.mPath.mEndpointId, kTestEndpointId); + EXPECT_GE(header.mEventNumber, firstEventNumber + 1); + EXPECT_LE(header.mEventNumber, lastEventNumber); Clusters::UnitTesting::Events::TestEvent::DecodableType eventData; - NL_TEST_ASSERT(apSuite, readCallback.mClusterCacheAdapter.Get(header.mEventNumber, eventData) == CHIP_NO_ERROR); + EXPECT_EQ(readCallback.mClusterCacheAdapter.Get(header.mEventNumber, eventData), CHIP_NO_ERROR); - NL_TEST_ASSERT(apSuite, eventData.arg1 == generationCount); + EXPECT_EQ(eventData.arg1, generationCount); generationCount++; return CHIP_NO_ERROR; }, app::EventPathParams(), firstEventNumber + 1); - NL_TEST_ASSERT(apSuite, generationCount == lastEventNumber - firstEventNumber + 1); + EXPECT_EQ(generationCount, lastEventNumber - firstEventNumber + 1); // // Re-run the iterator but pass in a min event number filter @@ -299,38 +314,38 @@ void TestReadEvents::TestBasicCaching(nlTestSuite * apSuite, void * apContext) // generationCount = 1; readCallback.mClusterCacheAdapter.ForEachEventData( - [&apSuite, &readCallback, &generationCount, firstEventNumber, lastEventNumber](const app::EventHeader & header) { - NL_TEST_ASSERT(apSuite, header.mPath.mClusterId == Clusters::UnitTesting::Id); - NL_TEST_ASSERT(apSuite, header.mPath.mEventId == Clusters::UnitTesting::Events::TestEvent::Id); - NL_TEST_ASSERT(apSuite, header.mPath.mEndpointId == kTestEndpointId); - NL_TEST_ASSERT(apSuite, header.mEventNumber >= firstEventNumber + 1); - NL_TEST_ASSERT(apSuite, header.mEventNumber <= lastEventNumber); + [&readCallback, &generationCount, firstEventNumber, lastEventNumber](const app::EventHeader & header) { + EXPECT_EQ(header.mPath.mClusterId, Clusters::UnitTesting::Id); + EXPECT_EQ(header.mPath.mEventId, Clusters::UnitTesting::Events::TestEvent::Id); + EXPECT_EQ(header.mPath.mEndpointId, kTestEndpointId); + EXPECT_GE(header.mEventNumber, firstEventNumber + 1); + EXPECT_LE(header.mEventNumber, lastEventNumber); Clusters::UnitTesting::Events::TestEvent::DecodableType eventData; - NL_TEST_ASSERT(apSuite, readCallback.mClusterCacheAdapter.Get(header.mEventNumber, eventData) == CHIP_NO_ERROR); + EXPECT_EQ(readCallback.mClusterCacheAdapter.Get(header.mEventNumber, eventData), CHIP_NO_ERROR); - NL_TEST_ASSERT(apSuite, eventData.arg1 == generationCount); + EXPECT_EQ(eventData.arg1, generationCount); generationCount++; return CHIP_NO_ERROR; }, app::EventPathParams(kInvalidEndpointId, Clusters::UnitTesting::Id, kInvalidEventId), firstEventNumber + 1); - NL_TEST_ASSERT(apSuite, generationCount == lastEventNumber - firstEventNumber + 1); + EXPECT_EQ(generationCount, lastEventNumber - firstEventNumber + 1); } // // Generate more events. // const EventNumber oldFirstEventNumber = firstEventNumber; - GenerateEvents(apSuite, firstEventNumber, lastEventNumber); + GenerateEvents(firstEventNumber, lastEventNumber); { - app::ReadClient readClient(engine, &ctx.GetExchangeManager(), readCallback.mClusterCacheAdapter.GetBufferedCallback(), - app::ReadClient::InteractionType::Read); + app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), + readCallback.mClusterCacheAdapter.GetBufferedCallback(), app::ReadClient::InteractionType::Read); - NL_TEST_ASSERT(apSuite, readClient.SendRequest(readParams) == CHIP_NO_ERROR); + EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); // // Validate that we still have all 5 of the old events we received, as well as the new ones that just got generated. @@ -338,27 +353,27 @@ void TestReadEvents::TestBasicCaching(nlTestSuite * apSuite, void * apContext) // uint8_t generationCount = 0; readCallback.mClusterCacheAdapter.ForEachEventData( - [&apSuite, &readCallback, &generationCount, oldFirstEventNumber, lastEventNumber](const app::EventHeader & header) { - NL_TEST_ASSERT(apSuite, header.mPath.mClusterId == Clusters::UnitTesting::Id); - NL_TEST_ASSERT(apSuite, header.mPath.mEventId == Clusters::UnitTesting::Events::TestEvent::Id); - NL_TEST_ASSERT(apSuite, header.mPath.mEndpointId == kTestEndpointId); - NL_TEST_ASSERT(apSuite, header.mEventNumber >= oldFirstEventNumber); - NL_TEST_ASSERT(apSuite, header.mEventNumber <= lastEventNumber); + [&readCallback, &generationCount, oldFirstEventNumber, lastEventNumber](const app::EventHeader & header) { + EXPECT_EQ(header.mPath.mClusterId, Clusters::UnitTesting::Id); + EXPECT_EQ(header.mPath.mEventId, Clusters::UnitTesting::Events::TestEvent::Id); + EXPECT_EQ(header.mPath.mEndpointId, kTestEndpointId); + EXPECT_GE(header.mEventNumber, oldFirstEventNumber); + EXPECT_LE(header.mEventNumber, lastEventNumber); Clusters::UnitTesting::Events::TestEvent::DecodableType eventData; - NL_TEST_ASSERT(apSuite, readCallback.mClusterCacheAdapter.Get(header.mEventNumber, eventData) == CHIP_NO_ERROR); + EXPECT_EQ(readCallback.mClusterCacheAdapter.Get(header.mEventNumber, eventData), CHIP_NO_ERROR); - NL_TEST_ASSERT(apSuite, eventData.arg1 == generationCount); + EXPECT_EQ(eventData.arg1, generationCount); generationCount++; return CHIP_NO_ERROR; }); - NL_TEST_ASSERT(apSuite, generationCount == lastEventNumber - oldFirstEventNumber + 1); + EXPECT_EQ(generationCount, lastEventNumber - oldFirstEventNumber + 1); Optional highestEventNumber; readCallback.mClusterCacheAdapter.GetHighestReceivedEventNumber(highestEventNumber); - NL_TEST_ASSERT(apSuite, highestEventNumber.HasValue() && highestEventNumber.Value() == 9); + EXPECT_TRUE(highestEventNumber.HasValue() && highestEventNumber.Value() == 9); readCallback.mClusterCacheAdapter.ClearEventCache(); generationCount = 0; @@ -367,9 +382,9 @@ void TestReadEvents::TestBasicCaching(nlTestSuite * apSuite, void * apContext) return CHIP_NO_ERROR; }); - NL_TEST_ASSERT(apSuite, generationCount == 0); + EXPECT_EQ(generationCount, 0u); readCallback.mClusterCacheAdapter.GetHighestReceivedEventNumber(highestEventNumber); - NL_TEST_ASSERT(apSuite, highestEventNumber.HasValue() && highestEventNumber.Value() == 9); + EXPECT_TRUE(highestEventNumber.HasValue() && highestEventNumber.Value() == 9); } // @@ -377,46 +392,46 @@ void TestReadEvents::TestBasicCaching(nlTestSuite * apSuite, void * apContext) // we don't receive events lower than that value. // { - app::ReadClient readClient(engine, &ctx.GetExchangeManager(), readCallback.mClusterCacheAdapter.GetBufferedCallback(), - app::ReadClient::InteractionType::Read); + app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), + readCallback.mClusterCacheAdapter.GetBufferedCallback(), app::ReadClient::InteractionType::Read); readCallback.mClusterCacheAdapter.ClearEventCache(); constexpr EventNumber kLastSeenEventNumber = 3; - NL_TEST_ASSERT(apSuite, kLastSeenEventNumber < lastEventNumber); + EXPECT_LT(kLastSeenEventNumber, lastEventNumber); readCallback.mClusterCacheAdapter.SetHighestReceivedEventNumber(kLastSeenEventNumber); readParams.mEventNumber.ClearValue(); readCallback.mEventsSeen = 0; - NL_TEST_ASSERT(apSuite, readClient.SendRequest(readParams) == CHIP_NO_ERROR); + EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); // We should only get events with event numbers larger than kHighestEventNumberSeen. - NL_TEST_ASSERT(apSuite, readCallback.mEventsSeen == lastEventNumber - kLastSeenEventNumber); + EXPECT_EQ(readCallback.mEventsSeen, lastEventNumber - kLastSeenEventNumber); uint8_t generationCount = kLastSeenEventNumber + 1; readCallback.mClusterCacheAdapter.ForEachEventData( - [&apSuite, &readCallback, &generationCount, lastEventNumber](const app::EventHeader & header) { - NL_TEST_ASSERT(apSuite, header.mPath.mClusterId == Clusters::UnitTesting::Id); - NL_TEST_ASSERT(apSuite, header.mPath.mEventId == Clusters::UnitTesting::Events::TestEvent::Id); - NL_TEST_ASSERT(apSuite, header.mPath.mEndpointId == kTestEndpointId); - NL_TEST_ASSERT(apSuite, header.mEventNumber > kLastSeenEventNumber); - NL_TEST_ASSERT(apSuite, header.mEventNumber <= lastEventNumber); + [&readCallback, &generationCount, lastEventNumber, kLastSeenEventNumber](const app::EventHeader & header) { + EXPECT_EQ(header.mPath.mClusterId, Clusters::UnitTesting::Id); + EXPECT_EQ(header.mPath.mEventId, Clusters::UnitTesting::Events::TestEvent::Id); + EXPECT_EQ(header.mPath.mEndpointId, kTestEndpointId); + EXPECT_GT(header.mEventNumber, kLastSeenEventNumber); + EXPECT_LE(header.mEventNumber, lastEventNumber); Clusters::UnitTesting::Events::TestEvent::DecodableType eventData; - NL_TEST_ASSERT(apSuite, readCallback.mClusterCacheAdapter.Get(header.mEventNumber, eventData) == CHIP_NO_ERROR); + EXPECT_EQ(readCallback.mClusterCacheAdapter.Get(header.mEventNumber, eventData), CHIP_NO_ERROR); - NL_TEST_ASSERT(apSuite, eventData.arg1 == generationCount); + EXPECT_EQ(eventData.arg1, generationCount); generationCount++; return CHIP_NO_ERROR; }); - NL_TEST_ASSERT(apSuite, generationCount == lastEventNumber - oldFirstEventNumber + 1); + EXPECT_EQ(generationCount, lastEventNumber - oldFirstEventNumber + 1); Optional highestEventNumber; readCallback.mClusterCacheAdapter.GetHighestReceivedEventNumber(highestEventNumber); - NL_TEST_ASSERT(apSuite, highestEventNumber.HasValue() && highestEventNumber.Value() == lastEventNumber); + EXPECT_TRUE(highestEventNumber.HasValue() && highestEventNumber.Value() == lastEventNumber); } // @@ -426,65 +441,42 @@ void TestReadEvents::TestBasicCaching(nlTestSuite * apSuite, void * apContext) { readParams.mEventNumber.SetValue(5); - app::ReadClient readClient(engine, &ctx.GetExchangeManager(), readCallback.mClusterCacheAdapter.GetBufferedCallback(), - app::ReadClient::InteractionType::Read); + app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), + readCallback.mClusterCacheAdapter.GetBufferedCallback(), app::ReadClient::InteractionType::Read); readCallback.mClusterCacheAdapter.ClearEventCache(true); - NL_TEST_ASSERT(apSuite, readClient.SendRequest(readParams) == CHIP_NO_ERROR); + EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); // // Validate that we would receive 5 events // uint8_t generationCount = 5; - readCallback.mClusterCacheAdapter.ForEachEventData( - [&apSuite, &readCallback, &generationCount](const app::EventHeader & header) { - NL_TEST_ASSERT(apSuite, header.mPath.mClusterId == Clusters::UnitTesting::Id); - NL_TEST_ASSERT(apSuite, header.mPath.mEventId == Clusters::UnitTesting::Events::TestEvent::Id); - NL_TEST_ASSERT(apSuite, header.mPath.mEndpointId == kTestEndpointId); + readCallback.mClusterCacheAdapter.ForEachEventData([&readCallback, &generationCount](const app::EventHeader & header) { + EXPECT_EQ(header.mPath.mClusterId, Clusters::UnitTesting::Id); + EXPECT_EQ(header.mPath.mEventId, Clusters::UnitTesting::Events::TestEvent::Id); + EXPECT_EQ(header.mPath.mEndpointId, kTestEndpointId); - Clusters::UnitTesting::Events::TestEvent::DecodableType eventData; - NL_TEST_ASSERT(apSuite, readCallback.mClusterCacheAdapter.Get(header.mEventNumber, eventData) == CHIP_NO_ERROR); + Clusters::UnitTesting::Events::TestEvent::DecodableType eventData; + EXPECT_EQ(readCallback.mClusterCacheAdapter.Get(header.mEventNumber, eventData), CHIP_NO_ERROR); - NL_TEST_ASSERT(apSuite, eventData.arg1 == generationCount); - generationCount++; + EXPECT_EQ(eventData.arg1, generationCount); + generationCount++; - return CHIP_NO_ERROR; - }); + return CHIP_NO_ERROR; + }); - NL_TEST_ASSERT(apSuite, generationCount == 10); + EXPECT_EQ(generationCount, 10u); Optional highestEventNumber; readCallback.mClusterCacheAdapter.GetHighestReceivedEventNumber(highestEventNumber); - NL_TEST_ASSERT(apSuite, highestEventNumber.HasValue() && highestEventNumber.Value() == 9); + EXPECT_TRUE(highestEventNumber.HasValue() && highestEventNumber.Value() == 9); } - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(0); } -const nlTest sTests[] = { - NL_TEST_DEF("TestBasicCaching", TestReadEvents::TestBasicCaching), - NL_TEST_SENTINEL(), -}; - -nlTestSuite sSuite = { - "TestEventCaching", - &sTests[0], - TestContext::nlTestSetUpTestSuite, - TestContext::nlTestTearDownTestSuite, - TestContext::nlTestSetUp, - TestContext::nlTestTearDown, -}; - } // namespace - -int TestEventCaching() -{ - gSuite = &sSuite; - return chip::ExecuteTestsWithContext(&sSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestEventCaching) diff --git a/src/controller/tests/TestEventChunking.cpp b/src/controller/tests/TestEventChunking.cpp index fb2b068fcbc0a0..c7790959e6866e 100644 --- a/src/controller/tests/TestEventChunking.cpp +++ b/src/controller/tests/TestEventChunking.cpp @@ -16,6 +16,8 @@ * limitations under the License. */ +#include + #include "app-common/zap-generated/ids/Attributes.h" #include "app-common/zap-generated/ids/Clusters.h" #include "app/ConcreteAttributePath.h" @@ -38,12 +40,8 @@ #include #include #include -#include -#include -#include #include #include -#include using namespace chip; using namespace chip::app; @@ -56,11 +54,49 @@ static uint8_t gInfoEventBuffer[4096]; static uint8_t gCritEventBuffer[4096]; static chip::app::CircularEventBuffer gCircularEventBuffer[3]; -class TestContext : public chip::Test::AppContext +using TestContext = chip::Test::AppContext; + +uint32_t gIterationCount = 0; + +// +// The generated endpoint_config for the controller app has Endpoint 1 +// already used in the fixed endpoint set of size 1. Consequently, let's use the next +// number higher than that for our dynamic test endpoint. +// +constexpr EndpointId kTestEndpointId = 2; +constexpr AttributeId kTestListLargeAttribute = 8; // This attribute will be larger than the event size we used in this test. + +// The size of the attribute which is a bit larger than the size of event used in the test. +constexpr size_t kSizeOfLargeAttribute = 60; + +class TestEventChunking : public ::testing::Test { public: - // Performs setup for each individual test in the test suite - void SetUp() override + // Performs shared setup for all tests in the test suite + static void SetUpTestSuite() + { + if (mpContext == nullptr) + { + mpContext = new TestContext(); + ASSERT_NE(mpContext, nullptr); + } + mpContext->SetUpTestSuite(); + } + + // Performs shared teardown for all tests in the test suite + static void TearDownTestSuite() + { + mpContext->TearDownTestSuite(); + if (mpContext != nullptr) + { + delete mpContext; + mpContext = nullptr; + } + } + +protected: + // Performs setup for each test in the suite + void SetUp() { const chip::app::LogStorageResources logStorageResources[] = { { &gDebugEventBuffer[0], sizeof(gDebugEventBuffer), chip::app::PriorityLevel::Debug }, @@ -68,51 +104,29 @@ class TestContext : public chip::Test::AppContext { &gCritEventBuffer[0], sizeof(gCritEventBuffer), chip::app::PriorityLevel::Critical }, }; - chip::Test::AppContext::SetUp(); + mpContext->SetUp(); CHIP_ERROR err = CHIP_NO_ERROR; // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete VerifyOrDieWithMsg((err = mEventCounter.Init(0)) == CHIP_NO_ERROR, AppServer, "Init EventCounter failed: %" CHIP_ERROR_FORMAT, err.Format()); - chip::app::EventManagement::CreateEventManagement(&GetExchangeManager(), ArraySize(logStorageResources), + chip::app::EventManagement::CreateEventManagement(&mpContext->GetExchangeManager(), ArraySize(logStorageResources), gCircularEventBuffer, logStorageResources, &mEventCounter); } - // Performs teardown for each individual test in the test suite - void TearDown() override + // Performs teardown for each test in the suite + void TearDown() { chip::app::EventManagement::DestroyEventManagement(); - chip::Test::AppContext::TearDown(); + mpContext->TearDown(); } -private: - MonotonicallyIncreasingCounter mEventCounter; -}; - -uint32_t gIterationCount = 0; -nlTestSuite * gSuite = nullptr; - -// -// The generated endpoint_config for the controller app has Endpoint 1 -// already used in the fixed endpoint set of size 1. Consequently, let's use the next -// number higher than that for our dynamic test endpoint. -// -constexpr EndpointId kTestEndpointId = 2; -constexpr AttributeId kTestListLargeAttribute = 8; // This attribute will be larger than the event size we used in this test. - -// The size of the attribute which is a bit larger than the size of event used in the test. -constexpr size_t kSizeOfLargeAttribute = 60; - -class TestReadEvents -{ -public: - TestReadEvents() {} - static void TestEventChunking(nlTestSuite * apSuite, void * apContext); - static void TestMixedEventsAndAttributesChunking(nlTestSuite * apSuite, void * apContext); - static void TestMixedEventsAndLargeAttributesChunking(nlTestSuite * apSuite, void * apContext); + static TestContext * mpContext; private: + MonotonicallyIncreasingCounter mEventCounter; }; +TestContext * TestEventChunking::mpContext = nullptr; //clang-format off DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(testClusterAttrs) @@ -167,30 +181,30 @@ void TestReadCallback::OnAttributeData(const app::ConcreteDataAttributePath & aP if (aPath.mAttributeId == Globals::Attributes::GeneratedCommandList::Id) { app::DataModel::DecodableList v; - NL_TEST_ASSERT(gSuite, app::DataModel::Decode(*apData, v) == CHIP_NO_ERROR); + EXPECT_EQ(app::DataModel::Decode(*apData, v), CHIP_NO_ERROR); auto it = v.begin(); size_t arraySize = 0; while (it.Next()) { - NL_TEST_ASSERT(gSuite, false); + FAIL(); } - NL_TEST_ASSERT(gSuite, it.GetStatus() == CHIP_NO_ERROR); - NL_TEST_ASSERT(gSuite, v.ComputeSize(&arraySize) == CHIP_NO_ERROR); - NL_TEST_ASSERT(gSuite, arraySize == 0); + EXPECT_EQ(it.GetStatus(), CHIP_NO_ERROR); + EXPECT_EQ(v.ComputeSize(&arraySize), CHIP_NO_ERROR); + EXPECT_EQ(arraySize, 0u); } else if (aPath.mAttributeId == Globals::Attributes::AcceptedCommandList::Id) { app::DataModel::DecodableList v; - NL_TEST_ASSERT(gSuite, app::DataModel::Decode(*apData, v) == CHIP_NO_ERROR); + EXPECT_EQ(app::DataModel::Decode(*apData, v), CHIP_NO_ERROR); auto it = v.begin(); size_t arraySize = 0; while (it.Next()) { - NL_TEST_ASSERT(gSuite, false); + FAIL(); } - NL_TEST_ASSERT(gSuite, it.GetStatus() == CHIP_NO_ERROR); - NL_TEST_ASSERT(gSuite, v.ComputeSize(&arraySize) == CHIP_NO_ERROR); - NL_TEST_ASSERT(gSuite, arraySize == 0); + EXPECT_EQ(it.GetStatus(), CHIP_NO_ERROR); + EXPECT_EQ(v.ComputeSize(&arraySize), CHIP_NO_ERROR); + EXPECT_EQ(arraySize, 0u); } #if CHIP_CONFIG_ENABLE_EVENTLIST_ATTRIBUTE else if (aPath.mAttributeId == Globals::Attributes::EventList::Id) @@ -205,17 +219,17 @@ void TestReadCallback::OnAttributeData(const app::ConcreteDataAttributePath & aP else if (aPath.mAttributeId == kTestListLargeAttribute) { app::DataModel::DecodableList v; - NL_TEST_ASSERT(gSuite, app::DataModel::Decode(*apData, v) == CHIP_NO_ERROR); + EXPECT_EQ(app::DataModel::Decode(*apData, v), CHIP_NO_ERROR); auto it = v.begin(); size_t arraySize = 0; - NL_TEST_ASSERT(gSuite, v.ComputeSize(&arraySize) == CHIP_NO_ERROR); - NL_TEST_ASSERT(gSuite, arraySize == 4); + EXPECT_EQ(v.ComputeSize(&arraySize), CHIP_NO_ERROR); + EXPECT_EQ(arraySize, 4u); } else { uint8_t v; - NL_TEST_ASSERT(gSuite, app::DataModel::Decode(*apData, v) == CHIP_NO_ERROR); - NL_TEST_ASSERT(gSuite, v == (uint8_t) gIterationCount); + EXPECT_EQ(app::DataModel::Decode(*apData, v), CHIP_NO_ERROR); + EXPECT_EQ(v, (uint8_t) gIterationCount); } mAttributeCount++; } @@ -267,9 +281,7 @@ CHIP_ERROR TestAttrAccess::Write(const app::ConcreteDataAttributePath & aPath, a return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; } -namespace { - -void GenerateEvents(nlTestSuite * apSuite, chip::EventNumber & firstEventNumber, chip::EventNumber & lastEventNumber) +void GenerateEvents(chip::EventNumber & firstEventNumber, chip::EventNumber & lastEventNumber) { CHIP_ERROR err = CHIP_NO_ERROR; @@ -278,7 +290,7 @@ void GenerateEvents(nlTestSuite * apSuite, chip::EventNumber & firstEventNumber, for (int i = 0; i < 5; i++) { - NL_TEST_ASSERT(apSuite, (err = app::LogEvent(content, kTestEndpointId, lastEventNumber)) == CHIP_NO_ERROR); + EXPECT_EQ((err = app::LogEvent(content, kTestEndpointId, lastEventNumber)), CHIP_NO_ERROR); if (i == 0) { firstEventNumber = lastEventNumber; @@ -286,8 +298,6 @@ void GenerateEvents(nlTestSuite * apSuite, chip::EventNumber & firstEventNumber, } } -} // namespace - /* * This validates all the various corner cases encountered during chunking by * artificially reducing the size of a packet buffer used to encode attribute & event data @@ -305,10 +315,9 @@ void GenerateEvents(nlTestSuite * apSuite, chip::EventNumber & firstEventNumber, * as we can possibly cover. * */ -void TestReadEvents::TestEventChunking(nlTestSuite * apSuite, void * apContext) +TEST_F(TestEventChunking, TestEventChunking) { - TestContext & ctx = *static_cast(apContext); - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = mpContext->GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -321,7 +330,7 @@ void TestReadEvents::TestEventChunking(nlTestSuite * apSuite, void * apContext) chip::EventNumber firstEventNumber; chip::EventNumber lastEventNumber; - GenerateEvents(apSuite, firstEventNumber, lastEventNumber); + GenerateEvents(firstEventNumber, lastEventNumber); app::EventPathParams eventPath; eventPath.mEndpointId = kTestEndpointId; @@ -349,20 +358,20 @@ void TestReadEvents::TestEventChunking(nlTestSuite * apSuite, void * apContext) app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetWriterReserved(static_cast(800 + i)); - app::ReadClient readClient(engine, &ctx.GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Read); - NL_TEST_ASSERT(apSuite, readClient.SendRequest(readParams) == CHIP_NO_ERROR); + EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); - NL_TEST_ASSERT(apSuite, readCallback.mEventCount == static_cast((lastEventNumber - firstEventNumber) + 1)); - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(readCallback.mEventCount, static_cast((lastEventNumber - firstEventNumber) + 1)); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); // // Stop the test if we detected an error. Otherwise, it'll be difficult to read the logs. // - if (apSuite->flagError) + if (HasFailure()) { break; } @@ -372,10 +381,9 @@ void TestReadEvents::TestEventChunking(nlTestSuite * apSuite, void * apContext) } // Similar to the tests above, but it will read attributes AND events -void TestReadEvents::TestMixedEventsAndAttributesChunking(nlTestSuite * apSuite, void * apContext) +TEST_F(TestEventChunking, TestMixedEventsAndAttributesChunking) { - TestContext & ctx = *static_cast(apContext); - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = mpContext->GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -389,7 +397,7 @@ void TestReadEvents::TestMixedEventsAndAttributesChunking(nlTestSuite * apSuite, chip::EventNumber lastEventNumber; // We will always read from the first event, so it is enough to only generate events once. - GenerateEvents(apSuite, firstEventNumber, lastEventNumber); + GenerateEvents(firstEventNumber, lastEventNumber); app::EventPathParams eventPath; app::AttributePathParams attributePath(kTestEndpointId, app::Clusters::UnitTesting::Id); @@ -418,26 +426,26 @@ void TestReadEvents::TestMixedEventsAndAttributesChunking(nlTestSuite * apSuite, app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetWriterReserved(static_cast(800 + i)); - app::ReadClient readClient(engine, &ctx.GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Read); - NL_TEST_ASSERT(apSuite, readClient.SendRequest(readParams) == CHIP_NO_ERROR); + EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); // // Always returns the same number of attributes read (5 + revision + GlobalAttributesNotInMetadata). // - NL_TEST_ASSERT(apSuite, readCallback.mOnReportEnd); - NL_TEST_ASSERT(apSuite, readCallback.mAttributeCount == 6 + ArraySize(GlobalAttributesNotInMetadata)); - NL_TEST_ASSERT(apSuite, readCallback.mEventCount == static_cast(lastEventNumber - firstEventNumber + 1)); + EXPECT_TRUE(readCallback.mOnReportEnd); + EXPECT_EQ(readCallback.mAttributeCount, 6 + ArraySize(GlobalAttributesNotInMetadata)); + EXPECT_EQ(readCallback.mEventCount, static_cast(lastEventNumber - firstEventNumber + 1)); - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); // // Stop the test if we detected an error. Otherwise, it'll be difficult to read the logs. // - if (apSuite->flagError) + if (HasFailure()) { break; } @@ -449,10 +457,9 @@ void TestReadEvents::TestMixedEventsAndAttributesChunking(nlTestSuite * apSuite, // Similar to the tests above, however, there is one another case -- the event payload is very large usually, so when it is failed // to encode an attribute, it is usually impossible to encode a event data, so we cannot verify the case when events and attributes // can be encoded in to one chunk in the tests above. This test will force it by reading only one attribtue and read many events. -void TestReadEvents::TestMixedEventsAndLargeAttributesChunking(nlTestSuite * apSuite, void * apContext) +TEST_F(TestEventChunking, TestMixedEventsAndLargeAttributesChunking) { - TestContext & ctx = *static_cast(apContext); - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = mpContext->GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -466,7 +473,7 @@ void TestReadEvents::TestMixedEventsAndLargeAttributesChunking(nlTestSuite * apS chip::EventNumber lastEventNumber; // We will always read from the first event, so it is enough to only generate events once. - GenerateEvents(apSuite, firstEventNumber, lastEventNumber); + GenerateEvents(firstEventNumber, lastEventNumber); app::EventPathParams eventPath; app::AttributePathParams attributePath(kTestEndpointId, app::Clusters::UnitTesting::Id, kTestListLargeAttribute); @@ -495,23 +502,23 @@ void TestReadEvents::TestMixedEventsAndLargeAttributesChunking(nlTestSuite * apS app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetWriterReserved(static_cast(800 + i)); - app::ReadClient readClient(engine, &ctx.GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Read); - NL_TEST_ASSERT(apSuite, readClient.SendRequest(readParams) == CHIP_NO_ERROR); + EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); - NL_TEST_ASSERT(apSuite, readCallback.mOnReportEnd); - NL_TEST_ASSERT(apSuite, readCallback.mAttributeCount == 1); - NL_TEST_ASSERT(apSuite, readCallback.mEventCount == static_cast(lastEventNumber - firstEventNumber + 1)); + EXPECT_TRUE(readCallback.mOnReportEnd); + EXPECT_EQ(readCallback.mAttributeCount, 1u); + EXPECT_EQ(readCallback.mEventCount, static_cast(lastEventNumber - firstEventNumber + 1)); - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); // // Stop the test if we detected an error. Otherwise, it'll be difficult to read the logs. // - if (apSuite->flagError) + if (HasFailure()) { break; } @@ -520,28 +527,4 @@ void TestReadEvents::TestMixedEventsAndLargeAttributesChunking(nlTestSuite * apS emberAfClearDynamicEndpoint(0); } -const nlTest sTests[] = { - NL_TEST_DEF("TestEventChunking", TestReadEvents::TestEventChunking), - NL_TEST_DEF("TestMixedEventsAndAttributesChunking", TestReadEvents::TestMixedEventsAndAttributesChunking), - NL_TEST_DEF("TestMixedEventsAndLargeAttributesChunking", TestReadEvents::TestMixedEventsAndLargeAttributesChunking), - NL_TEST_SENTINEL(), -}; - -nlTestSuite sSuite = { - "TestEventChunking", - &sTests[0], - TestContext::nlTestSetUpTestSuite, - TestContext::nlTestTearDownTestSuite, - TestContext::nlTestSetUp, - TestContext::nlTestTearDown, -}; - } // namespace - -int TestEventChunkingTests() -{ - gSuite = &sSuite; - return chip::ExecuteTestsWithContext(&sSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestEventChunkingTests) diff --git a/src/controller/tests/TestEventNumberCaching.cpp b/src/controller/tests/TestEventNumberCaching.cpp index 1244a77481209e..4d77813262a691 100644 --- a/src/controller/tests/TestEventNumberCaching.cpp +++ b/src/controller/tests/TestEventNumberCaching.cpp @@ -16,6 +16,8 @@ * limitations under the License. */ +#include + #include "app-common/zap-generated/ids/Clusters.h" #include "app/ClusterStateCache.h" #include @@ -30,12 +32,8 @@ #include #include #include -#include -#include -#include #include #include -#include using namespace chip; using namespace chip::app; @@ -48,11 +46,43 @@ static uint8_t gInfoEventBuffer[4096]; static uint8_t gCritEventBuffer[4096]; static chip::app::CircularEventBuffer gCircularEventBuffer[3]; -class TestContext : public chip::Test::AppContext +using TestContext = chip::Test::AppContext; + +// +// The generated endpoint_config for the controller app has Endpoint 1 +// already used in the fixed endpoint set of size 1. Consequently, let's use the next +// number higher than that for our dynamic test endpoint. +// +constexpr EndpointId kTestEndpointId = 2; + +class TestEventNumberCaching : public ::testing::Test { public: - // Performs setup for each individual test in the test suite - void SetUp() override + // Performs shared setup for all tests in the test suite + static void SetUpTestSuite() + { + if (mpContext == nullptr) + { + mpContext = new TestContext(); + ASSERT_NE(mpContext, nullptr); + } + mpContext->SetUpTestSuite(); + } + + // Performs shared teardown for all tests in the test suite + static void TearDownTestSuite() + { + mpContext->TearDownTestSuite(); + if (mpContext != nullptr) + { + delete mpContext; + mpContext = nullptr; + } + } + +protected: + // Performs setup for each test in the suite + void SetUp() { const chip::app::LogStorageResources logStorageResources[] = { { &gDebugEventBuffer[0], sizeof(gDebugEventBuffer), chip::app::PriorityLevel::Debug }, @@ -60,44 +90,29 @@ class TestContext : public chip::Test::AppContext { &gCritEventBuffer[0], sizeof(gCritEventBuffer), chip::app::PriorityLevel::Critical }, }; - chip::Test::AppContext::SetUp(); + mpContext->SetUp(); CHIP_ERROR err = CHIP_NO_ERROR; // TODO: use ASSERT_EQ, once transition to pw_unit_test is complete VerifyOrDieWithMsg((err = mEventCounter.Init(0)) == CHIP_NO_ERROR, AppServer, "Init EventCounter failed: %" CHIP_ERROR_FORMAT, err.Format()); - chip::app::EventManagement::CreateEventManagement(&GetExchangeManager(), ArraySize(logStorageResources), + chip::app::EventManagement::CreateEventManagement(&mpContext->GetExchangeManager(), ArraySize(logStorageResources), gCircularEventBuffer, logStorageResources, &mEventCounter); } - // Performs teardown for each individual test in the test suite - void TearDown() override + // Performs teardown for each test in the suite + void TearDown() { chip::app::EventManagement::DestroyEventManagement(); - chip::Test::AppContext::TearDown(); + mpContext->TearDown(); } -private: - MonotonicallyIncreasingCounter mEventCounter; -}; - -nlTestSuite * gSuite = nullptr; - -// -// The generated endpoint_config for the controller app has Endpoint 1 -// already used in the fixed endpoint set of size 1. Consequently, let's use the next -// number higher than that for our dynamic test endpoint. -// -constexpr EndpointId kTestEndpointId = 2; - -class TestReadEvents -{ -public: - TestReadEvents() {} - static void TestEventNumberCaching(nlTestSuite * apSuite, void * apContext); + static TestContext * mpContext; private: + MonotonicallyIncreasingCounter mEventCounter; }; +TestContext * TestEventNumberCaching::mpContext = nullptr; //clang-format off DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(testClusterAttrs) @@ -127,9 +142,7 @@ class TestReadCallback : public app::ClusterStateCache::Callback size_t mEventsSeen = 0; }; -namespace { - -void GenerateEvents(nlTestSuite * apSuite, chip::EventNumber & firstEventNumber, chip::EventNumber & lastEventNumber) +void GenerateEvents(chip::EventNumber & firstEventNumber, chip::EventNumber & lastEventNumber) { CHIP_ERROR err = CHIP_NO_ERROR; static uint8_t generationCount = 0; @@ -139,7 +152,7 @@ void GenerateEvents(nlTestSuite * apSuite, chip::EventNumber & firstEventNumber, for (int i = 0; i < 5; i++) { content.arg1 = static_cast(generationCount++); - NL_TEST_ASSERT(apSuite, (err = app::LogEvent(content, kTestEndpointId, lastEventNumber)) == CHIP_NO_ERROR); + EXPECT_EQ((err = app::LogEvent(content, kTestEndpointId, lastEventNumber)), CHIP_NO_ERROR); if (i == 0) { firstEventNumber = lastEventNumber; @@ -147,18 +160,15 @@ void GenerateEvents(nlTestSuite * apSuite, chip::EventNumber & firstEventNumber, } } -} // namespace - /* * This validates event caching by forcing a bunch of events to get generated, then reading them back * and upon completion of that operation, check the received version from cache, and note that cache would store * correpsonding attribute data since data cache is disabled. * */ -void TestReadEvents::TestEventNumberCaching(nlTestSuite * apSuite, void * apContext) +TEST_F(TestEventNumberCaching, TestEventNumberCaching) { - TestContext & ctx = *static_cast(apContext); - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = mpContext->GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -171,8 +181,8 @@ void TestReadEvents::TestEventNumberCaching(nlTestSuite * apSuite, void * apCont chip::EventNumber firstEventNumber; chip::EventNumber lastEventNumber; - GenerateEvents(apSuite, firstEventNumber, lastEventNumber); - NL_TEST_ASSERT(apSuite, lastEventNumber > firstEventNumber); + GenerateEvents(firstEventNumber, lastEventNumber); + EXPECT_GT(lastEventNumber, firstEventNumber); app::EventPathParams eventPath; eventPath.mEndpointId = kTestEndpointId; @@ -188,25 +198,24 @@ void TestReadEvents::TestEventNumberCaching(nlTestSuite * apSuite, void * apCont { Optional highestEventNumber; readCallback.mClusterCacheAdapter.GetHighestReceivedEventNumber(highestEventNumber); - NL_TEST_ASSERT(apSuite, !highestEventNumber.HasValue()); - app::ReadClient readClient(engine, &ctx.GetExchangeManager(), readCallback.mClusterCacheAdapter.GetBufferedCallback(), - app::ReadClient::InteractionType::Read); + EXPECT_FALSE(highestEventNumber.HasValue()); + app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), + readCallback.mClusterCacheAdapter.GetBufferedCallback(), app::ReadClient::InteractionType::Read); - NL_TEST_ASSERT(apSuite, readClient.SendRequest(readParams) == CHIP_NO_ERROR); + EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); - NL_TEST_ASSERT(apSuite, readCallback.mEventsSeen == lastEventNumber - firstEventNumber + 1); + EXPECT_EQ(readCallback.mEventsSeen, lastEventNumber - firstEventNumber + 1); - readCallback.mClusterCacheAdapter.ForEachEventData([&apSuite](const app::EventHeader & header) { + readCallback.mClusterCacheAdapter.ForEachEventData([](const app::EventHeader & header) { // We are not caching data. - NL_TEST_ASSERT(apSuite, false); - + ADD_FAILURE(); // Can't use FAIL() because lambda has non-void return type. return CHIP_NO_ERROR; }); readCallback.mClusterCacheAdapter.GetHighestReceivedEventNumber(highestEventNumber); - NL_TEST_ASSERT(apSuite, highestEventNumber.HasValue() && highestEventNumber.Value() == lastEventNumber); + EXPECT_TRUE(highestEventNumber.HasValue() && highestEventNumber.Value() == lastEventNumber); } // @@ -214,68 +223,42 @@ void TestReadEvents::TestEventNumberCaching(nlTestSuite * apSuite, void * apCont // we don't receive events except ones larger than that value. // { - app::ReadClient readClient(engine, &ctx.GetExchangeManager(), readCallback.mClusterCacheAdapter.GetBufferedCallback(), - app::ReadClient::InteractionType::Read); + app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), + readCallback.mClusterCacheAdapter.GetBufferedCallback(), app::ReadClient::InteractionType::Read); readCallback.mClusterCacheAdapter.ClearEventCache(true); Optional highestEventNumber; readCallback.mClusterCacheAdapter.GetHighestReceivedEventNumber(highestEventNumber); - NL_TEST_ASSERT(apSuite, !highestEventNumber.HasValue()); + EXPECT_FALSE(highestEventNumber.HasValue()); const EventNumber kHighestEventNumberSeen = lastEventNumber - 1; - NL_TEST_ASSERT(apSuite, kHighestEventNumberSeen < lastEventNumber); + EXPECT_LT(kHighestEventNumberSeen, lastEventNumber); readCallback.mClusterCacheAdapter.SetHighestReceivedEventNumber(kHighestEventNumberSeen); readCallback.mEventsSeen = 0; readParams.mEventNumber.ClearValue(); - NL_TEST_ASSERT(apSuite, !readParams.mEventNumber.HasValue()); - NL_TEST_ASSERT(apSuite, readClient.SendRequest(readParams) == CHIP_NO_ERROR); + EXPECT_FALSE(readParams.mEventNumber.HasValue()); + EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); // We should only get events with event numbers larger than kHighestEventNumberSeen. - NL_TEST_ASSERT(apSuite, readCallback.mEventsSeen == lastEventNumber - kHighestEventNumberSeen); + EXPECT_EQ(readCallback.mEventsSeen, lastEventNumber - kHighestEventNumberSeen); - readCallback.mClusterCacheAdapter.ForEachEventData([&apSuite](const app::EventHeader & header) { + readCallback.mClusterCacheAdapter.ForEachEventData([](const app::EventHeader & header) { // We are not caching data. - NL_TEST_ASSERT(apSuite, false); - + ADD_FAILURE(); // Can't use FAIL() because lambda has non-void return type. return CHIP_NO_ERROR; }); readCallback.mClusterCacheAdapter.GetHighestReceivedEventNumber(highestEventNumber); - NL_TEST_ASSERT(apSuite, highestEventNumber.HasValue() && highestEventNumber.Value() == lastEventNumber); + EXPECT_TRUE(highestEventNumber.HasValue() && highestEventNumber.Value() == lastEventNumber); } - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(0); } -const nlTest sTests[] = { - NL_TEST_DEF("TestEventNumberCaching", TestReadEvents::TestEventNumberCaching), - NL_TEST_SENTINEL(), -}; - -// clang-format off -nlTestSuite sSuite = -{ - "TestEventNumberCaching", - &sTests[0], - TestContext::nlTestSetUpTestSuite, - TestContext::nlTestTearDownTestSuite, - TestContext::nlTestSetUp, - TestContext::nlTestTearDown, -}; -// clang-format on - } // namespace - -int TestEventNumberCaching() -{ - gSuite = &sSuite; - return chip::ExecuteTestsWithContext(&sSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestEventNumberCaching) diff --git a/src/controller/tests/TestReadChunking.cpp b/src/controller/tests/TestReadChunking.cpp index 1095e0f26ebf61..8fe5e51c2b097f 100644 --- a/src/controller/tests/TestReadChunking.cpp +++ b/src/controller/tests/TestReadChunking.cpp @@ -16,6 +16,12 @@ * limitations under the License. */ +#include +#include +#include + +#include + #include "app-common/zap-generated/ids/Attributes.h" #include "app-common/zap-generated/ids/Clusters.h" #include "app/ConcreteAttributePath.h" @@ -34,17 +40,11 @@ #include #include #include -#include #include #include -#include -#include #include #include -#include #include -#include -#include using TestContext = chip::Test::AppContext; using namespace chip; @@ -54,8 +54,6 @@ using namespace chip::app::Clusters; namespace { uint32_t gIterationCount = 0; -nlTestSuite * gSuite = nullptr; -TestContext * gCtx = nullptr; // // The generated endpoint_config for the controller app has Endpoint 1 @@ -74,18 +72,41 @@ constexpr AttributeId kTestBadAttribute = constexpr int kListAttributeItems = 5; -class TestReadChunking +class TestReadChunking : public ::testing::Test { public: - TestReadChunking() {} - static void TestChunking(nlTestSuite * apSuite, void * apContext); - static void TestListChunking(nlTestSuite * apSuite, void * apContext); - static void TestBadChunking(nlTestSuite * apSuite, void * apContext); - static void TestDynamicEndpoint(nlTestSuite * apSuite, void * apContext); - static void TestSetDirtyBetweenChunks(nlTestSuite * apSuite, void * apContext); - -private: + // Performs shared setup for all tests in the test suite + static void SetUpTestSuite() + { + if (mpContext == nullptr) + { + mpContext = new TestContext(); + ASSERT_NE(mpContext, nullptr); + } + mpContext->SetUpTestSuite(); + } + + // Performs shared teardown for all tests in the test suite + static void TearDownTestSuite() + { + mpContext->TearDownTestSuite(); + if (mpContext != nullptr) + { + delete mpContext; + mpContext = nullptr; + } + } + +protected: + // Performs setup for each test in the suite + void SetUp() { mpContext->SetUp(); } + + // Performs teardown for each test in the suite + void TearDown() { mpContext->TearDown(); } + + static TestContext * mpContext; }; +TestContext * TestReadChunking::mpContext = nullptr; //clang-format off DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(testClusterAttrs) @@ -271,30 +292,30 @@ void TestReadCallback::OnAttributeData(const app::ConcreteDataAttributePath & aP if (aPath.mAttributeId == Globals::Attributes::GeneratedCommandList::Id) { app::DataModel::DecodableList v; - NL_TEST_ASSERT(gSuite, app::DataModel::Decode(*apData, v) == CHIP_NO_ERROR); + EXPECT_EQ(app::DataModel::Decode(*apData, v), CHIP_NO_ERROR); auto it = v.begin(); size_t arraySize = 0; while (it.Next()) { - NL_TEST_ASSERT(gSuite, false); + FAIL(); } - NL_TEST_ASSERT(gSuite, it.GetStatus() == CHIP_NO_ERROR); - NL_TEST_ASSERT(gSuite, v.ComputeSize(&arraySize) == CHIP_NO_ERROR); - NL_TEST_ASSERT(gSuite, arraySize == 0); + EXPECT_EQ(it.GetStatus(), CHIP_NO_ERROR); + EXPECT_EQ(v.ComputeSize(&arraySize), CHIP_NO_ERROR); + EXPECT_EQ(arraySize, 0u); } else if (aPath.mAttributeId == Globals::Attributes::AcceptedCommandList::Id) { app::DataModel::DecodableList v; - NL_TEST_ASSERT(gSuite, app::DataModel::Decode(*apData, v) == CHIP_NO_ERROR); + EXPECT_EQ(app::DataModel::Decode(*apData, v), CHIP_NO_ERROR); auto it = v.begin(); size_t arraySize = 0; while (it.Next()) { - NL_TEST_ASSERT(gSuite, false); + FAIL(); } - NL_TEST_ASSERT(gSuite, it.GetStatus() == CHIP_NO_ERROR); - NL_TEST_ASSERT(gSuite, v.ComputeSize(&arraySize) == CHIP_NO_ERROR); - NL_TEST_ASSERT(gSuite, arraySize == 0); + EXPECT_EQ(it.GetStatus(), CHIP_NO_ERROR); + EXPECT_EQ(v.ComputeSize(&arraySize), CHIP_NO_ERROR); + EXPECT_EQ(arraySize, 0u); } #if CHIP_CONFIG_ENABLE_EVENTLIST_ATTRIBUTE else if (aPath.mAttributeId == Globals::Attributes::EventList::Id) @@ -309,22 +330,22 @@ void TestReadCallback::OnAttributeData(const app::ConcreteDataAttributePath & aP else if (aPath.mAttributeId != kTestListAttribute) { uint8_t v; - NL_TEST_ASSERT(gSuite, app::DataModel::Decode(*apData, v) == CHIP_NO_ERROR); - NL_TEST_ASSERT(gSuite, v == (uint8_t) gIterationCount); + EXPECT_EQ(app::DataModel::Decode(*apData, v), CHIP_NO_ERROR); + EXPECT_EQ(v, (uint8_t) gIterationCount); } else { app::DataModel::DecodableList v; - NL_TEST_ASSERT(gSuite, app::DataModel::Decode(*apData, v) == CHIP_NO_ERROR); + EXPECT_EQ(app::DataModel::Decode(*apData, v), CHIP_NO_ERROR); auto it = v.begin(); size_t arraySize = 0; while (it.Next()) { - NL_TEST_ASSERT(gSuite, it.GetValue() == static_cast(gIterationCount)); + EXPECT_EQ(it.GetValue(), static_cast(gIterationCount)); } - NL_TEST_ASSERT(gSuite, it.GetStatus() == CHIP_NO_ERROR); - NL_TEST_ASSERT(gSuite, v.ComputeSize(&arraySize) == CHIP_NO_ERROR); - NL_TEST_ASSERT(gSuite, arraySize == 5); + EXPECT_EQ(it.GetStatus(), CHIP_NO_ERROR); + EXPECT_EQ(v.ComputeSize(&arraySize), CHIP_NO_ERROR); + EXPECT_EQ(arraySize, 5u); } mAttributeCount++; } @@ -448,13 +469,13 @@ void TestMutableReadCallback::OnAttributeData(const app::ConcreteDataAttributePa const app::StatusIB & aStatus) { VerifyOrReturn(apData != nullptr); - NL_TEST_ASSERT(gSuite, aPath.mClusterId == Clusters::UnitTesting::Id); + EXPECT_EQ(aPath.mClusterId, Clusters::UnitTesting::Id); mAttributeCount++; if (aPath.mAttributeId <= 5) { uint8_t v; - NL_TEST_ASSERT(gSuite, app::DataModel::Decode(*apData, v) == CHIP_NO_ERROR); + EXPECT_EQ(app::DataModel::Decode(*apData, v), CHIP_NO_ERROR); mValues[std::make_pair(aPath.mEndpointId, aPath.mAttributeId)] = v; auto action = mActionOn.find(std::make_pair(aPath.mEndpointId, aPath.mAttributeId)); @@ -488,10 +509,9 @@ void TestMutableReadCallback::OnAttributeData(const app::ConcreteDataAttributePa * as we can possibly cover. * */ -void TestReadChunking::TestChunking(nlTestSuite * apSuite, void * apContext) +TEST_F(TestReadChunking, TestChunking) { - TestContext & ctx = *static_cast(apContext); - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = mpContext->GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -522,26 +542,26 @@ void TestReadChunking::TestChunking(nlTestSuite * apSuite, void * apContext) app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetWriterReserved(static_cast(850 + i)); - app::ReadClient readClient(engine, &ctx.GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Read); - NL_TEST_ASSERT(apSuite, readClient.SendRequest(readParams) == CHIP_NO_ERROR); + EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); - NL_TEST_ASSERT(apSuite, readCallback.mOnReportEnd); + mpContext->DrainAndServiceIO(); + EXPECT_TRUE(readCallback.mOnReportEnd); // // Always returns the same number of attributes read (5 + revision + GlobalAttributesNotInMetadata). // - NL_TEST_ASSERT(apSuite, readCallback.mAttributeCount == 6 + ArraySize(GlobalAttributesNotInMetadata)); + EXPECT_EQ(readCallback.mAttributeCount, 6 + ArraySize(GlobalAttributesNotInMetadata)); readCallback.mAttributeCount = 0; - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); // // Stop the test if we detected an error. Otherwise, it'll be difficult to read the logs. // - if (apSuite->flagError) + if (HasFailure()) { break; } @@ -551,10 +571,9 @@ void TestReadChunking::TestChunking(nlTestSuite * apSuite, void * apContext) } // Similar to the test above, but for the list chunking feature. -void TestReadChunking::TestListChunking(nlTestSuite * apSuite, void * apContext) +TEST_F(TestReadChunking, TestListChunking) { - TestContext & ctx = *static_cast(apContext); - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = mpContext->GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -598,12 +617,12 @@ void TestReadChunking::TestListChunking(nlTestSuite * apSuite, void * apContext) app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetWriterReserved( static_cast(maxPacketSize - packetSize)); - app::ReadClient readClient(engine, &ctx.GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Read); - NL_TEST_ASSERT(apSuite, readClient.SendRequest(readParams) == CHIP_NO_ERROR); + EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); // Up until our packets are big enough, we might just keep getting // errors due to the inability to encode even a single IB in a packet. @@ -612,14 +631,13 @@ void TestReadChunking::TestListChunking(nlTestSuite * apSuite, void * apContext) { gotFailureResponse = true; // Check for the right error type. - NL_TEST_ASSERT(apSuite, - StatusIB(readCallback.mReadError).mStatus == Protocols::InteractionModel::Status::ResourceExhausted); + EXPECT_EQ(StatusIB(readCallback.mReadError).mStatus, Protocols::InteractionModel::Status::ResourceExhausted); } else { gotSuccessfulEncode = true; - NL_TEST_ASSERT(apSuite, readCallback.mOnReportEnd); + EXPECT_TRUE(readCallback.mOnReportEnd); // // Always returns the same number of attributes read (merged by buffered read callback). The content is checked in @@ -628,36 +646,35 @@ void TestReadChunking::TestListChunking(nlTestSuite * apSuite, void * apContext) // just a replace of the first read's path and buffers it all up as a // single value. // - NL_TEST_ASSERT(apSuite, readCallback.mAttributeCount == 1); + EXPECT_EQ(readCallback.mAttributeCount, 1u); readCallback.mAttributeCount = 0; // Check that we never saw an empty-list data IB. - NL_TEST_ASSERT(apSuite, !readCallback.mBufferedCallback.mDecodingFailed); - NL_TEST_ASSERT(apSuite, !readCallback.mBufferedCallback.mSawEmptyList); + EXPECT_FALSE(readCallback.mBufferedCallback.mDecodingFailed); + EXPECT_FALSE(readCallback.mBufferedCallback.mSawEmptyList); } - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); // // Stop the test if we detected an error. Otherwise, it'll be difficult to read the logs. // - if (apSuite->flagError) + if (HasFailure()) { break; } } // If this fails, our smallest packet size was not small enough. - NL_TEST_ASSERT(apSuite, gotFailureResponse); + EXPECT_TRUE(gotFailureResponse); emberAfClearDynamicEndpoint(0); } // Read an attribute that can never fit into the buffer. Result in an empty report, server should shutdown the transaction. -void TestReadChunking::TestBadChunking(nlTestSuite * apSuite, void * apContext) +TEST_F(TestReadChunking, TestBadChunking) { - TestContext & ctx = *static_cast(apContext); - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = mpContext->GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -678,27 +695,27 @@ void TestReadChunking::TestBadChunking(nlTestSuite * apSuite, void * apContext) TestReadCallback readCallback; { - app::ReadClient readClient(engine, &ctx.GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Read); - NL_TEST_ASSERT(apSuite, readClient.SendRequest(readParams) == CHIP_NO_ERROR); + EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); // The server should return an empty list as attribute data for the first report (for list chunking), and encodes nothing // (then shuts down the read handler) for the second report. // // Nothing is actually encoded. buffered callback does not handle the message to us. - NL_TEST_ASSERT(apSuite, readCallback.mAttributeCount == 0); - NL_TEST_ASSERT(apSuite, !readCallback.mOnReportEnd); + EXPECT_EQ(readCallback.mAttributeCount, 0u); + EXPECT_FALSE(readCallback.mOnReportEnd); // The server should shutted down, while the client is still alive (pending for the attribute data.) - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); } // Sanity check - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(0); } @@ -706,10 +723,9 @@ void TestReadChunking::TestBadChunking(nlTestSuite * apSuite, void * apContext) /* * This test contains two parts, one is to enable a new endpoint on the fly, another is to disable it and re-enable it. */ -void TestReadChunking::TestDynamicEndpoint(nlTestSuite * apSuite, void * apContext) +TEST_F(TestReadChunking, TestDynamicEndpoint) { - TestContext & ctx = *static_cast(apContext); - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = mpContext->GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); // Initialize the ember side server logic @@ -729,30 +745,28 @@ void TestReadChunking::TestDynamicEndpoint(nlTestSuite * apSuite, void * apConte { - app::ReadClient readClient(engine, &ctx.GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Subscribe); // Enable the new endpoint emberAfSetDynamicEndpoint(0, kTestEndpointId, &testEndpoint, Span(dataVersionStorage)); - NL_TEST_ASSERT(apSuite, readClient.SendRequest(readParams) == CHIP_NO_ERROR); + EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); - NL_TEST_ASSERT(apSuite, readCallback.mOnSubscriptionEstablished); + EXPECT_TRUE(readCallback.mOnSubscriptionEstablished); readCallback.mAttributeCount = 0; emberAfSetDynamicEndpoint(0, kTestEndpointId4, &testEndpoint4, Span(dataVersionStorage)); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); // Ensure we have received the report, we do not care about the initial report here. // GlobalAttributesNotInMetadata attributes are not included in testClusterAttrsOnEndpoint4. - NL_TEST_ASSERT(apSuite, - readCallback.mAttributeCount == - ArraySize(testClusterAttrsOnEndpoint4) + ArraySize(GlobalAttributesNotInMetadata)); + EXPECT_EQ(readCallback.mAttributeCount, ArraySize(testClusterAttrsOnEndpoint4) + ArraySize(GlobalAttributesNotInMetadata)); // We have received all report data. - NL_TEST_ASSERT(apSuite, readCallback.mOnReportEnd); + EXPECT_TRUE(readCallback.mOnReportEnd); readCallback.mAttributeCount = 0; readCallback.mOnReportEnd = false; @@ -760,7 +774,7 @@ void TestReadChunking::TestDynamicEndpoint(nlTestSuite * apSuite, void * apConte // Disable the new endpoint emberAfEndpointEnableDisable(kTestEndpointId4, false); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); // We may receive some attribute reports for descriptor cluster, but we do not care about it for now. @@ -770,24 +784,22 @@ void TestReadChunking::TestDynamicEndpoint(nlTestSuite * apSuite, void * apConte readCallback.mOnReportEnd = false; emberAfEndpointEnableDisable(kTestEndpointId4, true); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); // Ensure we have received the report, we do not care about the initial report here. // GlobalAttributesNotInMetadata attributes are not included in testClusterAttrsOnEndpoint4. - NL_TEST_ASSERT(apSuite, - readCallback.mAttributeCount == - ArraySize(testClusterAttrsOnEndpoint4) + ArraySize(GlobalAttributesNotInMetadata)); + EXPECT_EQ(readCallback.mAttributeCount, ArraySize(testClusterAttrsOnEndpoint4) + ArraySize(GlobalAttributesNotInMetadata)); // We have received all report data. - NL_TEST_ASSERT(apSuite, readCallback.mOnReportEnd); + EXPECT_TRUE(readCallback.mOnReportEnd); } chip::test_utils::SleepMillis(SecondsToMilliseconds(2)); // Destroying the read client will terminate the subscription transaction. - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(0); } @@ -845,20 +857,20 @@ struct Instruction std::vector attributesWithSameDataVersion; }; -void DriveIOUntilSubscriptionEstablished(TestMutableReadCallback * callback) +void DriveIOUntilSubscriptionEstablished(TestContext * pContext, TestMutableReadCallback * callback) { callback->mOnReportEnd = false; - gCtx->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return callback->mOnSubscriptionEstablished; }); - NL_TEST_ASSERT(gSuite, callback->mOnReportEnd); - NL_TEST_ASSERT(gSuite, callback->mOnSubscriptionEstablished); + pContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return callback->mOnSubscriptionEstablished; }); + EXPECT_TRUE(callback->mOnReportEnd); + EXPECT_TRUE(callback->mOnSubscriptionEstablished); callback->mActionOn.clear(); } -void DriveIOUntilEndOfReport(TestMutableReadCallback * callback) +void DriveIOUntilEndOfReport(TestContext * pContext, TestMutableReadCallback * callback) { callback->mOnReportEnd = false; - gCtx->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return callback->mOnReportEnd; }); - NL_TEST_ASSERT(gSuite, callback->mOnReportEnd); + pContext->GetIOContext().DriveIOUntil(System::Clock::Seconds16(5), [&]() { return callback->mOnReportEnd; }); + EXPECT_TRUE(callback->mOnReportEnd); callback->mActionOn.clear(); } @@ -866,7 +878,7 @@ void CheckValues(TestMutableReadCallback * callback, std::vectormValues[vals.first] == vals.second); + EXPECT_EQ(callback->mValues[vals.first], vals.second); } } @@ -879,11 +891,11 @@ void ExpectSameDataVersions(TestMutableReadCallback * callback, AttributesList a DataVersion expectedVersion = callback->mDataVersions[attrList[0]]; for (const auto & attr : attrList) { - NL_TEST_ASSERT(gSuite, callback->mDataVersions[attr] == expectedVersion); + EXPECT_EQ(callback->mDataVersions[attr], expectedVersion); } } -void DoTest(TestMutableReadCallback * callback, Instruction instruction) +void DoTest(TestContext * pContext, TestMutableReadCallback * callback, Instruction instruction) { app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetMaxAttributesPerChunk(instruction.chunksize); @@ -892,7 +904,7 @@ void DoTest(TestMutableReadCallback * callback, Instruction instruction) act(); } - DriveIOUntilEndOfReport(callback); + DriveIOUntilEndOfReport(pContext, callback); CheckValues(callback, instruction.expectedValues); @@ -904,16 +916,12 @@ void DoTest(TestMutableReadCallback * callback, Instruction instruction) }; // namespace TestSetDirtyBetweenChunksUtil -void TestReadChunking::TestSetDirtyBetweenChunks(nlTestSuite * apSuite, void * apContext) +TEST_F(TestReadChunking, TestSetDirtyBetweenChunks) { using namespace TestSetDirtyBetweenChunksUtil; - TestContext & ctx = *static_cast(apContext); - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = mpContext->GetSessionBobToAlice(); app::InteractionModelEngine * engine = app::InteractionModelEngine::GetInstance(); - gCtx = &ctx; - gSuite = apSuite; - // Initialize the ember side server logic InitDataModelHandler(); @@ -945,10 +953,10 @@ void TestReadChunking::TestSetDirtyBetweenChunks(nlTestSuite * apSuite, void * a gIterationCount = 1; - app::ReadClient readClient(engine, &ctx.GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Subscribe); - NL_TEST_ASSERT(apSuite, readClient.SendRequest(readParams) == CHIP_NO_ERROR); + EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); // CASE 1 -- Touch an attribute during priming report, then verify it is included in first report after priming report. { @@ -957,11 +965,11 @@ void TestReadChunking::TestSetDirtyBetweenChunks(nlTestSuite * apSuite, void * a // We are expected to miss attributes on kTestEndpointId during initial reports. ChipLogProgress(DataManagement, "Case 1-1: Set dirty during priming report."); readCallback.mActionOn[AttrOnEp5] = TouchAttrOp(AttrOnEp1); - DriveIOUntilSubscriptionEstablished(&readCallback); + DriveIOUntilSubscriptionEstablished(mpContext, &readCallback); CheckValues(&readCallback, { { AttrOnEp1, 1 } }); ChipLogProgress(DataManagement, "Case 1-2: Check for attributes missed last report."); - DoTest(&readCallback, Instruction{ .chunksize = 2, .expectedValues = { { AttrOnEp1, 2 } } }); + DoTest(mpContext, &readCallback, Instruction{ .chunksize = 2, .expectedValues = { { AttrOnEp1, 2 } } }); } // CASE 2 -- Set dirty during chunked report, the attribute is already dirty. @@ -969,7 +977,7 @@ void TestReadChunking::TestSetDirtyBetweenChunks(nlTestSuite * apSuite, void * a ChipLogProgress(DataManagement, "Case 2: Set dirty during chunked report by wildcard path."); readCallback.mActionOn[AttrOnEp5] = WriteAttrOp(AttrOnEp5, 3); DoTest( - &readCallback, + mpContext, &readCallback, Instruction{ .chunksize = 2, .preworks = { WriteAttrOp(AttrOnEp5, 2), WriteAttrOp(AttrOnEp5, 2), WriteAttrOp(AttrOnEp5, 2) }, @@ -983,7 +991,7 @@ void TestReadChunking::TestSetDirtyBetweenChunks(nlTestSuite * apSuite, void * a "Case 3-1: Set dirty during chunked report by wildcard path -- new dirty attribute."); readCallback.mActionOn[AttrOnEp5] = WriteAttrOp(AttrOnEp5, 4); DoTest( - &readCallback, + mpContext, &readCallback, Instruction{ .chunksize = 1, .preworks = { WriteAttrOp(AttrOnEp5, 4), WriteAttrOp(AttrOnEp5, 4) }, .expectedValues = { { AttrOnEp5, 4 }, { AttrOnEp5, 4 }, { AttrOnEp5, 4 } }, @@ -994,7 +1002,7 @@ void TestReadChunking::TestSetDirtyBetweenChunks(nlTestSuite * apSuite, void * a app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetMaxAttributesPerChunk(1); readCallback.mActionOn[AttrOnEp5] = WriteAttrOp(AttrOnEp5, 5); DoTest( - &readCallback, + mpContext, &readCallback, Instruction{ .chunksize = 1, .preworks = { WriteAttrOp(AttrOnEp5, 5), WriteAttrOp(AttrOnEp5, 5) }, .expectedValues = { { AttrOnEp5, 5 }, { AttrOnEp5, 5 }, { AttrOnEp5, 5 } }, @@ -1024,18 +1032,18 @@ void TestReadChunking::TestSetDirtyBetweenChunks(nlTestSuite * apSuite, void * a { TestMutableReadCallback readCallback; - app::ReadClient readClient(engine, &ctx.GetExchangeManager(), readCallback.mBufferedCallback, + app::ReadClient readClient(engine, &mpContext->GetExchangeManager(), readCallback.mBufferedCallback, app::ReadClient::InteractionType::Subscribe); - NL_TEST_ASSERT(apSuite, readClient.SendRequest(readParams) == CHIP_NO_ERROR); + EXPECT_EQ(readClient.SendRequest(readParams), CHIP_NO_ERROR); - DriveIOUntilSubscriptionEstablished(&readCallback); + DriveIOUntilSubscriptionEstablished(mpContext, &readCallback); // Note, although the two attributes comes from the same cluster, they are generated by different interested paths. // In this case, we won't reset the path iterator. ChipLogProgress(DataManagement, "Case 1-1: Test set dirty during reports generated by concrete paths."); readCallback.mActionOn[AttrOnEp5] = WriteAttrOp(AttrOnEp5, 4); - DoTest(&readCallback, + DoTest(mpContext, &readCallback, Instruction{ .chunksize = 1, .preworks = { WriteAttrOp(AttrOnEp5, 3), WriteAttrOp(AttrOnEp5, 3), WriteAttrOp(AttrOnEp5, 3) }, @@ -1043,46 +1051,20 @@ void TestReadChunking::TestSetDirtyBetweenChunks(nlTestSuite * apSuite, void * a // The attribute failed to catch last report will be picked by this report. ChipLogProgress(DataManagement, "Case 1-2: Check for attributes missed last report."); - DoTest(&readCallback, { .chunksize = 1, .expectedValues = { { AttrOnEp5, 4 } } }); + DoTest(mpContext, &readCallback, { .chunksize = 1, .expectedValues = { { AttrOnEp5, 4 } } }); } } chip::test_utils::SleepMillis(SecondsToMilliseconds(3)); // Destroying the read client will terminate the subscription transaction. - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(1); emberAfClearDynamicEndpoint(0); app::InteractionModelEngine::GetInstance()->GetReportingEngine().SetMaxAttributesPerChunk(UINT32_MAX); } -const nlTest sTests[] = { - NL_TEST_DEF("TestChunking", TestReadChunking::TestChunking), - NL_TEST_DEF("TestListChunking", TestReadChunking::TestListChunking), - NL_TEST_DEF("TestBadChunking", TestReadChunking::TestBadChunking), - NL_TEST_DEF("TestDynamicEndpoint", TestReadChunking::TestDynamicEndpoint), - NL_TEST_DEF("TestSetDirtyBetweenChunks", TestReadChunking::TestSetDirtyBetweenChunks), - NL_TEST_SENTINEL(), -}; - -nlTestSuite sSuite = { - "TestReadChunking", - &sTests[0], - TestContext::nlTestSetUpTestSuite, - TestContext::nlTestTearDownTestSuite, - TestContext::nlTestSetUp, - TestContext::nlTestTearDown, -}; - } // namespace - -int TestReadChunkingTests() -{ - gSuite = &sSuite; - return chip::ExecuteTestsWithContext(&sSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestReadChunkingTests) diff --git a/src/controller/tests/TestServerCommandDispatch.cpp b/src/controller/tests/TestServerCommandDispatch.cpp index a87ec5d1bcd8d3..41fab0ae0e3802 100644 --- a/src/controller/tests/TestServerCommandDispatch.cpp +++ b/src/controller/tests/TestServerCommandDispatch.cpp @@ -22,6 +22,8 @@ * */ +#include + #include "app-common/zap-generated/ids/Attributes.h" #include "app-common/zap-generated/ids/Clusters.h" #include "protocols/interaction_model/Constants.h" @@ -33,11 +35,8 @@ #include #include #include -#include -#include #include #include -#include using TestContext = chip::Test::AppContext; @@ -131,22 +130,45 @@ CHIP_ERROR TestClusterCommandHandler::EnumerateAcceptedCommands(const ConcreteCl namespace { -class TestCommandInteraction +class TestServerCommandDispatch : public ::testing::Test { public: - TestCommandInteraction() {} - static void TestNoHandler(nlTestSuite * apSuite, void * apContext); - static void TestDataResponse(nlTestSuite * apSuite, void * apContext); - static void TestDataResponseNoCommand1(nlTestSuite * apSuite, void * apContext); - static void TestDataResponseNoCommand2(nlTestSuite * apSuite, void * apContext); - static void TestDataResponseNoCommand3(nlTestSuite * apSuite, void * apContext); - static void TestDataResponseHandlerOverride1(nlTestSuite * apSuite, void * apContext); - static void TestDataResponseHandlerOverride2(nlTestSuite * apSuite, void * apContext); + // Performs shared setup for all tests in the test suite + static void SetUpTestSuite() + { + if (mpContext == nullptr) + { + mpContext = new TestContext(); + ASSERT_NE(mpContext, nullptr); + } + mpContext->SetUpTestSuite(); + } -private: - static void TestDataResponseHelper(nlTestSuite * apSuite, void * apContext, const EmberAfEndpointType * aEndpoint, - bool aExpectSuccess); + // Performs shared teardown for all tests in the test suite + static void TearDownTestSuite() + { + mpContext->TearDownTestSuite(); + if (mpContext != nullptr) + { + delete mpContext; + mpContext = nullptr; + } + } + +protected: + // Performs setup for each test in the suite + void SetUp() { mpContext->SetUp(); } + + // Performs teardown for each test in the suite + void TearDown() { mpContext->TearDown(); } + + static TestContext * mpContext; + + // Helpers + + static void TestDataResponseHelper(const EmberAfEndpointType * aEndpoint, bool aExpectSuccess); }; +TestContext * TestServerCommandDispatch::mpContext = nullptr; // We want to send a TestSimpleArgumentRequest::Type, but get a // TestStructArrayArgumentResponse in return, so need to shadow the actual @@ -156,40 +178,37 @@ struct FakeRequest : public Clusters::UnitTesting::Commands::TestSimpleArgumentR using ResponseType = Clusters::UnitTesting::Commands::TestStructArrayArgumentResponse::DecodableType; }; -void TestCommandInteraction::TestNoHandler(nlTestSuite * apSuite, void * apContext) +TEST_F(TestServerCommandDispatch, TestNoHandler) { - TestContext & ctx = *static_cast(apContext); FakeRequest request; - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = mpContext->GetSessionBobToAlice(); request.arg1 = true; // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's // not safe to do so. - auto onSuccessCb = [apSuite](const app::ConcreteCommandPath & commandPath, const app::StatusIB & aStatus, - const auto & dataResponse) { + auto onSuccessCb = [](const app::ConcreteCommandPath & commandPath, const app::StatusIB & aStatus, const auto & dataResponse) { // // We shouldn't be arriving here, since we don't have a command handler installed. // - NL_TEST_ASSERT(apSuite, false); + FAIL(); }; // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's // not safe to do so. - auto onFailureCb = [apSuite](CHIP_ERROR aError) { - NL_TEST_ASSERT(apSuite, - aError.IsIMStatus() && - app::StatusIB(aError).mStatus == Protocols::InteractionModel::Status::UnsupportedEndpoint); + auto onFailureCb = [](CHIP_ERROR aError) { + EXPECT_TRUE(aError.IsIMStatus() && + app::StatusIB(aError).mStatus == Protocols::InteractionModel::Status::UnsupportedEndpoint); }; responseDirective = kSendDataResponse; - chip::Controller::InvokeCommandRequest(&ctx.GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, + chip::Controller::InvokeCommandRequest(&mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, onFailureCb); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); } static const int kDescriptorAttributeArraySize = 254; @@ -239,12 +258,10 @@ DECLARE_DYNAMIC_CLUSTER(chip::app::Clusters::UnitTesting::Id, testClusterAttrs, DECLARE_DYNAMIC_ENDPOINT(testEndpoint3, testEndpointClusters3); -void TestCommandInteraction::TestDataResponseHelper(nlTestSuite * apSuite, void * apContext, const EmberAfEndpointType * aEndpoint, - bool aExpectSuccess) +void TestServerCommandDispatch::TestDataResponseHelper(const EmberAfEndpointType * aEndpoint, bool aExpectSuccess) { - TestContext & ctx = *static_cast(apContext); FakeRequest request; - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = mpContext->GetSessionBobToAlice(); bool onSuccessWasCalled = false; bool onFailureWasCalled = false; @@ -263,23 +280,23 @@ void TestCommandInteraction::TestDataResponseHelper(nlTestSuite * apSuite, void // Passing of stack variables by reference is only safe because of synchronous completion of the interaction. Otherwise, it's // not safe to do so. - auto onSuccessCb = [apSuite, &onSuccessWasCalled](const app::ConcreteCommandPath & commandPath, const app::StatusIB & aStatus, - const auto & dataResponse) { + auto onSuccessCb = [&onSuccessWasCalled](const app::ConcreteCommandPath & commandPath, const app::StatusIB & aStatus, + const auto & dataResponse) { uint8_t i = 0; auto iter = dataResponse.arg1.begin(); while (iter.Next()) { auto & item = iter.GetValue(); - NL_TEST_ASSERT(apSuite, item.a == i); - NL_TEST_ASSERT(apSuite, item.b == false); - NL_TEST_ASSERT(apSuite, item.c.a == i); - NL_TEST_ASSERT(apSuite, item.c.b == true); + EXPECT_EQ(item.a, i); + EXPECT_FALSE(item.b); + EXPECT_EQ(item.c.a, i); + EXPECT_TRUE(item.c.b); i++; } - NL_TEST_ASSERT(apSuite, iter.GetStatus() == CHIP_NO_ERROR); - NL_TEST_ASSERT(apSuite, dataResponse.arg6 == true); + EXPECT_EQ(iter.GetStatus(), CHIP_NO_ERROR); + EXPECT_TRUE(dataResponse.arg6); onSuccessWasCalled = true; }; @@ -290,36 +307,36 @@ void TestCommandInteraction::TestDataResponseHelper(nlTestSuite * apSuite, void responseDirective = kSendDataResponse; - chip::Controller::InvokeCommandRequest(&ctx.GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, + chip::Controller::InvokeCommandRequest(&mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, request, onSuccessCb, onFailureCb); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); - NL_TEST_ASSERT(apSuite, onSuccessWasCalled == aExpectSuccess && onFailureWasCalled != aExpectSuccess); - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_TRUE(onSuccessWasCalled == aExpectSuccess && onFailureWasCalled != aExpectSuccess); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); onSuccessWasCalled = false; onFailureWasCalled = false; - auto readSuccessCb = [apSuite, &onSuccessWasCalled, aExpectSuccess](const ConcreteDataAttributePath &, - const DataModel::DecodableList & commandList) { + auto readSuccessCb = [&onSuccessWasCalled, aExpectSuccess](const ConcreteDataAttributePath &, + const DataModel::DecodableList & commandList) { auto count = 0; auto iter = commandList.begin(); while (iter.Next()) { // We only expect 0 or 1 command ids here. - NL_TEST_ASSERT(apSuite, count == 0); - NL_TEST_ASSERT(apSuite, iter.GetValue() == Clusters::UnitTesting::Commands::TestSimpleArgumentRequest::Id); + EXPECT_EQ(count, 0); + EXPECT_EQ(iter.GetValue(), Clusters::UnitTesting::Commands::TestSimpleArgumentRequest::Id); ++count; } - NL_TEST_ASSERT(apSuite, iter.GetStatus() == CHIP_NO_ERROR); + EXPECT_EQ(iter.GetStatus(), CHIP_NO_ERROR); if (aExpectSuccess) { - NL_TEST_ASSERT(apSuite, count == 1); + EXPECT_EQ(count, 1); } else { - NL_TEST_ASSERT(apSuite, count == 0); + EXPECT_EQ(count, 0); } onSuccessWasCalled = true; }; @@ -329,91 +346,60 @@ void TestCommandInteraction::TestDataResponseHelper(nlTestSuite * apSuite, void }; chip::Controller::ReadAttribute( - &ctx.GetExchangeManager(), sessionHandle, kTestEndpointId, readSuccessCb, readFailureCb); + &mpContext->GetExchangeManager(), sessionHandle, kTestEndpointId, readSuccessCb, readFailureCb); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); - NL_TEST_ASSERT(apSuite, onSuccessWasCalled && !onFailureWasCalled); - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_TRUE(onSuccessWasCalled && !onFailureWasCalled); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(0); } -void TestCommandInteraction::TestDataResponse(nlTestSuite * apSuite, void * apContext) +TEST_F(TestServerCommandDispatch, TestDataResponse) { TestClusterCommandHandler commandHandler; - TestDataResponseHelper(apSuite, apContext, &testEndpoint1, true); + TestDataResponseHelper(&testEndpoint1, true); } -void TestCommandInteraction::TestDataResponseNoCommand1(nlTestSuite * apSuite, void * apContext) +TEST_F(TestServerCommandDispatch, TestDataResponseNoCommand1) { // Check what happens if we don't claim our command id is supported, by // overriding the acceptedCommandList with an empty list. TestClusterCommandHandler commandHandler; commandHandler.OverrideAcceptedCommands(); commandHandler.ClaimNoCommands(); - TestDataResponseHelper(apSuite, apContext, &testEndpoint1, false); + TestDataResponseHelper(&testEndpoint1, false); } -void TestCommandInteraction::TestDataResponseNoCommand2(nlTestSuite * apSuite, void * apContext) +TEST_F(TestServerCommandDispatch, TestDataResponseNoCommand2) { // Check what happens if we don't claim our command id is supported, by // having an acceptedCommandList that ends immediately. TestClusterCommandHandler commandHandler; - TestDataResponseHelper(apSuite, apContext, &testEndpoint2, false); + TestDataResponseHelper(&testEndpoint2, false); } -void TestCommandInteraction::TestDataResponseNoCommand3(nlTestSuite * apSuite, void * apContext) +TEST_F(TestServerCommandDispatch, TestDataResponseNoCommand3) { // Check what happens if we don't claim our command id is supported, by // having an acceptedCommandList that is null. TestClusterCommandHandler commandHandler; - TestDataResponseHelper(apSuite, apContext, &testEndpoint3, false); + TestDataResponseHelper(&testEndpoint3, false); } -void TestCommandInteraction::TestDataResponseHandlerOverride1(nlTestSuite * apSuite, void * apContext) +TEST_F(TestServerCommandDispatch, TestDataResponseHandlerOverride1) { TestClusterCommandHandler commandHandler; commandHandler.OverrideAcceptedCommands(); - TestDataResponseHelper(apSuite, apContext, &testEndpoint2, true); + TestDataResponseHelper(&testEndpoint2, true); } -void TestCommandInteraction::TestDataResponseHandlerOverride2(nlTestSuite * apSuite, void * apContext) +TEST_F(TestServerCommandDispatch, TestDataResponseHandlerOverride2) { TestClusterCommandHandler commandHandler; commandHandler.OverrideAcceptedCommands(); - TestDataResponseHelper(apSuite, apContext, &testEndpoint3, true); + TestDataResponseHelper(&testEndpoint3, true); } -// clang-format off -const nlTest sTests[] = -{ - NL_TEST_DEF("TestNoHandler", TestCommandInteraction::TestNoHandler), - NL_TEST_DEF("TestDataResponse", TestCommandInteraction::TestDataResponse), - NL_TEST_DEF("TestDataResponseNoCommand1", TestCommandInteraction::TestDataResponseNoCommand1), - NL_TEST_DEF("TestDataResponseNoCommand2", TestCommandInteraction::TestDataResponseNoCommand2), - NL_TEST_DEF("TestDataResponseNoCommand3", TestCommandInteraction::TestDataResponseNoCommand3), - NL_TEST_DEF("TestDataResponseHandlerOverride1", TestCommandInteraction::TestDataResponseHandlerOverride1), - NL_TEST_DEF("TestDataResponseHandlerOverride2", TestCommandInteraction::TestDataResponseHandlerOverride2), - NL_TEST_SENTINEL() -}; - -// clang-format on - -nlTestSuite sSuite = { - "TestCommands", - &sTests[0], - TestContext::nlTestSetUpTestSuite, - TestContext::nlTestTearDownTestSuite, - TestContext::nlTestSetUp, - TestContext::nlTestTearDown, -}; - } // namespace - -int TestCommandInteractionTest() -{ - return chip::ExecuteTestsWithContext(&sSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestCommandInteractionTest) diff --git a/src/controller/tests/TestWriteChunking.cpp b/src/controller/tests/TestWriteChunking.cpp index d8c748129a755d..60be2212aa00e8 100644 --- a/src/controller/tests/TestWriteChunking.cpp +++ b/src/controller/tests/TestWriteChunking.cpp @@ -16,6 +16,11 @@ * limitations under the License. */ +#include +#include + +#include + #include "app-common/zap-generated/ids/Attributes.h" #include "app-common/zap-generated/ids/Clusters.h" #include "app/ConcreteAttributePath.h" @@ -32,14 +37,8 @@ #include #include #include -#include -#include #include #include -#include - -#include -#include using TestContext = chip::Test::AppContext; using namespace chip; @@ -49,7 +48,6 @@ using namespace chip::app::Clusters; namespace { uint32_t gIterationCount = 0; -nlTestSuite * gSuite = nullptr; // // The generated endpoint_config for the controller app has Endpoint 1 @@ -64,18 +62,41 @@ constexpr uint32_t kTestListLength = 5; // We don't really care about the content, we just need a buffer. uint8_t sByteSpanData[app::kMaxSecureSduLengthBytes]; -class TestWriteChunking +class TestWriteChunking : public ::testing::Test { public: - TestWriteChunking() {} - static void TestListChunking(nlTestSuite * apSuite, void * apContext); - static void TestBadChunking(nlTestSuite * apSuite, void * apContext); - static void TestConflictWrite(nlTestSuite * apSuite, void * apContext); - static void TestNonConflictWrite(nlTestSuite * apSuite, void * apContext); - static void TestTransactionalList(nlTestSuite * apSuite, void * apContext); - -private: + // Performs shared setup for all tests in the test suite + static void SetUpTestSuite() + { + if (mpContext == nullptr) + { + mpContext = new TestContext(); + ASSERT_NE(mpContext, nullptr); + } + mpContext->SetUpTestSuite(); + } + + // Performs shared teardown for all tests in the test suite + static void TearDownTestSuite() + { + mpContext->TearDownTestSuite(); + if (mpContext != nullptr) + { + delete mpContext; + mpContext = nullptr; + } + } + +protected: + // Performs setup for each test in the suite + void SetUp() { mpContext->SetUp(); } + + // Performs teardown for each test in the suite + void TearDown() { mpContext->TearDown(); } + + static TestContext * mpContext; }; +TestContext * TestWriteChunking::mpContext = nullptr; //clang-format off DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(testClusterAttrsOnEndpoint) @@ -188,10 +209,9 @@ CHIP_ERROR TestAttrAccess::Write(const app::ConcreteDataAttributePath & aPath, a * This will cause all the various corner cases encountered of closing out the various containers within the write request and * thoroughly and definitely validate those edge cases. */ -void TestWriteChunking::TestListChunking(nlTestSuite * apSuite, void * apContext) +TEST_F(TestWriteChunking, TestListChunking) { - TestContext & ctx = *static_cast(apContext); - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = mpContext->GetSessionBobToAlice(); // Initialize the ember side server logic InitDataModelHandler(); @@ -218,16 +238,16 @@ void TestWriteChunking::TestListChunking(nlTestSuite * apSuite, void * apContext gIterationCount = i; - app::WriteClient writeClient(&ctx.GetExchangeManager(), &writeCallback, Optional::Missing(), + app::WriteClient writeClient(&mpContext->GetExchangeManager(), &writeCallback, Optional::Missing(), static_cast(minReservationSize + i) /* reserved buffer size */); ByteSpan list[kTestListLength]; err = writeClient.EncodeAttribute(attributePath, app::DataModel::List(list, kTestListLength)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writeClient.SendWriteRequest(sessionHandle); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // // Service the IO + Engine till we get a ReportEnd callback on the client. @@ -236,20 +256,19 @@ void TestWriteChunking::TestListChunking(nlTestSuite * apSuite, void * apContext // for (int j = 0; j < 10 && writeCallback.mOnDoneCount == 0; j++) { - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); } - NL_TEST_ASSERT(apSuite, - writeCallback.mSuccessCount == kTestListLength + 1 /* an extra item for the empty list at the beginning */); - NL_TEST_ASSERT(apSuite, writeCallback.mErrorCount == 0); - NL_TEST_ASSERT(apSuite, writeCallback.mOnDoneCount == 1); + EXPECT_EQ(writeCallback.mSuccessCount, kTestListLength + 1 /* an extra item for the empty list at the beginning */); + EXPECT_EQ(writeCallback.mErrorCount, 0u); + EXPECT_EQ(writeCallback.mOnDoneCount, 1u); - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); // // Stop the test if we detected an error. Otherwise, it'll be difficult to read the logs. // - if (apSuite->flagError) + if (HasFailure()) { break; } @@ -260,10 +279,9 @@ void TestWriteChunking::TestListChunking(nlTestSuite * apSuite, void * apContext // We encode a pretty large write payload to test the corner cases related to message layer and secure session overheads. // The test should gurantee that if encode returns no error, the send should also success. // As the actual overhead may change, we will test over a few possible payload lengths, from 850 to MTU used in write clients. -void TestWriteChunking::TestBadChunking(nlTestSuite * apSuite, void * apContext) +TEST_F(TestWriteChunking, TestBadChunking) { - TestContext & ctx = *static_cast(apContext); - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = mpContext->GetSessionBobToAlice(); bool atLeastOneRequestSent = false; bool atLeastOneRequestFailed = false; @@ -288,7 +306,7 @@ void TestWriteChunking::TestBadChunking(nlTestSuite * apSuite, void * apContext) gIterationCount = (uint32_t) i; - app::WriteClient writeClient(&ctx.GetExchangeManager(), &writeCallback, Optional::Missing()); + app::WriteClient writeClient(&mpContext->GetExchangeManager(), &writeCallback, Optional::Missing()); ByteSpan list[kTestListLength]; for (auto & item : list) @@ -308,7 +326,7 @@ void TestWriteChunking::TestBadChunking(nlTestSuite * apSuite, void * apContext) // If we successfully encoded the attribute, then we must be able to send the message. err = writeClient.SendWriteRequest(sessionHandle); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); // // Service the IO + Engine till we get a ReportEnd callback on the client. @@ -317,26 +335,25 @@ void TestWriteChunking::TestBadChunking(nlTestSuite * apSuite, void * apContext) // for (int j = 0; j < 10 && writeCallback.mOnDoneCount == 0; j++) { - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); } - NL_TEST_ASSERT(apSuite, - writeCallback.mSuccessCount == kTestListLength + 1 /* an extra item for the empty list at the beginning */); - NL_TEST_ASSERT(apSuite, writeCallback.mErrorCount == 0); - NL_TEST_ASSERT(apSuite, writeCallback.mOnDoneCount == 1); + EXPECT_EQ(writeCallback.mSuccessCount, kTestListLength + 1 /* an extra item for the empty list at the beginning */); + EXPECT_EQ(writeCallback.mErrorCount, 0u); + EXPECT_EQ(writeCallback.mOnDoneCount, 1u); - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); // // Stop the test if we detected an error. Otherwise, it'll be difficult to read the logs. // - if (apSuite->flagError) + if (HasFailure()) { break; } } - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); - NL_TEST_ASSERT(apSuite, atLeastOneRequestSent && atLeastOneRequestFailed); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); + EXPECT_TRUE(atLeastOneRequestSent && atLeastOneRequestFailed); emberAfClearDynamicEndpoint(0); } @@ -344,10 +361,9 @@ void TestWriteChunking::TestBadChunking(nlTestSuite * apSuite, void * apContext) * When chunked write is enabled, it is dangerious to handle multiple write requests at the same time. In this case, we will reject * the latter write requests to the same attribute. */ -void TestWriteChunking::TestConflictWrite(nlTestSuite * apSuite, void * apContext) +TEST_F(TestWriteChunking, TestConflictWrite) { - TestContext & ctx = *static_cast(apContext); - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = mpContext->GetSessionBobToAlice(); // Initialize the ember side server logic InitDataModelHandler(); @@ -364,11 +380,11 @@ void TestWriteChunking::TestConflictWrite(nlTestSuite * apSuite, void * apContex constexpr size_t kReserveSize = kMaxSecureSduLengthBytes - 128; TestWriteCallback writeCallback1; - app::WriteClient writeClient1(&ctx.GetExchangeManager(), &writeCallback1, Optional::Missing(), + app::WriteClient writeClient1(&mpContext->GetExchangeManager(), &writeCallback1, Optional::Missing(), static_cast(kReserveSize)); TestWriteCallback writeCallback2; - app::WriteClient writeClient2(&ctx.GetExchangeManager(), &writeCallback2, Optional::Missing(), + app::WriteClient writeClient2(&mpContext->GetExchangeManager(), &writeCallback2, Optional::Missing(), static_cast(kReserveSize)); ByteSpan list[kTestListLength]; @@ -376,17 +392,17 @@ void TestWriteChunking::TestConflictWrite(nlTestSuite * apSuite, void * apContex CHIP_ERROR err = CHIP_NO_ERROR; err = writeClient1.EncodeAttribute(attributePath, app::DataModel::List(list, kTestListLength)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writeClient2.EncodeAttribute(attributePath, app::DataModel::List(list, kTestListLength)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writeClient1.SendWriteRequest(sessionHandle); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writeClient2.SendWriteRequest(sessionHandle); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); { const TestWriteCallback * writeCallbackRef1 = &writeCallback1; @@ -400,19 +416,17 @@ void TestWriteChunking::TestConflictWrite(nlTestSuite * apSuite, void * apContex writeCallbackRef1 = &writeCallback2; } - NL_TEST_ASSERT(apSuite, - writeCallbackRef1->mSuccessCount == - kTestListLength + 1 /* an extra item for the empty list at the beginning */); - NL_TEST_ASSERT(apSuite, writeCallbackRef1->mErrorCount == 0); - NL_TEST_ASSERT(apSuite, writeCallbackRef2->mSuccessCount == 0); - NL_TEST_ASSERT(apSuite, writeCallbackRef2->mErrorCount == kTestListLength + 1); - NL_TEST_ASSERT(apSuite, writeCallbackRef2->mLastErrorReason.mStatus == Protocols::InteractionModel::Status::Busy); + EXPECT_EQ(writeCallbackRef1->mSuccessCount, kTestListLength + 1 /* an extra item for the empty list at the beginning */); + EXPECT_EQ(writeCallbackRef1->mErrorCount, 0u); + EXPECT_EQ(writeCallbackRef2->mSuccessCount, 0u); + EXPECT_EQ(writeCallbackRef2->mErrorCount, kTestListLength + 1); + EXPECT_EQ(writeCallbackRef2->mLastErrorReason.mStatus, Protocols::InteractionModel::Status::Busy); - NL_TEST_ASSERT(apSuite, writeCallbackRef1->mOnDoneCount == 1); - NL_TEST_ASSERT(apSuite, writeCallbackRef2->mOnDoneCount == 1); + EXPECT_EQ(writeCallbackRef1->mOnDoneCount, 1u); + EXPECT_EQ(writeCallbackRef2->mOnDoneCount, 1u); } - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(0); } @@ -421,10 +435,9 @@ void TestWriteChunking::TestConflictWrite(nlTestSuite * apSuite, void * apContex * When chunked write is enabled, it is dangerious to handle multiple write requests at the same time. However, we will allow such * change when writing to different attributes in parallel. */ -void TestWriteChunking::TestNonConflictWrite(nlTestSuite * apSuite, void * apContext) +TEST_F(TestWriteChunking, TestNonConflictWrite) { - TestContext & ctx = *static_cast(apContext); - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = mpContext->GetSessionBobToAlice(); // Initialize the ember side server logic InitDataModelHandler(); @@ -442,11 +455,11 @@ void TestWriteChunking::TestNonConflictWrite(nlTestSuite * apSuite, void * apCon constexpr size_t kReserveSize = kMaxSecureSduLengthBytes - 128; TestWriteCallback writeCallback1; - app::WriteClient writeClient1(&ctx.GetExchangeManager(), &writeCallback1, Optional::Missing(), + app::WriteClient writeClient1(&mpContext->GetExchangeManager(), &writeCallback1, Optional::Missing(), static_cast(kReserveSize)); TestWriteCallback writeCallback2; - app::WriteClient writeClient2(&ctx.GetExchangeManager(), &writeCallback2, Optional::Missing(), + app::WriteClient writeClient2(&mpContext->GetExchangeManager(), &writeCallback2, Optional::Missing(), static_cast(kReserveSize)); ByteSpan list[kTestListLength]; @@ -454,29 +467,29 @@ void TestWriteChunking::TestNonConflictWrite(nlTestSuite * apSuite, void * apCon CHIP_ERROR err = CHIP_NO_ERROR; err = writeClient1.EncodeAttribute(attributePath1, app::DataModel::List(list, kTestListLength)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writeClient2.EncodeAttribute(attributePath2, app::DataModel::List(list, kTestListLength)); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writeClient1.SendWriteRequest(sessionHandle); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); err = writeClient2.SendWriteRequest(sessionHandle); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.DrainAndServiceIO(); + mpContext->DrainAndServiceIO(); { - NL_TEST_ASSERT(apSuite, writeCallback1.mErrorCount == 0); - NL_TEST_ASSERT(apSuite, writeCallback1.mSuccessCount == kTestListLength + 1); - NL_TEST_ASSERT(apSuite, writeCallback2.mErrorCount == 0); - NL_TEST_ASSERT(apSuite, writeCallback2.mSuccessCount == kTestListLength + 1); + EXPECT_EQ(writeCallback1.mErrorCount, 0u); + EXPECT_EQ(writeCallback1.mSuccessCount, kTestListLength + 1); + EXPECT_EQ(writeCallback2.mErrorCount, 0u); + EXPECT_EQ(writeCallback2.mSuccessCount, kTestListLength + 1); - NL_TEST_ASSERT(apSuite, writeCallback1.mOnDoneCount == 1); - NL_TEST_ASSERT(apSuite, writeCallback2.mOnDoneCount == 1); + EXPECT_EQ(writeCallback1.mOnDoneCount, 1u); + EXPECT_EQ(writeCallback2.mOnDoneCount, 1u); } - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(0); } @@ -510,14 +523,14 @@ struct Instructions std::vector expectedStatus; }; -void RunTest(nlTestSuite * apSuite, TestContext & ctx, Instructions instructions) +void RunTest(TestContext * pContext, Instructions instructions) { CHIP_ERROR err = CHIP_NO_ERROR; - auto sessionHandle = ctx.GetSessionBobToAlice(); + auto sessionHandle = pContext->GetSessionBobToAlice(); TestWriteCallback writeCallback; std::unique_ptr writeClient = std::make_unique( - &ctx.GetExchangeManager(), &writeCallback, Optional::Missing(), + &pContext->GetExchangeManager(), &writeCallback, Optional::Missing(), static_cast(kMaxSecureSduLengthBytes - 128) /* use a smaller chunk so we only need a few attributes in the write request. */); @@ -525,7 +538,7 @@ void RunTest(nlTestSuite * apSuite, TestContext & ctx, Instructions instructions std::vector status; testServer.mOnListWriteBegin = [&](const ConcreteAttributePath & aPath) { - NL_TEST_ASSERT(apSuite, onGoingPath == ConcreteAttributePath()); + EXPECT_EQ(onGoingPath, ConcreteAttributePath()); onGoingPath = aPath; ChipLogProgress(Zcl, "OnListWriteBegin endpoint=%u Cluster=" ChipLogFormatMEI " attribute=" ChipLogFormatMEI, aPath.mEndpointId, ChipLogValueMEI(aPath.mClusterId), ChipLogValueMEI(aPath.mAttributeId)); @@ -542,7 +555,7 @@ void RunTest(nlTestSuite * apSuite, TestContext & ctx, Instructions instructions } }; testServer.mOnListWriteEnd = [&](const ConcreteAttributePath & aPath, bool aWasSuccessful) { - NL_TEST_ASSERT(apSuite, onGoingPath == aPath); + EXPECT_EQ(onGoingPath, aPath); status.push_back(PathStatus(aPath, aWasSuccessful)); onGoingPath = ConcreteAttributePath(); ChipLogProgress(Zcl, "OnListWriteEnd endpoint=%u Cluster=" ChipLogFormatMEI " attribute=" ChipLogFormatMEI, @@ -556,7 +569,7 @@ void RunTest(nlTestSuite * apSuite, TestContext & ctx, Instructions instructions { instructions.data = std::vector(instructions.paths.size(), ListData::kList); } - NL_TEST_ASSERT(apSuite, instructions.paths.size() == instructions.data.size()); + EXPECT_EQ(instructions.paths.size(), instructions.data.size()); for (size_t i = 0; i < instructions.paths.size(); i++) { @@ -579,22 +592,22 @@ void RunTest(nlTestSuite * apSuite, TestContext & ctx, Instructions instructions break; } } - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); } err = writeClient->SendWriteRequest(sessionHandle); - NL_TEST_ASSERT(apSuite, err == CHIP_NO_ERROR); + EXPECT_EQ(err, CHIP_NO_ERROR); - ctx.GetIOContext().DriveIOUntil(sessionHandle->ComputeRoundTripTimeout(app::kExpectedIMProcessingTime) + - System::Clock::Seconds16(1), - [&]() { return ctx.GetExchangeManager().GetNumActiveExchanges() == 0; }); + pContext->GetIOContext().DriveIOUntil(sessionHandle->ComputeRoundTripTimeout(app::kExpectedIMProcessingTime) + + System::Clock::Seconds16(1), + [&]() { return pContext->GetExchangeManager().GetNumActiveExchanges() == 0; }); - NL_TEST_ASSERT(apSuite, onGoingPath == app::ConcreteAttributePath()); - NL_TEST_ASSERT(apSuite, status.size() == instructions.expectedStatus.size()); + EXPECT_EQ(onGoingPath, app::ConcreteAttributePath()); + EXPECT_EQ(status.size(), instructions.expectedStatus.size()); for (size_t i = 0; i < status.size(); i++) { - NL_TEST_ASSERT(apSuite, status[i] == PathStatus(instructions.paths[i], instructions.expectedStatus[i])); + EXPECT_EQ(status[i], PathStatus(instructions.paths[i], instructions.expectedStatus[i])); } testServer.mOnListWriteBegin = nullptr; @@ -603,12 +616,10 @@ void RunTest(nlTestSuite * apSuite, TestContext & ctx, Instructions instructions } // namespace TestTransactionalListInstructions -void TestWriteChunking::TestTransactionalList(nlTestSuite * apSuite, void * apContext) +TEST_F(TestWriteChunking, TestTransactionalList) { using namespace TestTransactionalListInstructions; - TestContext & ctx = *static_cast(apContext); - // Initialize the ember side server logic InitDataModelHandler(); @@ -620,7 +631,7 @@ void TestWriteChunking::TestTransactionalList(nlTestSuite * apSuite, void * apCo // Test 1: we should receive transaction notifications ChipLogProgress(Zcl, "Test 1: we should receive transaction notifications"); - RunTest(apSuite, ctx, + RunTest(mpContext, Instructions{ .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, .expectedStatus = { true }, @@ -628,7 +639,7 @@ void TestWriteChunking::TestTransactionalList(nlTestSuite * apSuite, void * apCo ChipLogProgress(Zcl, "Test 2: we should receive transaction notifications for incomplete list operations"); RunTest( - apSuite, ctx, + mpContext, Instructions{ .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, .onListWriteBeginActions = [&](const app::ConcreteAttributePath & aPath) { return Operations::kShutdownWriteClient; }, @@ -636,7 +647,7 @@ void TestWriteChunking::TestTransactionalList(nlTestSuite * apSuite, void * apCo }); ChipLogProgress(Zcl, "Test 3: we should receive transaction notifications for every list in the transaction"); - RunTest(apSuite, ctx, + RunTest(mpContext, Instructions{ .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute2) }, @@ -644,7 +655,7 @@ void TestWriteChunking::TestTransactionalList(nlTestSuite * apSuite, void * apCo }); ChipLogProgress(Zcl, "Test 4: we should receive transaction notifications with the status of each list"); - RunTest(apSuite, ctx, + RunTest(mpContext, Instructions{ .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute2) }, @@ -662,7 +673,7 @@ void TestWriteChunking::TestTransactionalList(nlTestSuite * apSuite, void * apCo ChipLogProgress(Zcl, "Test 5: transactional list callbacks will be called for nullable lists, test if it is handled correctly for " "null value before non null values"); - RunTest(apSuite, ctx, + RunTest(mpContext, Instructions{ .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, @@ -673,7 +684,7 @@ void TestWriteChunking::TestTransactionalList(nlTestSuite * apSuite, void * apCo ChipLogProgress(Zcl, "Test 6: transactional list callbacks will be called for nullable lists, test if it is handled correctly for " "null value after non null values"); - RunTest(apSuite, ctx, + RunTest(mpContext, Instructions{ .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, @@ -684,7 +695,7 @@ void TestWriteChunking::TestTransactionalList(nlTestSuite * apSuite, void * apCo ChipLogProgress(Zcl, "Test 7: transactional list callbacks will be called for nullable lists, test if it is handled correctly for " "null value between non null values"); - RunTest(apSuite, ctx, + RunTest(mpContext, Instructions{ .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute), @@ -694,7 +705,7 @@ void TestWriteChunking::TestTransactionalList(nlTestSuite * apSuite, void * apCo }); ChipLogProgress(Zcl, "Test 8: transactional list callbacks will be called for nullable lists"); - RunTest(apSuite, ctx, + RunTest(mpContext, Instructions{ .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, .data = { ListData::kNull }, @@ -704,42 +715,16 @@ void TestWriteChunking::TestTransactionalList(nlTestSuite * apSuite, void * apCo ChipLogProgress(Zcl, "Test 9: for nullable lists, we should receive notifications for unsuccessful writes when non-fatal occurred " "during processing the requests"); - RunTest(apSuite, ctx, + RunTest(mpContext, Instructions{ .paths = { ConcreteAttributePath(kTestEndpointId, Clusters::UnitTesting::Id, kTestListAttribute) }, .data = { ListData::kBadValue }, .expectedStatus = { false }, }); - NL_TEST_ASSERT(apSuite, ctx.GetExchangeManager().GetNumActiveExchanges() == 0); + EXPECT_EQ(mpContext->GetExchangeManager().GetNumActiveExchanges(), 0u); emberAfClearDynamicEndpoint(0); } -const nlTest sTests[] = { - NL_TEST_DEF("TestListChunking", TestWriteChunking::TestListChunking), - NL_TEST_DEF("TestBadChunking", TestWriteChunking::TestBadChunking), - NL_TEST_DEF("TestConflictWrite", TestWriteChunking::TestConflictWrite), - NL_TEST_DEF("TestNonConflictWrite", TestWriteChunking::TestNonConflictWrite), - NL_TEST_DEF("TestTransactionalList", TestWriteChunking::TestTransactionalList), - NL_TEST_SENTINEL(), -}; - -nlTestSuite sSuite = { - "TestWriteChunking", - &sTests[0], - TestContext::nlTestSetUpTestSuite, - TestContext::nlTestTearDownTestSuite, - TestContext::nlTestSetUp, - TestContext::nlTestTearDown, -}; - } // namespace - -int TestWriteChunkingTests() -{ - gSuite = &sSuite; - return chip::ExecuteTestsWithContext(&sSuite); -} - -CHIP_REGISTER_TEST_SUITE(TestWriteChunkingTests)