From 204d57680d4a342be6d6e8ea0ca382f9aa65e1fc Mon Sep 17 00:00:00 2001 From: Yuliya Kamatkova Date: Mon, 22 Dec 2014 18:12:40 -0500 Subject: [PATCH] Add C++ Unit tests Added unit tests for OCPlatform and OCResource C++ APIs. All tests are passing Change-Id: Ib31295db92ad3934dec1ea32e59315cea8fff2a8 Signed-off-by: Yuliya Kamatkova (cherry picked from commit f488ad57ad2b45197ab5a1f4a5ed06565d7b473d) Reviewed-on: https://gerrit.iotivity.org/gerrit/203 Tested-by: jenkins-iotivity Reviewed-by: Sudarshan Prasad --- resource/unittests/ConstructResourceTest.cpp | 63 +++++++ resource/unittests/OCPlatformTest.cpp | 243 +++++++++++++++++++++++++++ resource/unittests/OCResourceTest.cpp | 152 +++++++++++++++++ resource/unittests/README | 11 +- resource/unittests/makefile | 27 +-- resource/unittests/tests.cpp | 101 ----------- 6 files changed, 478 insertions(+), 119 deletions(-) create mode 100644 resource/unittests/ConstructResourceTest.cpp create mode 100644 resource/unittests/OCPlatformTest.cpp create mode 100644 resource/unittests/OCResourceTest.cpp delete mode 100644 resource/unittests/tests.cpp diff --git a/resource/unittests/ConstructResourceTest.cpp b/resource/unittests/ConstructResourceTest.cpp new file mode 100644 index 0000000..2359202 --- /dev/null +++ b/resource/unittests/ConstructResourceTest.cpp @@ -0,0 +1,63 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#include +#include + +//Uncomment the below line for testing with Mocks +//#define WITH_MOCKS + +#include "hippomocks.h" +#include "Framework.h" + +#define GTEST_DONT_DEFINE_TEST 1 + +#include + +namespace ConstructResourceTest +{ + using namespace OC; + std::vector ifaces = {DEFAULT_INTERFACE}; + //using mocks framework + GTEST_TEST(ConstructResourceObjectTest, ConstructResourceObjectValidReturnValue) + { + MockRepository mocks; + OCResource::Ptr rightdoor = std::shared_ptr(); + mocks.ExpectCallFunc(OCPlatform::constructResourceObject).Return(rightdoor); + std::vector types = {"core.leftdoor"}; + OCResource::Ptr leftdoor = OCPlatform::constructResourceObject("192.168.1.2:5000", + "a/leftdoor", false, types, ifaces); + EXPECT_EQ(leftdoor, rightdoor); + + } + + GTEST_TEST(ConstructResourceObjectTest, ConstructResourceObjectInValidReturnValue) + { + MockRepository mocks; + OCResource::Ptr rightdoor = std::shared_ptr(); + mocks.ExpectCallFunc(OCPlatform::constructResourceObject).Return(NULL); + std::vector types = {"core.rightdoor"}; + OCResource::Ptr leftdoor = OCPlatform::constructResourceObject("192.168.1.2:5000", + "a/rightdoor", false, types, ifaces); + bool value = (leftdoor == NULL); + EXPECT_EQ(true, value); + } +} + diff --git a/resource/unittests/OCPlatformTest.cpp b/resource/unittests/OCPlatformTest.cpp new file mode 100644 index 0000000..70b1bc4 --- /dev/null +++ b/resource/unittests/OCPlatformTest.cpp @@ -0,0 +1,243 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +#include +#include +#include + +namespace OCPlatformTest +{ + using namespace OC; + + // Callbacks + OCEntityHandlerResult entityHandler(std::shared_ptr request) + { + return OC_EH_OK; + } + + const OCResourceHandle HANDLE_ZERO = 0; + + PlatformConfig cfg; + + void foundResource(std::shared_ptr resource) + { + } + + std::string resourceURI; + std::string resourceTypeName = "core.res"; + std::string resourceInterface = DEFAULT_INTERFACE; + uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE; + OCResourceHandle resourceHandle; + + //Helper methods + OCResourceHandle RegisterResource(std::string uri, std::string type, std::string iface) + { + EXPECT_EQ(OC_STACK_OK,OCPlatform::registerResource( + resourceHandle, uri, type, + iface, entityHandler, resourceProperty)); + return resourceHandle; + } + + OCResourceHandle RegisterResource(std::string uri, std::string type) + { + EXPECT_EQ(OC_STACK_OK, OCPlatform::registerResource( + resourceHandle, uri, type, + resourceInterface, entityHandler, resourceProperty)); + return resourceHandle; + } + + OCResourceHandle RegisterResource(std::string uri) + { + EXPECT_EQ(OC_STACK_OK, OCPlatform::registerResource( + resourceHandle, uri, resourceTypeName, + resourceInterface, entityHandler, resourceProperty)); + return resourceHandle; + } + + //RegisterResourceTest + TEST(RegisterResourceTest, RegisterSingleResource) + { + std::string uri = "/a/res2"; + EXPECT_NE(HANDLE_ZERO, RegisterResource(uri)); + } + + TEST(RegisterResourceTest, RegisterMultipleResources) + { + std::string uri = "/a/multi"; + //Good enough for 5 resources. + for(int i=0; i< 5; i++) + { + uri +=std::to_string(i); + EXPECT_NE(HANDLE_ZERO, RegisterResource(uri)); + } + } + + TEST(RegisterResourceTest, ReregisterResource) + { + OCResourceHandle resourceHandle = RegisterResource(std::string("/a/light5"), + std::string("core.light")); + EXPECT_EQ(OC_STACK_OK, OC::OCPlatform::unregisterResource(resourceHandle)); + + EXPECT_NE(HANDLE_ZERO, RegisterResource(std::string("/a/light5"), + std::string("core.light"))); + + } + + TEST(RegisterResourceTest, RegisterEmptyResource) + { + // We should not allow empty URI. + std::string emptyStr = ""; + EXPECT_ANY_THROW(OCPlatform::registerResource(resourceHandle, emptyStr, emptyStr, + emptyStr, entityHandler, resourceProperty)); + } + + TEST(RegisterResourceTest, RegisterZeroResourceProperty) + { + std::string uri = "/a/light6"; + std::string type = "core.light"; + uint8_t resourceProperty = 0; + EXPECT_EQ(OC_STACK_OK, OCPlatform::registerResource( + resourceHandle, uri, type, + resourceInterface, entityHandler, resourceProperty)); + } + + //UnregisterTest + TEST(UnregisterTest, UnregisterZeroHandleValue) + { + EXPECT_ANY_THROW(OC::OCPlatform::unregisterResource(HANDLE_ZERO)); + } + + //UnbindResourcesTest + TEST(UnbindResourcesTest, UnbindResources) + { + OCResourceHandle resourceHome = RegisterResource(std::string("a/home"), + std::string("core.home")); + OCResourceHandle resourceKitchen = RegisterResource(std::string("a/kitchen"), + std::string("core.kitchen"), LINK_INTERFACE); + OCResourceHandle resourceRoom = RegisterResource(std::string("a/office"), + std::string("core.office"), LINK_INTERFACE); + + std::vector rList; + rList.push_back(resourceKitchen); + rList.push_back(resourceRoom); + EXPECT_EQ(OC_STACK_OK, OCPlatform::bindResources(resourceHome, rList)); + EXPECT_EQ(OC_STACK_OK, OCPlatform::unbindResources(resourceHome, rList)); + } + + TEST(UnbindResourcesTest, UnbindResourcesWithZero) + { + OCResourceHandle resourceHandle1 = 0; + OCResourceHandle resourceHandle2 = 0; + OCResourceHandle resourceHandle3 = 0; + + std::vector rList; + + rList.push_back(resourceHandle2); + rList.push_back(resourceHandle3); + + EXPECT_ANY_THROW(OCPlatform::unbindResources(resourceHandle1, rList)); + } + + //BindInterfaceToResourceTest + TEST(BindInterfaceToResourceTest, BindResourceInterface) + { + OCResourceHandle resourceHandle = RegisterResource(std::string("/a/light"), + std::string("core.light")); + OCStackResult result = OC::OCPlatform::bindInterfaceToResource(resourceHandle, + BATCH_INTERFACE); + EXPECT_EQ(OC_STACK_OK, result); + } + + TEST(BindInterfaceToResourceTest, BindZeroResourceInterface) + { + OCResourceHandle resourceHandle = RegisterResource(std::string("/a/light1"), + std::string("core.light")); + EXPECT_ANY_THROW(OC::OCPlatform::bindInterfaceToResource(resourceHandle, 0)); + } + + //BindTypeToResourceTest + TEST(BindTypeToResourceTest, BindResourceType) + { + OCResourceHandle resourceHandle = RegisterResource(std::string("/a/light3"), + std::string("core.light")); + OCStackResult result = OC::OCPlatform::bindTypeToResource(resourceHandle, + "core.brightlight"); + EXPECT_EQ(OC_STACK_OK, result); + } + + TEST(BindTypeToResourceTest, BindZeroResourceType) + { + OCResourceHandle resourceHandle = RegisterResource(std::string("/a/light4"), + std::string("core.light")); + EXPECT_ANY_THROW(OC::OCPlatform::bindTypeToResource(resourceHandle, 0)); + } + + //UnbindResourceTest + TEST(UnbindResourceTest, BindAndUnbindResource) + { + OCResourceHandle resourceHandle1 = RegisterResource(std::string("a/unres"), + std::string("core.unres")); + OCResourceHandle resourceHandle2 = RegisterResource(std::string("a/unres2"), + std::string("core.unres"), LINK_INTERFACE); + + EXPECT_EQ(OC_STACK_OK, OCPlatform::bindResource(resourceHandle1, resourceHandle2)); + EXPECT_EQ(OC_STACK_OK, OCPlatform::unbindResource(resourceHandle1, resourceHandle2)); + } + + //PresenceTest + TEST(PresenceTest, StartAndStopPresence) + { + EXPECT_EQ(OC_STACK_OK, OCPlatform::startPresence(30)); + EXPECT_NE(HANDLE_ZERO, RegisterResource( std::string("/a/Presence"), + std::string("core.Presence"))); + EXPECT_EQ(OC_STACK_OK, OCPlatform::stopPresence()); + } + + TEST(OCPlatformTest, UnbindZeroRsourceHandleValue) + { + EXPECT_ANY_THROW(OCPlatform::unbindResource(HANDLE_ZERO, HANDLE_ZERO)); + } + + //NotifyAllObserverTest + TEST(NotifyAllObserverTest, NotifyAllObservers) + { + OCResourceHandle resourceHome = RegisterResource(std::string("/a/obs"), + std::string("core.obs")); + EXPECT_EQ(OC_STACK_NO_OBSERVERS, OCPlatform::notifyAllObservers(resourceHome)); + } + + TEST(NotifyAllObserverTest, NotifyListOfObservers) + { + OCResourceHandle resourceHome = RegisterResource(std::string("/a/obs2"), + std::string("core.obs")); + + std::shared_ptr resourceResponse(new OCResourceResponse()); + ObservationIds interestedObservers; + EXPECT_ANY_THROW(OCPlatform::notifyListOfObservers(resourceHome, + interestedObservers, resourceResponse)); + } + + //DeviceEntityHandlerTest + TEST(DeviceEntityHandlerTest, SetDefaultDeviceEntityHandler) + { + EXPECT_EQ(OC_STACK_OK, OCPlatform::setDefaultDeviceEntityHandler(entityHandler)); + EXPECT_EQ(OC_STACK_OK, OCPlatform::setDefaultDeviceEntityHandler(NULL)); + } +} diff --git a/resource/unittests/OCResourceTest.cpp b/resource/unittests/OCResourceTest.cpp new file mode 100644 index 0000000..4160314 --- /dev/null +++ b/resource/unittests/OCResourceTest.cpp @@ -0,0 +1,152 @@ +//****************************************************************** +// +// Copyright 2014 Intel Mobile Communications GmbH 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. +// +//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + + +#include +#include +#include + +namespace OCResourceTest +{ + using namespace OC; + // Callbacks + + void onObserve(const HeaderOptions headerOptions, const OCRepresentation& rep, + const int& eCode, const int& sequenceNumber) + { + } + + void onGetPut(const HeaderOptions& headerOptions, const OCRepresentation& rep, const int eCode) + { + } + + void foundResource(std::shared_ptr resource) + { + + } + + //Helper method + OCResource::Ptr ConstructResourceObject(std::string uri) + { + std::vector types = {"intel.rpost"}; + std::vector ifaces = {DEFAULT_INTERFACE}; + return OCPlatform::constructResourceObject(std::string(""), uri, + false, types, ifaces); + } + + //ConstructResourceTest + TEST(ConstructResourceTest, ConstructResourceObject) + { + EXPECT_ANY_THROW(ConstructResourceObject(std::string(""))); + } + + //ResourceGetTest + TEST(ResourceGetTest, ResourceGetForInvalidUri) + { + OCResource::Ptr resource = ConstructResourceObject("192.168.1.2:5000"); + if(resource) + { + QueryParamsMap test; + EXPECT_ANY_THROW(resource->get(test, &onGetPut)); + } + } + + TEST(ResourceGetTest, ResourceGetForValidUri) + { + OCResource::Ptr resource = ConstructResourceObject("coap://192.168.1.2:5000"); + if(resource) + { + QueryParamsMap test; + EXPECT_EQ(OC_STACK_OK, resource->get(OC::QueryParamsMap(), &onGetPut)); + } + } + + //ResourcePutTest + TEST(ResourcePutTest, ResourcePutForInvalidUri) + { + OCResource::Ptr resource = ConstructResourceObject("192.168.1.2:5000"); + if(resource) + { + OCRepresentation rep; + QueryParamsMap test; + EXPECT_ANY_THROW(resource->put(rep, test, &onGetPut)); + } + } + + TEST(ResourcePutTest, ResourcePutForValid) + { + OCResource::Ptr resource = ConstructResourceObject("coap://192.168.1.2:5000"); + if(resource) + { + QueryParamsMap test; + OCRepresentation rep; + EXPECT_EQ(OC_STACK_OK, resource->put(rep, test, &onGetPut)); + } + } + + //ResourcePostTest + TEST(ResourcePostTest, ResourcePostForInvalidUri) + { + OCResource::Ptr resource = ConstructResourceObject("192.168.1.2:5000"); + if(resource) + { + OCRepresentation rep; + QueryParamsMap test; + EXPECT_ANY_THROW(resource->post(rep, test, &onGetPut)); + } + } + + TEST(ResourcePostTest, ResourcePostValidConfiguration) + { + PlatformConfig cfg; + OCPlatform::Configure(cfg); + + OCResource::Ptr resource = ConstructResourceObject("coap://192.168.1.2:5000"); + if(resource) + { + OCRepresentation rep; + QueryParamsMap test; + EXPECT_EQ(OC_STACK_OK, resource->post(rep, test, &onGetPut)); + } + } + + //ResourceObserveTest + TEST(ResourceObserveTest, ResourceObserveInValidUri) + { + OCResource::Ptr resource = ConstructResourceObject("192.168.1.2:5000"); + if(resource) + { + QueryParamsMap test; + EXPECT_ANY_THROW(resource->observe(ObserveType::ObserveAll, test, &onObserve)); + } + } + + TEST(ResourceObserveTest, ResourceObserveValidUri) + { + OCResource::Ptr resource = ConstructResourceObject("coap://192.168.1.2:5000"); + if(resource) + { + QueryParamsMap test; + OCRepresentation rep; + EXPECT_EQ(OC_STACK_OK,resource->observe(ObserveType::ObserveAll, test, &onObserve)); + } + } + +} diff --git a/resource/unittests/README b/resource/unittests/README index 0fd09ea..a13dcde 100644 --- a/resource/unittests/README +++ b/resource/unittests/README @@ -11,17 +11,14 @@ in auto_build.sh which is also in the the repository root directory. //--------------------------------------------------------------------- -tests.cpp contains unittests for C++ APIs. It uses Google Test for the unit -tests. Note that the unit tests are only to test the functionality of OCApi.h. +The unittests folder contains unit tests for OCPlatfrom and OCResource APIs. +It uses Google Test for the unit tests. Please note that the unit tests are +only to test the functionality of public APIs. It is not a system or end-to-end test. -Unit Test Requirements: - 1. To run the unit test, first build the unit tests with the following command from : - make -f buildScript.mk linux_ub_unittests 2. Run the unit test by issuing the following command from : - - ./unittests/tests + ./unittests/unittests diff --git a/resource/unittests/makefile b/resource/unittests/makefile index 6a05e80..21fa477 100644 --- a/resource/unittests/makefile +++ b/resource/unittests/makefile @@ -26,11 +26,9 @@ CXX := g++ ROOT_DIR = ./ -# You must create the file "local.properties" on your local machine which contains any local paths, etc -# local.properties should NOT be committed to repo -include $(ROOT_DIR)/../csdk/local.properties - GTEST_DIR= ../../extlibs/gtest-1.7.0 +MOCKS_DIR= ../../extlibs/hippomocks-master + OUT_DIR := $(BUILD) ifeq ($(ROOT_DIR),) @@ -45,6 +43,8 @@ INC_DIRS += -I../csdk/ocrandom/include INC_DIRS += -I../csdk/logger/include INC_DIRS += -I../csdk/libcoap INC_DIRS += -I$(GTEST_DIR)/include +INC_DIRS += -I$(MOCKS_DIR)/HippoMocks +INC_DIRS += -I$(MOCKS_DIR)/HippoMocksTest LIB_OC_LOGGER := ../oc_logger/lib/oc_logger.a @@ -59,21 +59,26 @@ CC_FLAGS.release := -Os -Wall -fdata-sections -Wl,--gc-sections -Wl,-s \ CPPFLAGS += $(CC_FLAGS.$(BUILD)) $(CXX_LIBS) -lpthread -all: prep_dirs tests +all: prep_dirs $(MOCKS_DIR) unittests prep_dirs: -mkdir -p $(OUT_DIR) -tests: tests.cpp $(GTEST_LIBS) +unittests: OCPlatformTest.cpp OCResourceTest.cpp ConstructResourceTest.cpp $(GTEST_LIBS) $(CXX) $^ $(CPPFLAGS) -o $(OUT_DIR)/$@ - -$(GTEST_LIBS): $(GTEST_DIR) - cd $(GTEST_DIR) && ./configure && make - -$(GTEST_DIR): + +$(GTEST_DIR): cd ../../extlibs && \ wget -q https://googletest.googlecode.com/files/gtest-1.7.0.zip && \ unzip gtest-1.7.0.zip + +$(GTEST_LIBS): $(GTEST_DIR) + cd $(GTEST_DIR) && ./configure && make + +$(MOCKS_DIR): + cd ../../extlibs && \ + wget -q https://github.com/dascandy/hippomocks/archive/master.zip && \ + unzip master.zip .PHONY: clean diff --git a/resource/unittests/tests.cpp b/resource/unittests/tests.cpp deleted file mode 100644 index e299b43..0000000 --- a/resource/unittests/tests.cpp +++ /dev/null @@ -1,101 +0,0 @@ -//****************************************************************** -// -// Copyright 2014 Intel Mobile Communications GmbH 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. -// -//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= - - -#include -#include -#include -#include - -#include -#include - -#include - -namespace PH = std::placeholders; - -using namespace OC; -using namespace std; - -// Entity handler used for register and find test -OCEntityHandlerResult entityHandler_rf(std::shared_ptr request) -{ - return OC_EH_OK; -} - -// Condition variables used for register and find -std::mutex mutex_rf; -std::condition_variable cv_rf; -std::shared_ptr res_rf; - -void foundResource_rf(std::shared_ptr resource) -{ - if(resource) - { - res_rf = resource; - cv_rf.notify_all(); - } -} - -// Resource : Register and find test -TEST(Resource, rf) { - // Create PlatformConfig object - PlatformConfig cfg { - OC::ServiceType::InProc, - OC::ModeType::Both, - "0.0.0.0", // By setting to "0.0.0.0", it binds to all available interfaces - 0, // Uses randomly available port - OC::QualityOfService::LowQos - }; - OCPlatform::Configure(cfg); - - std::string resourceURI = "/a/res"; - std::string resourceTypeName = "core.res"; - std::string resourceInterface = DEFAULT_INTERFACE; - - uint8_t resourceProperty = OC_DISCOVERABLE | OC_OBSERVABLE; - - OCResourceHandle resourceHandle; - - // This will internally create and register the resource. - if(OC_STACK_OK == OCPlatform::registerResource( - resourceHandle, resourceURI, resourceTypeName, - resourceInterface, entityHandler_rf, resourceProperty)) - { - OCPlatform::findResource("","coap://224.0.1.187/oc/core?rt=core.res", foundResource_rf); - - { - std::unique_lock lk(mutex_rf); - cv_rf.wait(lk); - } - - if(res_rf) - { - EXPECT_EQ(res_rf->uri(), "/a/res"); - vector rts = res_rf->getResourceTypes(); - EXPECT_EQ(rts.size(), (unsigned) 1); - EXPECT_EQ(rts[0], "core.res"); - vector ifs = res_rf->getResourceInterfaces(); - EXPECT_EQ(ifs.size(), (unsigned) 1); - EXPECT_EQ(ifs[0], DEFAULT_INTERFACE); - } - } -} - -- 2.7.4