From 7ba1c8941530eb0882ec8b6372ea7011ecf950c2 Mon Sep 17 00:00:00 2001 From: Pawel Winogrodzki Date: Thu, 9 Mar 2017 13:57:05 -0800 Subject: [PATCH] IOT-1907: Fixing PMCloneOCProvisionDev, Fixing PMCloneOCProvisionDev to perform a proper deep copy of the internal doxm::subOwners and doxm::mom fields, so that they no longer point to the same structs as the original. Change-Id: I5b30e4e7012934b9a17a4f8d7cecd6d2b65b1055 Signed-off-by: Pawel Winogrodzki Reviewed-on: https://gerrit.iotivity.org/gerrit/17843 Tested-by: jenkins-iotivity Reviewed-by: Mike Fenelon Reviewed-by: Alex Kelley Reviewed-by: Kevin Kane --- .../include/internal/pmutilityinternal.h | 71 +++ .../src/multipleownershiptransfermanager.c | 15 +- .../csdk/security/provisioning/src/pmutility.c | 153 ++++++- .../security/provisioning/unittest/otmunittest.cpp | 1 - .../provisioning/unittest/pmutilitytest.cpp | 499 +++++++++++++++++++++ 5 files changed, 722 insertions(+), 17 deletions(-) create mode 100644 resource/csdk/security/provisioning/include/internal/pmutilityinternal.h diff --git a/resource/csdk/security/provisioning/include/internal/pmutilityinternal.h b/resource/csdk/security/provisioning/include/internal/pmutilityinternal.h new file mode 100644 index 0000000..378a1b0 --- /dev/null +++ b/resource/csdk/security/provisioning/include/internal/pmutilityinternal.h @@ -0,0 +1,71 @@ +/* ***************************************************************** + * + * Copyright 2017 Microsoft + * + * + * 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. + * + ******************************************************************/ + +#ifndef _PM_UTILITY_INTERNAL_H_ +#define _PM_UTILITY_INTERNAL_H_ + +#include "pmtypes.h" + +#ifdef __cplusplus +extern "C" +{ +#endif + +#ifdef MULTIPLE_OWNER +/** + * Performs a deep copy of a single OicSecMom_t struct. + * + * @param[in] src The source struct to be copied. + * + * @return A pointer to the copy or NULL in case of an error. + */ +OicSecMom_t* CloneOicSecMom(const OicSecMom_t* src); + +/** + * Performs a deep copy of a single OicSecSubOwner_t struct. + * + * @param[in] src The source struct to be copied. + * + * @return A pointer to the copy or NULL in case of an error. + */ +OicSecSubOwner_t* CloneOicSecSubOwner(const OicSecSubOwner_t* src); +#endif //MULTIPLE_OWNER + +/** + * Performs a deep copy of a single OicSecDoxm_t struct. + * + * @param[in] src The source struct to be copied. + * + * @return A pointer to the copy or NULL in case of an error. + */ +OicSecDoxm_t* CloneOicSecDoxm(const OicSecDoxm_t* src); + +/** + * API to perform a deep copy of a list of OCProvisionDev_t. The result must be + * freed using PMDeleteDeviceList. + * + * @param[in] source Source list to be cloned. Must not be null. + * @return Cloned source or NULL in case of an error. + */ +OCProvisionDev_t* PMCloneOCProvisionDevList(const OCProvisionDev_t* source); + +#ifdef __cplusplus +} +#endif +#endif //_PM_UTILITY_INTERNAL_H_ diff --git a/resource/csdk/security/provisioning/src/multipleownershiptransfermanager.c b/resource/csdk/security/provisioning/src/multipleownershiptransfermanager.c index 45ee265..be2eb6f 100644 --- a/resource/csdk/security/provisioning/src/multipleownershiptransfermanager.c +++ b/resource/csdk/security/provisioning/src/multipleownershiptransfermanager.c @@ -47,6 +47,7 @@ #include "oxmjustworks.h" #include "pmtypes.h" #include "pmutility.h" +#include "pmutilityinternal.h" #include "srmutility.h" #include "provisioningdatabasemanager.h" #include "oxmrandompin.h" @@ -155,12 +156,13 @@ static OCStackResult MOTSendPostDoxm(void *ctx, VERIFY_SUCCESS(TAG, (true == queryGenRes), ERROR); OIC_LOG_V(DEBUG, TAG, "Query=%s", query); - localTargetDeviceInfo = PMCloneOCProvisionDev(targetDeviceInfo); - VERIFY_NOT_NULL(TAG, localTargetDeviceInfo, ERROR); - //Create the MOT Context to handle the response message motCtx = (OTMContext_t*)OICCalloc(1, sizeof(OTMContext_t)); VERIFY_NOT_NULL(TAG, motCtx, ERROR); + + localTargetDeviceInfo = PMCloneOCProvisionDevList(targetDeviceInfo); + VERIFY_NOT_NULL(TAG, localTargetDeviceInfo, ERROR); + motCtx->selectedDeviceInfo = localTargetDeviceInfo; motCtx->ctxResultCallback = resultCallback; motCtx->ctxResultArraySize = 1; @@ -428,12 +430,13 @@ OCStackResult MOTProvisionPreconfigPIN(void *ctx, const OCProvisionDev_t *target VERIFY_SUCCESS(TAG, (true == queryGenRes), ERROR); OIC_LOG_V(DEBUG, TAG, "Query=%s", query); - localTargetDeviceInfo = PMCloneOCProvisionDev(targetDeviceInfo); - VERIFY_NOT_NULL(TAG, localTargetDeviceInfo, ERROR); - //Create the MOT Context to handle the response message motCtx = (OTMContext_t*)OICCalloc(1, sizeof(OTMContext_t)); VERIFY_NOT_NULL(TAG, motCtx, ERROR); + + localTargetDeviceInfo = PMCloneOCProvisionDevList(targetDeviceInfo); + VERIFY_NOT_NULL(TAG, localTargetDeviceInfo, ERROR); + motCtx->selectedDeviceInfo= localTargetDeviceInfo; motCtx->ctxResultCallback = resultCallback; motCtx->ctxResultArraySize =1; diff --git a/resource/csdk/security/provisioning/src/pmutility.c b/resource/csdk/security/provisioning/src/pmutility.c index 0d54ea0..da4f1db 100644 --- a/resource/csdk/security/provisioning/src/pmutility.c +++ b/resource/csdk/security/provisioning/src/pmutility.c @@ -45,6 +45,7 @@ #include "pmtypes.h" #include "pmutility.h" +#include "pmutilityinternal.h" #include "srmutility.h" @@ -132,6 +133,116 @@ static OCStackApplicationResult SecVersionDiscoveryHandler(void *ctx, OCDoHandle OCClientResponse *clientResponse); #endif +#ifdef MULTIPLE_OWNER +OicSecMom_t* CloneOicSecMom(const OicSecMom_t* src) +{ + OIC_LOG_V(DEBUG, TAG, "IN %s", __func__); + + if (!src) + { + OIC_LOG_V(ERROR, TAG, "%s : Invalid parameter", __func__); + return NULL; + } + + OicSecMom_t* newMom = (OicSecMom_t*)OICMalloc(sizeof(*newMom)); + if (newMom) + { + *newMom = *src; + } + else + { + OIC_LOG_V(ERROR, TAG, "%s : Failed to allocate memory", __func__); + } + + OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__); + + return newMom; +} + +OicSecSubOwner_t* CloneOicSecSubOwner(const OicSecSubOwner_t* src) +{ + OIC_LOG_V(DEBUG, TAG, "IN %s", __func__); + + if (!src) + { + OIC_LOG_V(ERROR, TAG, "%s : Invalid parameter", __func__); + return NULL; + } + + OicSecSubOwner_t* newSubOwner = (OicSecSubOwner_t*)OICCalloc(1, sizeof(*newSubOwner)); + VERIFY_NOT_NULL(TAG, newSubOwner, ERROR); + + memcpy(newSubOwner, src, sizeof(OicSecSubOwner_t)); + + if (src->next) + { + newSubOwner->next = CloneOicSecSubOwner(src->next); + VERIFY_NOT_NULL(TAG, newSubOwner->next, ERROR); + } + + OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__); + + return newSubOwner; + +exit: + OIC_LOG_V(ERROR, TAG, "%s : Failed to allocate memory", __func__); + if (newSubOwner) + { + OICFree(newSubOwner); + } + return NULL; +} +#endif //MULTIPLE_OWNER + +OicSecDoxm_t* CloneOicSecDoxm(const OicSecDoxm_t* src) +{ + OIC_LOG_V(DEBUG, TAG, "IN %s", __func__); + + if (!src) + { + OIC_LOG_V(ERROR, TAG, "%s : Invalid parameter", __func__); + return NULL; + } + + OicSecDoxm_t* newDoxm = (OicSecDoxm_t*)OICCalloc(1, sizeof(OicSecDoxm_t)); + VERIFY_NOT_NULL(TAG, newDoxm, ERROR); + + memcpy(newDoxm, src, sizeof(OicSecDoxm_t)); + +#ifdef MULTIPLE_OWNER + newDoxm->subOwners = NULL; + newDoxm->mom = NULL; + + if (src->subOwners) + { + newDoxm->subOwners = CloneOicSecSubOwner(src->subOwners); + VERIFY_NOT_NULL(TAG, newDoxm->subOwners, ERROR); + } + + if (src->mom) + { + newDoxm->mom = CloneOicSecMom(src->mom); + VERIFY_NOT_NULL(TAG, newDoxm->mom, ERROR); + } +#endif //MULTIPLE_OWNER + + // We have to assign NULL for not necessary information to prevent memory corruption. + newDoxm->oxmType = NULL; + newDoxm->oxmTypeLen = 0; + newDoxm->oxm = NULL; + newDoxm->oxmLen = 0; + + OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__); + + return newDoxm; + +exit: + OIC_LOG_V(ERROR, TAG, "%s : Failed to allocate memory", __func__); + DeleteDoxmBinData(newDoxm); + + return NULL; +} + /** * Function to search node in linked list that matches given IP and port. * @@ -350,13 +461,8 @@ OCProvisionDev_t* PMCloneOCProvisionDev(const OCProvisionDev_t* src) if (src->doxm) { - newDev->doxm = (OicSecDoxm_t*)OICCalloc(1, sizeof(OicSecDoxm_t)); + newDev->doxm = CloneOicSecDoxm(src->doxm); VERIFY_NOT_NULL(TAG, newDev->doxm, ERROR); - - memcpy(newDev->doxm, src->doxm, sizeof(OicSecDoxm_t)); - // We have to assign NULL for not necessary information to prevent memory corruption. - newDev->doxm->oxmType = NULL; - newDev->doxm->oxm = NULL; } if (0 == strlen(src->secVer)) @@ -379,12 +485,39 @@ OCProvisionDev_t* PMCloneOCProvisionDev(const OCProvisionDev_t* src) exit: OIC_LOG(ERROR, TAG, "PMCloneOCProvisionDev : Failed to allocate memory"); - if (newDev) + PMDeleteDeviceList(newDev); + return NULL; +} + +OCProvisionDev_t* PMCloneOCProvisionDevList(const OCProvisionDev_t* src) +{ + OIC_LOG_V(DEBUG, TAG, "IN %s", __func__); + + if (!src) { - OICFree(newDev->pstat); - OICFree(newDev->doxm); - OICFree(newDev); + OIC_LOG_V(ERROR, TAG, "%s : Invalid parameter", __func__); + return NULL; } + + OCProvisionDev_t* newDev = PMCloneOCProvisionDev(src); + VERIFY_NOT_NULL(TAG, newDev, ERROR); + + OCProvisionDev_t* current = newDev; + for (OCProvisionDev_t* next = src->next; NULL != next; next = next->next) + { + current->next = PMCloneOCProvisionDev(next); + VERIFY_NOT_NULL(TAG, current->next, ERROR); + + current = current->next; + } + + OIC_LOG_V(DEBUG, TAG, "OUT %s", __func__); + + return newDev; + +exit: + OIC_LOG_V(ERROR, TAG, "%s : Failed to allocate memory", __func__); + PMDeleteDeviceList(newDev); return NULL; } diff --git a/resource/csdk/security/provisioning/unittest/otmunittest.cpp b/resource/csdk/security/provisioning/unittest/otmunittest.cpp index ceff880..9e211d7 100644 --- a/resource/csdk/security/provisioning/unittest/otmunittest.cpp +++ b/resource/csdk/security/provisioning/unittest/otmunittest.cpp @@ -816,4 +816,3 @@ TEST(FinalizeOTMTest, NullParam) int interpreter_res2 = system("pkill -f \"sample_server2\""); EXPECT_TRUE(0 <= interpreter_res2); } - diff --git a/resource/csdk/security/provisioning/unittest/pmutilitytest.cpp b/resource/csdk/security/provisioning/unittest/pmutilitytest.cpp index daacef7..cb07ba9 100644 --- a/resource/csdk/security/provisioning/unittest/pmutilitytest.cpp +++ b/resource/csdk/security/provisioning/unittest/pmutilitytest.cpp @@ -19,7 +19,10 @@ * *****************************************************************/ #include "gtest/gtest.h" #include "pmutility.h" +#include "pmutilityinternal.h" +#include "doxmresource.h" #include "ocstack.h" +#include "oic_malloc.h" #include "utlist.h" using namespace std; @@ -37,6 +40,502 @@ extern OCStackResult AddDevice(OCProvisionDev_t **ppDevicesList, const char* add OCProvisionDev_t* gList = NULL; +static bool UuidsIdentical(const OicUuid_t* first, const OicUuid_t* second) +{ + return (0 == memcmp(first, second, sizeof(OicUuid_t))); +} + +#ifdef MULTIPLE_OWNER +class CloneOicSecMomTest : public testing::Test +{ +public: + CloneOicSecMomTest() : + m_originalStruct({OIC_MULTIPLE_OWNER_DISABLE}), + m_clonedStruct(NULL) + {} + + void TearDown() + { + OICFree(m_clonedStruct); + } +protected: + + OicSecMom_t m_originalStruct; + OicSecMom_t* m_clonedStruct; +}; + +TEST(CloneOicSecMomSimpleTest, shouldReturnNullForNullInput) +{ + EXPECT_TRUE(NULL == CloneOicSecMom(NULL)); +} + +TEST_F(CloneOicSecMomTest, shouldReturnValidPointerForValidInput) +{ + m_clonedStruct = CloneOicSecMom(&m_originalStruct); + EXPECT_FALSE(NULL == m_clonedStruct); +} + +TEST_F(CloneOicSecMomTest, copyShouldHaveTheSameValueAsOriginal) +{ + m_clonedStruct = CloneOicSecMom(&m_originalStruct); + EXPECT_EQ(m_originalStruct.mode, m_clonedStruct->mode); +} + +TEST_F(CloneOicSecMomTest, shouldReturnDifferentAddressThanOriginalForValidInput) +{ + m_clonedStruct = CloneOicSecMom(&m_originalStruct); + EXPECT_NE(&m_originalStruct, m_clonedStruct); +} + +static OicSecSubOwner_t* BuildSampleOicSecSubOwner(MotStatus_t status, + const OicUuid_t* uuid) +{ + OicSecSubOwner_t* result = + (OicSecSubOwner_t*)OICCalloc(1, sizeof(OicSecSubOwner_t)); + if (NULL == result) + { + return NULL; + } + + result->status = status; + memcpy(&result->uuid, uuid, sizeof(OicUuid_t)); + result->next = NULL; + + return result; +} + +static void FreeOicSecSubOwner(OicSecSubOwner_t* input) +{ + OicSecSubOwner_t* current = input; + OicSecSubOwner_t* temp = input; + while (NULL != current) + { + temp = current; + current = temp->next; + OICFree(temp); + } +} + +class CloneOicSecSubOwnerTest : public testing::Test +{ +public: + CloneOicSecSubOwnerTest() : + m_originalStruct(NULL), + m_clonedStruct(NULL) + {} + + void SetUp() + { + m_originalStruct = + BuildSampleOicSecSubOwner(MOT_STATUS_READY, &s_sampleUuid); + ASSERT_FALSE(NULL == m_originalStruct); + + m_originalStruct->next = + BuildSampleOicSecSubOwner(MOT_STATUS_IN_PROGRESS, &s_sampleNextUuid); + ASSERT_FALSE(NULL == m_originalStruct->next); + } + + void TearDown() + { + FreeOicSecSubOwner(m_originalStruct); + FreeOicSecSubOwner(m_clonedStruct); + } +protected: + + static const OicUuid_t s_sampleUuid; + static const OicUuid_t s_sampleNextUuid; + + OicSecSubOwner_t* m_originalStruct; + OicSecSubOwner_t* m_clonedStruct; +}; + +const OicUuid_t CloneOicSecSubOwnerTest::s_sampleUuid = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +const OicUuid_t CloneOicSecSubOwnerTest::s_sampleNextUuid = { + { 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF } +}; + +TEST(CloneOicSecSubOwnerSimpleTest, shouldReturnNullForNullInput) +{ + EXPECT_TRUE(NULL == CloneOicSecSubOwner(NULL)); +} + +TEST_F(CloneOicSecSubOwnerTest, shouldReturnValidPointerForValidInput) +{ + m_clonedStruct = CloneOicSecSubOwner(m_originalStruct); + EXPECT_FALSE(NULL == m_clonedStruct); +} + +TEST_F(CloneOicSecSubOwnerTest, copyShouldHaveTheSameStatusAsOriginal) +{ + m_clonedStruct = CloneOicSecSubOwner(m_originalStruct); + EXPECT_EQ(m_originalStruct->status, m_clonedStruct->status); +} + +TEST_F(CloneOicSecSubOwnerTest, copyShouldHaveTheSameUuidAsOriginal) +{ + m_clonedStruct = CloneOicSecSubOwner(m_originalStruct); + EXPECT_TRUE(UuidsIdentical(&m_originalStruct->uuid, &m_clonedStruct->uuid)); +} + +TEST_F(CloneOicSecSubOwnerTest, copyShouldHaveNext) +{ + m_clonedStruct = CloneOicSecSubOwner(m_originalStruct); + EXPECT_FALSE(NULL == m_clonedStruct->next); +} + +TEST_F(CloneOicSecSubOwnerTest, copyNextShouldHaveTheSameStatusAsOriginal) +{ + m_clonedStruct = CloneOicSecSubOwner(m_originalStruct); + EXPECT_EQ(m_originalStruct->next->status, m_clonedStruct->next->status); +} + +TEST_F(CloneOicSecSubOwnerTest, copyNextShouldHaveTheSameUuidAsOriginal) +{ + m_clonedStruct = CloneOicSecSubOwner(m_originalStruct); + EXPECT_TRUE(UuidsIdentical(&m_originalStruct->next->uuid, + &m_clonedStruct->next->uuid)); +} + +TEST_F(CloneOicSecSubOwnerTest, copyShouldHaveDifferentAddressThanOriginal) +{ + m_clonedStruct = CloneOicSecSubOwner(m_originalStruct); + EXPECT_NE(m_originalStruct, m_clonedStruct); +} + +TEST_F(CloneOicSecSubOwnerTest, copyNextShouldHaveDifferentAddressThanOriginal) +{ + m_clonedStruct = CloneOicSecSubOwner(m_originalStruct); + EXPECT_NE(m_originalStruct->next, m_clonedStruct->next); +} + +TEST_F(CloneOicSecSubOwnerTest, copyShouldHaveNullLastNext) +{ + m_clonedStruct = CloneOicSecSubOwner(m_originalStruct); + EXPECT_TRUE(NULL == m_clonedStruct->next->next); +} +#endif + +class CloneOicSecDoxmTest : public testing::Test +{ +public: + CloneOicSecDoxmTest() : + m_originalStruct(NULL), + m_clonedStruct(NULL) + {} + + void SetUp() + { + m_originalStruct = BuildSampleOicSecDoxm(); + ASSERT_FALSE(NULL == m_originalStruct); + } + + void TearDown() + { + DeleteDoxmBinData(m_originalStruct); + DeleteDoxmBinData(m_clonedStruct); + } + +protected: + + static const OicUuid_t s_sampleDeviceId; + static const OicUuid_t s_sampleOwner; + static const OicUuid_t s_sampleOwnerId; + static const OicUuid_t s_sampleSubOwner; + + OicSecDoxm_t* m_originalStruct; + OicSecDoxm_t* m_clonedStruct; + +private: + + OicSecDoxm_t* BuildSampleOicSecDoxm() + { + OicSecDoxm_t* result = + (OicSecDoxm_t*)OICCalloc(1, sizeof(OicSecDoxm_t)); + if (NULL == result) + { + return NULL; + } + + memcpy(&result->deviceID, &s_sampleDeviceId, sizeof(result->deviceID)); + result->dpc = true; + +#ifdef MULTIPLE_OWNER + result->mom = (OicSecMom_t*)OICCalloc(1, sizeof(OicSecMom_t)); + if (NULL == result->mom) + { + return NULL; + } + result->mom->mode = OIC_MULTIPLE_OWNER_DISABLE; + result->subOwners = + BuildSampleOicSecSubOwner(MOT_STATUS_IN_PROGRESS, &s_sampleSubOwner); + if (NULL == result->subOwners) + { + return NULL; + } +#endif + + result->owned = true; + memcpy(&result->owner, &s_sampleOwner, sizeof(result->owner)); + result->oxm = (OicSecOxm_t*)OICCalloc(1, sizeof(OicSecOxm_t)); + if (NULL == result->oxm) + { + return NULL; + } + result->oxm[0] = OIC_JUST_WORKS; + result->oxmLen = 1U; + result->oxmSel = OIC_JUST_WORKS; + result->oxmType = (OicUrn_t*)OICCalloc(1, sizeof(OicUrn_t)); + if (NULL == result->oxm) + { + return NULL; + } + result->oxmType[0] = NULL; + result->oxmTypeLen = 1U; + memcpy(&result->rownerID, &s_sampleOwnerId, sizeof(result->rownerID)); + result->sct = NO_SECURITY_MODE; + + return result; + } +}; + +const OicUuid_t CloneOicSecDoxmTest::s_sampleDeviceId = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 } +}; + +const OicUuid_t CloneOicSecDoxmTest::s_sampleOwner = { + { 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAA } +}; + +const OicUuid_t CloneOicSecDoxmTest::s_sampleOwnerId = { + { 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF } +}; + +const OicUuid_t CloneOicSecDoxmTest::s_sampleSubOwner = { + { 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xCC } +}; + +TEST(CloneOicSecDoxmSimpleTest, shouldReturnNullForNullInput) +{ + EXPECT_TRUE(NULL == CloneOicSecDoxm(NULL)); +} + +TEST_F(CloneOicSecDoxmTest, shouldReturnValidPointerForValidInput) +{ + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_FALSE(NULL == m_clonedStruct); +} + +TEST_F(CloneOicSecDoxmTest, copyShouldHaveNulledOxmType) +{ + ASSERT_FALSE(NULL == m_originalStruct->oxmType); + + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_TRUE(NULL == m_clonedStruct->oxmType); +} + +TEST_F(CloneOicSecDoxmTest, copyShouldHaveZeroedOxmTypeLen) +{ + ASSERT_NE(0U, m_originalStruct->oxmTypeLen); + + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_EQ(0U, m_clonedStruct->oxmTypeLen); +} + +TEST_F(CloneOicSecDoxmTest, copyShouldHaveNulledOxm) +{ + ASSERT_FALSE(NULL == m_originalStruct->oxm); + + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_TRUE(NULL == m_clonedStruct->oxm); +} + +TEST_F(CloneOicSecDoxmTest, copyShouldHaveZeroedOxmLen) +{ + ASSERT_NE(0U, m_originalStruct->oxmLen); + + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_EQ(0U, m_clonedStruct->oxmLen); +} + +#ifdef MULTIPLE_OWNER +TEST_F(CloneOicSecDoxmTest, shouldReturnValidPointerForInputWithNullMom) +{ + OICFree(m_originalStruct->mom); + m_originalStruct->mom = NULL; + + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_FALSE(NULL == m_clonedStruct); +} + +TEST_F(CloneOicSecDoxmTest, copyShouldHaveNonNullMom) +{ + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_FALSE(NULL == m_clonedStruct->mom); +} + +TEST_F(CloneOicSecDoxmTest, copyShouldHaveDifferentMomAddress) +{ + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_NE(m_originalStruct->mom, m_clonedStruct->mom); +} + +TEST_F(CloneOicSecDoxmTest, copyShouldHaveNullMomForNullOriginal) +{ + OICFree(m_originalStruct->mom); + m_originalStruct->mom = NULL; + + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_TRUE(NULL == m_clonedStruct->mom); +} + +TEST_F(CloneOicSecDoxmTest, shouldReturnValidPointerForInputWithNullSubOwners) +{ + FreeOicSecSubOwner(m_originalStruct->subOwners); + m_originalStruct->subOwners = NULL; + + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_FALSE(NULL == m_clonedStruct); +} + +TEST_F(CloneOicSecDoxmTest, copyShouldHaveNonNullSubOwners) +{ + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_FALSE(NULL == m_clonedStruct->subOwners); +} + +TEST_F(CloneOicSecDoxmTest, copyShouldHaveDifferentSubOwnersAddress) +{ + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_NE(m_originalStruct->subOwners, m_clonedStruct->subOwners); +} + +TEST_F(CloneOicSecDoxmTest, copyShouldHaveNullSubOwnersForNullOriginal) +{ + FreeOicSecSubOwner(m_originalStruct->subOwners); + m_originalStruct->subOwners = NULL; + + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_TRUE(NULL == m_clonedStruct->subOwners); +} +#endif + +TEST_F(CloneOicSecDoxmTest, copyShouldHaveTheSameDeviceIdAsOriginal) +{ + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_TRUE(UuidsIdentical(&m_originalStruct->deviceID, + &m_clonedStruct->deviceID)); +} + +TEST_F(CloneOicSecDoxmTest, copyShouldHaveTheSameOwnerIdAsOriginal) +{ + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_TRUE(UuidsIdentical(&m_originalStruct->owner, + &m_clonedStruct->owner)); +} + +TEST_F(CloneOicSecDoxmTest, copyShouldHaveTheSameRownerIdAsOriginal) +{ + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_TRUE(UuidsIdentical(&m_originalStruct->rownerID, + &m_clonedStruct->rownerID)); +} + +TEST_F(CloneOicSecDoxmTest, copyShouldHaveTheSameSctAsOriginal) +{ + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_EQ(m_originalStruct->sct, m_clonedStruct->sct); +} + +TEST_F(CloneOicSecDoxmTest, copyShouldHaveTheSameOwnedAsOriginal) +{ + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_EQ(m_originalStruct->owned, m_clonedStruct->owned); +} + +TEST_F(CloneOicSecDoxmTest, copyShouldHaveTheSameDpcAsOriginal) +{ + m_clonedStruct = CloneOicSecDoxm(m_originalStruct); + EXPECT_EQ(m_originalStruct->dpc, m_clonedStruct->dpc); +} + +class CloneOCProvisionDevListTest : public ::testing::Test +{ +public: + CloneOCProvisionDevListTest() : + m_originalStruct(NULL), + m_clonedStruct(NULL) + {} + + void SetUp() + { + m_originalStruct = BuildSampleOCProvisionDev(); + ASSERT_FALSE(NULL == m_originalStruct); + + m_originalStruct->next = BuildSampleOCProvisionDev(); + ASSERT_FALSE(NULL == m_originalStruct->next); + } + + void TearDown() + { + PMDeleteDeviceList(m_originalStruct); + PMDeleteDeviceList(m_clonedStruct); + } +protected: + + OCProvisionDev_t* m_originalStruct; + OCProvisionDev_t* m_clonedStruct; + +private: + + OCProvisionDev_t* BuildSampleOCProvisionDev() + { + return (OCProvisionDev_t*)OICCalloc(1, sizeof(OCProvisionDev_t)); + } +}; + +TEST(CloneOCProvisionDevListSimpleTest, shouldReturnNullForNullInput) +{ + EXPECT_TRUE(NULL == PMCloneOCProvisionDevList(NULL)); +} + +TEST_F(CloneOCProvisionDevListTest, shouldReturnValidPointerForNonNullInput) +{ + m_clonedStruct = PMCloneOCProvisionDevList(m_originalStruct); + + EXPECT_FALSE(NULL == m_clonedStruct); +} + +TEST_F(CloneOCProvisionDevListTest, shouldReturnValidPointerForNonNext) +{ + m_clonedStruct = PMCloneOCProvisionDevList(m_originalStruct); + + EXPECT_FALSE(NULL == m_clonedStruct->next); +} + +TEST_F(CloneOCProvisionDevListTest, copyShouldHaveDifferentAddress) +{ + m_clonedStruct = PMCloneOCProvisionDevList(m_originalStruct); + + EXPECT_NE(m_originalStruct, m_clonedStruct); +} + +TEST_F(CloneOCProvisionDevListTest, copyShouldHaveDifferentAddressForNext) +{ + m_clonedStruct = PMCloneOCProvisionDevList(m_originalStruct); + + EXPECT_NE(m_originalStruct->next, m_clonedStruct->next); +} + + // List add Tests TEST(ProvisionListTest, Addition) { -- 2.7.4