1029a365080f6ecd60ee6633117a3a1ec491ae80
[platform/upstream/iotivity.git] / service / resource-encapsulation / unittests / DiscoveryManagerTest.cpp
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
7 // Licensed under the Apache License, Version 2.0 (the "License");
8 // you may not use this file except in compliance with the License.
9 // You may obtain a copy of the License at
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include "UnitTestHelper.h"
22
23 #include "RCSRemoteResourceObject.h"
24 #include "RCSDiscoveryManager.h"
25 #include "RCSResourceObject.h"
26 #include "RCSAddress.h"
27
28 #include "OCPlatform.h"
29
30 #include <condition_variable>
31 #include <mutex>
32
33 using namespace OIC::Service;
34 using namespace OC::OCPlatform;
35
36 constexpr char RESOURCEURI[]{ "/a/TemperatureSensor" };
37 constexpr char SECOND_RESOURCEURI[]{ "/a/Light" };
38 constexpr char RESOURCETYPE[]{ "resource.type" };
39 constexpr char SECOND_RESOURCETYPE[]{ "resource.type.second" };
40 constexpr char RESOURCEINTERFACE[]{ "oic.if.baseline" };
41 constexpr int DEFAULT_DISCOVERYTASK_DELAYTIME = 3000;
42
43 void resourceDiscoveredForTwoTimesCall(RCSRemoteResourceObject::Ptr) {}
44 void resourceDiscoveredForCall(RCSRemoteResourceObject::Ptr) {}
45 void resourceDiscoveredForNeverCall(RCSRemoteResourceObject::Ptr) {}
46
47 class DiscoveryManagerTest: public TestWithMock
48 {
49 public:
50
51     typedef std::unique_ptr<RCSDiscoveryManager::DiscoveryTask> DiscoveryTaskPtr;
52     typedef std::function< void(std::shared_ptr< RCSRemoteResourceObject >) >
53                                        ResourceDiscoveredCallback;
54 public:
55
56     static DiscoveryTaskPtr discoverResource(ResourceDiscoveredCallback cb)
57     {
58         const std::string uri  = "/oic/res";
59         return RCSDiscoveryManager::getInstance()->discoverResourceByType(RCSAddress::multicast(),
60                  uri, RESOURCETYPE, cb);
61     }
62
63     void startDiscovery()
64     {
65         discoveryTask = discoverResource(resourceDiscoveredForCall);
66     }
67
68     void cancelDiscovery()
69     {
70         discoveryTask->cancel();
71     }
72
73     bool isCanceled()
74     {
75         return discoveryTask->isCanceled();
76     }
77
78     void createResource()
79     {
80         server = RCSResourceObject::Builder(RESOURCEURI, RESOURCETYPE, RESOURCEINTERFACE).build();
81     }
82
83     void createSecondResource()
84     {
85         secondServer = RCSResourceObject::Builder(SECOND_RESOURCEURI, SECOND_RESOURCETYPE, RESOURCEINTERFACE).build();
86     }
87
88     void proceed()
89     {
90         cond.notify_all();
91     }
92
93     void waitForDiscoveryTask(int waitingTime = DEFAULT_DISCOVERYTASK_DELAYTIME)
94     {
95         std::unique_lock< std::mutex > lock{ mutex };
96         cond.wait_for(lock, std::chrono::milliseconds{ waitingTime });
97     }
98
99 private:
100
101     std::condition_variable cond;
102     std::mutex mutex;
103     RCSResourceObject::Ptr server;
104     RCSResourceObject::Ptr secondServer;
105     RCSRemoteResourceObject::Ptr object;
106     DiscoveryTaskPtr discoveryTask;
107 };
108
109 TEST_F(DiscoveryManagerTest, resourceIsNotSupportedPresenceBeforeDiscovering)
110 {
111     createResource();
112
113     mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
114         [this](RCSRemoteResourceObject::Ptr){ proceed();});
115
116     startDiscovery();
117     waitForDiscoveryTask();
118 }
119
120 TEST_F(DiscoveryManagerTest, resourceIsSupportedPresenceBeforeDiscovering)
121 {
122     startPresence(10);
123     createResource();
124
125     mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
126         [this](RCSRemoteResourceObject::Ptr){ proceed();});
127
128     startDiscovery();
129     waitForDiscoveryTask();
130     stopPresence();
131 }
132
133 TEST_F(DiscoveryManagerTest, resourceIsNotSupportedPresenceAfterDiscovering)
134 {
135     mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
136         [this](RCSRemoteResourceObject::Ptr){ proceed();});
137
138     startDiscovery();
139     createResource();
140     waitForDiscoveryTask();
141 }
142
143 TEST_F(DiscoveryManagerTest, resourceIsSupportedPresenceAndAfterDiscovering)
144 {
145     mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
146         [this](RCSRemoteResourceObject::Ptr){ proceed();});
147
148     startPresence(10);
149     startDiscovery();
150     createResource();
151     waitForDiscoveryTask();
152     stopPresence();
153 }
154
155 TEST_F(DiscoveryManagerTest, discoveryRequestByMultipleResourceTypesAndFindResourceOfOneResourceType)
156 {
157     std::vector<std::string> resourceTypes{RESOURCETYPE, SECOND_RESOURCETYPE};
158     const std::string uri  = "/oic/res";
159
160     createSecondResource();
161
162     mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
163         [this](RCSRemoteResourceObject::Ptr){ proceed();});
164
165     RCSDiscoveryManager::getInstance()->discoverResourceByTypes(RCSAddress::multicast(),
166             uri, resourceTypes, resourceDiscoveredForCall);
167
168     waitForDiscoveryTask();
169 }
170
171 TEST_F(DiscoveryManagerTest, discoveryRequestByMultipleResourceTypesAndFindResourcesOfTwoResourceTypes)
172 {
173     std::vector<std::string> resourceTypes{RESOURCETYPE, SECOND_RESOURCETYPE};
174     const std::string uri  = "/oic/res";
175     unsigned int callTimes = 0;
176
177     createResource();
178     createSecondResource();
179
180     mocks.OnCallFunc(resourceDiscoveredForTwoTimesCall).Do(
181         [this, &callTimes](RCSRemoteResourceObject::Ptr){ 
182             callTimes++;
183             if (callTimes == 2) proceed();
184         }
185     );
186
187     RCSDiscoveryManager::getInstance()->discoverResourceByTypes(RCSAddress::multicast(),
188             uri, resourceTypes, resourceDiscoveredForTwoTimesCall);
189
190     waitForDiscoveryTask();
191
192     EXPECT_EQ(resourceTypes.size(), callTimes);
193 }
194
195 TEST_F(DiscoveryManagerTest, cancelDiscoveryTaskAfterDiscoveryResource)
196 {
197     startDiscovery();
198     cancelDiscovery();
199
200     mocks.NeverCallFunc(resourceDiscoveredForCall);
201
202     waitForDiscoveryTask();
203     createResource();
204 }
205
206 TEST_F(DiscoveryManagerTest, cancelDiscoveryTaskNotStartDiscoveryResource)
207 {
208     startDiscovery();
209     cancelDiscovery();
210     cancelDiscovery();
211 }
212
213 TEST_F(DiscoveryManagerTest, isCanceledAfterCancelDiscoveryTask)
214 {
215     startDiscovery();
216     cancelDiscovery();
217
218     ASSERT_TRUE(isCanceled());
219 }
220
221 TEST_F(DiscoveryManagerTest, multipleDiscoveryRequestAndCancelJustOneDiscoveryRequest)
222 {
223     DiscoveryTaskPtr canceledTask = discoverResource(resourceDiscoveredForCall);
224     DiscoveryTaskPtr notCanceledTask_1 = discoverResource(resourceDiscoveredForCall);
225     DiscoveryTaskPtr notCanceledTask_2 = discoverResource(resourceDiscoveredForCall);
226
227     canceledTask->cancel();
228
229     ASSERT_TRUE(canceledTask->isCanceled());
230     ASSERT_FALSE(notCanceledTask_1->isCanceled());
231     ASSERT_FALSE(notCanceledTask_2->isCanceled());
232 }
233
234 TEST_F(DiscoveryManagerTest, equalDiscoveryRequestsAndCancelJustOneRequest)
235 {
236     mocks.ExpectCallFunc(resourceDiscoveredForCall).Do(
237         [this](RCSRemoteResourceObject::Ptr){ proceed();});
238
239     mocks.NeverCallFunc(resourceDiscoveredForNeverCall);
240
241     DiscoveryTaskPtr notCanceledTask = discoverResource(resourceDiscoveredForCall);
242     DiscoveryTaskPtr canceledTask = discoverResource(resourceDiscoveredForNeverCall);
243     canceledTask->cancel();
244
245     createResource();
246     waitForDiscoveryTask();
247 }