add update server test
diff --git a/src/lib/profiles/data-management/Current/SubscriptionClient.h b/src/lib/profiles/data-management/Current/SubscriptionClient.h
index 5e3b492..5e3fb05 100644
--- a/src/lib/profiles/data-management/Current/SubscriptionClient.h
+++ b/src/lib/profiles/data-management/Current/SubscriptionClient.h
@@ -403,6 +403,7 @@
friend class TestTdm;
friend class TestWdm;
friend class WdmUpdateEncoderTest;
+ friend class WdmUpdateServerTest;
friend class MockWdmSubscriptionInitiatorImpl;
friend class TraitDataSink;
friend class TraitSchemaEngine;
diff --git a/src/lib/profiles/data-management/Current/SubscriptionEngine.h b/src/lib/profiles/data-management/Current/SubscriptionEngine.h
index 1bc7e39..7ae183d 100644
--- a/src/lib/profiles/data-management/Current/SubscriptionEngine.h
+++ b/src/lib/profiles/data-management/Current/SubscriptionEngine.h
@@ -356,6 +356,7 @@
friend class NotificationEngine;
friend class TestTdm;
friend class TestWdm;
+ friend class WdmUpdateServerTest;
nl::Weave::WeaveExchangeManager * mExchangeMgr;
void * mAppState;
diff --git a/src/lib/profiles/data-management/Current/TraitData.h b/src/lib/profiles/data-management/Current/TraitData.h
index 980740c..e99eefb 100644
--- a/src/lib/profiles/data-management/Current/TraitData.h
+++ b/src/lib/profiles/data-management/Current/TraitData.h
@@ -831,6 +831,7 @@
private:
friend class SubscriptionClient;
friend class UpdateEncoder;
+ friend class WdmUpdateServerTest;
/**
* Checks if a DataVersion is more recent than the one currently stored in the Sink.
@@ -965,6 +966,7 @@
const TraitSchemaEngine * mSchemaEngine;
private:
+ friend class WdmUpdateServerTest;
// Current version of the data in this source.
uint64_t mVersion;
// Tracks whether SetDirty was called within a Lock/Unlock 'session'
diff --git a/src/test-apps/Makefile.am b/src/test-apps/Makefile.am
index b613399..f636b31 100644
--- a/src/test-apps/Makefile.am
+++ b/src/test-apps/Makefile.am
@@ -364,6 +364,7 @@
TestPathStore \
TestWdmUpdateEncoder \
TestWdmUpdateResponse \
+ TestWdmUpdateServer \
$(NULL)
if WEAVE_BUILD_WARM
@@ -479,6 +480,7 @@
TestPathStore \
TestWdmUpdateEncoder \
TestWdmUpdateResponse \
+ TestWdmUpdateServer \
$(NULL)
endif
@@ -1263,6 +1265,22 @@
TestWdmUpdateResponse_LDFLAGS = $(AM_CPPFLAGS)
TestWdmUpdateResponse_LDADD = libWeaveTestCommon.a $(COMMON_LDADD)
+TestWdmUpdateServer_SOURCES = TestWdmUpdateServer.cpp \
+ MockSinkTraits.cpp \
+ MockSourceTraits.cpp \
+ schema/nest/test/trait/TestATrait.cpp \
+ schema/nest/test/trait/TestBTrait.cpp \
+ schema/nest/test/trait/TestETrait.cpp \
+ schema/nest/test/trait/TestCommon.cpp \
+ schema/weave/trait/security/BoltLockSettingsTrait.cpp \
+ schema/weave/trait/telemetry/NetworkWiFiTelemetryTrait.cpp \
+ MockWdmNodeOptions.cpp \
+ TestPersistedStorageImplementation.cpp
+
+TestWdmUpdateServer_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/test-apps/schema
+TestWdmUpdateServer_LDFLAGS = $(AM_CPPFLAGS)
+TestWdmUpdateServer_LDADD = libWeaveTestCommon.a $(COMMON_LDADD)
+
TestFabricStateDelegate_SOURCES = TestFabricStateDelegate.cpp TestPersistedStorageImplementation.cpp
TestFabricStateDelegate_LDFLAGS = $(AM_CPPFLAGS)
TestFabricStateDelegate_LDADD = libWeaveTestCommon.a $(COMMON_LDADD)
diff --git a/src/test-apps/MockSinkTraits.h b/src/test-apps/MockSinkTraits.h
index 1b1d506..9474eef 100644
--- a/src/test-apps/MockSinkTraits.h
+++ b/src/test-apps/MockSinkTraits.h
@@ -86,6 +86,7 @@
namespace Profiles {
namespace DataManagement_Current {
class WdmUpdateEncoderTest;
+class WdmUpdateServerTest;
} // namespace DataManagement_Current
} // namespace Profiles
} // namespace Weave
@@ -107,7 +108,7 @@
private:
friend class nl::Weave::Profiles::DataManagement_Current::WdmUpdateEncoderTest;
-
+ friend class nl::Weave::Profiles::DataManagement_Current::WdmUpdateServerTest;
void SetNullifiedPath(nl::Weave::Profiles::DataManagement::PropertyPathHandle aHandle, bool isNull);
WEAVE_ERROR SetData(nl::Weave::Profiles::DataManagement::PropertyPathHandle aHandle, nl::Weave::TLV::TLVReader &aReader, bool aIsNull) __OVERRIDE;
WEAVE_ERROR SetLeafData(nl::Weave::Profiles::DataManagement::PropertyPathHandle aLeafHandle, nl::Weave::TLV::TLVReader &aReader) __OVERRIDE;
diff --git a/src/test-apps/MockSourceTraits.cpp b/src/test-apps/MockSourceTraits.cpp
index 2994a42..d0b5ea3 100644
--- a/src/test-apps/MockSourceTraits.cpp
+++ b/src/test-apps/MockSourceTraits.cpp
@@ -1626,8 +1626,12 @@
}
}
-TestBTraitDataSource::TestBTraitDataSource()
- : TraitDataSource(&TestBTrait::TraitSchema)
+TestBTraitDataSource::TestBTraitDataSource():
+#if WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT
+ TraitUpdatableDataSource(&TestBTrait::TraitSchema)
+#else
+ TraitDataSource(&TestBTrait::TraitSchema)
+#endif
{
SetVersion(200);
taa = TestATrait::ENUM_A_VALUE_1;
@@ -1651,6 +1655,207 @@
MOCK_strlcpy(tbc_seac, "hallo", sizeof(tbc_seac));
}
+#if WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT
+WEAVE_ERROR
+TestBTraitDataSource::SetLeafData(PropertyPathHandle aLeafHandle, TLVReader &aReader)
+{
+ WEAVE_ERROR err = WEAVE_NO_ERROR;
+
+ switch (aLeafHandle) {
+ //
+ // TestATrait
+ //
+
+ case TestBTrait::kPropertyHandle_TaA:
+ int32_t next_taa;
+ err = aReader.Get(next_taa);
+ SuccessOrExit(err);
+ if (next_taa != taa)
+ {
+ WeaveLogDetail(DataManagement, "<< ta_a is changed from %u to %u", taa, next_taa);
+ taa = next_taa;
+ }
+
+ WeaveLogDetail(DataManagement, "<< ta_a = %u", taa);
+ break;
+
+ case TestBTrait::kPropertyHandle_TaB:
+ int32_t next_tab;
+ err = aReader.Get(next_tab);
+ SuccessOrExit(err);
+ if (next_tab != tab)
+ {
+ WeaveLogDetail(DataManagement, "<< ta_b is changed from %u to %u", tab, next_tab);
+ tab = next_tab;
+ }
+
+ WeaveLogDetail(DataManagement, "<< ta_b = %u", tab);
+ break;
+
+ case TestBTrait::kPropertyHandle_TaC:
+ uint32_t next_tac;
+ err = aReader.Get(next_tac);
+ SuccessOrExit(err);
+ if (next_tac != tac)
+ {
+ WeaveLogDetail(DataManagement, "<< ta_c is changed from %u to %u", tac, next_tac);
+ tac = next_tac;
+ }
+
+ WeaveLogDetail(DataManagement, "<< ta_c = %u", tac);
+ break;
+
+ case TestBTrait::kPropertyHandle_TaD_SaA:
+ uint32_t next_tad_saa;
+ err = aReader.Get(next_tad_saa);
+ SuccessOrExit(err);
+ if (next_tad_saa != tad_saa)
+ {
+ WeaveLogDetail(DataManagement, "<< ta_d.sa_a is changed from %u to %u", tad_saa, next_tad_saa);
+ tad_saa = next_tad_saa;
+ }
+
+ WeaveLogDetail(DataManagement, "<< ta_d.sa_a = %u", tad_saa);
+ break;
+
+ case TestBTrait::kPropertyHandle_TaD_SaB:
+ bool next_tad_sab;
+ err = aReader.Get(next_tad_sab);
+ SuccessOrExit(err);
+ if (next_tad_sab != tad_sab)
+ {
+ WeaveLogDetail(DataManagement, "<< ta_d.sa_b is changed from %u to %u", tad_sab, next_tad_sab);
+ tad_sab = next_tad_sab;
+ }
+
+ WeaveLogDetail(DataManagement, "<< ta_d.sa_b = %u", tad_sab);
+ break;
+
+ case TestBTrait::kPropertyHandle_TaE:
+ {
+ TLVType outerType;
+ uint32_t i = 0;
+
+ err = aReader.EnterContainer(outerType);
+ SuccessOrExit(err);
+
+ while (((err = aReader.Next()) == WEAVE_NO_ERROR) && (i < (sizeof(tae) / sizeof(tae[0])))) {
+ uint32_t next_tae;
+ err = aReader.Get(next_tae);
+ SuccessOrExit(err);
+ if (tae[i] != next_tae)
+ {
+ WeaveLogDetail(DataManagement, "<< ta_e[%u] is changed from %u to %u", i, tae[i], next_tae);
+ tae[i] = next_tae;
+ }
+
+ WeaveLogDetail(DataManagement, "<< ta_e[%u] = %u", i, tae[i]);
+ i++;
+ }
+
+ err = aReader.ExitContainer(outerType);
+ break;
+ }
+
+ case TestBTrait::kPropertyHandle_TaP:
+ err = aReader.Get(tap);
+ SuccessOrExit(err);
+
+ WeaveLogDetail(DataManagement, "<< ta_p = %" PRId64, tap);
+ break;
+
+ //
+ // TestBTrait
+ //
+
+ case TestBTrait::kPropertyHandle_TbA:
+ uint32_t next_tba;
+ err = aReader.Get(next_tba);
+ SuccessOrExit(err);
+ if (tba != next_tba)
+ {
+ WeaveLogDetail(DataManagement, "<< tb_a is changed from %u to %u", tba, next_tba);
+ tba = next_tba;
+ }
+
+ WeaveLogDetail(DataManagement, "<< tb_a = %u", tba);
+ break;
+
+ case TestBTrait::kPropertyHandle_TbB_SbA:
+ char next_tbb_sba[10];
+ err = aReader.GetString(next_tbb_sba, 10);
+ SuccessOrExit(err);
+ if (strncmp(tbb_sba, next_tbb_sba, 10))
+ {
+ WeaveLogDetail(DataManagement, "<< tb_b.sb_a is changed from %s to %s", tbb_sba, next_tbb_sba);
+ memcpy(tbb_sba, next_tbb_sba, 10);
+ }
+
+ WeaveLogDetail(DataManagement, "<< tb_b.sb_a = %s", tbb_sba);
+ break;
+
+ case TestBTrait::kPropertyHandle_TbB_SbB:
+ uint32_t next_tbb_sbb;
+ err = aReader.Get(next_tbb_sbb);
+ SuccessOrExit(err);
+ if (tbb_sbb != next_tbb_sbb)
+ {
+ WeaveLogDetail(DataManagement, "<< tb_b.sb_b is changed from %u to %u", tbb_sbb, next_tbb_sbb);
+ tbb_sbb = next_tbb_sbb;
+ }
+
+ WeaveLogDetail(DataManagement, "<< tb_b.sb_b = %u", tbb_sbb);
+ break;
+
+ case TestBTrait::kPropertyHandle_TbC_SaA:
+ uint32_t next_tbc_saa;
+ err = aReader.Get(next_tbc_saa);
+ SuccessOrExit(err);
+ if (tbc_saa != next_tbc_saa)
+ {
+ WeaveLogDetail(DataManagement, "<< tb_c.sa_a is changed from %u to %u", tbc_saa, next_tbc_saa);
+ tbc_saa = next_tbc_saa;
+ }
+
+ WeaveLogDetail(DataManagement, "<< tb_c.sa_a = %u", tbc_saa);
+ break;
+
+ case TestBTrait::kPropertyHandle_TbC_SaB:
+ bool next_tbc_sab;
+ err = aReader.Get(next_tbc_sab);
+ SuccessOrExit(err);
+ if (tbc_sab != next_tbc_sab)
+ {
+ WeaveLogDetail(DataManagement, "<< tb_c.sa_b is changed from %u to %u", tbc_sab, next_tbc_sab);
+ tbc_sab = next_tbc_sab;
+ }
+
+ WeaveLogDetail(DataManagement, "<< tb_c.sa_b = %u", tbc_sab);
+ break;
+
+ case TestBTrait::kPropertyHandle_TbC_SeaC:
+ char next_tbc_seac[10];
+ err = aReader.GetString(next_tbc_seac, 10);
+ SuccessOrExit(err);
+ if (strncmp(tbc_seac, next_tbc_seac, 10))
+ {
+ WeaveLogDetail(DataManagement, "<< tb_c.sea_c is changed from \"%s\" to \"%s\"", tbc_seac, next_tbc_seac);
+ memcpy(tbc_seac, next_tbc_seac, 10);
+ }
+
+ WeaveLogDetail(DataManagement, "<< tb_c.sea_c = \"%s\"", tbc_seac);
+ break;
+
+ default:
+ WeaveLogDetail(DataManagement, "<< TestBTrait UNKNOWN! %08x", aLeafHandle);
+ }
+
+exit:
+ return err;
+}
+
+#endif // WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT
+
void TestBTraitDataSource::Mutate()
{
Lock();
diff --git a/src/test-apps/MockSourceTraits.h b/src/test-apps/MockSourceTraits.h
index 9e802a1..6b401f3 100644
--- a/src/test-apps/MockSourceTraits.h
+++ b/src/test-apps/MockSourceTraits.h
@@ -195,18 +195,26 @@
uint32_t mTestCounter;
};
-class TestBTraitDataSource : public nl::Weave::Profiles::DataManagement::TraitDataSource
+class TestBTraitDataSource:
+#if WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT
+ public nl::Weave::Profiles::DataManagement::TraitUpdatableDataSource
+#else
+ public nl::Weave::Profiles::DataManagement::TraitDataSource
+#endif
{
public:
TestBTraitDataSource();
void Mutate();
private:
+#if WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT
+ WEAVE_ERROR SetLeafData(nl::Weave::Profiles::DataManagement::PropertyPathHandle aLeafHandle, nl::Weave::TLV::TLVReader &aReader) __OVERRIDE;
+#endif // WDM_ENABLE_PUBLISHER_UPDATE_SERVER_SUPPORT
WEAVE_ERROR GetLeafData(nl::Weave::Profiles::DataManagement::PropertyPathHandle aLeafHandle, uint64_t aTagToWrite, nl::Weave::TLV::TLVWriter &aWriter) __OVERRIDE;
WEAVE_ERROR GetNextDictionaryItemKey(nl::Weave::Profiles::DataManagement::PropertyPathHandle aDictionaryHandle, uintptr_t &aContext, nl::Weave::Profiles::DataManagement::PropertyDictionaryKey &aKey) __OVERRIDE;
- Schema::Nest::Test::Trait::TestATrait::EnumA taa;
- Schema::Nest::Test::Trait::TestCommon::CommonEnumA tab;
+ int32_t taa;
+ int32_t tab;
uint32_t tac;
uint32_t tad_saa;
bool tad_sab;
diff --git a/src/test-apps/TestWdmUpdateServer.cpp b/src/test-apps/TestWdmUpdateServer.cpp
new file mode 100644
index 0000000..eddb2de
--- /dev/null
+++ b/src/test-apps/TestWdmUpdateServer.cpp
@@ -0,0 +1,634 @@
+/*
+ *
+ * Copyright (c) 2020 Google LLC.
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * @file
+ * This file implements unit tests for the Wdm Update Server.
+ *
+ */
+
+#include "ToolCommon.h"
+
+#include <nlbyteorder.h>
+#include <nlunit-test.h>
+
+#include <Weave/Core/WeaveCore.h>
+
+#include <Weave/Profiles/data-management/Current/WdmManagedNamespace.h>
+#include <Weave/Profiles/data-management/DataManagement.h>
+
+#include <nest/test/trait/TestATrait.h>
+#include "MockSinkTraits.h"
+#include "MockSourceTraits.h"
+#include <new>
+#include <map>
+#include <set>
+#include <algorithm>
+#include <set>
+#include <string>
+#include <iterator>
+
+#if WEAVE_SYSTEM_CONFIG_USE_LWIP
+#include <lwip/init.h>
+#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP
+
+#define PRINT_TEST_NAME() printf("\n%s\n", __func__);
+
+using namespace nl;
+using namespace nl::Weave::TLV;
+using namespace nl::Weave::Profiles::DataManagement;
+using namespace Schema::Nest::Test::Trait;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// System/Platform definitions
+//
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+namespace nl {
+namespace Weave {
+namespace Profiles {
+namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) {
+
+SubscriptionEngine * SubscriptionEngine::GetInstance()
+{
+ static nl::Weave::Profiles::DataManagement::SubscriptionEngine gWdmSubscriptionEngine;
+ return &gWdmSubscriptionEngine;
+}
+
+namespace Platform {
+// For unit tests, a dummy critical section is sufficient.
+void CriticalSectionEnter()
+{
+ return;
+}
+
+void CriticalSectionExit()
+{
+ return;
+}
+
+} // namespace Platform
+
+} // namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current)
+} // namespace Profiles
+} // namespace Weave
+} // namespace nl
+
+#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING && WEAVE_CONFIG_ENABLE_WDM_UPDATE
+namespace nl {
+namespace Weave {
+namespace Profiles {
+namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) {
+
+class WdmUpdateServerTest
+{
+public:
+ WdmUpdateServerTest();
+ ~WdmUpdateServerTest() { }
+
+ // Tests
+ void SetupTest();
+ void TearDownTest();
+
+ void TestInitCleanup(nlTestSuite * inSuite, void * inContext);
+ void TestUpdateServerConditionalOneLeaf(nlTestSuite * inSuite, void * inContext);
+ void TestUpdateServerUnconditionalOneLeaf(nlTestSuite * inSuite, void * inContext);
+ void TestUpdateServerMixedConditionalOneLeaf(nlTestSuite * inSuite, void * inContext);
+ void TestUpdateServerConditionalTwoProperties(nlTestSuite * inSuite, void * inContext);
+ void TestUpdateServerUnconditionalTwoProperties(nlTestSuite * inSuite, void * inContext);
+ void TestUpdateServerMixedConditionalTwoProperties(nlTestSuite * inSuite, void * inContext);
+
+private:
+ // The encoder
+ UpdateEncoder mEncoder;
+ UpdateEncoder::Context mContext;
+
+ // These are here for convenience
+ PacketBuffer * mBuf;
+ TraitPath mTP;
+
+ //
+ // The state usually held by the SubscriptionClient
+ //
+
+ // The list of path to encode
+ TraitPathStore mPathList;
+ TraitPathStore::Record mStorage[10];
+
+ // The Trait instances
+ TestATraitUpdatableDataSink mTestATraitUpdatableDataSink0;
+ TestATraitDataSource mTestATraitDataSource0;
+ TestBTraitUpdatableDataSink mTestBTraitUpdatableDataSink;
+ TestBTraitDataSource mTestBTraitDataSource;
+ // The catalog
+ SingleResourceSinkTraitCatalog mSinkCatalog;
+ SingleResourceSinkTraitCatalog::CatalogItem mSinkCatalogStore[9];
+ SingleResourceSourceTraitCatalog mSourceCatalog;
+ SingleResourceSourceTraitCatalog::CatalogItem mSourceCatalogStore[9];
+ // The set of TraitDataHandles assigned by the catalog
+ // to the Trait instances
+ enum
+ {
+ kTestATraitSink0Index = 0,
+ kTestATraitSink1Index,
+ kTestBTraitSinkIndex,
+
+ kTestATraitSource0Index,
+ kTestATraitSource1Index,
+ kTestBTraitSourceIndex,
+ kMaxNumTraitHandles,
+ };
+ TraitDataHandle mTraitHandleSet[kMaxNumTraitHandles];
+
+ // Test support functions
+ void UpdateServerBasicTestBody(nlTestSuite * inSuite);
+ void InitEncoderContext(nlTestSuite * inSuite);
+ static void TLVPrettyPrinter(const char * aFormat, ...);
+ WEAVE_ERROR DebugPrettyPrint(PacketBuffer * apMsgBuf);
+
+ WEAVE_ERROR VerifyUpdateRequest(nlTestSuite * inSuite, PacketBuffer * aPayload, size_t aItemToStartFrom = 0);
+};
+
+WdmUpdateServerTest::WdmUpdateServerTest() :
+ mBuf(NULL), mSinkCatalog(ResourceIdentifier(ResourceIdentifier::SELF_NODE_ID), mSinkCatalogStore,
+ sizeof(mSinkCatalogStore) / sizeof(mSinkCatalogStore[0])),
+ mSourceCatalog(ResourceIdentifier(ResourceIdentifier::SELF_NODE_ID), mSourceCatalogStore,
+ sizeof(mSourceCatalogStore) / sizeof(mSourceCatalogStore[0]))
+{
+ mPathList.Init(mStorage, ArraySize(mStorage));
+
+ mSinkCatalog.Add(0, &mTestATraitUpdatableDataSink0, mTraitHandleSet[kTestATraitSink0Index]);
+ mSourceCatalog.Add(0, &mTestATraitDataSource0, mTraitHandleSet[kTestBTraitSourceIndex]);
+
+ mSinkCatalog.Add(0, &mTestBTraitUpdatableDataSink, mTraitHandleSet[kTestBTraitSinkIndex]);
+ mSourceCatalog.Add(0, &mTestBTraitDataSource, mTraitHandleSet[kTestBTraitSourceIndex]);
+
+ mTestATraitUpdatableDataSink0.SetUpdateEncoder(&mEncoder);
+}
+
+void WdmUpdateServerTest::SetupTest()
+{
+ mPathList.Clear();
+
+ mTestATraitUpdatableDataSink0.tai_map.clear();
+
+ for (int32_t i = 0; i < 10; i++)
+ {
+ mTestATraitUpdatableDataSink0.tai_map[i] = i + 100;
+ }
+}
+
+void WdmUpdateServerTest::TearDownTest()
+{
+ if (mBuf != NULL)
+ {
+ PacketBuffer::Free(mBuf);
+ mBuf = 0;
+ }
+}
+
+void WdmUpdateServerTest::InitEncoderContext(nlTestSuite * inSuite)
+{
+ if (NULL == mBuf)
+ {
+ mBuf = PacketBuffer::New(0);
+ NL_TEST_ASSERT(inSuite, mBuf != NULL);
+ }
+
+ mBuf->SetDataLength(0);
+
+ mContext.mBuf = mBuf;
+ mContext.mMaxPayloadSize = mBuf->AvailableDataLength();
+ mContext.mUpdateRequestIndex = 7;
+ mContext.mExpiryTimeMicroSecond = 0;
+ mContext.mItemInProgress = 0;
+ mContext.mNextDictionaryElementPathHandle = kNullPropertyPathHandle;
+ mContext.mInProgressUpdateList = &mPathList;
+ mContext.mDataSinkCatalog = &mSinkCatalog;
+}
+
+void WdmUpdateServerTest::TestInitCleanup(nlTestSuite * inSuite, void * inContext)
+{
+ PRINT_TEST_NAME();
+
+ NL_TEST_ASSERT(inSuite, 0 == mPathList.GetNumItems());
+}
+
+void WdmUpdateServerTest::TLVPrettyPrinter(const char * aFormat, ...)
+{
+ va_list args;
+
+ va_start(args, aFormat);
+
+ vprintf(aFormat, args);
+
+ va_end(args);
+}
+
+WEAVE_ERROR WdmUpdateServerTest::DebugPrettyPrint(PacketBuffer * apMsgBuf)
+{
+ WEAVE_ERROR err = WEAVE_NO_ERROR;
+ nl::Weave::TLV::TLVReader reader;
+ reader.Init(apMsgBuf);
+ err = reader.Next();
+ SuccessOrExit(err);
+ nl::Weave::TLV::Debug::Dump(reader, TLVPrettyPrinter);
+
+exit:
+ if (WEAVE_NO_ERROR != err)
+ {
+ WeaveLogProgress(DataManagement, "DebugPrettyPrint fails with err %d", err);
+ }
+
+ return err;
+}
+
+WEAVE_ERROR WdmUpdateServerTest::VerifyUpdateRequest(nlTestSuite * inSuite, PacketBuffer * aPayload, size_t aItemToStartFrom)
+{
+ WEAVE_ERROR err = WEAVE_NO_ERROR;
+ PacketBuffer * pBuf = NULL;
+ UpdateRequest::Parser update;
+ Weave::TLV::TLVReader reader;
+ bool isDataListPresent = false;
+ bool existFailure = false;
+ uint32_t numDataElements = 0;
+ uint32_t maxPayloadSize = 0;
+ SubscriptionEngine::StatusDataHandleElement * statusDataHandleList = NULL;
+ uint8_t * pBufEndAddr = NULL;
+ SubscriptionEngine::UpdateRequestDataElementAccessControlDelegate acDelegate(NULL);
+
+ err = SubscriptionEngine::GetInstance()->Init(&ExchangeMgr, this, NULL);
+ SuccessOrExit(err);
+
+ err = SubscriptionEngine::GetInstance()->EnablePublisher(NULL, &mSourceCatalog);
+ SuccessOrExit(err);
+
+ DebugPrettyPrint(aPayload);
+
+ reader.Init(aPayload);
+
+ err = reader.Next();
+ SuccessOrExit(err);
+
+ err = update.Init(reader);
+ SuccessOrExit(err);
+
+#if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK
+ err = update.CheckSchemaValidity();
+ SuccessOrExit(err);
+#endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK
+
+ {
+ DataList::Parser dataList;
+ err = update.GetDataList(&dataList);
+ if (WEAVE_NO_ERROR == err)
+ {
+ isDataListPresent = true;
+ }
+ else if (WEAVE_END_OF_TLV == err)
+ {
+ isDataListPresent = false;
+ err = WEAVE_NO_ERROR;
+ }
+ SuccessOrExit(err);
+
+ // re-initialize the reader to point to individual date element (reuse to save stack depth).
+ dataList.GetReader(&reader);
+ }
+
+ err = SubscriptionEngine::AllocateRightSizedBuffer(pBuf, WDM_MAX_UPDATE_RESPONSE_SIZE, WDM_MIN_UPDATE_RESPONSE_SIZE,
+ maxPayloadSize);
+ SuccessOrExit(err);
+
+ statusDataHandleList =
+ reinterpret_cast<SubscriptionEngine::StatusDataHandleElement *> WEAVE_SYSTEM_ALIGN_SIZE((size_t)(pBuf->Start()), 4);
+ pBufEndAddr = pBuf->Start() + maxPayloadSize;
+ err = SubscriptionEngine::InitializeStatusDataHandleList(reader, statusDataHandleList, numDataElements, pBufEndAddr);
+ SuccessOrExit(err);
+
+ err = SubscriptionEngine::ProcessUpdateRequestDataList(reader, statusDataHandleList, &mSourceCatalog, acDelegate, existFailure,
+ numDataElements);
+ SuccessOrExit(err);
+exit:
+ if (pBuf != NULL)
+ {
+ PacketBuffer::Free(pBuf);
+ pBuf = NULL;
+ }
+
+ return err;
+}
+
+void WdmUpdateServerTest::UpdateServerBasicTestBody(nlTestSuite * inSuite)
+{
+ WEAVE_ERROR err;
+
+ InitEncoderContext(inSuite);
+
+ err = mEncoder.EncodeRequest(mContext);
+ NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
+ NL_TEST_ASSERT(inSuite, mPathList.GetPathStoreSize() == mContext.mItemInProgress);
+ NL_TEST_ASSERT(inSuite, kNullPropertyPathHandle == mContext.mNextDictionaryElementPathHandle);
+
+ err = VerifyUpdateRequest(inSuite, mBuf);
+ NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
+}
+
+void WdmUpdateServerTest::TestUpdateServerConditionalOneLeaf(nlTestSuite * inSuite, void * inContext)
+{
+ WEAVE_ERROR err = WEAVE_NO_ERROR;
+
+ mTestATraitDataSource0.SetVersion(100);
+ mTestATraitUpdatableDataSink0.SetUpdateRequiredVersion(100);
+ mTestATraitUpdatableDataSink0.SetConditionalUpdate(true);
+
+ PRINT_TEST_NAME();
+
+ mTP = { mTraitHandleSet[kTestATraitSink0Index], CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaC) };
+
+ err = mPathList.AddItem(mTP);
+ NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
+
+ UpdateServerBasicTestBody(inSuite);
+
+ NL_TEST_ASSERT(inSuite, mTestATraitDataSource0.GetVersion() == 101);
+ mTestATraitUpdatableDataSink0.ClearUpdateRequiredVersion();
+ mTestATraitUpdatableDataSink0.SetConditionalUpdate(false);
+ NL_TEST_ASSERT(inSuite, 1 == mPathList.GetNumItems());
+}
+
+void WdmUpdateServerTest::TestUpdateServerUnconditionalOneLeaf(nlTestSuite * inSuite, void * inContext)
+{
+ WEAVE_ERROR err = WEAVE_NO_ERROR;
+ mTestATraitDataSource0.SetVersion(100);
+
+ PRINT_TEST_NAME();
+
+ mTP = { mTraitHandleSet[kTestATraitSink0Index], CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaC) };
+
+ err = mPathList.AddItem(mTP);
+ NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
+
+ UpdateServerBasicTestBody(inSuite);
+ NL_TEST_ASSERT(inSuite, mTestATraitDataSource0.GetVersion() == 101);
+
+ NL_TEST_ASSERT(inSuite, 1 == mPathList.GetNumItems());
+}
+
+void WdmUpdateServerTest::TestUpdateServerMixedConditionalOneLeaf(nlTestSuite * inSuite, void * inContext)
+{
+ WEAVE_ERROR err = WEAVE_NO_ERROR;
+ mTestATraitDataSource0.SetVersion(100);
+ mTestATraitUpdatableDataSink0.SetUpdateRequiredVersion(100);
+ mTestATraitUpdatableDataSink0.SetConditionalUpdate(true);
+
+ mTestBTraitDataSource.SetVersion(200);
+
+ PRINT_TEST_NAME();
+
+ mTP = { mTraitHandleSet[kTestATraitSink0Index], CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaC) };
+
+ err = mPathList.AddItem(mTP);
+ NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
+
+ mTP = { mTraitHandleSet[kTestBTraitSinkIndex], CreatePropertyPathHandle(TestBTrait::kPropertyHandle_TaC) };
+
+ err = mPathList.AddItem(mTP);
+ NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
+
+ UpdateServerBasicTestBody(inSuite);
+
+ NL_TEST_ASSERT(inSuite, mTestATraitDataSource0.GetVersion() == 101);
+ NL_TEST_ASSERT(inSuite, mTestBTraitDataSource.GetVersion() == 201);
+
+ mTestATraitUpdatableDataSink0.ClearUpdateRequiredVersion();
+ mTestATraitUpdatableDataSink0.SetConditionalUpdate(false);
+ NL_TEST_ASSERT(inSuite, 2 == mPathList.GetNumItems());
+}
+
+void WdmUpdateServerTest::TestUpdateServerConditionalTwoProperties(nlTestSuite * inSuite, void * inContext)
+{
+ WEAVE_ERROR err = WEAVE_NO_ERROR;
+ mTestATraitDataSource0.SetVersion(100);
+ mTestATraitUpdatableDataSink0.SetUpdateRequiredVersion(100);
+ mTestATraitUpdatableDataSink0.SetConditionalUpdate(true);
+
+ PRINT_TEST_NAME();
+
+ mTP = { mTraitHandleSet[kTestATraitSink0Index], CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaA) };
+
+ err = mPathList.AddItem(mTP);
+ NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
+
+ mTP.mPropertyPathHandle = CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaB);
+ err = mPathList.AddItem(mTP);
+ NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
+
+ UpdateServerBasicTestBody(inSuite);
+
+ NL_TEST_ASSERT(inSuite, mTestATraitDataSource0.GetVersion() == 101);
+
+ mTestATraitUpdatableDataSink0.ClearUpdateRequiredVersion();
+ mTestATraitUpdatableDataSink0.SetConditionalUpdate(false);
+
+ NL_TEST_ASSERT(inSuite, 2 == mPathList.GetNumItems());
+}
+
+void WdmUpdateServerTest::TestUpdateServerUnconditionalTwoProperties(nlTestSuite * inSuite, void * inContext)
+{
+ WEAVE_ERROR err = WEAVE_NO_ERROR;
+ mTestATraitDataSource0.SetVersion(100);
+
+ PRINT_TEST_NAME();
+
+ mTP = { mTraitHandleSet[kTestATraitSink0Index], CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaA) };
+
+ err = mPathList.AddItem(mTP);
+ NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
+
+ mTP.mPropertyPathHandle = CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaB);
+ err = mPathList.AddItem(mTP);
+ NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
+
+ UpdateServerBasicTestBody(inSuite);
+
+ NL_TEST_ASSERT(inSuite, mTestATraitDataSource0.GetVersion() == 101);
+
+ NL_TEST_ASSERT(inSuite, 2 == mPathList.GetNumItems());
+}
+
+void WdmUpdateServerTest::TestUpdateServerMixedConditionalTwoProperties(nlTestSuite * inSuite, void * inContext)
+{
+ WEAVE_ERROR err = WEAVE_NO_ERROR;
+ mTestATraitDataSource0.SetVersion(100);
+ mTestATraitUpdatableDataSink0.SetUpdateRequiredVersion(100);
+ mTestATraitUpdatableDataSink0.SetConditionalUpdate(true);
+
+ PRINT_TEST_NAME();
+
+ mTP = { mTraitHandleSet[kTestATraitSink0Index], CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaA) };
+
+ err = mPathList.AddItem(mTP);
+ NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
+
+ mTP.mPropertyPathHandle = CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaB);
+ err = mPathList.AddItem(mTP);
+ NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
+
+ mTP = { mTraitHandleSet[kTestBTraitSinkIndex], CreatePropertyPathHandle(TestBTrait::kPropertyHandle_TaC) };
+
+ err = mPathList.AddItem(mTP);
+ NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
+
+ mTP.mPropertyPathHandle = CreatePropertyPathHandle(TestATrait::kPropertyHandle_TaD_SaA);
+ err = mPathList.AddItem(mTP);
+ NL_TEST_ASSERT(inSuite, err == WEAVE_NO_ERROR);
+
+ UpdateServerBasicTestBody(inSuite);
+
+ NL_TEST_ASSERT(inSuite, mTestATraitDataSource0.GetVersion() == 101);
+ NL_TEST_ASSERT(inSuite, mTestBTraitDataSource.GetVersion() == 202);
+
+ mTestATraitUpdatableDataSink0.ClearUpdateRequiredVersion();
+ mTestATraitUpdatableDataSink0.SetConditionalUpdate(false);
+
+ NL_TEST_ASSERT(inSuite, 4 == mPathList.GetNumItems());
+}
+
+} // namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current)
+} // namespace Profiles
+} // namespace Weave
+} // namespace nl
+
+WdmUpdateServerTest gWdmUpdateServerTest;
+
+void WdmUpdateEncoderTest_InitCleanup(nlTestSuite * inSuite, void * inContext)
+{
+ gWdmUpdateServerTest.TestInitCleanup(inSuite, inContext);
+}
+
+void WdmUpdateServerTest_ConditionalOneLeaf(nlTestSuite * inSuite, void * inContext)
+{
+ gWdmUpdateServerTest.TestUpdateServerConditionalOneLeaf(inSuite, inContext);
+}
+
+void WdmUpdateServerTest_UnconditionalOneLeaf(nlTestSuite * inSuite, void * inContext)
+{
+ gWdmUpdateServerTest.TestUpdateServerUnconditionalOneLeaf(inSuite, inContext);
+}
+
+void WdmUpdateServerTest_MiexedConditionalOneLeaf(nlTestSuite * inSuite, void * inContext)
+{
+ gWdmUpdateServerTest.TestUpdateServerMixedConditionalOneLeaf(inSuite, inContext);
+}
+
+void WdmUpdateServerTest_ConditionalTwoProperties(nlTestSuite * inSuite, void * inContext)
+{
+ gWdmUpdateServerTest.TestUpdateServerConditionalTwoProperties(inSuite, inContext);
+}
+
+void WdmUpdateServerTest_UnconditionalTwoProperties(nlTestSuite * inSuite, void * inContext)
+{
+ gWdmUpdateServerTest.TestUpdateServerUnconditionalTwoProperties(inSuite, inContext);
+}
+
+void WdmUpdateServerTest_MixedConditionalTwoProperties(nlTestSuite * inSuite, void * inContext)
+{
+ gWdmUpdateServerTest.TestUpdateServerMixedConditionalTwoProperties(inSuite, inContext);
+}
+
+// Test Suite
+
+/**
+ * Test Suite that lists all the test functions.
+ */
+static const nlTest sTests[] = { NL_TEST_DEF("Init and cleanup", WdmUpdateEncoderTest_InitCleanup),
+ NL_TEST_DEF("Decode conditional one leaf", WdmUpdateServerTest_ConditionalOneLeaf),
+ NL_TEST_DEF("Decode unconditional one leaf", WdmUpdateServerTest_UnconditionalOneLeaf),
+ NL_TEST_DEF("Decode mixedconditional one leaf", WdmUpdateServerTest_MiexedConditionalOneLeaf),
+ NL_TEST_DEF("Decode conditional two properties", WdmUpdateServerTest_ConditionalTwoProperties),
+ NL_TEST_DEF("Decode unconditional two properties", WdmUpdateServerTest_UnconditionalTwoProperties),
+ NL_TEST_DEF("Decode mixedconditional two properties",
+ WdmUpdateServerTest_MixedConditionalTwoProperties),
+ NL_TEST_SENTINEL() };
+
+/**
+ * Set up the test suite.
+ */
+static int SuiteSetup(void * inContext)
+{
+ return 0;
+}
+
+/**
+ * Tear down the test suite.
+ */
+static int SuiteTeardown(void * inContext)
+{
+ return 0;
+}
+
+/**
+ * Set up each test.
+ */
+static int TestSetup(void * inContext)
+{
+ gWdmUpdateServerTest.SetupTest();
+
+ return 0;
+}
+
+/**
+ * Tear down each test.
+ */
+static int TestTeardown(void * inContext)
+{
+ gWdmUpdateServerTest.TearDownTest();
+
+ return 0;
+}
+
+/**
+ * Main
+ */
+int main(int argc, char * argv[])
+{
+#if WEAVE_SYSTEM_CONFIG_USE_LWIP
+ tcpip_init(NULL, NULL);
+#endif // WEAVE_SYSTEM_CONFIG_USE_LWIP
+
+ nlTestSuite theSuite = { "weave-WdmUpdateServer", &sTests[0], SuiteSetup, SuiteTeardown, TestSetup, TestTeardown };
+
+ // Generate machine-readable, comma-separated value (CSV) output.
+ nl_test_set_output_style(OUTPUT_CSV);
+
+ // Run test suit against one context
+ nlTestRunner(&theSuite, NULL);
+
+ return nlTestRunnerStats(&theSuite);
+}
+
+#else // WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING && WEAVE_CONFIG_ENABLE_WDM_UPDATE
+
+int main(int argc, char * argv[])
+{
+ return 0;
+}
+
+#endif // WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING && WEAVE_CONFIG_ENABLE_WDM_UPDATE