Unit test of Notification serivces is added for public APIs on positive case.
Change-Id: Ie658a444b2b7cc6052cb64933f54bfd58ceceb5c
Signed-off-by: jyong2.kim <jyong2.kim@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/8209
Tested-by: jenkins-iotivity <jenkins-iotivity@opendaylight.org>
Reviewed-by: Uze Choi <uzchoi@samsung.com>
# 'service/notification', 'NSConsumerIngerface.h')
# Go to build Unit test
-#if target_os == 'linux':
-# SConscript('unittest/SConscript')
+if target_os == 'linux':
+ SConscript('unittest/SConscript')
# Go to build sample apps
SConscript('examples/SConscript')
--- /dev/null
+//******************************************************************
+//
+// Copyright 2016 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _NS_CONSUMER_SIMULATOR_H_
+#define _NS_CONSUMER_SIMULATOR_H_
+
+#include <iostream>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+
+class NSConsumerSimulator
+{
+private:
+ std::function<void(const std::string&, const std::string&, const std::string&)> m_messageFunc;
+ std::function<void(int, const std::string&)> m_syncFunc;
+
+ std::shared_ptr<OC::OCResource> m_syncResource;
+
+
+public:
+ NSConsumerSimulator()
+ : m_messageFunc(), m_syncFunc(),
+ m_syncResource() { };
+ ~NSConsumerSimulator() = default;
+
+ NSConsumerSimulator(const NSConsumerSimulator &) = delete;
+ NSConsumerSimulator & operator = (const NSConsumerSimulator &) = delete;
+
+ NSConsumerSimulator(NSConsumerSimulator &&) = delete;
+ NSConsumerSimulator & operator = (NSConsumerSimulator &&) = delete;
+
+ void findProvider()
+ {
+ OC::OCPlatform::findResource("", std::string("/oic/res?rt=oic.r.notification"),
+ OCConnectivityType::CT_DEFAULT,
+ std::bind(&NSConsumerSimulator::findResultCallback, this, std::placeholders::_1),
+ OC::QualityOfService::LowQos);
+ }
+
+ void syncToProvider(int & type, const std::string & id)
+ {
+ if (m_syncResource == nullptr)
+ {
+ std::cout << "m_syncResource is null" << std::endl;
+ return;
+ }
+
+ OC::OCRepresentation rep;
+ rep.setValue("ID", id);
+ rep.setValue("STATE", type);
+
+ m_syncResource->post(rep, OC::QueryParamsMap(), &onPost, OC::QualityOfService::LowQos);
+ }
+
+ void setCallback(const std::function<void(const std::string&, const std::string&, const std::string&)> & messageFunc,
+ const std::function<void(int, const std::string&)> & syncFunc)
+ {
+ m_messageFunc = messageFunc;
+ m_syncFunc = syncFunc;
+ }
+
+private:
+ static void onPost(const OC::HeaderOptions &/*headerOption*/,
+ const OC::OCRepresentation & /*rep*/ , const int eCode)
+ {
+ std::cout << __func__ << " result : " << eCode << std::endl;
+ }
+ void findResultCallback(std::shared_ptr<OC::OCResource> resource)
+ {
+ std::cout << __func__ << " " << resource->host() << std::endl;
+ resource->get(OC::QueryParamsMap(),
+ std::bind(&NSConsumerSimulator::onGet, this,
+ std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, resource),
+ OC::QualityOfService::LowQos);
+ }
+ void onGet(const OC::HeaderOptions &/*headerOption*/,
+ const OC::OCRepresentation & rep , const int eCode,
+ std::shared_ptr<OC::OCResource> resource)
+ {
+ std::cout << __func__ << " " << rep.getHost() << " result : " << eCode << std::endl;
+
+ std::shared_ptr<OC::OCResource> msgResource
+ = OC::OCPlatform::constructResourceObject(resource->host(), resource->uri() + "/message",
+ resource->connectivityType(), false, resource->getResourceTypes(),
+ resource->getResourceInterfaces());
+ m_syncResource
+ = OC::OCPlatform::constructResourceObject(resource->host(), resource->uri() + "/sync",
+ resource->connectivityType(), false, resource->getResourceTypes(),
+ resource->getResourceInterfaces());
+
+ msgResource->observe(OC::ObserveType::Observe, OC::QueryParamsMap(),
+ std::bind(&NSConsumerSimulator::onObserve, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3, std::placeholders::_4, resource),
+ OC::QualityOfService::LowQos);
+ m_syncResource->observe(OC::ObserveType::Observe, OC::QueryParamsMap(),
+ std::bind(&NSConsumerSimulator::onObserve, this,
+ std::placeholders::_1, std::placeholders::_2,
+ std::placeholders::_3, std::placeholders::_4, resource),
+ OC::QualityOfService::LowQos);
+
+ }
+ void onObserve(const OC::HeaderOptions &/*headerOption*/,
+ const OC::OCRepresentation &rep , const int &eCode, const int &,
+ std::shared_ptr<OC::OCResource> )
+ {
+ std::cout << __func__ << " " << rep.getHost() << " result : " << eCode;
+ std::cout << " uri : " << rep.getUri() << std::endl;
+
+ if (rep.getUri() == "/notification/message" && rep.hasAttribute("ID")
+ && rep.getValueToString("ID") != "0000-0000-0000-0000")
+ {
+ std::cout << "ID : " << rep.getValueToString("ID") << std::endl;
+ std::cout << "TITLE : " << rep.getValueToString("TITLE") << std::endl;
+ std::cout << "CONTENT : " << rep.getValueToString("CONTENT") << std::endl;
+ m_messageFunc(std::string(rep.getValueToString("ID")),
+ std::string(rep.getValueToString("TITLE")),
+ std::string(rep.getValueToString("CONTENT")));
+ }
+ else if (rep.getUri() == "/notification/sync")
+ {
+ m_syncFunc(int(rep.getValue<int>("STATE")),
+ std::string(rep.getValueToString("ID")));
+ }
+ }
+};
+
+
+#endif //_NS_CONSUMER_SIMULATOR_H_
--- /dev/null
+//******************************************************************
+//
+// Copyright 2016 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 <gtest/gtest.h>
+#include <HippoMocks/hippomocks.h>
+#include <atomic>
+#include <functional>
+#include <condition_variable>
+#include <mutex>
+#include <chrono>
+
+#include "ocstack.h"
+
+#include "NSCommon.h"
+#include "NSConsumerInterface.h"
+
+#include "NSProviderSimulator.h"
+
+namespace
+{
+ NSProviderSimulator g_providerSimul;
+ NSProvider * g_provider;
+
+ std::atomic_bool g_isStartedStack(false);
+
+ std::chrono::milliseconds g_waitForResponse(500);
+
+ std::condition_variable responseCon;
+ std::mutex mutexForCondition;
+
+}
+
+class TestWithMock: public testing::Test
+{
+public:
+ MockRepository mocks;
+
+protected:
+ virtual ~TestWithMock() noexcept(noexcept(std::declval<Test>().~Test())) {}
+
+ virtual void TearDown() {
+ try
+ {
+ mocks.VerifyAll();
+ }
+ catch (...)
+ {
+ mocks.reset();
+ throw;
+ }
+ }
+};
+
+class NotificationConsumerTest : public TestWithMock
+{
+public:
+ NotificationConsumerTest() = default;
+ ~NotificationConsumerTest() = default;
+
+ static void NSProviderDiscoveredCallbackEmpty(NSProvider *)
+ {
+ std::cout << __func__ << std::endl;
+ }
+
+ static void NSNotificationReceivedCallbackEmpty(NSProvider *, NSMessage *) { }
+
+ static void NSSyncCallbackEmpty(NSProvider *, NSSync *) { }
+
+ static void foundResourceEmpty(std::shared_ptr< OC::OCResource >) { }
+
+protected:
+
+ void SetUp()
+ {
+ TestWithMock::SetUp();
+
+ if (g_isStartedStack == false)
+ {
+ OC::PlatformConfig cfg
+ {
+ OC::ServiceType::InProc,
+ OC::ModeType::Both,
+ "0.0.0.0",
+ 0,
+ OC::QualityOfService::LowQos
+ };
+ OC::OCPlatform::Configure(cfg);
+
+ try
+ {
+ OC::OCPlatform::stopPresence();
+ }
+ catch (...)
+ {
+
+ }
+
+ g_isStartedStack = true;
+ }
+
+ }
+
+ void TearDown()
+ {
+ TestWithMock::TearDown();
+ }
+
+};
+
+TEST_F(NotificationConsumerTest, StartConsumerPositive)
+{
+ EXPECT_EQ(NS_OK,
+ NSStartConsumer(
+ NSProviderDiscoveredCallbackEmpty,
+ NSNotificationReceivedCallbackEmpty,
+ NSSyncCallbackEmpty));
+}
+
+TEST_F(NotificationConsumerTest, StopConsumerPositive)
+{
+ EXPECT_EQ(NSStopConsumer(), NS_OK);
+}
+
+TEST_F(NotificationConsumerTest, DiscoverProviderWithNonAccepterWhenStartedConsumerFirst)
+{
+ mocks.ExpectCallFunc(NSProviderDiscoveredCallbackEmpty).Do(
+ [this, & responseCon](NSProvider *)
+ {
+ std::cout << "Call Discovered" << std::endl;
+ responseCon.notify_all();
+ });
+
+ NSStartConsumer(
+ NSProviderDiscoveredCallbackEmpty,
+ NSNotificationReceivedCallbackEmpty,
+ NSSyncCallbackEmpty);
+
+ g_providerSimul.setAccepter(1);
+ g_providerSimul.createNotificationResource();
+
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+
+ NSStopConsumer();
+ g_providerSimul.deleteNotificationResource();
+}
+
+TEST_F(NotificationConsumerTest, DiscoverProviderWithNonAccepterWhenStartedConsumerAfter)
+{
+ g_providerSimul.setAccepter(1);
+ g_providerSimul.createNotificationResource();
+ {
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+ }
+
+ mocks.ExpectCallFunc(NSProviderDiscoveredCallbackEmpty).Do(
+ [this, & responseCon](NSProvider *)
+ {
+ std::cout << "Call Discovered" << std::endl;
+ responseCon.notify_all();
+ });
+
+ NSStartConsumer(
+ NSProviderDiscoveredCallbackEmpty,
+ NSNotificationReceivedCallbackEmpty,
+ NSSyncCallbackEmpty);
+
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+
+}
+
+TEST_F(NotificationConsumerTest, DiscoverProviderWithNonAccepterWhenRescan)
+{
+ mocks.ExpectCallFunc(NSProviderDiscoveredCallbackEmpty)
+ .Do(
+ [this, & responseCon](NSProvider * provider)
+ {
+ std::cout << "Call Discovered" << std::endl;
+ g_provider = provider;
+ responseCon.notify_all();
+ });
+
+ NSRescanProvider();
+
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+
+// NSStopConsumer();
+}
+
+TEST_F(NotificationConsumerTest, ExpectSubscribeSuccess)
+{
+ NSResult ret = NSSubscribe(g_provider);
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+
+ EXPECT_EQ(NS_OK, ret);
+}
+
+TEST_F(NotificationConsumerTest, ExpectReceiveNotification)
+{
+ std::string id = "id";
+ std::string title = "title";
+ std::string msg = "msg";
+
+ mocks.ExpectCallFunc(NSNotificationReceivedCallbackEmpty).Do(
+ [](NSProvider *, NSMessage * message)
+ {
+ std::cout << "Income Notification : " << message->mId << std::endl;
+ NSDropNSObject(message);
+ });
+
+ g_providerSimul.notifyMessage(id, title, msg);
+
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+
+}
+
+TEST_F(NotificationConsumerTest, ExpectUnsubscribeSuccess)
+{
+ NSResult ret = NSUnsubscribe(g_provider);
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+
+ EXPECT_EQ(NS_OK, ret);
+}
+
+TEST_F(NotificationConsumerTest, ExpectReceiveNotificationWithAccepterisProvider)
+{
+ std::string id = "ExpectReceiveNotificationWithAccepterisProvider";
+ std::string title = "title";
+ std::string msg = "msg";
+
+ g_providerSimul.setAccepter(0);
+
+ NSRescanProvider();
+ {
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+ }
+
+ mocks.ExpectCallFunc(NSNotificationReceivedCallbackEmpty).Do(
+ [](NSProvider *, NSMessage * message)
+ {
+ std::cout << "Income Notification : " << message->mId << std::endl;
+ NSDropNSObject(message);
+ });
+
+ g_providerSimul.notifyMessage(id, title, msg);
+
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+
+// g_providerSimul.deleteNotificationResource();
+// NSStopConsumer();
+}
+
+TEST_F(NotificationConsumerTest, ExpectCallbackReadCheckWhenProviderNotifySync)
+{
+ std::string id = "ExpectCallbackReadCheckWhenProviderNotifySync";
+ std::string title = "title";
+ std::string msg = "msg";
+
+ NSSyncTypes type = Notification_Dismiss;
+
+ mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
+ [](NSProvider *, NSMessage * message)
+ {
+ std::cout << "Income Notification : " << message->mId << std::endl;
+ NSDropNSObject(message);
+ });
+
+ mocks.ExpectCallFunc(NSSyncCallbackEmpty).Do(
+ [& type](NSProvider *, NSSync * sync)
+ {
+ std::cout << "Income Notification : " << sync->mMessageId
+ << ", State : " << sync->mState << std::endl;
+ type = sync->mState;
+
+ });
+
+ g_providerSimul.notifyMessage(id, title, msg);
+ {
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+ }
+
+ g_providerSimul.sendRead(id);
+ {
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+ }
+
+// g_providerSimul.deleteNotificationResource();
+// NSStopConsumer();
+
+ EXPECT_EQ(Notification_Read, type);
+}
+
+TEST_F(NotificationConsumerTest, ExpectCallbackDismissCheckWhenProviderNotifySync)
+{
+ std::string id = "ExpectCallbackDismissCheckWhenProviderNotifySync";
+ std::string title = "title";
+ std::string msg = "msg";
+
+ NSSyncTypes type = Notification_Read;
+
+ mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
+ [](NSProvider *, NSMessage * message)
+ {
+ std::cout << "Income Notification : " << message->mId << std::endl;
+ NSDropNSObject(message);
+ });
+
+ mocks.ExpectCallFunc(NSSyncCallbackEmpty).Do(
+ [& type](NSProvider *, NSSync * sync)
+ {
+ std::cout << "Income Notification : " << sync->mMessageId
+ << ", State : " << sync->mState << std::endl;
+ type = sync->mState;
+
+ });
+
+ g_providerSimul.notifyMessage(id, title, msg);
+ {
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+ }
+
+ g_providerSimul.sendDismiss(id);
+ {
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+ }
+
+// g_providerSimul.deleteNotificationResource();
+// NSStopConsumer();
+
+ EXPECT_EQ(Notification_Dismiss, type);
+}
+
+TEST_F(NotificationConsumerTest, ExpectCallbackReadCheckWhenConsumerPostSync)
+{
+ std::string id = "ExpectCallbackReadCheckWhenConsumerPostSync";
+ std::string title = "title";
+ std::string msg = "msg";
+
+ NSSyncTypes type = Notification_Dismiss;
+
+ mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
+ [](NSProvider *, NSMessage * message)
+ {
+ std::cout << "Income Notification : " << message->mId << std::endl;
+ NSConsumerReadCheck(message);
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+ });
+
+ mocks.ExpectCallFunc(NSSyncCallbackEmpty).Do(
+ [& type](NSProvider *, NSSync * sync)
+ {
+ std::cout << "Income Notification : " << sync->mMessageId
+ << ", State : " << sync->mState << std::endl;
+ type = sync->mState;
+
+ });
+
+ g_providerSimul.notifyMessage(id, title, msg);
+ {
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+ }
+
+// g_providerSimul.deleteNotificationResource();
+// NSStopConsumer();
+
+ EXPECT_EQ(Notification_Read, type);
+}
+
+TEST_F(NotificationConsumerTest, ExpectCallbackDismissCheckWhenConsumerPostSync)
+{
+ std::string id = "ExpectCallbackDismissCheckWhenConsumerPostSync";
+ std::string title = "title";
+ std::string msg = "msg";
+
+ NSSyncTypes type = Notification_Read;
+
+ mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
+ [](NSProvider *, NSMessage * message)
+ {
+ std::cout << "Income Notification : " << message->mId << std::endl;
+ NSConsumerDismissCheck(message);
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+ });
+
+ mocks.ExpectCallFunc(NSSyncCallbackEmpty).Do(
+ [& type](NSProvider *, NSSync * sync)
+ {
+ std::cout << "Income Notification : " << sync->mMessageId
+ << ", State : " << sync->mState << std::endl;
+ type = sync->mState;
+
+ });
+
+ g_providerSimul.notifyMessage(id, title, msg);
+ {
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+ }
+
+ g_providerSimul.deleteNotificationResource();
+ NSStopConsumer();
+
+ EXPECT_EQ(Notification_Dismiss, type);
+}
--- /dev/null
+//******************************************************************
+//
+// Copyright 2016 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef _NS_PROVIDER_SIMULATOR_H_
+#define _NS_PROVIDER_SIMULATOR_H_
+
+#include <iostream>
+
+#include "OCPlatform.h"
+#include "OCApi.h"
+#include "OCResourceResponse.h"
+
+namespace
+{
+ enum class requestType
+ {
+ NS_NOTIFICATION,
+ NS_MESSAGE,
+ NS_SYNC,
+ };
+}
+
+class NSProviderSimulator
+{
+private:
+ OCResourceHandle m_notificationHandle;
+ OCResourceHandle m_messageHandle;
+ OCResourceHandle m_syncHandle;
+ OC::OCRepresentation m_syncRep;
+ OC::OCRepresentation m_messageRep;
+ int m_accepter;
+
+ std::string m_notificationUri;
+ std::string m_messageUri;
+ std::string m_syncUri;
+
+ OC::ObservationIds m_syncObservers;
+
+public:
+ NSProviderSimulator()
+ : m_notificationHandle(), m_messageHandle(), m_syncHandle(),
+ m_syncRep(), m_messageRep(), m_accepter(0),
+ m_notificationUri(std::string("/notification")),
+ m_messageUri(std::string("/message")),
+ m_syncUri(std::string("/sync")),
+ m_syncObservers() { };
+
+ ~NSProviderSimulator() = default;
+
+ NSProviderSimulator(const NSProviderSimulator &) = delete;
+ NSProviderSimulator & operator = (const NSProviderSimulator &) = delete;
+
+ NSProviderSimulator(NSProviderSimulator &&) = delete;
+ NSProviderSimulator & operator = (NSProviderSimulator &&) = delete;
+
+private:
+ std::shared_ptr<OC::OCResourceResponse> getResponse(
+ std::shared_ptr< OC::OCResourceRequest > requests, requestType type)
+ {
+ auto response = std::make_shared<OC::OCResourceResponse>();
+ response->setRequestHandle(requests->getRequestHandle());
+ response->setResourceHandle(requests->getResourceHandle());
+
+ int requestFlag = requests->getRequestHandlerFlag();
+ if (requestFlag == OC::RequestHandlerFlag::RequestFlag)
+ {
+ std::string request = requests->getRequestType();
+
+ response->setErrorCode(200);
+ response->setResponseResult(OC_EH_OK);
+
+ if (request == "GET")
+ {
+ OC::OCRepresentation rep;
+
+ if (type == requestType::NS_NOTIFICATION)
+ {
+ std::string msgUri = m_notificationUri + m_messageUri;
+ std::string syncUri = m_notificationUri + m_syncUri;
+ rep.setValue("ACCEPTER", m_accepter);
+ rep.setValue("MESSAGE_URI", msgUri);
+ rep.setValue("SYNC_URI", syncUri);
+ }
+ else if (type == requestType::NS_SYNC)
+ {
+ rep = m_syncRep;
+ }
+ else if (type == requestType::NS_MESSAGE)
+ {
+ rep = m_messageRep;
+ }
+ else
+ {
+ return NULL;
+ }
+
+ response->setResourceRepresentation(rep);
+ return response;
+ }
+
+ else if (request == "POST" && type == requestType::NS_SYNC)
+ {
+ m_syncRep = requests->getResourceRepresentation();
+
+ std::cout << "Receive POST at Sync" << std::endl;
+ std::cout << "Sync Id : " << m_syncRep.getValueToString("ID") << std::endl;
+ std::cout << "Sync State : " << m_syncRep.getValueToString("STATE") << std::endl;
+
+ response->setResourceRepresentation(m_syncRep);
+
+ OC::OCPlatform::notifyListOfObservers(m_syncHandle, m_syncObservers, response);
+
+ return response;
+ }
+ }
+
+ return NULL;
+ }
+
+ void setObserver(std::shared_ptr< OC::OCResourceRequest > requests, requestType type)
+ {
+ if (type == requestType::NS_SYNC)
+ {
+ OC::ObservationInfo observationInfo = requests->getObservationInfo();
+ if (OC::ObserveAction::ObserveRegister == observationInfo.action)
+ {
+ m_syncObservers.push_back(observationInfo.obsId);
+ }
+ else if (OC::ObserveAction::ObserveUnregister == observationInfo.action)
+ {
+ m_syncObservers.erase(std::remove(
+ m_syncObservers.begin(), m_syncObservers.end(),
+ observationInfo.obsId), m_syncObservers.end());
+ }
+ }
+ }
+
+ OCEntityHandlerResult entityHandler(
+ std::shared_ptr< OC::OCResourceRequest > request, requestType type)
+ {
+ if (!request)
+ {
+ return OC_EH_ERROR;
+ }
+
+ std::cout << "Provider : Income request : " << request->getRequestHandlerFlag() << std::endl;
+ if ((request->getRequestHandlerFlag() & OC::RequestHandlerFlag::ObserverFlag))
+ {
+ std::cout << "Provider : Income Observe : " << std::endl;
+ setObserver(request, type);
+ return OC_EH_OK;
+ }
+
+ auto pResponse = getResponse(request, type);
+ if (pResponse == nullptr)
+ {
+ return OC_EH_ERROR;
+ }
+
+ try
+ {
+ OC::OCPlatform::sendResponse(pResponse);
+ }
+ catch (std::exception & e)
+ {
+ return OC_EH_ERROR;
+ }
+
+ return OC_EH_OK;
+ }
+
+public:
+
+ void setAccepter(int accepter)
+ {
+ m_accepter = accepter;
+ }
+
+ void notifyMessage()
+ {
+ std::cout << "Provider : notify~" << std::endl;
+ OC::OCPlatform::notifyAllObservers(m_messageHandle);
+ }
+
+ void notifyMessage(const std::string & id, const std::string & title, const std::string & content)
+ {
+ setMessage(id, title, content);
+ notifyMessage();
+ }
+
+ void sendRead(const std::string & id)
+ {
+ m_syncRep.setValue("ID", id);
+ m_syncRep.setValue("STATE", (int)0);
+ OC::OCPlatform::notifyAllObservers(m_syncHandle);
+ }
+ void sendDismiss(const std::string & id)
+ {
+ m_syncRep.setValue("ID", id);
+ m_syncRep.setValue("STATE", (int)1);
+ OC::OCPlatform::notifyAllObservers(m_syncHandle);
+ }
+
+ void setMessage(const std::string & id, const std::string & title, const std::string & content)
+ {
+ m_messageRep.setValue("ID", id);
+ m_messageRep.setValue("TITLE", title);
+ m_messageRep.setValue("CONTENTTEXT", content);
+ }
+
+ void deleteNotificationResource()
+ {
+ OC::OCPlatform::unregisterResource(m_notificationHandle);
+ OC::OCPlatform::unregisterResource(m_messageHandle);
+ OC::OCPlatform::unregisterResource(m_syncHandle);
+ }
+
+ void createNotificationResource()
+ {
+ createNotificationResource(m_notificationUri);
+ }
+
+ void createNotificationResource(const std::string & uri)
+ {
+ if (m_notificationUri != uri)
+ {
+ m_notificationUri = uri;
+ }
+
+ OC::OCPlatform::startPresence(30);
+
+ std::string notificationUri = m_notificationUri;
+ std::string resourceTypeName = "oic.r.message.notification";
+ std::string resourceInterface = OC::DEFAULT_INTERFACE;
+
+ uint8_t resourceProperty = OC_OBSERVABLE;
+ std::string childUri = uri + m_messageUri;
+ try
+ {
+ OC::OCPlatform::registerResource(
+ m_messageHandle, childUri,
+ resourceTypeName, resourceInterface,
+ std::bind(& NSProviderSimulator::entityHandler, this,
+ std::placeholders::_1, requestType::NS_MESSAGE),
+ resourceProperty);
+ } catch (std::exception & e)
+ {
+ std::cout << e.what() << std::endl;
+ }
+
+ resourceTypeName = "oic.r.sync.notification";
+ childUri = uri + m_syncUri;
+ try
+ {
+ OC::OCPlatform::registerResource(
+ m_syncHandle, childUri,
+ resourceTypeName, resourceInterface,
+ std::bind(& NSProviderSimulator::entityHandler, this,
+ std::placeholders::_1, requestType::NS_SYNC),
+ resourceProperty);
+ } catch (std::exception & e)
+ {
+ std::cout << e.what() << std::endl;
+ }
+
+ resourceProperty = OC_DISCOVERABLE;
+ resourceTypeName = "oic.r.notification";
+ try
+ {
+ OC::OCPlatform::registerResource(
+ m_notificationHandle, notificationUri,
+ resourceTypeName, resourceInterface,
+ std::bind(& NSProviderSimulator::entityHandler, this,
+ std::placeholders::_1, requestType::NS_NOTIFICATION),
+ resourceProperty);
+ } catch (std::exception & e)
+ {
+ std::cout << e.what() << std::endl;
+ }
+ }
+};
+
+#endif /* _NS_PROVIDER_SIMULATOR_H_ */
--- /dev/null
+//******************************************************************
+//
+// Copyright 2016 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 <gtest/gtest.h>
+#include <HippoMocks/hippomocks.h>
+#include <atomic>
+#include <functional>
+#include <condition_variable>
+#include <mutex>
+#include <chrono>
+
+#include "NSConsumerSimulator.h"
+
+#include "NSCommon.h"
+#include "NSProviderInterface.h"
+
+namespace
+{
+ std::atomic_bool g_isStartedStack(false);
+
+ std::chrono::milliseconds g_waitForResponse(500);
+
+ std::condition_variable responseCon;
+ std::mutex mutexForCondition;
+
+ NSConsumerSimulator g_consumerSimul;
+ NSConsumer * g_consumer;
+
+}
+
+class TestWithMock: public testing::Test
+{
+public:
+ MockRepository mocks;
+
+protected:
+ virtual ~TestWithMock() noexcept(noexcept(std::declval<Test>().~Test())) {}
+
+ virtual void TearDown() {
+ try
+ {
+ mocks.VerifyAll();
+ }
+ catch (...)
+ {
+ mocks.reset();
+ throw;
+ }
+ }
+};
+
+class NotificationProviderTest : public TestWithMock
+{
+public:
+ NotificationProviderTest() = default;
+ ~NotificationProviderTest() = default;
+
+ static void NSRequestedSubscribeCallbackEmpty(NSConsumer *)
+ {
+ std::cout << __func__ << std::endl;
+ }
+
+ static void NSSyncCallbackEmpty(NSSync *)
+ {
+ std::cout << __func__ << std::endl;
+ }
+
+ static void NSMessageCallbackFromConsumerEmpty(
+ const std::string &, const std::string &, const std::string &)
+ {
+ std::cout << __func__ << std::endl;
+ }
+
+ static void NSSyncCallbackFromConsumerEmpty(int, const std::string &)
+ {
+ std::cout << __func__ << std::endl;
+ }
+
+protected:
+
+ void SetUp()
+ {
+ TestWithMock::SetUp();
+
+ if (g_isStartedStack == false)
+ {
+ OC::PlatformConfig cfg
+ {
+ OC::ServiceType::InProc,
+ OC::ModeType::Both,
+ "0.0.0.0",
+ 0,
+ OC::QualityOfService::LowQos
+ };
+ OC::OCPlatform::Configure(cfg);
+
+ try
+ {
+ OC::OCPlatform::stopPresence();
+ }
+ catch (...)
+ {
+
+ }
+
+ g_isStartedStack = true;
+ }
+
+ }
+
+ void TearDown()
+ {
+ TestWithMock::TearDown();
+ }
+
+};
+
+TEST_F(NotificationProviderTest, StartProviderPositive)
+{
+ NSResult ret = NSStartProvider(NS_ACCEPTER_PROVIDER,
+ NSRequestedSubscribeCallbackEmpty,
+ NSSyncCallbackEmpty);
+
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+
+ EXPECT_EQ(ret, NS_OK);
+}
+
+TEST_F(NotificationProviderTest, StopProviderPositive)
+{
+ NSResult ret = NSStopProvider();
+
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+
+ EXPECT_EQ(ret, NS_OK);
+}
+
+TEST_F(NotificationProviderTest, ExpectCallbackWhenReceiveSubscribeRequestWithAccepterProvider)
+{
+ mocks.ExpectCallFunc(NSRequestedSubscribeCallbackEmpty).Do(
+ [](NSConsumer * consumer)
+ {
+ std::cout << "NSRequestedSubscribeCallback" << std::endl;
+ g_consumer = consumer;
+ responseCon.notify_all();
+ });
+
+ NSStartProvider(NS_ACCEPTER_PROVIDER,
+ NSRequestedSubscribeCallbackEmpty, NSSyncCallbackEmpty);
+
+ {
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+ }
+
+ g_consumerSimul.setCallback(NSMessageCallbackFromConsumerEmpty,
+ NSSyncCallbackFromConsumerEmpty);
+ g_consumerSimul.findProvider();
+
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, std::chrono::milliseconds(1000));
+}
+
+TEST_F(NotificationProviderTest, NeverCallNotifyOnConsumerByAcceptIsFalse)
+{
+ bool expectTrue = true;
+
+ mocks.OnCallFunc(NSMessageCallbackFromConsumerEmpty).Do(
+ [& expectTrue](const std::string &id, const std::string&, const std::string&)
+ {
+ if (id == "NeverCallNotifyOnConsumerByAcceptIsFalse")
+ {
+ std::cout << "This function never call" << std::endl;
+ expectTrue = false;
+ }
+ });
+
+ NSAccept(g_consumer, false);
+
+ NSMessage * msg = new NSMessage();
+ msg->mId = strdup(std::string("NeverCallNotifyOnConsumerByAcceptIsFalse").c_str());
+ msg->mTitle = strdup(std::string("Title").c_str());
+ msg->mContentText = strdup(std::string("ContentText").c_str());
+ NSSendNotification(msg);
+ {
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+ }
+
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, std::chrono::milliseconds(1000));
+
+ EXPECT_EQ(expectTrue, true);
+}
+
+TEST_F(NotificationProviderTest, ExpectCallNotifyOnConsumerByAcceptIsTrue)
+{
+ mocks.ExpectCallFunc(NSMessageCallbackFromConsumerEmpty).Do(
+ [](const std::string &id, const std::string&, const std::string&)
+ {
+ if (id == "ExpectCallNotifyOnConsumerByAcceptIsTrue")
+ {
+ std::cout << "ExpectCallNotifyOnConsumerByAcceptIsTrue" << std::endl;
+ responseCon.notify_all();
+ }
+ });
+
+ NSAccept(g_consumer, true);
+
+ NSMessage * msg = new NSMessage();
+ msg->mId = strdup(std::string("ExpectCallNotifyOnConsumerByAcceptIsTrue").c_str());
+ msg->mTitle = strdup(std::string("Title").c_str());
+ msg->mContentText = strdup(std::string("ContentText").c_str());
+ NSSendNotification(msg);
+ {
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+ }
+
+ std::unique_lock< std::mutex > lock{ mutexForCondition };
+ responseCon.wait_for(lock, g_waitForResponse);
+}
+
+//TEST_F(NotificationProviderTest, ExpectCallbackSyncOnReadToConsumer)
+//{
+// int type = 0;
+// std::string id = "ExpectCallNotifyOnConsumerByAcceptIsTrue";
+// mocks.ExpectCallFunc(NSSyncCallbackFromConsumerEmpty).Do(
+// [& id](int type, const std::string & syncId)
+// {
+// std::cout << "NSSyncCallbackEmpty" << std::endl;
+// if (syncId == id &&
+// type == Notification_Read)
+// {
+// std::cout << "ExpectCallbackSyncOnReadFromConsumer" << std::endl;
+// responseCon.notify_all();
+// }
+// });
+//
+// NSMessage * msg = new NSMessage();
+// msg->mId = strdup(std::string("ExpectCallNotifyOnConsumerByAcceptIsTrue").c_str());
+// msg->mTitle = strdup(std::string("Title").c_str());
+// msg->mContentText = strdup(std::string("ContentText").c_str());
+// NSProviderReadCheck(msg);
+// std::unique_lock< std::mutex > lock{ mutexForCondition };
+// responseCon.wait_for(lock, std::chrono::milliseconds(5000));
+//}
+
+//TEST_F(NotificationProviderTest, ExpectCallbackSyncOnReadFromConsumer)
+//{
+// int type = 0;
+// std::string id("ExpectCallNotifyOnConsumerByAcceptIsTrue");
+// mocks.ExpectCallFunc(NSSyncCallbackEmpty).Do(
+// [& id](NSSync * sync)
+// {
+// std::cout << "NSSyncCallbackEmpty" << std::endl;
+// if (sync->mMessageId == id && sync->mState == Notification_Read)
+// {
+// std::cout << "ExpectCallbackSyncOnReadFromConsumer" << std::endl;
+// responseCon.notify_all();
+// }
+// });
+//
+// g_consumerSimul.syncToProvider(type, std::string(id));
+// std::unique_lock< std::mutex > lock{ mutexForCondition };
+// responseCon.wait_for(lock, std::chrono::milliseconds(5000));
+//}
--- /dev/null
+#******************************************************************
+#
+# Copyright 2016 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.
+#
+#-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+##
+# Notification Unit Test build script
+##
+
+Import('env')
+
+if env.get('RELEASE'):
+ env.AppendUnique(CCFLAGS = ['-Os'])
+ env.AppendUnique(CPPDEFINES = ['NDEBUG'])
+else:
+ env.AppendUnique(CCFLAGS = ['-g'])
+
+if env.get('LOGGING'):
+ env.AppendUnique(CPPDEFINES = ['TB_LOG'])
+
+lib_env = env.Clone()
+SConscript(env.get('SRC_DIR') + '/service/third_party_libs.scons', 'lib_env')
+
+######################################################################
+#unit test setting
+######################################################################
+src_dir = lib_env.get('SRC_DIR')
+gtest_dir = src_dir + '/extlibs/gtest/gtest-1.7.0'
+
+notification_test_env = lib_env.Clone()
+target_os = env.get('TARGET_OS')
+
+######################################################################
+# Build flags
+######################################################################
+GTest = File(gtest_dir + '/lib/.libs/libgtest.a')
+GTest_Main = File(gtest_dir + '/lib/.libs/libgtest_main.a')
+
+notification_test_env.AppendUnique(LIBPATH = [lib_env.get('BUILD_DIR')])
+notification_test_env.AppendUnique(LIBS = [
+ 'connectivity_abstraction', 'oc', 'octbstack', 'oc_logger', 'coap',
+ GTest_Main, GTest])
+
+if target_os not in ['windows', 'winrt']:
+ notification_test_env.AppendUnique(CXXFLAGS = ['-O2', '-g', '-Wall', '-fmessage-length=0', '-std=c++0x'])
+
+notification_test_env.AppendUnique(CXXFLAGS = ['-pthread'])
+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'])
+
+#if not env.get('RELEASE'):
+# notification_test_env.PrependUnique(LIBS = ['gcov'])
+# notification_test_env.AppendUnique(CXXFLAGS = ['--coverage'])
+
+######################################################################
+# Build Test
+######################################################################
+
+notification_consumer_test_env = notification_test_env.Clone()
+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 = 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)
+Alias("notification_provider_test", notification_provider_test)
+env.AppendTarget('notification_provider_test')
+
+if env.get('TEST') == '1':
+ if target_os == 'linux':
+ from tools.scons.RunTest import *
+ run_test(notification_consumer_test_env, '', 'service/notification/unittest/notification_consumer_test')
+ #run_test(notification_provider_test_env, '', 'service/notification/unittest/notification_provider_test')
\ No newline at end of file