From c15b5abae13eb0a3bc1ecd22891cfb1e351672a5 Mon Sep 17 00:00:00 2001 From: KIM JungYong Date: Tue, 21 Feb 2017 21:28:52 +0900 Subject: [PATCH] Fix unit test of notification service. Unit test of notification service sometimes failures due to time delay. In this patch, network related procedure(including multicast discovery) was removed on the c layer of notification service. Patch #2 Resolve build error in previous unittest. Patch #3 Apply changes about changed CA interface APIs. Remove checking resource type on the Presence callback. Change-Id: Ifa46c346fa6236266dc2a73a2f8d948c57d2f736 Signed-off-by: KIM JungYong Reviewed-on: https://gerrit.iotivity.org/gerrit/17397 Reviewed-by: Uze Choi Tested-by: Uze Choi --- service/notification/SConscript | 4 +- .../notification/src/provider/NSProviderListener.h | 8 + service/notification/unittest/NSConsumerTest.cpp | 4 +- service/notification/unittest/NSConsumerTest2.cpp | 625 +++++++++++++++++++++ service/notification/unittest/NSProviderTest.cpp | 6 +- service/notification/unittest/NSProviderTest2.cpp | 519 +++++++++++++++++ service/notification/unittest/SConscript | 21 +- 7 files changed, 1177 insertions(+), 10 deletions(-) create mode 100644 service/notification/unittest/NSConsumerTest2.cpp create mode 100644 service/notification/unittest/NSProviderTest2.cpp diff --git a/service/notification/SConscript b/service/notification/SConscript index 62d0b05..fe0c19e 100755 --- a/service/notification/SConscript +++ b/service/notification/SConscript @@ -146,8 +146,8 @@ notification_consumer_env.UserInstallTargetHeader('include/NSCommon.h',\ # Go to build Unit test -#if target_os == 'linux': -# SConscript('unittest/SConscript') +if target_os == 'linux': + SConscript('unittest/SConscript') # Go to build c++ wrapper SConscript('cpp-wrapper/SConscript') diff --git a/service/notification/src/provider/NSProviderListener.h b/service/notification/src/provider/NSProviderListener.h index 0e0d791..8e468fe 100644 --- a/service/notification/src/provider/NSProviderListener.h +++ b/service/notification/src/provider/NSProviderListener.h @@ -21,6 +21,10 @@ #ifndef _NS_PROVIDER_LISTENER__H_ #define _NS_PROVIDER_LISTENER__H_ +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + #include #include "ocstack.h" #include "logger.h" @@ -60,3 +64,7 @@ OCStackApplicationResult NSProviderPublishMQResponseCB(void *ctx, OCDoHandle han #endif #endif /* _NS_PROVIDER_LISTENER__H_ */ + +#ifdef __cplusplus +} +#endif // __cplusplus diff --git a/service/notification/unittest/NSConsumerTest.cpp b/service/notification/unittest/NSConsumerTest.cpp index 56ccfa2..38cc2ab 100644 --- a/service/notification/unittest/NSConsumerTest.cpp +++ b/service/notification/unittest/NSConsumerTest.cpp @@ -44,8 +44,8 @@ namespace /// Reasonable timeout is set to 1000 ms in unsecured mode. unsigned int g_timeout = 1000; -#ifndef SECURED - g_timeout = 2 * g_timeout +#ifdef SECURED + g_timeout = 2 * g_timeout; #endif std::chrono::milliseconds g_waitForResponse(g_timeout); diff --git a/service/notification/unittest/NSConsumerTest2.cpp b/service/notification/unittest/NSConsumerTest2.cpp new file mode 100644 index 0000000..eb4886a --- /dev/null +++ b/service/notification/unittest/NSConsumerTest2.cpp @@ -0,0 +1,625 @@ +//****************************************************************** +// +// Copyright 2017 Samsung Electronics 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 "OCPlatform.h" +#include "octypes.h" +#include "ocstack.h" +#include "ocpayload.h" +#include "cainterface.h" + +#include "NSCommon.h" +#include "NSConsumerInterface.h" +#include "NSConsumerDiscovery.h" +#include "NSConsumerCommunication.h" +#include "NSConsumerInternalTaskController.h" + +namespace +{ + NSProvider * g_provider = NULL; + NSProvider_internal * g_provider_internal = NULL; + + OCClientResponse * g_testResponse = NULL; + OCDevAddr * testAddr = NULL; + + uint64_t revId = 0; + NSSyncType type = NS_SYNC_DELETED; + NSProviderState revState = NS_STOPPED; + NSProviderState expectedState = NS_STOPPED; + + NSConsumerConfig cfg; + + std::chrono::milliseconds g_waitForResponse(1000); + + std::condition_variable messageReceive; + std::mutex messageReceiveLock; + + std::condition_variable syncReceive; + std::mutex syncReceiveLock; + + std::condition_variable providerChanged; + std::mutex providerChangedLock; + + const std::string testProviderID = "123456789012345678901234567890123456"; + + static void NSNotificationReceivedCallback(NSMessage * message) + { + if (0 != testProviderID.compare(message->providerId)) + { + NSRemoveMessage(message); + return; + } + + std::cout << __func__ << std::endl; + std::cout << "Income Notification : " << message->messageId << std::endl; + revId = message->messageId; + + NSRemoveMessage(message); + messageReceive.notify_all(); + } + + static void NSSyncCallback(NSSyncInfo * sync) + { + if (0 != testProviderID.compare(sync->providerId)) + { + free(sync); + return; + } + + std::cout << __func__ << std::endl; + std::cout << "Income SyncInfo : " << sync->messageId + << ", State : " << sync->state << std::endl; + type = sync->state; + + free(sync); + syncReceive.notify_all(); + } + + static void NSProviderChangedCallback(NSProvider * provider, NSProviderState state) + { + if (0 != testProviderID.compare(provider->providerId)) + { + NSRemoveProvider(provider); + return; + } + + std::cout << __func__ << " " << state << std::endl; + std::cout << provider->providerId << std::endl; + if (g_provider) + { + NSRemoveProvider(g_provider); + g_provider = NULL; + } + g_provider = provider; + + if (expectedState == state) + { + revState = state; + providerChanged.notify_all(); + } + } + static FILE* client_open(const char * path, const char * mode) + { + if (0 == strcmp(path, OC_SECURITY_DB_DAT_FILE_NAME)) + { + std::string file_name = "./oic_svr_db_ns.dat"; + return fopen(file_name.c_str(), mode); + } + else + { + return fopen(path, mode); + } + } + + OCDevAddr * getDevAddr() + { + CAEndpoint_t * ninfo = NULL; + size_t size = 0; + CAResult_t ret = CAGetNetworkInformation(&ninfo, &size); + if (ret != CA_STATUS_OK || size == 0) + { + return NULL; + } + + OCDevAddr * addr = + (OCDevAddr *)malloc(sizeof(OCDevAddr)); + if (addr == NULL) + { + free(ninfo); + return NULL; + } + addr->adapter = (ninfo[0].adapter == CA_ALL_ADAPTERS) ? OC_ADAPTER_IP : + (OCTransportAdapter) ninfo[0].adapter; + strncpy(addr->addr, ninfo[0].addr, sizeof(ninfo[0].addr)); + addr->flags = (OCTransportFlags)ninfo[0].flags; + addr->ifindex = ninfo[0].ifindex; + addr->port = ninfo[0].port; + strncpy(addr->remoteId, ninfo[0].remoteId, 37); + + free(ninfo); + ninfo = NULL; + return addr; + } + + OCRepPayload * getDiscoverPayload() + { + OCRepPayload * payload = OCRepPayloadCreate(); + EXPECT_NE((void *)NULL, payload); + + std::string msgUri = "/notifiationTest/message"; + std::string syncUri = "/notifiationTest/sync"; + std::string topicUri = "/notifiationTest/topic"; + + bool getResult = OCRepPayloadSetPropBool(payload, NS_ATTRIBUTE_POLICY, false); + getResult &= OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, testProviderID.c_str()); + getResult &= OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_MESSAGE, msgUri.c_str()); + getResult &= OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_SYNC, syncUri.c_str()); + getResult &= OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_TOPIC, topicUri.c_str()); + if (getResult == false) + { + OCRepPayloadDestroy(payload); + } + EXPECT_EQ(true, getResult); + + return payload; + } + + OCRepPayload * getMsgPayload(uint64_t msgId) + { + OCRepPayload * payload = OCRepPayloadCreate(); + EXPECT_NE((void *)NULL, payload); + bool getResult = OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, msgId); + getResult &= OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, testProviderID.c_str()); + if (getResult == false) + { + OCRepPayloadDestroy(payload); + } + EXPECT_EQ(true, getResult); + + return payload; + } + + OCRepPayload * getSyncPayload(uint64_t msgId, int64_t state) + { + OCRepPayload * payload = OCRepPayloadCreate(); + EXPECT_NE((void *)NULL, payload); + bool getResult = OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, msgId); + getResult &= OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, testProviderID.c_str()); + getResult &= OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_STATE, state); + if (getResult == false) + { + OCRepPayloadDestroy(payload); + } + EXPECT_EQ(true, getResult); + + return payload; + } + + OCRepPayload * getTopicPayload() + { + size_t dimensions[MAX_REP_ARRAY_DEPTH] = {3, 0, 0}; + OCRepPayload ** topicList = (OCRepPayload **)malloc(sizeof(OCRepPayload *)*3); + EXPECT_NE((void *)NULL, topicList); + for (int i = 0; i < 3; ++i) + { + topicList[i] = OCRepPayloadCreate(); + EXPECT_NE((void *)NULL, topicList[i]); + + bool getResult = OCRepPayloadSetPropInt(topicList[i], + NS_ATTRIBUTE_TOPIC_SELECTION, 1); + getResult &= OCRepPayloadSetPropString(topicList[i], + NS_ATTRIBUTE_TOPIC_NAME, std::to_string(i+1).c_str()); + EXPECT_EQ(true, getResult); + } + + OCRepPayload * payload = OCRepPayloadCreate(); + EXPECT_NE((void *)NULL, payload); + bool getResult = OCRepPayloadSetPropString(payload, + NS_ATTRIBUTE_CONSUMER_ID, testProviderID.c_str()); + getResult &= OCRepPayloadSetPropObjectArray(payload, + NS_ATTRIBUTE_TOPIC_LIST, (const OCRepPayload **)topicList, dimensions); + if (getResult == false) + { + OCRepPayloadDestroy(payload); + } + EXPECT_EQ(true, getResult); + + return payload; + } + + OCClientResponse * getResponse() + { + OCClientResponse * testResponse = + (OCClientResponse *)malloc(sizeof(OCClientResponse)); + EXPECT_NE((void *)NULL, testResponse); + + std::string notiUri = "/notifiationTest"; + + testResponse->addr = testAddr; + testResponse->devAddr = *testAddr; + testResponse->connType = CT_ADAPTER_IP; + testResponse->identity.id_length = 37; + strncpy((char *)(testResponse->identity.id), testProviderID.c_str(), 37); + testResponse->numRcvdVendorSpecificHeaderOptions = 0; + testResponse->resourceUri = (char*)malloc(sizeof(char)*notiUri.size() + 1); + strncpy((char*)testResponse->resourceUri, notiUri.c_str(), notiUri.size()+1); + testResponse->result = OC_STACK_OK; + testResponse->sequenceNumber = 1; + testResponse->payload = NULL; + + return testResponse; + } + + NSProvider_internal * getProvider(OCDevAddr * addr) + { + if (addr == NULL) + { + return NULL; + } + + NSProviderConnectionInfo * info = + (NSProviderConnectionInfo *)malloc(sizeof(NSProviderConnectionInfo)); + if (info == NULL) + { + free(addr); + return NULL; + } + info->isCloudConnection = false; + info->isSubscribing = false; + info->messageHandle = NULL; + info->syncHandle = NULL; + info->next = NULL; + info->addr = addr; + + NSProvider_internal * provider = + (NSProvider_internal *)malloc(sizeof(NSProvider_internal)); + if (provider == NULL) + { + free(addr); + free(info); + return NULL; + } + provider->accessPolicy = NSSelector::NS_SELECTION_CONSUMER; + provider->state = NS_DISCOVERED; + strcpy(provider->providerId, testProviderID.c_str()); + provider->messageUri = strdup("/notificationTest/message"); + provider->syncUri = strdup("/notificationTest/sync"); + provider->topicUri = strdup("/notificationTest/topic"); + provider->topicLL = NULL; + provider->connection = info; + + return provider; + } + + void stackInit() + { + static OCPersistentStorage gps {client_open, fread, fwrite, fclose, unlink }; + OC::PlatformConfig occfg + { + OC::ServiceType::InProc, + OC::ModeType::Both, + "0.0.0.0", + 0, + OC::QualityOfService::LowQos, + &gps + }; + OC::OCPlatform::Configure(occfg); + + try + { + OC::OCPlatform::stopPresence(); + } + catch (...) + { + + } + + testAddr = getDevAddr(); + if (testAddr == NULL) + { + throw std::exception(); + } + } + void stackTearDown() + { + if (testAddr) + { + free(testAddr); + testAddr = NULL; + } + if (g_provider) + { + NSRemoveProvider(g_provider); + g_provider = NULL; + } + if (g_testResponse) + { + free((void*)(g_testResponse->resourceUri)); + free(g_testResponse); + g_testResponse = NULL; + } + } +} + +TEST(NotificationConsumerTest, StartConsumerNegativeNonSetChangedCB) +{ + cfg.changedCb = NULL; + cfg.messageCb = NSNotificationReceivedCallback; + cfg.syncInfoCb = NSSyncCallback; + + EXPECT_EQ(NS_ERROR, NSStartConsumer(cfg)); +} + +TEST(NotificationConsumerTest, StartConsumerNegativeNonSetNotiReceiveCB) +{ + cfg.changedCb = NSProviderChangedCallback; + cfg.messageCb = NULL; + cfg.syncInfoCb = NSSyncCallback; + + EXPECT_EQ(NS_ERROR, NSStartConsumer(cfg)); +} + +TEST(NotificationConsumerTest, StartConsumerNegativeNonSetSyncCB) +{ + cfg.changedCb = NSProviderChangedCallback; + cfg.messageCb = NSNotificationReceivedCallback; + cfg.syncInfoCb = NULL; + + EXPECT_EQ(NS_ERROR, NSStartConsumer(cfg)); +} + +TEST(NotificationConsumerTest, StartConsumerPositive) +{ + + EXPECT_NO_THROW(stackInit()); + + cfg.changedCb = NSProviderChangedCallback; + cfg.messageCb = NSNotificationReceivedCallback; + cfg.syncInfoCb = NSSyncCallback; + + EXPECT_EQ(NS_OK, NSStartConsumer(cfg)); +} + +TEST(NotificationConsumerTest, StopConsumerPositive) +{ + EXPECT_EQ(NSStopConsumer(), NS_OK); +} + +TEST(NotificationConsumerTest, StopConsumerNegative) +{ + EXPECT_EQ(NSStopConsumer(), NS_ERROR); +} + +TEST(NotificationConsumerTest, ExpectCallbackDiscovered) +{ + cfg.changedCb = NSProviderChangedCallback; + cfg.messageCb = NSNotificationReceivedCallback; + cfg.syncInfoCb = NSSyncCallback; + + NSStartConsumer(cfg); + + revState = NS_STOPPED; + expectedState = NS_DISCOVERED; + + g_testResponse = getResponse(); + g_testResponse->payload = (OCPayload *)getDiscoverPayload(); + NSIntrospectProvider(NULL, NULL, g_testResponse); + + std::unique_lock< std::mutex > lock{ providerChangedLock }; + providerChanged.wait_for(lock, g_waitForResponse); + + OCRepPayloadDestroy((OCRepPayload *)g_testResponse->payload); + g_testResponse->payload = NULL; + + EXPECT_EQ(NS_DISCOVERED, revState); +} + +TEST(NotificationConsumerTest, ExpectCallbackAllow) +{ + revState = NS_STOPPED; + expectedState = NS_ALLOW; + + g_testResponse->payload = (OCPayload *)getMsgPayload(NS_ALLOW); + NSConsumerMessageListener(NULL,NULL, g_testResponse); + + std::unique_lock< std::mutex > lock{ providerChangedLock }; + providerChanged.wait_for(lock, g_waitForResponse); + + OCRepPayloadDestroy((OCRepPayload *)g_testResponse->payload); + g_testResponse->payload = NULL; + + EXPECT_EQ(NS_ALLOW, revState); +} + +TEST(NotificationConsumerTest, ExpectReceiveNotification) +{ + uint64_t id = 100; + + g_testResponse->payload = (OCPayload *)getMsgPayload(id); + NSConsumerMessageListener(NULL,NULL, g_testResponse); + + std::unique_lock< std::mutex > lock{ messageReceiveLock }; + messageReceive.wait_for(lock, g_waitForResponse); + + OCRepPayloadDestroy((OCRepPayload *)g_testResponse->payload); + g_testResponse->payload = NULL; + + EXPECT_EQ(id, revId); +} + +TEST(NotificationConsumerTest, ExpectReceiveSyncInfo) +{ + uint64_t id = 100; + type = NS_SYNC_DELETED; + + g_testResponse->payload = (OCPayload *)getSyncPayload(id, NS_SYNC_READ); + NSConsumerSyncInfoListener(NULL,NULL, g_testResponse); + + std::unique_lock< std::mutex > lock{ syncReceiveLock }; + syncReceive.wait_for(lock, g_waitForResponse); + + OCRepPayloadDestroy((OCRepPayload *)g_testResponse->payload); + g_testResponse->payload = NULL; + + EXPECT_EQ(NS_SYNC_READ, type); +} + +TEST(NotificationConsumerTest, ExpectSuccessSendSyncInfo) +{ + uint64_t id = 100; + type = NS_SYNC_READ; + + auto ret = NSConsumerSendSyncInfo(g_provider->providerId, id, NS_SYNC_DELETED); + + EXPECT_EQ(NS_OK, ret); +} + +TEST(NotificationConsumerTest, GetValidProvider) +{ + NSProvider * provider = NSConsumerGetProvider(g_provider->providerId); + EXPECT_NE((void *)NULL, provider); + NSRemoveProvider(provider); +} + +TEST(NotificationConsumerTest, GetInvalidProvider) +{ + NSProvider * provider = NSConsumerGetProvider(NULL); + EXPECT_EQ((void *)NULL, provider); +} + +TEST(NotificationConsumerTest, ExpectGetTopicListIsNULL) +{ + NSTopicLL * currentTopics = NSConsumerGetTopicList(g_provider->providerId); + EXPECT_EQ(NULL, currentTopics); + + if (currentTopics) + { + NSRemoveTopicLL(currentTopics); + } +} + +TEST(NotificationConsumerTest, ExpectCallbackTopicUpdated) +{ + revState = NS_STOPPED; + + g_testResponse->payload = (OCPayload *)getTopicPayload(); + g_provider_internal = getProvider(testAddr); + NSIntrospectTopic((void *)g_provider_internal, NULL, g_testResponse); + + expectedState = NS_TOPIC; + std::unique_lock< std::mutex > lock{ providerChangedLock }; + providerChanged.wait_for(lock, g_waitForResponse); + + EXPECT_EQ(NS_TOPIC, revState); + + OCRepPayloadDestroy((OCRepPayload *)g_testResponse->payload); + g_testResponse->payload = NULL; + + expectedState = NS_STOPPED; +} + +TEST(NotificationConsumerTest, ExpectEQTopicList) +{ + bool isSame = true; + + typedef std::list TesttopicList; + TesttopicList topics; + topics.push_back("1"); + topics.push_back("2"); + topics.push_back("3"); + + NSTopicLL * retTopic = NSConsumerGetTopicList(g_provider_internal->providerId); + EXPECT_NE((void *)NULL, retTopic); + + NSTopicLL * iter = retTopic; + std::for_each (topics.begin(), topics.end(), + [this, & iter, & isSame](const std::string & str) + { + isSame &= (str == std::string(iter->topicName)); + iter = iter->next; + }); + + NSRemoveTopicLL(retTopic); + + EXPECT_EQ(true, isSame); +} + +TEST(NotificationConsumerTest, ExpectSuccessUpdateTopicOnConsumer) +{ + NSTopicLL * retTopic = NSConsumerGetTopicList(g_provider_internal->providerId); + + NSTopicLL * iter = retTopic; + for (; iter; iter = iter->next) + { + iter->state = NS_TOPIC_SUBSCRIBED; + } + NSResult ret = NSConsumerUpdateTopicList(g_provider_internal->providerId, retTopic); + + NSRemoveTopicLL(retTopic); + + EXPECT_EQ(NS_OK, ret); +} + +TEST(NotificationConsumerTest, ExpectUnsubscribeSuccess) +{ + revState = NS_DENY; + NSResult ret = NSUnsubscribe(g_provider_internal->providerId); + + expectedState = NS_STOPPED; + std::unique_lock< std::mutex > lock{ providerChangedLock }; + providerChanged.wait_for(lock, g_waitForResponse); + + EXPECT_EQ(NS_STOPPED, revState); + EXPECT_EQ(NS_OK, ret); +} + +TEST(NotificationConsumerTest, ExpectUnsubscribeWithPresenceStart) +{ + OCPresencePayload * payload = OCPresencePayloadCreate(1, 2, OC_PRESENCE_TRIGGER_CREATE, NULL); + EXPECT_NE((void *)NULL, payload); + g_testResponse->payload = (OCPayload *)payload; + + auto ret = NSConsumerPresenceListener(NULL,NULL, g_testResponse); + + EXPECT_EQ(OC_STACK_KEEP_TRANSACTION, ret); + OCPresencePayloadDestroy(payload); +} + +TEST(NotificationConsumerTest, ExpectUnsubscribeWithPresenceStop) +{ + OCPresencePayload * payload = OCPresencePayloadCreate(2, 2, OC_PRESENCE_TRIGGER_DELETE, NULL); + EXPECT_NE((void *)NULL, payload); + g_testResponse->payload = (OCPayload *)payload; + + auto ret = NSConsumerPresenceListener(NULL,NULL, g_testResponse); + + EXPECT_EQ(OC_STACK_KEEP_TRANSACTION, ret); + OCPresencePayloadDestroy(payload); + + NSStopConsumer(); + + stackTearDown(); +} diff --git a/service/notification/unittest/NSProviderTest.cpp b/service/notification/unittest/NSProviderTest.cpp index 74044c5..0a5390a 100755 --- a/service/notification/unittest/NSProviderTest.cpp +++ b/service/notification/unittest/NSProviderTest.cpp @@ -37,7 +37,7 @@ namespace /// Reasonable timeout is set to 1000 ms in unsecured mode unsigned int g_timeout = 1000; #ifdef SECURED - g_timeout = 2 * g_timeout + g_timeout = 2 * g_timeout; #endif std::chrono::milliseconds g_waitForResponse(g_timeout); @@ -239,7 +239,7 @@ TEST_F(NotificationProviderTest, ExpectCallbackWhenReceiveSubscribeRequestWithAc #ifdef SECURED timemout = 2 * timemout; #endif - std::chrono::milliseconds waitForSubscription(timemout); + std::chrono::milliseconds waitForSubscription(timeout); std::unique_lock< std::mutex > lock{ responseProviderSubLock }; responseProviderSub.wait_for(lock, waitForSubscription); @@ -578,7 +578,7 @@ TEST_F(NotificationProviderTest, CancelObserves) { bool ret = g_consumerSimul.cancelObserves(); - std::chrono::milliseconds waitForTerminate(g_timemout); + std::chrono::milliseconds waitForTerminate(g_timeout); std::this_thread::sleep_for(waitForTerminate); EXPECT_EQ(ret, true); diff --git a/service/notification/unittest/NSProviderTest2.cpp b/service/notification/unittest/NSProviderTest2.cpp new file mode 100644 index 0000000..25b9cae --- /dev/null +++ b/service/notification/unittest/NSProviderTest2.cpp @@ -0,0 +1,519 @@ +//****************************************************************** +// +// Copyright 2017 Samsung Electronics 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 "OCPlatform.h" +#include "ocpayload.h" + +#include "NSCommon.h" +#include "NSConstants.h" +#include "NSProviderInterface.h" + +#include "NSProviderListener.h" +#include "NSUnittestUtil.h" + +namespace +{ + std::chrono::milliseconds g_waitForResponse(1000); + + std::condition_variable responseProviderSub; + std::mutex responseProviderSubLock; + + std::condition_variable responseProviderSync; + std::mutex responseProviderSyncLock; + + char * g_consumerID = NULL; + int expectedMsgId; + int expectedSyncType = NS_SYNC_READ; + + const std::string testConsumerId = "123456789012345678901234567890123457"; + + static FILE* server_open(const char * path, const char * mode) + { + if (0 == strcmp(path, OC_SECURITY_DB_DAT_FILE_NAME)) + { + std::string file_name = "./oic_svr_db_ns.dat"; +#ifndef LOCAL_RUNNING + file_name = "./service/notification/unittest/oic_svr_db_ns.dat"; +#endif + return fopen(file_name.c_str(), mode); + } + else + { + return fopen(path, mode); + } + } + + static void NSRequestedSubscribeCallback(NSConsumer * consumer) + { + if (g_consumerID) + { + free(g_consumerID); + } + g_consumerID = strdup(consumer->consumerId); + + responseProviderSub.notify_all(); + } + + static void NSSyncCallback(NSSyncInfo * sync) + { + expectedSyncType = sync->state; + expectedMsgId = sync->messageId; + free(sync); + responseProviderSync.notify_all(); + } + + OCEntityHandlerRequest * getEntityRequest(OCMethod method, OCObserveAction action) + { + static OCObservationId id = 10; + OCEntityHandlerRequest * request = + (OCEntityHandlerRequest *)malloc(sizeof(OCEntityHandlerRequest)); + EXPECT_NE((void *)NULL, request); + + if (OC_REST_OBSERVE == method) + { + request->obsInfo.action = action; + request->obsInfo.obsId = id++; + + std::string query = std::string(NS_QUERY_CONSUMER_ID) + + "=" + testConsumerId; + request->query = (char *)malloc(sizeof(char) * query.size() + 1); + strncpy(request->query, query.c_str(), query.size() + 1); + } + request->method = method; + request->numRcvdVendorSpecificHeaderOptions = 0; + + return request; + } + + OCEntityHandlerRequest * getPostSyncEntityRequest(uint64_t id) + { + OCEntityHandlerRequest * request = + (OCEntityHandlerRequest *)malloc(sizeof(OCEntityHandlerRequest)); + EXPECT_NE((void *)NULL, request); + + request->method = OC_REST_POST; + request->numRcvdVendorSpecificHeaderOptions = 0; + request->query = NULL; + + OCRepPayload * payload = OCRepPayloadCreate(); + EXPECT_NE((void *)NULL, payload); + + bool ret = OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, id); + OCUUIdentity provider; + OC::OCPlatform::getDeviceId(&provider); + ret &= OCRepPayloadSetPropString(payload, + NS_ATTRIBUTE_PROVIDER_ID, (const char *)provider.id); + ret &= OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_STATE, NS_SYNC_READ); + EXPECT_EQ(true, ret); + + request->payload = (OCPayload *) payload; + + return request; + } + + void stackInit() + { + static OCPersistentStorage gps {server_open, fread, fwrite, fclose, unlink }; + + OC::PlatformConfig cfg + { + OC::ServiceType::InProc, + OC::ModeType::Both, + "0.0.0.0", + 0, + OC::QualityOfService::HighQos, + &gps + }; + OC::OCPlatform::Configure(cfg); + + try + { + OC::OCPlatform::stopPresence(); + } + catch (...) + { + + } + } +} + +TEST(NotificationProviderTest, StartProviderPositiveWithNSPolicyTrue) +{ + stackInit(); + + NSProviderConfig config; + config.subRequestCallback = NSRequestedSubscribeCallback; + config.syncInfoCallback = NSSyncCallback; + config.subControllability = true; + config.userInfo = strdup("user1"); + config.resourceSecurity = false; + + NSResult ret = NSStartProvider(config); + + EXPECT_EQ(ret, NS_OK); + free(config.userInfo); + config.userInfo = NULL; +} + +TEST(NotificationProviderTest, StopProviderPositive) +{ + NSResult ret = NSStopProvider(); + + EXPECT_EQ(ret, NS_OK); +} + +TEST(NotificationProviderTest, ExpectCallbackSubscribeRequestWithAccepterProvider) +{ + NSProviderConfig config; + config.subRequestCallback = NSRequestedSubscribeCallback; + config.syncInfoCallback = NSSyncCallback; + config.subControllability = true; + config.userInfo = NULL; + config.resourceSecurity = false; + + NSStartProvider(config); + + OCEntityHandlerFlag flag = OC_OBSERVE_FLAG; + OCEntityHandlerRequest * msgRequest = getEntityRequest(OC_REST_OBSERVE, OC_OBSERVE_REGISTER); + NSEntityHandlerMessageCb(flag, msgRequest, NULL); + { + std::unique_lock< std::mutex > lock{ responseProviderSubLock }; + responseProviderSub.wait_for(lock, g_waitForResponse); + } + free(msgRequest->query); + free(msgRequest); + + OCEntityHandlerRequest * syncRequest = getEntityRequest(OC_REST_OBSERVE, OC_OBSERVE_REGISTER); + NSEntityHandlerSyncCb(flag, syncRequest, NULL); + + free(syncRequest->query); + free(syncRequest); + + EXPECT_NE((void *)NULL, g_consumerID); +} + +TEST(NotificationProviderTest, ExpectSuccessSendAllow) +{ + auto ret = NSAcceptSubscription(g_consumerID, true); + EXPECT_EQ(NS_OK, ret); +} + +TEST(NotificationProviderTest, ExpectFailGetRequestForNotificationWithInvalidInterface) +{ + OCEntityHandlerFlag flag = OC_REQUEST_FLAG; + OCEntityHandlerRequest * getRequest = getEntityRequest(OC_REST_GET, OC_OBSERVE_NO_OPTION); + std::string query = std::string("if=") + "test.invalid"; + getRequest->query = strdup(query.c_str()); + auto ret = NSEntityHandlerNotificationCb(flag, getRequest, NULL); + + EXPECT_NE(ret, OC_EH_OK); + + free(getRequest->query); + free(getRequest); +} + +TEST(NotificationProviderTest, ExpectFailGetRequestForMsgWithInvalidInterface) +{ + OCEntityHandlerFlag flag = OC_REQUEST_FLAG; + OCEntityHandlerRequest * getRequest = getEntityRequest(OC_REST_GET, OC_OBSERVE_NO_OPTION); + std::string query = std::string("if=") + "test.invalid"; + getRequest->query = strdup(query.c_str()); + auto ret = NSEntityHandlerMessageCb(flag, getRequest, NULL); + + EXPECT_NE(ret, OC_EH_OK); + + free(getRequest->query); + free(getRequest); +} + +TEST(NotificationProviderTest, ExpectFailGetRequestForSyncWithInvalidInterface) +{ + OCEntityHandlerFlag flag = OC_REQUEST_FLAG; + OCEntityHandlerRequest * getRequest = getEntityRequest(OC_REST_GET, OC_OBSERVE_NO_OPTION); + std::string query = std::string("if=") + "test.invalid"; + getRequest->query = strdup(query.c_str()); + auto ret = NSEntityHandlerSyncCb(flag, getRequest, NULL); + + EXPECT_NE(ret, OC_EH_OK); + + free(getRequest->query); + free(getRequest); +} + +TEST(NotificationProviderTest, ExpectFailGetRequestForTopicWithInvalidInterface) +{ + OCEntityHandlerFlag flag = OC_REQUEST_FLAG; + OCEntityHandlerRequest * getRequest = getEntityRequest(OC_REST_GET, OC_OBSERVE_NO_OPTION); + std::string query = std::string("if=") + "test.invalid"; + getRequest->query = strdup(query.c_str()); + auto ret = NSEntityHandlerTopicCb(flag, getRequest, NULL); + + EXPECT_NE(ret, OC_EH_OK); + + free(getRequest->query); + free(getRequest); +} + +TEST(NotificationProviderTest, ExpectSuccessGetRequestForTopicWithInvalidInterface) +{ + OCEntityHandlerFlag flag = OC_REQUEST_FLAG; + OCEntityHandlerRequest * getRequest = getEntityRequest(OC_REST_GET, OC_OBSERVE_NO_OPTION); + std::string query = std::string("if=") + NS_INTERFACE_BASELINE; + getRequest->query = strdup(query.c_str()); + auto ret = NSEntityHandlerTopicCb(flag, getRequest, NULL); + + EXPECT_EQ(ret, OC_EH_OK); + + free(getRequest->query); + free(getRequest); +} + +TEST(NotificationProviderTest, ExpectCallbackReceiveSync) +{ + int id = 100; + int type = NS_SYNC_READ; + + OCEntityHandlerFlag flag = OC_REQUEST_FLAG; + NSEntityHandlerSyncCb(flag, getPostSyncEntityRequest(id), NULL); + + std::unique_lock< std::mutex > lock{ responseProviderSyncLock }; + responseProviderSync.wait_for(lock, g_waitForResponse); + + EXPECT_EQ(expectedMsgId, id); + EXPECT_EQ(expectedSyncType, type); +} + +TEST(NotificationProviderTest, ExpectSuccessSetTopics) +{ + std::string str("TEST1"); + std::string str2("TEST2"); + auto ret = NSProviderRegisterTopic(str.c_str()); + EXPECT_EQ(NS_OK, ret); + ret = NSProviderRegisterTopic(str2.c_str()); + EXPECT_EQ(NS_OK, ret); +} + +TEST(NotificationProviderTest, ExpectSuccessUnsetTopics) +{ + std::string str("TEST1"); + std::string str2("TEST2"); + auto ret = NSProviderUnregisterTopic(str.c_str()); + EXPECT_EQ(NS_OK, ret); + ret = NSProviderUnregisterTopic(str2.c_str()); + EXPECT_EQ(NS_OK, ret); +} + +TEST(NotificationProviderTest, ExpectSuccessTopicAllowConsumer) +{ + std::string str("TEST1"); + std::string str2("TEST2"); + auto ret = NSProviderRegisterTopic(str.c_str()); + EXPECT_EQ(NS_OK, ret); + ret = NSProviderRegisterTopic(str2.c_str()); + EXPECT_EQ(NS_OK, ret); + + ret = NSProviderSetConsumerTopic(g_consumerID, str.c_str()); + EXPECT_EQ(NS_OK, ret); + ret = NSProviderSetConsumerTopic(g_consumerID, str2.c_str()); + EXPECT_EQ(NS_OK, ret); +} + +TEST(NotificationProviderTest, ExpectSuccessTopicDenyConsumer) +{ + std::string str("TEST1"); + std::string str2("TEST2"); + + auto ret = NSProviderUnsetConsumerTopic(g_consumerID, str.c_str()); + EXPECT_EQ(NS_OK, ret); + ret = NSProviderUnsetConsumerTopic(g_consumerID, str2.c_str()); + EXPECT_EQ(NS_OK, ret); +} + +TEST(NotificationProviderTest, ExpectEqualUnSetConsumerTopicsAndGetConsumerTopics) +{ + std::string str("TEST1"); + std::string str2("TEST2"); + NSProviderSetConsumerTopic(g_consumerID, str2.c_str()); + + bool isSame = false; + + NSTopicLL * topics = NSProviderGetConsumerTopics(g_consumerID); + + if(!topics) + { + isSame = false; + } + else + { + NSTopicLL * firstData = topics; + NSTopicLL * secondData = firstData->next; + + if(str.compare(firstData->topicName) == 0 && str2.compare(secondData->topicName) == 0 + && ((int)firstData->state) == 0 && ((int)secondData->state) == 1) + { + isSame = true; + } + } + + removeTopics(topics); + + NSProviderUnregisterTopic(str.c_str()); + NSProviderUnregisterTopic(str2.c_str()); + EXPECT_EQ(isSame, true); +} + +TEST(NotificationProviderTest, ExpectSuccessCreateMessage) +{ + auto msg = NSCreateMessage(); + EXPECT_NE((void *)NULL, msg); + NSFreeMessage(msg); +} + +TEST(NotificationProviderTest, ExpectCopyMessage) +{ + auto msg = NSCreateMessage(); + auto copied = NSDuplicateMessage(msg); + EXPECT_EQ(msg->messageId, copied->messageId); + NSFreeMessage(msg); + NSFreeMessage(copied); +} + +TEST(NotificationProviderTest, ExpectSuccessSendMessage) +{ + auto msg = NSCreateMessage(); + auto ret = NSSendMessage(msg); + EXPECT_EQ(NS_OK, ret); + NSFreeMessage(msg); +} + +TEST(NotificationProviderTest, ExpectCopyConsumer) +{ + auto consumer = (NSConsumer *)malloc(sizeof(NSConsumer)); + strcpy(consumer->consumerId, g_consumerID); + + auto copied = NSDuplicateConsumer(consumer); + EXPECT_EQ(0, strcmp(copied->consumerId, consumer->consumerId)); + + NSFreeConsumer(consumer); + NSFreeConsumer(copied); +} + +TEST(NotificationProviderTest, ExpectFailSendMessageWithNULL) +{ + NSResult ret = NSSendMessage(NULL); + EXPECT_NE(NS_OK, ret); +} + +TEST(NotificationProviderTest, ExpectFailAcceptSubscription) +{ + NSResult result; + result = NS_SUCCESS; + result = NSAcceptSubscription(NULL, true); + result = NSAcceptSubscription("\0", true); + + EXPECT_EQ(result, NS_FAIL); +} + +TEST(NotificationProviderTest, ExpectFailRegisterTopic) +{ + NSResult result; + result = NS_SUCCESS; + result = NSProviderRegisterTopic(NULL); + result = NSProviderRegisterTopic("\0"); + + EXPECT_EQ(result, NS_FAIL); +} + +TEST(NotificationProviderTest, ExpectFailUnregisterTopic) +{ + NSResult result; + result = NS_SUCCESS; + result = NSProviderUnregisterTopic(NULL); + result = NSProviderUnregisterTopic("\0"); + + EXPECT_EQ(result, NS_FAIL); +} + +TEST(NotificationProviderTest, ExpectFailGetConsumerTopics) +{ + NSTopicLL topic; + NSTopicLL * topicLL = &topic; + + topicLL = NSProviderGetConsumerTopics(NULL); + topicLL = NSProviderGetConsumerTopics("\0"); + + EXPECT_EQ(topicLL, (NSTopicLL *)NULL); +} + +TEST(NotificationProviderTest, ExpectFailSetConsumerTopics) +{ + NSResult result; + result = NS_SUCCESS; + result = NSProviderSetConsumerTopic(NULL, NULL); + result = NSProviderSetConsumerTopic(NULL, "\0"); + result = NSProviderSetConsumerTopic("\0", NULL); + result = NSProviderSetConsumerTopic("\0", "\0"); + result = NSProviderSetConsumerTopic("abc", NULL); + result = NSProviderSetConsumerTopic(NULL, "abc"); + result = NSProviderSetConsumerTopic("abc", "\0"); + result = NSProviderSetConsumerTopic("\0", "abc"); + + EXPECT_EQ(result, NS_FAIL); +} + +TEST(NotificationProviderTest, ExpectFailUnsetConsumerTopics) +{ + NSResult result; + result = NS_SUCCESS; + result = NSProviderUnsetConsumerTopic(NULL, NULL); + result = NSProviderUnsetConsumerTopic(NULL, "\0"); + result = NSProviderUnsetConsumerTopic("\0", NULL); + result = NSProviderUnsetConsumerTopic("\0", "\0"); + result = NSProviderUnsetConsumerTopic("abc", NULL); + result = NSProviderUnsetConsumerTopic(NULL, "abc"); + result = NSProviderUnsetConsumerTopic("abc", "\0"); + result = NSProviderUnsetConsumerTopic("\0", "abc"); + + EXPECT_EQ(result, NS_FAIL); +} + +TEST(NotificationProviderTest, ExpectSuccessUnsub) +{ + OCEntityHandlerFlag flag = OC_OBSERVE_FLAG; + OCEntityHandlerRequest * msgRequest = + getEntityRequest(OC_REST_OBSERVE, OC_OBSERVE_DEREGISTER); + NSEntityHandlerMessageCb(flag, msgRequest, NULL); + free(msgRequest->query); + free(msgRequest); + + OCEntityHandlerRequest * syncRequest = + getEntityRequest(OC_REST_OBSERVE, OC_OBSERVE_DEREGISTER); + NSEntityHandlerSyncCb(flag, syncRequest, NULL); + free(syncRequest->query); + free(syncRequest); + + NSStopProvider(); +} diff --git a/service/notification/unittest/SConscript b/service/notification/unittest/SConscript index 9d6ccaa..609f0b3 100644 --- a/service/notification/unittest/SConscript +++ b/service/notification/unittest/SConscript @@ -68,11 +68,16 @@ notification_test_env.AppendUnique(LIBS = ['pthread']) notification_test_env.PrependUnique(CPPPATH = [ src_dir + '/extlibs/hippomocks-master', gtest_dir + '/include']) notification_test_env.AppendUnique(CPPPATH = ['../include']) +notification_test_env.AppendUnique(CPPPATH = ['../src/consumer']) +notification_test_env.AppendUnique(CPPPATH = ['../src/provider']) +notification_test_env.AppendUnique(CPPPATH = ['../src/common']) +notification_test_env.AppendUnique(CPPPATH = [src_dir + '/resource/csdk/connectivity/api']) if env.get('WITH_TCP') == True: notification_test_env.AppendUnique(CPPDEFINES = ['WITH_TCP']) if env.get('SECURED') == '1': notification_test_env.AppendUnique(LIBS = ['mbedtls', 'mbedx509', 'mbedcrypto']) + notification_test_env.AppendUnique(CPPPATH = ['#/resource/csdk/security/include']) ###################################################################### # Build Test @@ -84,16 +89,26 @@ notification_consumer_test_env.AppendUnique(LIBS = ['notification_consumer']) notification_provider_test_env = notification_test_env.Clone() notification_provider_test_env.AppendUnique(LIBS = ['notification_provider']) -notification_consumer_test_src = env.Glob('./NSConsumerTest.cpp') +notification_consumer_test_src = env.Glob('./NSConsumerTest2.cpp') notification_consumer_test = notification_consumer_test_env.Program('notification_consumer_test', notification_consumer_test_src) Alias("notification_consumer_test", notification_consumer_test) env.AppendTarget('notification_consumer_test') -notification_provider_test_src = env.Glob('./NSProviderTest.cpp') -notification_provider_test = notification_provider_test_env.Program('notification_provider_test', notification_provider_test_src) +notification_consumer_test_src = env.Glob('./NSConsumerTest.cpp') +notification_consumer_internaltest = notification_consumer_test_env.Program('notification_consumer_internaltest', notification_consumer_test_src) +Alias("notification_consumer_internaltest", notification_consumer_internaltest) + +notification_provider_test_src = env.Glob('./NSProviderTest2.cpp') +notification_provider_test = notification_provider_test_env.Program( + 'notification_provider_test', notification_provider_test_src) Alias("notification_provider_test", notification_provider_test) env.AppendTarget('notification_provider_test') +notification_provider_test_src = env.Glob('./NSProviderTest.cpp') +notification_provider_internaltest = notification_provider_test_env.Program( + 'notification_provider_internaltest', notification_provider_test_src) +Alias("notification_provider_internaltest", notification_provider_internaltest) + # TODO: Fix this test for MLK and remove commented lines if env.get('TEST') == '1': if target_os in ['linux'] and env.get('SECURED') != '1': -- 2.7.4