namespace
{
- constexpr unsigned int LIMITNUMBER = std::numeric_limits<unsigned int>::max();;
+ constexpr unsigned int LIMITNUMBER = std::numeric_limits<unsigned int>::max();
constexpr unsigned int INTERVALTIME = 60000;
}
}
void RCSDiscoveryManagerImpl::onResourceFound(std::shared_ptr< PrimitiveResource > resource,
- RCSDiscoveryManagerImpl::ID discoveryId, const RCSDiscoveryManager::ResourceDiscoveredCallback& discoverCB)
+ RCSDiscoveryManagerImpl::ID discoveryId,
+ const RCSDiscoveryManager::ResourceDiscoveredCallback& discoverCB)
{
{
std::lock_guard<std::mutex> lock(m_mutex);
ID discoveryId = createId();
auto discoverCb = std::bind(&RCSDiscoveryManagerImpl::onResourceFound, this,
std::placeholders::_1, discoveryId, std::move(cb));
- DiscoverRequestInfo discoveryItem(RCSAddressDetail::getDetail(address)->getAddress(), relativeUri,
+ DiscoveryRequestInfo discoveryItem(RCSAddressDetail::getDetail(address)->getAddress(), relativeUri,
resourceType, std::move(discoverCb));
discoveryItem.discoverRequest();
+ std::lock_guard<std::mutex> lock(m_mutex);
m_discoveryMap.insert(std::make_pair(discoveryId, std::move(discoveryItem)));
return std::unique_ptr<RCSDiscoveryManager::DiscoveryTask>(
{
throw RCSException { "Discovery request is full!" };
}
-
+ s_uniqueId++;
while(m_discoveryMap.find(s_uniqueId) != m_discoveryMap.end())
{
s_uniqueId++;
m_discoveryMap.erase(id);
}
- DiscoverRequestInfo::DiscoverRequestInfo(const std::string &address, const std::string &relativeUri,
+ bool RCSDiscoveryManagerImpl::isCanceled(unsigned int id)
+ {
+ std::lock_guard<std::mutex> lock(m_mutex);
+ auto it = m_discoveryMap.find(id);
+ if(it == m_discoveryMap.end()) return true;
+
+ return false;
+ }
+
+ DiscoveryRequestInfo::DiscoveryRequestInfo(const std::string &address, const std::string &relativeUri,
const std::string &resourceType, DiscoverCallback cb) : m_address(address),
m_relativeUri(relativeUri), m_resourceType(resourceType), m_discoverCB(cb) {}
- void DiscoverRequestInfo::discoverRequest() const
+ void DiscoveryRequestInfo::discoverRequest() const
{
OIC::Service::discoverResource(m_address, m_relativeUri + "?rt=" + m_resourceType,
OCConnectivityType::CT_DEFAULT, m_discoverCB);
}
- bool DiscoverRequestInfo::isKnownResource(const std::shared_ptr<PrimitiveResource>& resource)
+ bool DiscoveryRequestInfo::isKnownResource(const std::shared_ptr<PrimitiveResource>& resource)
{
std::string resourceId = resource->getSid() + resource->getUri();
return false;
}
- bool DiscoverRequestInfo::isMatchingAddress(const std::string& address) const
+ bool DiscoveryRequestInfo::isMatchingAddress(const std::string& address) const
{
return m_address == RCSAddressDetail::getDetail(RCSAddress::multicast())->getAddress()
|| m_address == address;
#include "OCPlatform.h"
+#include <condition_variable>
+#include <mutex>
+
using namespace OIC::Service;
using namespace OC::OCPlatform;
constexpr char RESOURCEURI[]{ "/a/TemperatureSensor" };
constexpr char RESOURCETYPE[]{ "resource.type" };
constexpr char RESOURCEINTERFACE[]{ "oic.if.baseline" };
-constexpr int DiscoveryTaskDELAYTIME = 7;
+constexpr int DEFAULT_DISCOVERYTASK_DELAYTIME = 3000;
+
+void resourceDiscoveredForCall(RCSRemoteResourceObject::Ptr) {}
+void resourceDiscoveredForNeverCall(RCSRemoteResourceObject::Ptr) {}
class DiscoveryManagerTest: public TestWithMock
{
public:
- RCSResourceObject::Ptr server;
- RCSRemoteResourceObject::Ptr object;
- std::unique_ptr<RCSDiscoveryManager::DiscoveryTask> discoveryTask;
-
+ typedef std::unique_ptr<RCSDiscoveryManager::DiscoveryTask> DiscoveryTaskPtr;
+ typedef std::function< void(std::shared_ptr< RCSRemoteResourceObject >) >
+ ResourceDiscoveredCallback;
public:
- void startDiscovery()
+ static DiscoveryTaskPtr discoverResource(ResourceDiscoveredCallback cb)
{
const std::string uri = "/oic/res";
- discoveryTask = RCSDiscoveryManager::getInstance()->discoverResourceByType(RCSAddress::multicast(),
- uri, RESOURCETYPE, &resourceDiscovered);
+ return RCSDiscoveryManager::getInstance()->discoverResourceByType(RCSAddress::multicast(),
+ uri, RESOURCETYPE, cb);
+ }
+
+ void startDiscovery()
+ {
+ discoveryTask = discoverResource(resourceDiscoveredForCall);
}
void cancelDiscovery()
discoveryTask->cancel();
}
+ bool isCanceled()
+ {
+ return discoveryTask->isCanceled();
+ }
+
void createResource()
{
server = RCSResourceObject::Builder(RESOURCEURI, RESOURCETYPE, RESOURCEINTERFACE).build();
}
- void waitForDiscoveryTask()
+ void proceed()
+ {
+ cond.notify_all();
+ }
+
+ void waitForDiscoveryTask(int waitingTime = DEFAULT_DISCOVERYTASK_DELAYTIME)
{
- sleep(DiscoveryTaskDELAYTIME);
+ std::unique_lock< std::mutex > lock{ mutex };
+ cond.wait_for(lock, std::chrono::milliseconds{ waitingTime });
}
- static void resourceDiscovered(std::shared_ptr< RCSRemoteResourceObject >) {}
+private:
+ std::condition_variable cond;
+ std::mutex mutex;
+ RCSResourceObject::Ptr server;
+ RCSRemoteResourceObject::Ptr object;
+ DiscoveryTaskPtr discoveryTask;
};
TEST_F(DiscoveryManagerTest, resourceIsNotSupportedPresenceBeforeDiscovering)
{
createResource();
- mocks.ExpectCallFunc(resourceDiscovered);
+ mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
+ [this](RCSRemoteResourceObject::Ptr){ proceed();});
startDiscovery();
waitForDiscoveryTask();
startPresence(10);
createResource();
- mocks.ExpectCallFunc(resourceDiscovered);
+ mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
+ [this](RCSRemoteResourceObject::Ptr){ proceed();});
startDiscovery();
waitForDiscoveryTask();
+ stopPresence();
}
TEST_F(DiscoveryManagerTest, resourceIsNotSupportedPresenceAfterDiscovering)
{
- mocks.ExpectCallFunc(resourceDiscovered);
+ mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
+ [this](RCSRemoteResourceObject::Ptr){ proceed();});
startDiscovery();
createResource();
TEST_F(DiscoveryManagerTest, resourceIsSupportedPresenceAndAfterDiscovering)
{
- mocks.ExpectCallFunc(resourceDiscovered);
+ mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
+ [this](RCSRemoteResourceObject::Ptr){ proceed();});
startPresence(10);
startDiscovery();
createResource();
waitForDiscoveryTask();
+ stopPresence();
}
TEST_F(DiscoveryManagerTest, cancelDiscoveryTaskAfterDiscoveryResource)
startDiscovery();
cancelDiscovery();
- mocks.NeverCallFunc(resourceDiscovered);
+ mocks.NeverCallFunc(resourceDiscoveredForCall);
- sleep(3);
+ waitForDiscoveryTask();
createResource();
-
}
TEST_F(DiscoveryManagerTest, cancelDiscoveryTaskNotStartDiscoveryResource)
cancelDiscovery();
cancelDiscovery();
}
+
+TEST_F(DiscoveryManagerTest, isCanceledAfterCancelDiscoveryTask)
+{
+ startDiscovery();
+ cancelDiscovery();
+
+ ASSERT_TRUE(isCanceled());
+}
+
+TEST_F(DiscoveryManagerTest, multipleDiscoveryRequestAndCancelJustOneDiscoveryRequest)
+{
+ DiscoveryTaskPtr canceledTask = discoverResource(resourceDiscoveredForCall);
+ DiscoveryTaskPtr notCanceledTask_1 = discoverResource(resourceDiscoveredForCall);
+ DiscoveryTaskPtr notCanceledTask_2 = discoverResource(resourceDiscoveredForCall);
+
+ canceledTask->cancel();
+
+ ASSERT_TRUE(canceledTask->isCanceled());
+ ASSERT_FALSE(notCanceledTask_1->isCanceled());
+ ASSERT_FALSE(notCanceledTask_2->isCanceled());
+}
+
+TEST_F(DiscoveryManagerTest, equalDiscoveryRequestsAndCancelJustOneRequest)
+{
+ mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
+ [this](RCSRemoteResourceObject::Ptr){ proceed();});
+
+ mocks.NeverCallFunc(resourceDiscoveredForNeverCall);
+
+ DiscoveryTaskPtr notCanceledTask = discoverResource(resourceDiscoveredForCall);
+ DiscoveryTaskPtr canceledTask = discoverResource(resourceDiscoveredForNeverCall);
+ canceledTask->cancel();
+
+ createResource();
+ waitForDiscoveryTask();
+}