diff --git a/src/lib/profiles/data-management/Current/MessageDef.cpp b/src/lib/profiles/data-management/Current/MessageDef.cpp index bcc165b5..8b9595c9 100644 --- a/src/lib/profiles/data-management/Current/MessageDef.cpp +++ b/src/lib/profiles/data-management/Current/MessageDef.cpp @@ -62,6 +62,26 @@ static uint32_t gPrettyPrintingDepthLevel = 0; static char gLineBuffer[256]; static uint32_t gCurLineBufferSize = 0; +/** + * Simple object to checkpoint the pretty-print indentation level and make + * sure it is restored at the end of a block (even in case of early exit). + */ +class PrettyPrintCheckpoint +{ +public: + PrettyPrintCheckpoint() + { + mLevel = gPrettyPrintingDepthLevel; + } + ~PrettyPrintCheckpoint() + { + gPrettyPrintingDepthLevel = mLevel; + } +private: + uint32_t mLevel; +}; +#define PRETTY_PRINT_CHECKPOINT() PrettyPrintCheckpoint lPrettyPrintCheckpoint; + #define PRETTY_PRINT(fmt, ...) \ do \ { \ @@ -254,7 +274,12 @@ BuilderBase::BuilderBase() : void BuilderBase::ResetError() { - mError = WEAVE_NO_ERROR; + return ResetError(WEAVE_NO_ERROR); +} + +void BuilderBase::ResetError(WEAVE_ERROR aErr) +{ + mError = aErr; mOuterContainerType = nl::Weave::TLV::kTLVType_NotSpecified; } @@ -296,6 +321,26 @@ WEAVE_ERROR ListBuilderBase::Init(nl::Weave::TLV::TLVWriter * const apWriter, co return mError; } +/** + * Init the TLV array container with an anonymous tag. + * Required to implement arrays of arrays, and to test ListBuilderBase. + * There is no WDM message that has an array as the outermost container. + * + * @param[in] apWriter Pointer to the TLVWriter that is encoding the message. + * + * @return WEAVE_ERROR codes returned by Weave::TLV objects. + */ +WEAVE_ERROR ListBuilderBase::Init(nl::Weave::TLV::TLVWriter * const apWriter) +{ + mpWriter = apWriter; + mOuterContainerType = nl::Weave::TLV::kTLVType_NotSpecified; + mError = + mpWriter->StartContainer(nl::Weave::TLV::AnonymousTag, nl::Weave::TLV::kTLVType_Array, mOuterContainerType); + WeaveLogFunctError(mError); + + return mError; +} + WEAVE_ERROR Path::Parser::Init(const nl::Weave::TLV::TLVReader & aReader) { WEAVE_ERROR err = WEAVE_NO_ERROR; @@ -837,7 +882,18 @@ WEAVE_ERROR StatusElement::Parser::Init(const nl::Weave::TLV::TLVReader & aReade // make a copy of the reader here mReader.Init(aReader); - VerifyOrExit(nl::Weave::TLV::kTLVType_Structure == mReader.GetType(), err = WEAVE_ERROR_WRONG_TLV_TYPE); + switch (mReader.GetType()) + { + case nl::Weave::TLV::kTLVType_Structure: + mDeprecatedFormat = true; + break; + case nl::Weave::TLV::kTLVType_Array: + mDeprecatedFormat = false; + break; + default: + ExitNow(err = WEAVE_ERROR_WRONG_TLV_TYPE); + break; + } // This is just a dummy, as we're not going to exit this container ever nl::Weave::TLV::TLVType OuterContainerType; @@ -849,27 +905,87 @@ WEAVE_ERROR StatusElement::Parser::Init(const nl::Weave::TLV::TLVReader & aReade return err; } -// WEAVE_END_OF_TLV if there is no such element -// WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not a Path -WEAVE_ERROR StatusElement::Parser::GetProfileID(uint32_t * const apProfileID) const +/** + * Read the ProfileID and the StatusCode from the StatusElement. + * + * @param[out] apProfileID Pointer to the storage for the ProfileID + * @param[out] apStatusCode Pointer to the storage for the StatusCode + * + * @return WEAVE_ERROR codes returned by Weave::TLV objects. WEAVE_END_OF_TLV if either + * element is missing. WEAVE_ERROR_WRONG_TLV_TYPE if the elements are of the wrong + * type. + */ +WEAVE_ERROR StatusElement::Parser::GetProfileIDAndStatusCode(uint32_t * const apProfileID, + uint16_t *const apStatusCode) const { - return GetUnsignedInteger(kCsTag_ProfileID, apProfileID); -} + WEAVE_ERROR err = WEAVE_NO_ERROR; -// WEAVE_END_OF_TLV if there is no such element -// WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types -WEAVE_ERROR StatusElement::Parser::GetStatus(uint16_t * const apStatus) const -{ - return GetUnsignedInteger(kCsTag_Status, apStatus); + if (mDeprecatedFormat) + { + err = GetUnsignedInteger(kCsTag_ProfileID, apProfileID); + SuccessOrExit(err); + err = GetUnsignedInteger(kCsTag_Status, apStatusCode); + SuccessOrExit(err); + } + else + { + nl::Weave::TLV::TLVReader lReader; + lReader.Init(mReader); + + err = lReader.Next(); + SuccessOrExit(err); + VerifyOrExit(lReader.GetType() == nl::Weave::TLV::kTLVType_UnsignedInteger, err = WEAVE_ERROR_WRONG_TLV_TYPE); + + err = lReader.Get(*apProfileID); + SuccessOrExit(err); + + err = lReader.Next(); + SuccessOrExit(err); + VerifyOrExit(lReader.GetType() == nl::Weave::TLV::kTLVType_UnsignedInteger, err = WEAVE_ERROR_WRONG_TLV_TYPE); + + err = lReader.Get(*apStatusCode); + SuccessOrExit(err); + } +exit: + return err; } #if WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK -// Roughly verify the schema is right, including -// 1) all mandatory tags are present -// 2) all elements have expected data type -// 3) any tag can only appear once -// At the top level of the structure, unknown tags are ignored for foward compatibility +/** + * Roughly verify the schema is right, including + * 1) all mandatory tags are present + * 2) all elements have expected data type + * 3) any tag can only appear once + * At the top level of the structure, unknown tags are ignored for forward compatibility. + * + * @return WEAVE_NO_ERROR in case of success; WEAVE_ERROR codes + * returned by Weave::TLV objects otherwise. + */ WEAVE_ERROR StatusElement::Parser::CheckSchemaValidity(void) const +{ + WEAVE_ERROR err; + + if (mDeprecatedFormat) + { + err = CheckSchemaValidityDeprecated(); + } + else + { + err = CheckSchemaValidityCurrent(); + } + + return err; +} + +/** + * Check the StatusElement is a structure with two elements with the + * required context tags. + * This format was deprecated for a more compact array based one. + * + * @return WEAVE_NO_ERROR in case of success; WEAVE_ERROR codes + * returned by Weave::TLV objects otherwise. + */ +WEAVE_ERROR StatusElement::Parser::CheckSchemaValidityDeprecated(void) const { WEAVE_ERROR err = WEAVE_NO_ERROR; uint16_t TagPresenceMask = 0; @@ -946,6 +1062,92 @@ WEAVE_ERROR StatusElement::Parser::CheckSchemaValidity(void) const } } +exit: + WeaveLogFunctError(err); + + return err; +} + +/** + * Check the StatusElement is an array with at least two unsigned integers. + * The first one is the ProfileID, the second one is the StatusCode. + * + * @return WEAVE_NO_ERROR in case of success; WEAVE_ERROR codes + * returned by Weave::TLV objects otherwise. + */ +WEAVE_ERROR StatusElement::Parser::CheckSchemaValidityCurrent(void) const +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + uint16_t TagPresenceMask = 0; + nl::Weave::TLV::TLVReader reader; + uint32_t tagNum = 0; + + PRETTY_PRINT("\t{"); + + // make a copy of the reader + reader.Init(mReader); + + while (WEAVE_NO_ERROR == (err = reader.Next())) + { + // This is an array; all elements are anonymous. + VerifyOrExit(nl::Weave::TLV::AnonymousTag == reader.GetTag(), err = WEAVE_ERROR_INVALID_TLV_TAG); + + if (!(TagPresenceMask & (1 << kCsTag_ProfileID))) + { + // The first element has to be the ProfileID. + TagPresenceMask |= (1 << kCsTag_ProfileID); + VerifyOrExit(nl::Weave::TLV::kTLVType_UnsignedInteger == reader.GetType(), err = WEAVE_ERROR_WRONG_TLV_TYPE); + +#if WEAVE_DETAIL_LOGGING + { + uint32_t profileID; + err = reader.Get(profileID); + SuccessOrExit(err); + + PRETTY_PRINT("\t\tProfileID = 0x%" PRIx32 ",", profileID); + } +#endif // WEAVE_DETAIL_LOGGING + } + else if (!(TagPresenceMask & (1 << kCsTag_Status))) + { + // The second element has to be the StatusCode. + TagPresenceMask |= (1 << kCsTag_Status); + VerifyOrExit(nl::Weave::TLV::kTLVType_UnsignedInteger == reader.GetType(), err = WEAVE_ERROR_WRONG_TLV_TYPE); + +#if WEAVE_DETAIL_LOGGING + { + uint16_t status; + err = reader.Get(status); + SuccessOrExit(err); + + PRETTY_PRINT("\t\tStatus = 0x%" PRIx16 ",", status); + } +#endif // WEAVE_DETAIL_LOGGING + } + else + { + PRETTY_PRINT("\t\tUnknown tag num %" PRIu32, tagNum); + } + } + + PRETTY_PRINT("\t},"); + + // if we have exhausted this container + if (WEAVE_END_OF_TLV == err) + { + // check for required fields: + const uint16_t RequiredFields = (1 << kCsTag_Status) | (1 << kCsTag_ProfileID); + + if ((TagPresenceMask & RequiredFields) == RequiredFields) + { + err = WEAVE_NO_ERROR; + } + else + { + err = WEAVE_ERROR_WDM_MALFORMED_STATUS_ELEMENT; + } + } + exit: WeaveLogFunctError(err); @@ -953,6 +1155,48 @@ WEAVE_ERROR StatusElement::Parser::CheckSchemaValidity(void) const } #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK +WEAVE_ERROR StatusElement::Builder::Init(nl::Weave::TLV::TLVWriter * const apWriter) +{ + mDeprecatedFormat = false; + return ListBuilderBase::Init(apWriter); +} + +WEAVE_ERROR StatusElement::Builder::InitDeprecated(nl::Weave::TLV::TLVWriter * const apWriter) +{ + mDeprecatedFormat = true; + return InitAnonymousStructure(apWriter); +} + +StatusElement::Builder & StatusElement::Builder::ProfileIDAndStatus(const uint32_t aProfileID, const uint16_t aStatusCode) +{ + uint64_t tag = nl::Weave::TLV::AnonymousTag; + SuccessOrExit(mError); + + if (mDeprecatedFormat) + { + tag = nl::Weave::TLV::ContextTag(kCsTag_ProfileID); + } + mError = mpWriter->Put(tag, aProfileID); + + if (mDeprecatedFormat) + { + tag = nl::Weave::TLV::ContextTag(kCsTag_Status); + } + mError = mpWriter->Put(tag, aStatusCode); + +exit: + WeaveLogFunctError(mError); + + return *this; +} + +StatusElement::Builder & StatusElement::Builder::EndOfStatusElement(void) +{ + EndOfContainer(); + + return *this; +} + // aReader has to be on the element of DataElement WEAVE_ERROR DataElement::Parser::Init(const nl::Weave::TLV::TLVReader & aReader) { @@ -1407,7 +1651,7 @@ WEAVE_ERROR DataElement::Builder::Init(nl::Weave::TLV::TLVWriter * const apWrite Path::Builder & DataElement::Builder::CreatePathBuilder() { // skip if error has already been set - SuccessOrExit(mError); + VerifyOrExit(WEAVE_NO_ERROR == mError, mPathBuilder.ResetError(mError)); mError = mPathBuilder.Init(mpWriter, nl::Weave::TLV::ContextTag(kCsTag_Path)); WeaveLogFunctError(mError); @@ -1513,7 +1757,7 @@ WEAVE_ERROR PathList::Parser::CheckSchemaValidity(void) const Path::Builder & PathList::Builder::CreatePathBuilder() { // skip if error has already been set - SuccessOrExit(mError); + VerifyOrExit(WEAVE_NO_ERROR == mError, mPathBuilder.ResetError(mError)); mError = mPathBuilder.Init(mpWriter); WeaveLogFunctError(mError); @@ -1588,7 +1832,7 @@ WEAVE_ERROR DataList::Parser::CheckSchemaValidity(void) const DataElement::Builder & DataList::Builder::CreateDataElementBuilder() { // skip if error has already been set - SuccessOrExit(mError); + VerifyOrExit(WEAVE_NO_ERROR == mError, mDataElementBuilder.ResetError(mError)); mError = mDataElementBuilder.Init(mpWriter); WeaveLogFunctError(mError); @@ -2340,7 +2584,7 @@ WEAVE_ERROR EventList::Parser::CheckSchemaValidity(void) const Event::Builder & EventList::Builder::CreateEventBuilder() { // skip if error has already been set - SuccessOrExit(mError); + VerifyOrExit(WEAVE_NO_ERROR == mError, mEventBuilder.ResetError(mError)); mError = mEventBuilder.Init(mpWriter); WeaveLogFunctError(mError); @@ -2411,17 +2655,66 @@ WEAVE_ERROR VersionList::Parser::CheckSchemaValidity(void) const } #endif // WEAVE_CONFIG_DATA_MANAGEMENT_ENABLE_SCHEMA_CHECK -WEAVE_ERROR StatusList::Parser::GetStatusAndProfileID(uint32_t * const apProfileID, uint16_t * const apStatusCode) +/** + * Append a StatusElement to the list. + * + * @param[in] aProfileID ProfileID + * @param[in] aStatusCode StatusCode + * + * @return Reference to this builder. + */ +StatusList::Builder & StatusList::Builder::AddStatus(uint32_t aProfileID, uint16_t aStatusCode) +{ + StatusElement::Builder builder; + + SuccessOrExit(mError); + + if (mDeprecatedFormat) + { + builder.InitDeprecated(mpWriter); + } + else + { + builder.Init(mpWriter); + } + + builder.ProfileIDAndStatus(aProfileID, aStatusCode); + builder.EndOfStatusElement(); + + mError = builder.GetError(); + +exit: + WeaveLogFunctError(mError); + + return *this; +} + +StatusList::Builder & StatusList::Builder::EndOfStatusList() +{ + EndOfContainer(); + + return *this; +} + +/** + * Read the ProfileID and the StatusCode from the current StatusElement. + * + * @param[out] apProfileID Pointer to the storage for the ProfileID + * @param[out] apStatusCode Pointer to the storage for the StatusCode + * + * @return WEAVE_ERROR codes returned by Weave::TLV objects. WEAVE_END_OF_TLV if either + * element is missing. WEAVE_ERROR_WRONG_TLV_TYPE if the elements are of the wrong + * type. + */ +WEAVE_ERROR StatusList::Parser::GetProfileIDAndStatusCode(uint32_t * const apProfileID, uint16_t * const apStatusCode) { WEAVE_ERROR err = WEAVE_NO_ERROR; StatusElement::Parser statusElement; - err = statusElement.Init(mReader); - SuccessOrExit(err); - statusElement.GetStatus(apStatusCode); + err = statusElement.Init(mReader); SuccessOrExit(err); - statusElement.GetProfileID(apProfileID); + err = statusElement.GetProfileIDAndStatusCode(apProfileID, apStatusCode); SuccessOrExit(err); exit: @@ -2450,12 +2743,11 @@ WEAVE_ERROR StatusList::Parser::CheckSchemaValidity(void) const { // TODO: The spec says the StatusList should be an array of arrays, but in // the current implementation it's an array of structures. The array of - // array is less intuitive but more space efficient. - //WeaveLogDetail(DataManagement, "tag: 0x%" PRIx64 "; I want 0x%" PRIx64 "", reader.GetTag(), nl::Weave::TLV::AnonymousTag); - //WeaveLogDetail(DataManagement, "type: 0x%" PRIx32 "; I want 0x%" PRIx32 "", reader.GetType(), nl::Weave::TLV::kTLVType_Array); + // arrays is less intuitive but more space efficient. VerifyOrExit(nl::Weave::TLV::AnonymousTag == reader.GetTag(), err = WEAVE_ERROR_INVALID_TLV_TAG); - VerifyOrExit(nl::Weave::TLV::kTLVType_Structure == reader.GetType(), err = WEAVE_ERROR_WRONG_TLV_TYPE); + VerifyOrExit((nl::Weave::TLV::kTLVType_Structure == reader.GetType() || + nl::Weave::TLV::kTLVType_Array), err = WEAVE_ERROR_WRONG_TLV_TYPE); { StatusElement::Parser status; @@ -2473,11 +2765,9 @@ WEAVE_ERROR StatusList::Parser::CheckSchemaValidity(void) const // if we have exhausted this container if (WEAVE_END_OF_TLV == err) { - // if we have at least one data element - if (NumStatusElement > 0) - { - err = WEAVE_NO_ERROR; - } + // The StatusList of an UpdateResponse can be empty, in case the update + // was successful for all DataElements + err = WEAVE_NO_ERROR; } exit: @@ -2871,7 +3161,7 @@ SubscribeRequest::Builder & SubscribeRequest::Builder::SubscribeToAllEvents(cons EventList::Builder & SubscribeRequest::Builder::CreateLastObservedEventIdListBuilder() { // skip if error has already been set - SuccessOrExit(mError); + VerifyOrExit(WEAVE_NO_ERROR == mError, mEventListBuilder.ResetError(mError)); mError = mEventListBuilder.Init(mpWriter, kCsTag_LastObservedEventIdList); WeaveLogFunctError(mError); @@ -2885,7 +3175,7 @@ EventList::Builder & SubscribeRequest::Builder::CreateLastObservedEventIdListBui PathList::Builder & SubscribeRequest::Builder::CreatePathListBuilder() { // skip if error has already been set - SuccessOrExit(mError); + VerifyOrExit(WEAVE_NO_ERROR == mError, mPathListBuilder.ResetError(mError)); mError = mPathListBuilder.Init(mpWriter, kCsTag_PathList); WeaveLogFunctError(mError); @@ -2899,7 +3189,7 @@ PathList::Builder & SubscribeRequest::Builder::CreatePathListBuilder() VersionList::Builder & SubscribeRequest::Builder::CreateVersionListBuilder() { // skip if error has already been set - SuccessOrExit(mError); + VerifyOrExit(WEAVE_NO_ERROR == mError, mVersionListBuilder.ResetError(mError)); mError = mVersionListBuilder.Init(mpWriter, kCsTag_VersionList); WeaveLogFunctError(mError); @@ -3091,7 +3381,7 @@ SubscribeResponse::Builder & SubscribeResponse::Builder::PossibleLossOfEvents(co EventList::Builder & SubscribeResponse::Builder::CreateLastVendedEventIdListBuilder() { // skip if error has already been set - SuccessOrExit(mError); + VerifyOrExit(WEAVE_NO_ERROR == mError, mEventListBuilder.ResetError(mError)); mError = mEventListBuilder.Init(mpWriter, kCsTag_LastVendedEventIdList); WeaveLogFunctError(mError); @@ -3683,7 +3973,7 @@ WEAVE_ERROR CustomCommand::Builder::Init(nl::Weave::TLV::TLVWriter * const apWri Path::Builder & CustomCommand::Builder::CreatePathBuilder() { // skip if error has already been set - SuccessOrExit(mError); + VerifyOrExit(WEAVE_NO_ERROR == mError, mPathBuilder.ResetError(mError)); mError = mPathBuilder.Init(mpWriter, nl::Weave::TLV::ContextTag(kCsTag_Path)); WeaveLogFunctError(mError); @@ -4162,6 +4452,8 @@ WEAVE_ERROR UpdateResponse::Parser::CheckSchemaValidity(void) const reader.Init(mReader); + PRETTY_PRINT_CHECKPOINT(); + PRETTY_PRINT("{"); while (WEAVE_NO_ERROR == (err = reader.Next())) @@ -4181,7 +4473,7 @@ WEAVE_ERROR UpdateResponse::Parser::CheckSchemaValidity(void) const PRETTY_PRINT_INCDEPTH(); - statusList.CheckSchemaValidity(); + err = statusList.CheckSchemaValidity(); SuccessOrExit(err); PRETTY_PRINT_DECDEPTH(); @@ -4197,7 +4489,7 @@ WEAVE_ERROR UpdateResponse::Parser::CheckSchemaValidity(void) const PRETTY_PRINT_INCDEPTH(); - versionList.CheckSchemaValidity(); + err = versionList.CheckSchemaValidity(); SuccessOrExit(err); PRETTY_PRINT_DECDEPTH(); @@ -4241,6 +4533,60 @@ WEAVE_ERROR UpdateResponse::Parser::GetVersionList(VersionList::Parser * const a return apVersionList->InitIfPresent(mReader, kCsTag_VersionList); } +WEAVE_ERROR UpdateResponse::Builder::Init(nl::Weave::TLV::TLVWriter * const apWriter) +{ + return InitAnonymousStructure(apWriter); +} + +VersionList::Builder & UpdateResponse::Builder::CreateVersionListBuilder() +{ + // skip if error has already been set + VerifyOrExit(WEAVE_NO_ERROR == mError, mVersionListBuilder.ResetError(mError)); + + mError = mVersionListBuilder.Init(mpWriter, kCsTag_VersionList); + WeaveLogFunctError(mError); + +exit: + + // on error, mVersionListBuilder would be un-/partial initialized and cannot be used to write anything + return mVersionListBuilder; +} + +StatusList::Builder & UpdateResponse::Builder::CreateStatusListBuilder() +{ + // Check if the VersionList::Builder has failed, or has not been used yet + if (WEAVE_NO_ERROR == mError) + { + mError = mVersionListBuilder.GetError(); + } + + // skip if error has already been set + VerifyOrExit(WEAVE_NO_ERROR == mError, mStatusListBuilder.ResetError(mError)); + + mError = mStatusListBuilder.Init(mpWriter, kCsTag_StatusList); + WeaveLogFunctError(mError); + +exit: + + // on error, mStatusListBuilder would be un-/partial initialized and cannot be used to write anything + return mStatusListBuilder; +} + +UpdateResponse::Builder & UpdateResponse::Builder::EndOfResponse(void) +{ + // Check if the StatusList::Builder has failed, or has not been used + if (WEAVE_NO_ERROR == mError) + { + mError = mStatusListBuilder.GetError(); + } + SuccessOrExit(mError); + + EndOfContainer(); + +exit: + return *this; +} + }; // namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) }; // namespace Profiles }; // namespace Weave diff --git a/src/lib/profiles/data-management/Current/MessageDef.h b/src/lib/profiles/data-management/Current/MessageDef.h index 2ab22df4..b991cbe4 100644 --- a/src/lib/profiles/data-management/Current/MessageDef.h +++ b/src/lib/profiles/data-management/Current/MessageDef.h @@ -197,6 +197,7 @@ class BuilderBase { public: void ResetError(void); + void ResetError(WEAVE_ERROR aErr); WEAVE_ERROR GetError(void) const { return mError; }; nl::Weave::TLV::TLVWriter * GetWriter(void) { return mpWriter; }; @@ -224,6 +225,7 @@ class ListBuilderBase : public BuilderBase public: WEAVE_ERROR Init(nl::Weave::TLV::TLVWriter * const apWriter, const uint8_t aContextTagToUse); + WEAVE_ERROR Init(nl::Weave::TLV::TLVWriter * const apWriter); }; /** @@ -324,6 +326,7 @@ namespace StatusElement { }; class Parser; + class Builder; }; // namespace DataElement /** @@ -342,16 +345,36 @@ class StatusElement::Parser : public ParserBase // 3) any tag can only appear once // At the top level of the structure, unknown tags are ignored for foward compatibility WEAVE_ERROR CheckSchemaValidity(void) const; + WEAVE_ERROR CheckSchemaValidityDeprecated(void) const; + WEAVE_ERROR CheckSchemaValidityCurrent(void) const; // WEAVE_END_OF_TLV if there is no such element // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types - WEAVE_ERROR GetProfileID(uint32_t * apProfileID) const; + WEAVE_ERROR GetProfileIDAndStatusCode(uint32_t * apProfileID, uint16_t * aStatusCode) const; - // WEAVE_END_OF_TLV if there is no such element - // WEAVE_ERROR_WRONG_TLV_TYPE if there is such element but it's not any of the defined unsigned integer types - WEAVE_ERROR GetStatus(uint16_t * apStatus) const; +private: + bool mDeprecatedFormat; +}; + +/** + * @brief + * WDM Status Element encoder definition + */ +class StatusElement::Builder : public ListBuilderBase +{ +public: + WEAVE_ERROR Init(nl::Weave::TLV::TLVWriter * const apWriter); + WEAVE_ERROR InitDeprecated(nl::Weave::TLV::TLVWriter * const apWriter); + + StatusElement::Builder & ProfileIDAndStatus(const uint32_t aProfileID, const uint16_t aStatusCode); + + StatusElement::Builder & EndOfStatusElement(void); + +private: + bool mDeprecatedFormat; }; + /** * @brief * WDM Data Element definition @@ -661,14 +684,35 @@ class VersionList::Builder : public ListBuilderBase namespace StatusList { class Parser; + class Builder; }; // namespace StatusList +/** + * StatusList builder. + * Supports both the current and the deprecated StatusList format. + */ +class StatusList::Builder : public ListBuilderBase +{ +public: + + /** + * Write the list as an array of structures, instead of an array of arrays. + */ + void UseDeprecatedFormat() { this->mDeprecatedFormat = true; } + + StatusList::Builder & AddStatus(uint32_t aProfileID, uint16_t aStatusCode); + + StatusList::Builder & EndOfStatusList(void); +private: + bool mDeprecatedFormat; + +}; + class StatusList::Parser : public ListParserBase { public: WEAVE_ERROR CheckSchemaValidity(void) const; - WEAVE_ERROR GetVersion(uint64_t * const apVersion); - WEAVE_ERROR GetStatusAndProfileID(uint32_t * const apProfileID, uint16_t * const apStatusCode); + WEAVE_ERROR GetProfileIDAndStatusCode(uint32_t * const apProfileID, uint16_t * const apStatusCode); }; namespace ViewRequest { @@ -1477,6 +1521,41 @@ namespace UpdateResponse { }; class Parser; + class Builder; +}; + +/** + * @brief + * WDM Update Response encoder definition + */ +class UpdateResponse::Builder : public BuilderBase +{ +public: + WEAVE_ERROR Init(nl::Weave::TLV::TLVWriter * const apWriter); + /** + * @brief Create the VersionList::Builder + * + * @return A reference to a VersionList::Builder + */ + VersionList::Builder & CreateVersionListBuilder(void); + + /** + * @brief Create the StatusList::Builder + * + * @return A reference to a StatusList::Builder + */ + StatusList::Builder & CreateStatusListBuilder(void); + + /** + * @brief Mark the end of this message + * + * @return A reference to *this + */ + UpdateResponse::Builder & EndOfResponse(void); + +private: + VersionList::Builder mVersionListBuilder; + StatusList::Builder mStatusListBuilder; }; class UpdateResponse::Parser : public ParserBase diff --git a/src/lib/profiles/data-management/Current/SubscriptionClient.cpp b/src/lib/profiles/data-management/Current/SubscriptionClient.cpp index 4b46c3de..986b8b3e 100644 --- a/src/lib/profiles/data-management/Current/SubscriptionClient.cpp +++ b/src/lib/profiles/data-management/Current/SubscriptionClient.cpp @@ -2490,7 +2490,7 @@ void SubscriptionClient::OnUpdateConfirm(WEAVE_ERROR aReason, nl::Weave::Profile { err = statusList.Next(); - err = statusList.GetStatusAndProfileID(&profileID, &statusCode); + err = statusList.GetProfileIDAndStatusCode(&profileID, &statusCode); SuccessOrExit(err); } diff --git a/src/system/SystemObject.h b/src/system/SystemObject.h index 9aee9128..00e03773 100644 --- a/src/system/SystemObject.h +++ b/src/system/SystemObject.h @@ -309,7 +309,7 @@ inline void ObjectPool::GetNumObjectsInUse(unsigned int aStartIndex, unsig aNumInUse += count; } -#endif +#endif // WEAVE_SYSTEM_CONFIG_PROVIDE_STATISTICS template diff --git a/src/test-apps/Makefile.am b/src/test-apps/Makefile.am index 75b9c328..800cf873 100644 --- a/src/test-apps/Makefile.am +++ b/src/test-apps/Makefile.am @@ -342,6 +342,7 @@ check_PROGRAMS += \ TestTDM \ TestPathStore \ TestWdmUpdateEncoder \ + TestWdmUpdateResponse \ $(NULL) if WEAVE_BUILD_WARM @@ -450,6 +451,7 @@ local_test_programs += \ TestWarm \ TestPathStore \ TestWdmUpdateEncoder \ + TestWdmUpdateResponse \ $(NULL) endif @@ -1212,6 +1214,13 @@ TestWdmUpdateEncoder_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_s TestWdmUpdateEncoder_LDFLAGS = $(AM_CPPFLAGS) TestWdmUpdateEncoder_LDADD = libWeaveTestCommon.a $(COMMON_LDADD) +TestWdmUpdateResponse_SOURCES = TestWdmUpdateResponse.cpp \ + TestPersistedStorageImplementation.cpp + +TestWdmUpdateResponse_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/test-apps/schema +TestWdmUpdateResponse_LDFLAGS = $(AM_CPPFLAGS) +TestWdmUpdateResponse_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/Makefile.in b/src/test-apps/Makefile.in index 14d5b1ed..b0891a37 100644 --- a/src/test-apps/Makefile.in +++ b/src/test-apps/Makefile.in @@ -197,6 +197,7 @@ target_triplet = @target@ @WEAVE_BUILD_TESTS_TRUE@ $(am__EXEEXT_1) TestTDM$(EXEEXT) \ @WEAVE_BUILD_TESTS_TRUE@ TestPathStore$(EXEEXT) \ @WEAVE_BUILD_TESTS_TRUE@ TestWdmUpdateEncoder$(EXEEXT) \ +@WEAVE_BUILD_TESTS_TRUE@ TestWdmUpdateResponse$(EXEEXT) \ @WEAVE_BUILD_TESTS_TRUE@ $(am__EXEEXT_2) $(am__EXEEXT_3) @HAVE_CXX11_TRUE@@WEAVE_BUILD_TESTS_TRUE@am__append_7 = \ @HAVE_CXX11_TRUE@@WEAVE_BUILD_TESTS_TRUE@ TestTDM \ @@ -227,6 +228,7 @@ target_triplet = @target@ @WEAVE_BUILD_TESTS_TRUE@@WEAVE_BUILD_WARM_TRUE@ TestWarm \ @WEAVE_BUILD_TESTS_TRUE@@WEAVE_BUILD_WARM_TRUE@ TestPathStore \ @WEAVE_BUILD_TESTS_TRUE@@WEAVE_BUILD_WARM_TRUE@ TestWdmUpdateEncoder \ +@WEAVE_BUILD_TESTS_TRUE@@WEAVE_BUILD_WARM_TRUE@ TestWdmUpdateResponse \ @WEAVE_BUILD_TESTS_TRUE@@WEAVE_BUILD_WARM_TRUE@ $(NULL) @WEAVE_BUILD_LEGACY_WDM_TRUE@@WEAVE_BUILD_TESTS_TRUE@am__append_14 = \ @@ -709,7 +711,8 @@ am__installdirs = "$(DESTDIR)$(libexecdir)" @HAVE_CXX11_TRUE@@WEAVE_BUILD_TESTS_TRUE@ TestWDM$(EXEEXT) @WEAVE_BUILD_TESTS_TRUE@@WEAVE_BUILD_WARM_TRUE@am__EXEEXT_6 = TestWarm$(EXEEXT) \ @WEAVE_BUILD_TESTS_TRUE@@WEAVE_BUILD_WARM_TRUE@ TestPathStore$(EXEEXT) \ -@WEAVE_BUILD_TESTS_TRUE@@WEAVE_BUILD_WARM_TRUE@ TestWdmUpdateEncoder$(EXEEXT) +@WEAVE_BUILD_TESTS_TRUE@@WEAVE_BUILD_WARM_TRUE@ TestWdmUpdateEncoder$(EXEEXT) \ +@WEAVE_BUILD_TESTS_TRUE@@WEAVE_BUILD_WARM_TRUE@ TestWdmUpdateResponse$(EXEEXT) @WEAVE_BUILD_TESTS_TRUE@am__EXEEXT_7 = GenerateEventLog$(EXEEXT) \ @WEAVE_BUILD_TESTS_TRUE@ TestASN1$(EXEEXT) TestAppKeys$(EXEEXT) \ @WEAVE_BUILD_TESTS_TRUE@ TestArgParser$(EXEEXT) \ @@ -1374,6 +1377,18 @@ TestWdmUpdateEncoder_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ $(AM_CXXFLAGS) $(CXXFLAGS) $(TestWdmUpdateEncoder_LDFLAGS) \ $(LDFLAGS) -o $@ +am__TestWdmUpdateResponse_SOURCES_DIST = TestWdmUpdateResponse.cpp \ + TestPersistedStorageImplementation.cpp +@WEAVE_BUILD_TESTS_TRUE@am_TestWdmUpdateResponse_OBJECTS = TestWdmUpdateResponse-TestWdmUpdateResponse.$(OBJEXT) \ +@WEAVE_BUILD_TESTS_TRUE@ TestWdmUpdateResponse-TestPersistedStorageImplementation.$(OBJEXT) +TestWdmUpdateResponse_OBJECTS = $(am_TestWdmUpdateResponse_OBJECTS) +@WEAVE_BUILD_TESTS_TRUE@TestWdmUpdateResponse_DEPENDENCIES = \ +@WEAVE_BUILD_TESTS_TRUE@ libWeaveTestCommon.a \ +@WEAVE_BUILD_TESTS_TRUE@ $(am__DEPENDENCIES_6) +TestWdmUpdateResponse_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \ + $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \ + $(AM_CXXFLAGS) $(CXXFLAGS) $(TestWdmUpdateResponse_LDFLAGS) \ + $(LDFLAGS) -o $@ am__TestWeaveCert_SOURCES_DIST = TestWeaveCert.cpp \ TestWeaveCertData.cpp @WEAVE_BUILD_TESTS_TRUE@am_TestWeaveCert_OBJECTS = \ @@ -1776,7 +1791,8 @@ SOURCES = $(libMockBleApplicationDelegate_a_SOURCES) \ $(TestWarm_SOURCES) $(TestWdmNext_SOURCES) \ $(TestWdmOneWayCommandReceiver_SOURCES) \ $(TestWdmOneWayCommandSender_SOURCES) \ - $(TestWdmUpdateEncoder_SOURCES) $(TestWeaveCert_SOURCES) \ + $(TestWdmUpdateEncoder_SOURCES) \ + $(TestWdmUpdateResponse_SOURCES) $(TestWeaveCert_SOURCES) \ $(TestWeaveEncoding_SOURCES) $(TestWeaveFabricState_SOURCES) \ $(TestWeaveMessageLayer_SOURCES) \ $(TestWeaveProvBundle_SOURCES) $(TestWeaveSignature_SOURCES) \ @@ -1846,6 +1862,7 @@ DIST_SOURCES = $(am__libMockBleApplicationDelegate_a_SOURCES_DIST) \ $(am__TestWdmOneWayCommandReceiver_SOURCES_DIST) \ $(am__TestWdmOneWayCommandSender_SOURCES_DIST) \ $(am__TestWdmUpdateEncoder_SOURCES_DIST) \ + $(am__TestWdmUpdateResponse_SOURCES_DIST) \ $(am__TestWeaveCert_SOURCES_DIST) \ $(am__TestWeaveEncoding_SOURCES_DIST) \ $(am__TestWeaveFabricState_SOURCES_DIST) \ @@ -3096,6 +3113,12 @@ EXTRA_DIST = \ @WEAVE_BUILD_TESTS_TRUE@TestWdmUpdateEncoder_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/test-apps/schema @WEAVE_BUILD_TESTS_TRUE@TestWdmUpdateEncoder_LDFLAGS = $(AM_CPPFLAGS) @WEAVE_BUILD_TESTS_TRUE@TestWdmUpdateEncoder_LDADD = libWeaveTestCommon.a $(COMMON_LDADD) +@WEAVE_BUILD_TESTS_TRUE@TestWdmUpdateResponse_SOURCES = TestWdmUpdateResponse.cpp \ +@WEAVE_BUILD_TESTS_TRUE@ TestPersistedStorageImplementation.cpp + +@WEAVE_BUILD_TESTS_TRUE@TestWdmUpdateResponse_CPPFLAGS = $(AM_CPPFLAGS) -I$(top_srcdir)/src/test-apps/schema +@WEAVE_BUILD_TESTS_TRUE@TestWdmUpdateResponse_LDFLAGS = $(AM_CPPFLAGS) +@WEAVE_BUILD_TESTS_TRUE@TestWdmUpdateResponse_LDADD = libWeaveTestCommon.a $(COMMON_LDADD) @WEAVE_BUILD_TESTS_TRUE@TestFabricStateDelegate_SOURCES = TestFabricStateDelegate.cpp TestPersistedStorageImplementation.cpp @WEAVE_BUILD_TESTS_TRUE@TestFabricStateDelegate_LDFLAGS = $(AM_CPPFLAGS) @WEAVE_BUILD_TESTS_TRUE@TestFabricStateDelegate_LDADD = libWeaveTestCommon.a $(COMMON_LDADD) @@ -3859,6 +3882,10 @@ TestWdmUpdateEncoder$(EXEEXT): $(TestWdmUpdateEncoder_OBJECTS) $(TestWdmUpdateEn @rm -f TestWdmUpdateEncoder$(EXEEXT) $(AM_V_CXXLD)$(TestWdmUpdateEncoder_LINK) $(TestWdmUpdateEncoder_OBJECTS) $(TestWdmUpdateEncoder_LDADD) $(LIBS) +TestWdmUpdateResponse$(EXEEXT): $(TestWdmUpdateResponse_OBJECTS) $(TestWdmUpdateResponse_DEPENDENCIES) $(EXTRA_TestWdmUpdateResponse_DEPENDENCIES) + @rm -f TestWdmUpdateResponse$(EXEEXT) + $(AM_V_CXXLD)$(TestWdmUpdateResponse_LINK) $(TestWdmUpdateResponse_OBJECTS) $(TestWdmUpdateResponse_LDADD) $(LIBS) + TestWeaveCert$(EXEEXT): $(TestWeaveCert_OBJECTS) $(TestWeaveCert_DEPENDENCIES) $(EXTRA_TestWeaveCert_DEPENDENCIES) @rm -f TestWeaveCert$(EXEEXT) $(AM_V_CXXLD)$(CXXLINK) $(TestWeaveCert_OBJECTS) $(TestWeaveCert_LDADD) $(LIBS) @@ -4095,6 +4122,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestWdmUpdateEncoder-MockWdmNodeOptions.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestWdmUpdateEncoder-TestPersistedStorageImplementation.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestWdmUpdateEncoder-TestWdmUpdateEncoder.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestWdmUpdateResponse-TestPersistedStorageImplementation.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestWdmUpdateResponse-TestWdmUpdateResponse.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestWeaveCert.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestWeaveCertData.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/TestWeaveEncoding.Po@am__quote@ @@ -5247,6 +5276,34 @@ TestWdmUpdateEncoder-TestPersistedStorageImplementation.obj: TestPersistedStorag @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TestWdmUpdateEncoder_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o TestWdmUpdateEncoder-TestPersistedStorageImplementation.obj `if test -f 'TestPersistedStorageImplementation.cpp'; then $(CYGPATH_W) 'TestPersistedStorageImplementation.cpp'; else $(CYGPATH_W) '$(srcdir)/TestPersistedStorageImplementation.cpp'; fi` +TestWdmUpdateResponse-TestWdmUpdateResponse.o: TestWdmUpdateResponse.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TestWdmUpdateResponse_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT TestWdmUpdateResponse-TestWdmUpdateResponse.o -MD -MP -MF $(DEPDIR)/TestWdmUpdateResponse-TestWdmUpdateResponse.Tpo -c -o TestWdmUpdateResponse-TestWdmUpdateResponse.o `test -f 'TestWdmUpdateResponse.cpp' || echo '$(srcdir)/'`TestWdmUpdateResponse.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/TestWdmUpdateResponse-TestWdmUpdateResponse.Tpo $(DEPDIR)/TestWdmUpdateResponse-TestWdmUpdateResponse.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TestWdmUpdateResponse.cpp' object='TestWdmUpdateResponse-TestWdmUpdateResponse.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TestWdmUpdateResponse_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o TestWdmUpdateResponse-TestWdmUpdateResponse.o `test -f 'TestWdmUpdateResponse.cpp' || echo '$(srcdir)/'`TestWdmUpdateResponse.cpp + +TestWdmUpdateResponse-TestWdmUpdateResponse.obj: TestWdmUpdateResponse.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TestWdmUpdateResponse_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT TestWdmUpdateResponse-TestWdmUpdateResponse.obj -MD -MP -MF $(DEPDIR)/TestWdmUpdateResponse-TestWdmUpdateResponse.Tpo -c -o TestWdmUpdateResponse-TestWdmUpdateResponse.obj `if test -f 'TestWdmUpdateResponse.cpp'; then $(CYGPATH_W) 'TestWdmUpdateResponse.cpp'; else $(CYGPATH_W) '$(srcdir)/TestWdmUpdateResponse.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/TestWdmUpdateResponse-TestWdmUpdateResponse.Tpo $(DEPDIR)/TestWdmUpdateResponse-TestWdmUpdateResponse.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TestWdmUpdateResponse.cpp' object='TestWdmUpdateResponse-TestWdmUpdateResponse.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TestWdmUpdateResponse_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o TestWdmUpdateResponse-TestWdmUpdateResponse.obj `if test -f 'TestWdmUpdateResponse.cpp'; then $(CYGPATH_W) 'TestWdmUpdateResponse.cpp'; else $(CYGPATH_W) '$(srcdir)/TestWdmUpdateResponse.cpp'; fi` + +TestWdmUpdateResponse-TestPersistedStorageImplementation.o: TestPersistedStorageImplementation.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TestWdmUpdateResponse_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT TestWdmUpdateResponse-TestPersistedStorageImplementation.o -MD -MP -MF $(DEPDIR)/TestWdmUpdateResponse-TestPersistedStorageImplementation.Tpo -c -o TestWdmUpdateResponse-TestPersistedStorageImplementation.o `test -f 'TestPersistedStorageImplementation.cpp' || echo '$(srcdir)/'`TestPersistedStorageImplementation.cpp +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/TestWdmUpdateResponse-TestPersistedStorageImplementation.Tpo $(DEPDIR)/TestWdmUpdateResponse-TestPersistedStorageImplementation.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TestPersistedStorageImplementation.cpp' object='TestWdmUpdateResponse-TestPersistedStorageImplementation.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TestWdmUpdateResponse_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o TestWdmUpdateResponse-TestPersistedStorageImplementation.o `test -f 'TestPersistedStorageImplementation.cpp' || echo '$(srcdir)/'`TestPersistedStorageImplementation.cpp + +TestWdmUpdateResponse-TestPersistedStorageImplementation.obj: TestPersistedStorageImplementation.cpp +@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TestWdmUpdateResponse_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT TestWdmUpdateResponse-TestPersistedStorageImplementation.obj -MD -MP -MF $(DEPDIR)/TestWdmUpdateResponse-TestPersistedStorageImplementation.Tpo -c -o TestWdmUpdateResponse-TestPersistedStorageImplementation.obj `if test -f 'TestPersistedStorageImplementation.cpp'; then $(CYGPATH_W) 'TestPersistedStorageImplementation.cpp'; else $(CYGPATH_W) '$(srcdir)/TestPersistedStorageImplementation.cpp'; fi` +@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/TestWdmUpdateResponse-TestPersistedStorageImplementation.Tpo $(DEPDIR)/TestWdmUpdateResponse-TestPersistedStorageImplementation.Po +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='TestPersistedStorageImplementation.cpp' object='TestWdmUpdateResponse-TestPersistedStorageImplementation.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(TestWdmUpdateResponse_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o TestWdmUpdateResponse-TestPersistedStorageImplementation.obj `if test -f 'TestPersistedStorageImplementation.cpp'; then $(CYGPATH_W) 'TestPersistedStorageImplementation.cpp'; else $(CYGPATH_W) '$(srcdir)/TestPersistedStorageImplementation.cpp'; fi` + mock_device-mock-device.o: mock-device.cpp @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(mock_device_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT mock_device-mock-device.o -MD -MP -MF $(DEPDIR)/mock_device-mock-device.Tpo -c -o mock_device-mock-device.o `test -f 'mock-device.cpp' || echo '$(srcdir)/'`mock-device.cpp @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/mock_device-mock-device.Tpo $(DEPDIR)/mock_device-mock-device.Po @@ -6279,6 +6336,13 @@ TestWdmUpdateEncoder.log: TestWdmUpdateEncoder$(EXEEXT) --log-file $$b.log --trs-file $$b.trs \ $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ "$$tst" $(AM_TESTS_FD_REDIRECT) +TestWdmUpdateResponse.log: TestWdmUpdateResponse$(EXEEXT) + @p='TestWdmUpdateResponse$(EXEEXT)'; \ + b='TestWdmUpdateResponse'; \ + $(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \ + --log-file $$b.log --trs-file $$b.trs \ + $(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \ + "$$tst" $(AM_TESTS_FD_REDIRECT) TestWarm.log: TestWarm$(EXEEXT) @p='TestWarm$(EXEEXT)'; \ b='TestWarm'; \ @@ -8298,8 +8362,8 @@ maintainer-clean-generic: @WEAVE_BUILD_COVERAGE_FALSE@clean-local: @WEAVE_BUILD_COVERAGE_REPORTS_FALSE@clean-local: @WEAVE_BUILD_TESTS_FALSE@clean-local: -@WEAVE_BUILD_TESTS_FALSE@uninstall-local: @WEAVE_BUILD_TESTS_FALSE@install-exec-local: +@WEAVE_BUILD_TESTS_FALSE@uninstall-local: clean: clean-am clean-am: clean-checkPROGRAMS clean-generic clean-libexecPROGRAMS \ diff --git a/src/test-apps/TestSystemObject.cpp b/src/test-apps/TestSystemObject.cpp index eef5f0df..0c05395f 100644 --- a/src/test-apps/TestSystemObject.cpp +++ b/src/test-apps/TestSystemObject.cpp @@ -523,4 +523,3 @@ int main(int argc, char *argv[]) return nlTestRunnerStats(&kTheSuite); } - diff --git a/src/test-apps/TestWdmUpdateResponse.cpp b/src/test-apps/TestWdmUpdateResponse.cpp new file mode 100644 index 00000000..e741e7e5 --- /dev/null +++ b/src/test-apps/TestWdmUpdateResponse.cpp @@ -0,0 +1,640 @@ +/* + * + * Copyright (c) 2018 Nest Labs, Inc. + * 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 encoding and parsing of + * of WDM UpdateResponse payloads. + * + */ + +#include "ToolCommon.h" + +#include +#include + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#if WEAVE_SYSTEM_CONFIG_USE_LWIP +#include +#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; + + +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// System/Platform definitions +// +/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + +namespace nl { +namespace Weave { +namespace Profiles { +namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) { + +SubscriptionEngine * SubscriptionEngine::GetInstance() +{ + static SubscriptionEngine *gSubscriptionEngine = NULL; + return gSubscriptionEngine; +} + +namespace Platform { + // For unit tests, a dummy critical section is sufficient. + void CriticalSectionEnter() + { + return; + } + + void CriticalSectionExit() + { + return; + } + +} // Platform + +} // WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) +} // Profiles +} // Weave +} // nl + +#if WEAVE_CONFIG_ENABLE_RELIABLE_MESSAGING && WEAVE_CONFIG_ENABLE_WDM_UPDATE +namespace nl { +namespace Weave { +namespace Profiles { +namespace WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) { + +class WdmUpdateResponseTest { + public: + WdmUpdateResponseTest() { } + ~WdmUpdateResponseTest() { } + + // Tests + void SetupTest(); + void TearDownTest(); + + void TestVersionList(nlTestSuite *inSuite, void *inContext); + void TestStatusList(nlTestSuite *inSuite, void *inContext, bool aUseDeprecatedFormat); + void TestStatusList(nlTestSuite *inSuite, void *inContext); + void TestDeprecatedStatusList(nlTestSuite *inSuite, void *inContext); + void TestUpdateResponse(nlTestSuite *inSuite, void *inContext); + void TestCompactResponse(nlTestSuite *inSuite, void *inContext); + + private: + // Objects under test + VersionList::Builder mVersionListBuilder; + VersionList::Parser mVersionListParser; + StatusList::Builder mStatusListBuilder; + StatusList::Parser mStatusListParser; + UpdateResponse::Builder mUpdateResponseBuilder; + UpdateResponse::Parser mUpdateResponseParser; + + + // These are here for convenience + uint8_t mBuf[1024]; + Weave::TLV::TLVWriter mWriter; + Weave::TLV::TLVReader mReader; + + // Test support functions + static WEAVE_ERROR WriteVersionList(VersionList::Builder &aBuilder); + static WEAVE_ERROR WriteStatusList(StatusList::Builder &aBuilder); + static void VerifyVersionList(nlTestSuite *inSuite, VersionList::Parser &aParser); + static void VerifyStatusList(nlTestSuite *inSuite, StatusList::Parser &aParser); +}; + +void WdmUpdateResponseTest::SetupTest() +{ + memset(mBuf, 0, sizeof(mBuf)); +} + +void WdmUpdateResponseTest::TearDownTest() +{ +} + +WEAVE_ERROR WdmUpdateResponseTest::WriteVersionList(VersionList::Builder &aBuilder) +{ + uint64_t version; + + version = 1; + aBuilder.AddVersion(version); + version = 2; + aBuilder.AddVersion(version); + + aBuilder.EndOfVersionList(); + + return aBuilder.GetError(); +} + +WEAVE_ERROR WdmUpdateResponseTest::WriteStatusList(StatusList::Builder &aBuilder) +{ + aBuilder.AddStatus(0x1, 0x2); + + aBuilder.AddStatus(0x1, 0x3); + + aBuilder.EndOfStatusList(); + + return aBuilder.GetError(); +} + +void WdmUpdateResponseTest::VerifyVersionList(nlTestSuite *inSuite, VersionList::Parser &aParser) +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + uint64_t version; + + err = aParser.Next(); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + err = aParser.GetVersion(&version); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + NL_TEST_ASSERT(inSuite, 1 == version); + + err = aParser.Next(); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + err = aParser.GetVersion(&version); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + NL_TEST_ASSERT(inSuite, 2 == version); + + err = aParser.Next(); + NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV); +} + +void WdmUpdateResponseTest::VerifyStatusList(nlTestSuite *inSuite, StatusList::Parser &aParser) +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + uint32_t profile; + uint16_t statusCode; + + err = aParser.Next(); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + err = aParser.GetProfileIDAndStatusCode(&profile, &statusCode); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + NL_TEST_ASSERT(inSuite, 1 == profile); + NL_TEST_ASSERT(inSuite, 2 == statusCode); + + err = aParser.Next(); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + err = aParser.GetProfileIDAndStatusCode(&profile, &statusCode); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + NL_TEST_ASSERT(inSuite, 1 == profile); + NL_TEST_ASSERT(inSuite, 3 == statusCode); + + err = aParser.Next(); + NL_TEST_ASSERT(inSuite, err == WEAVE_END_OF_TLV); +} + +void WdmUpdateResponseTest::TestVersionList(nlTestSuite *inSuite, void *inContext) +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + + PRINT_TEST_NAME(); + + mWriter.Init(mBuf, sizeof(mBuf)); + + mVersionListBuilder.Init(&mWriter); + + err = WriteVersionList(mVersionListBuilder); + + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + uint32_t lenWritten = mWriter.GetLengthWritten(); + printf("lenWritten: %" PRIu32 "\n", lenWritten); + + mReader.Init(mBuf, lenWritten); + err = mReader.Next(); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + err = mVersionListParser.Init(mReader); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + err = mVersionListParser.CheckSchemaValidity(); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + VerifyVersionList(inSuite, mVersionListParser); + + // Now test overflows + + for (size_t maxLen = 0; maxLen < lenWritten; maxLen++) + { + mWriter.Init(mBuf, maxLen); + + err = mVersionListBuilder.Init(&mWriter); + + if (WEAVE_NO_ERROR == err) + err = WriteVersionList(mVersionListBuilder); + + NL_TEST_ASSERT(inSuite, WEAVE_ERROR_BUFFER_TOO_SMALL == err); + + mReader.Init(mBuf, maxLen); + err = mReader.Next(); + + if (WEAVE_NO_ERROR == err) + err = mVersionListParser.Init(mReader); + + if (WEAVE_NO_ERROR == err) + err = mVersionListParser.CheckSchemaValidity(); + + // Note that CheckSchemaValidity succeeds if it can parse out the last StatusCode. + // It does not care if the containers are not terminated properly at the end. + NL_TEST_ASSERT(inSuite, WEAVE_END_OF_TLV == err || WEAVE_ERROR_WDM_MALFORMED_STATUS_ELEMENT == err || WEAVE_ERROR_TLV_UNDERRUN == err || WEAVE_NO_ERROR == err); + } +} + +void WdmUpdateResponseTest::TestStatusList(nlTestSuite *inSuite, void *inContext, bool aUseDeprecatedFormat) +{ + WEAVE_ERROR err; + + PRINT_TEST_NAME(); + + mWriter.Init(mBuf, sizeof(mBuf)); + + err = mStatusListBuilder.Init(&mWriter); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + if (aUseDeprecatedFormat) + { + mStatusListBuilder.UseDeprecatedFormat(); + } + + err = WriteStatusList(mStatusListBuilder); + + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + uint32_t lenWritten = mWriter.GetLengthWritten(); + printf("lenWritten: %" PRIu32 "\n", lenWritten); + + mReader.Init(mBuf, lenWritten); + err = mReader.Next(); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + err = mStatusListParser.Init(mReader); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + err = mStatusListParser.CheckSchemaValidity(); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + VerifyStatusList(inSuite, mStatusListParser); + + // Now test overflows + + for (size_t maxLen = 0; maxLen < lenWritten; maxLen++) + { + mWriter.Init(mBuf, maxLen); + + err = mStatusListBuilder.Init(&mWriter); + + if (aUseDeprecatedFormat) + { + mStatusListBuilder.UseDeprecatedFormat(); + } + + if (WEAVE_NO_ERROR == err) + err = WriteStatusList(mStatusListBuilder); + + printf("maxLen = %zu, err = %d\n", maxLen, err); + NL_TEST_ASSERT(inSuite, WEAVE_ERROR_BUFFER_TOO_SMALL == err); + + mReader.Init(mBuf, maxLen); + err = mReader.Next(); + + if (WEAVE_NO_ERROR == err) + err = mStatusListParser.Init(mReader); + + if (WEAVE_NO_ERROR == err) + err = mStatusListParser.CheckSchemaValidity(); + + // Note that CheckSchemaValidity succeeds if it can parse out the last StatusCode. + // It does not care if the containers are not terminated properly at the end. + NL_TEST_ASSERT(inSuite, WEAVE_END_OF_TLV == err || WEAVE_ERROR_WDM_MALFORMED_STATUS_ELEMENT == err || WEAVE_ERROR_TLV_UNDERRUN == err || WEAVE_NO_ERROR == err); + } +} + +void WdmUpdateResponseTest::TestStatusList(nlTestSuite *inSuite, void *inContext) +{ + TestStatusList(inSuite, inContext, false); +} + +void WdmUpdateResponseTest::TestDeprecatedStatusList(nlTestSuite *inSuite, void *inContext) +{ + TestStatusList(inSuite, inContext, true); +} + +void WdmUpdateResponseTest::TestUpdateResponse(nlTestSuite *inSuite, void *inContext) +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + + PRINT_TEST_NAME(); + + mWriter.Init(mBuf, sizeof(mBuf)); + + err = mUpdateResponseBuilder.Init(&mWriter); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + VersionList::Builder &lVLBuilder = mUpdateResponseBuilder.CreateVersionListBuilder(); + + err = WriteVersionList(lVLBuilder); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + uint32_t lenWritten = mWriter.GetLengthWritten(); + printf("After VersionList, lenWritten: %" PRIu32 "\n", lenWritten); + + StatusList::Builder &lSLBuilder = mUpdateResponseBuilder.CreateStatusListBuilder(); + + err = WriteStatusList(lSLBuilder); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + lenWritten = mWriter.GetLengthWritten(); + printf("After StatusList, lenWritten: %" PRIu32 "\n", lenWritten); + + mUpdateResponseBuilder.EndOfResponse(); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == mUpdateResponseBuilder.GetError()); + + lenWritten = mWriter.GetLengthWritten(); + printf("After whole response, lenWritten: %" PRIu32 "\n", lenWritten); + + mReader.Init(mBuf, lenWritten); + err = mReader.Next(); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + err = mUpdateResponseParser.Init(mReader); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + err = mUpdateResponseParser.CheckSchemaValidity(); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + err = mUpdateResponseParser.GetStatusList(&mStatusListParser); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + err = mUpdateResponseParser.GetVersionList(&mVersionListParser); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + VerifyStatusList(inSuite, mStatusListParser); + VerifyVersionList(inSuite, mVersionListParser); + + // Now test overflows + + for (size_t maxLen = 0; maxLen < lenWritten; maxLen++) + { + memset(mBuf, 0x42, sizeof(mBuf)); + + // Check that the error progates through all calls. + mWriter.Init(mBuf, maxLen); + + mUpdateResponseBuilder.Init(&mWriter); + + VersionList::Builder &lTmpVLBuilder = mUpdateResponseBuilder.CreateVersionListBuilder(); + + WriteVersionList(lTmpVLBuilder); + + StatusList::Builder &lTmpSLBuilder = mUpdateResponseBuilder.CreateStatusListBuilder(); + + WriteStatusList(lTmpSLBuilder); + + mUpdateResponseBuilder.EndOfResponse(); + + err = mUpdateResponseBuilder.GetError(); + + printf("maxLen = %zu, err = %d\n", maxLen, err); + NL_TEST_ASSERT(inSuite, WEAVE_ERROR_BUFFER_TOO_SMALL == err); + + // Check the TLVWriter has not gone over the max length + NL_TEST_ASSERT(inSuite, 0x42 == mBuf[maxLen]); + + mReader.Init(mBuf, maxLen); + err = mReader.Next(); + + if (WEAVE_NO_ERROR == err) + err = mUpdateResponseParser.Init(mReader); + + if (WEAVE_NO_ERROR == err) + err = mUpdateResponseParser.CheckSchemaValidity(); + + // Note that CheckSchemaValidity succeeds if it can parse out the last StatusCode. + // It does not care if the containers are not terminated properly at the end. + NL_TEST_ASSERT(inSuite, WEAVE_END_OF_TLV == err || WEAVE_ERROR_WDM_MALFORMED_STATUS_ELEMENT == err || WEAVE_ERROR_TLV_UNDERRUN == err || WEAVE_NO_ERROR == err); + } +} + +/** + * If the whole update is successful, the publisher can send an empty StatusList + */ +void WdmUpdateResponseTest::TestCompactResponse(nlTestSuite *inSuite, void *inContext) +{ + WEAVE_ERROR err = WEAVE_NO_ERROR; + + PRINT_TEST_NAME(); + + mWriter.Init(mBuf, sizeof(mBuf)); + + err = mUpdateResponseBuilder.Init(&mWriter); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + VersionList::Builder &lVLBuilder = mUpdateResponseBuilder.CreateVersionListBuilder(); + + err = WriteVersionList(lVLBuilder); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + uint32_t lenWritten = mWriter.GetLengthWritten(); + printf("After VersionList, lenWritten: %" PRIu32 "\n", lenWritten); + + StatusList::Builder &lSLBuilder = mUpdateResponseBuilder.CreateStatusListBuilder(); + + lSLBuilder.EndOfStatusList(); + + err = lSLBuilder.GetError(); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + lenWritten = mWriter.GetLengthWritten(); + printf("After StatusList, lenWritten: %" PRIu32 "\n", lenWritten); + + mUpdateResponseBuilder.EndOfResponse(); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == mUpdateResponseBuilder.GetError()); + + lenWritten = mWriter.GetLengthWritten(); + printf("After whole response, lenWritten: %" PRIu32 "\n", lenWritten); + + mReader.Init(mBuf, lenWritten); + err = mReader.Next(); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + err = mUpdateResponseParser.Init(mReader); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + err = mUpdateResponseParser.CheckSchemaValidity(); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + err = mUpdateResponseParser.GetStatusList(&mStatusListParser); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + err = mUpdateResponseParser.GetVersionList(&mVersionListParser); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR == err); + + VerifyVersionList(inSuite, mVersionListParser); + + uint32_t profile; + uint16_t statusCode; + err = mStatusListParser.Next(); + printf("Emtpy StatusList: Next err %d\n", err); + NL_TEST_ASSERT(inSuite, WEAVE_END_OF_TLV == err); + + err = mStatusListParser.GetProfileIDAndStatusCode(&profile, &statusCode); + printf("Emtpy StatusList: GetProfileIDAndStatusCode err %d\n", err); + NL_TEST_ASSERT(inSuite, WEAVE_NO_ERROR != err); +} + +} // WeaveMakeManagedNamespaceIdentifier(DataManagement, kWeaveManagedNamespaceDesignation_Current) +} +} +} + + +WdmUpdateResponseTest gWdmUpdateResponseTest; + + + +void WdmUpdateResponseTest_VersionList(nlTestSuite *inSuite, void *inContext) +{ + gWdmUpdateResponseTest.TestVersionList(inSuite, inContext); +} + +void WdmUpdateResponseTest_StatusList(nlTestSuite *inSuite, void *inContext) +{ + gWdmUpdateResponseTest.TestStatusList(inSuite, inContext); +} + +void WdmUpdateResponseTest_DeprecatedStatusList(nlTestSuite *inSuite, void *inContext) +{ + gWdmUpdateResponseTest.TestDeprecatedStatusList(inSuite, inContext); +} + +void WdmUpdateResponseTest_UpdateResponse(nlTestSuite *inSuite, void *inContext) +{ + gWdmUpdateResponseTest.TestUpdateResponse(inSuite, inContext); +} + +void WdmUpdateResponseTest_CompactResponse(nlTestSuite *inSuite, void *inContext) +{ + gWdmUpdateResponseTest.TestCompactResponse(inSuite, inContext); +} +// Test Suite + +/** + * Test Suite that lists all the test functions. + */ +static const nlTest sTests[] = { + NL_TEST_DEF("VersionList", WdmUpdateResponseTest_VersionList), + NL_TEST_DEF("StatusList", WdmUpdateResponseTest_StatusList), + NL_TEST_DEF("DeprecatedStatusList", WdmUpdateResponseTest_DeprecatedStatusList), + NL_TEST_DEF("UpdateResponse", WdmUpdateResponseTest_UpdateResponse), + NL_TEST_DEF("Compact UpdateResponse", WdmUpdateResponseTest_CompactResponse), + + 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) +{ + gWdmUpdateResponseTest.SetupTest(); + + return 0; +} + +/** + * Tear down each test. + */ +static int TestTeardown(void *inContext) +{ + gWdmUpdateResponseTest.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-WdmUpdateResponse", + &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 diff --git a/src/test-apps/happy/tests/service/wdmNext/test_weave_wdm_next_service_update_10_cond_Root_multi_traits.py b/src/test-apps/happy/tests/service/wdmNext/test_weave_wdm_next_service_update_10_cond_Root_multi_traits.py index 6053216c..d2508e7c 100755 --- a/src/test-apps/happy/tests/service/wdmNext/test_weave_wdm_next_service_update_10_cond_Root_multi_traits.py +++ b/src/test-apps/happy/tests/service/wdmNext/test_weave_wdm_next_service_update_10_cond_Root_multi_traits.py @@ -53,7 +53,7 @@ def test_weave_wdm_next_service_update_10_cond_Root_multi_traits(self): wdm_next_args['client_log_check'] = [('Mutual: Good Iteration', 1), ('Update: path result: success', 4), ('Update: no more pending updates', 1), - ('Suppressing error .*; will try again later', 1), # make sure to test failing to add a DataElement... + ('DataElement didn.*; will try again later', 1), # make sure to test failing to add a DataElement... ('Msg sent 0000000B:44', 1), # ... which will cause PartialUpdateRequests to be sent ('Msg sent 0000000B:34', 1), ('Removed 2 private InProgress items after 3', 1), # when the second TestATrait fails to fit, we have to remove diff --git a/src/test-apps/happy/tests/service/wdmNext/test_weave_wdm_next_service_update_12_uncond_OneLeaf_BeforeSub.py b/src/test-apps/happy/tests/service/wdmNext/test_weave_wdm_next_service_update_12_uncond_OneLeaf_BeforeSub.py index 56047cf8..5e5595b6 100755 --- a/src/test-apps/happy/tests/service/wdmNext/test_weave_wdm_next_service_update_12_uncond_OneLeaf_BeforeSub.py +++ b/src/test-apps/happy/tests/service/wdmNext/test_weave_wdm_next_service_update_12_uncond_OneLeaf_BeforeSub.py @@ -51,8 +51,8 @@ def test_weave_wdm_next_service_update_12_uncond_OneLeaf_BeforeSub(self): wdm_next_args['client_update_num_mutations'] = 1 wdm_next_args['client_log_check'] = [('Mutual: Good Iteration', 1), - ('Potential data loss set for traitDataHandle', 1), - ('Potential data loss cleared for traitDataHandle', 1), + ('Potential data loss set for traitDataHandle', 0), + ('Potential data loss cleared for traitDataHandle', 0), ('Update: path result: success', 1), ('Update: no more pending updates', 1), ('Update: path failed', 0),