Update consumer logic for stopped provider.
[platform/upstream/iotivity.git] / service / notification / unittest / NSConsumerTest.cpp
1 //******************************************************************
2 //
3 // Copyright 2016 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 <gtest/gtest.h>
22 #include <HippoMocks/hippomocks.h>
23 #include <atomic>
24 #include <functional>
25 #include <condition_variable>
26 #include <mutex>
27 #include <chrono>
28
29 #include "ocstack.h"
30
31 #include "NSCommon.h"
32 #include "NSConsumerInterface.h"
33
34 #include "NSProviderSimulator.h"
35
36 namespace
37 {
38     NSProviderSimulator g_providerSimul;
39     NSProvider * g_provider;
40
41     std::atomic_bool g_isStartedStack(false);
42
43     std::chrono::milliseconds g_waitForResponse(500);
44
45     std::condition_variable responseCon;
46     std::mutex mutexForCondition;
47
48     enum class NSSelector
49     {
50         NS_SELECTION_CONSUMER = 0,
51         NS_SELECTION_PROVIDER = 1
52     };
53
54     NSConsumerConfig cfg;
55 }
56
57 class TestWithMock: public testing::Test
58 {
59 public:
60     MockRepository mocks;
61
62 protected:
63     virtual ~TestWithMock() noexcept(noexcept(std::declval<Test>().~Test()))
64     {
65
66     }
67
68     virtual void TearDown()
69     {
70         try
71         {
72             mocks.VerifyAll();
73         }
74         catch (...)
75         {
76             mocks.reset();
77             throw;
78         }
79     }
80 };
81
82 class NotificationConsumerTest : public TestWithMock
83 {
84 public:
85     NotificationConsumerTest() = default;
86     ~NotificationConsumerTest() = default;
87
88     static void NSNotificationReceivedCallbackEmpty(NSMessage *)
89     {
90         std::cout << __func__ << std::endl;
91     }
92
93     static void NSSyncCallbackEmpty(NSSyncInfo *)
94     {
95         std::cout << __func__ << std::endl;
96     }
97
98     static void NSFoundResourceEmpty(std::shared_ptr< OC::OCResource >)
99     {
100         std::cout << __func__ << std::endl;
101     }
102
103     static void NSProviderChangedCallback(NSProvider *,  NSProviderState)
104     {
105         std::cout << __func__ << std::endl;
106     }
107
108 protected:
109
110     void SetUp()
111     {
112         TestWithMock::SetUp();
113
114         if (g_isStartedStack == false)
115         {
116             OC::PlatformConfig occfg
117             {
118                 OC::ServiceType::InProc,
119                 OC::ModeType::Both,
120                 "0.0.0.0",
121                 0,
122                 OC::QualityOfService::LowQos
123             };
124             OC::OCPlatform::Configure(occfg);
125
126             try
127             {
128                 OC::OCPlatform::stopPresence();
129             }
130             catch (...)
131             {
132
133             }
134
135             g_isStartedStack = true;
136
137             cfg.changedCb = NSProviderChangedCallback;
138             cfg.messageCb = NSNotificationReceivedCallbackEmpty;
139             cfg.syncInfoCb = NSSyncCallbackEmpty;
140         }
141
142     }
143
144     void TearDown()
145     {
146         TestWithMock::TearDown();
147     }
148
149 };
150
151 TEST_F(NotificationConsumerTest, StartConsumerPositive)
152 {
153     EXPECT_EQ(NS_OK, NSStartConsumer(cfg));
154 }
155
156 TEST_F(NotificationConsumerTest, StopConsumerPositive)
157 {
158     EXPECT_EQ(NSStopConsumer(), NS_OK);
159 }
160
161 TEST_F(NotificationConsumerTest, DiscoverProviderWithNonAccepterWhenStartedConsumerFirst)
162 {
163     mocks.ExpectCallFunc(NSProviderChangedCallback).Do(
164             [this](NSProvider *, NSProviderState)
165             {
166                 std::cout << "Call Discovered" << std::endl;
167                 responseCon.notify_all();
168             });
169
170     NSStartConsumer(cfg);
171
172     g_providerSimul.setAccepter((int)NSSelector::NS_SELECTION_CONSUMER);
173     g_providerSimul.createNotificationResource();
174
175     std::unique_lock< std::mutex > lock{ mutexForCondition };
176     responseCon.wait_for(lock, g_waitForResponse);
177
178     NSStopConsumer();
179     g_providerSimul.deleteNotificationResource();
180 }
181
182 TEST_F(NotificationConsumerTest, DiscoverProviderWithNonAccepterWhenStartedConsumerAfter)
183 {
184     g_providerSimul.setAccepter((int)NSSelector::NS_SELECTION_CONSUMER);
185     g_providerSimul.createNotificationResource();
186     {
187         std::unique_lock< std::mutex > lock{ mutexForCondition };
188         responseCon.wait_for(lock, g_waitForResponse);
189     }
190
191     mocks.ExpectCallFunc(NSProviderChangedCallback).Do(
192             [this](NSProvider * provider, NSProviderState)
193             {
194                 std::cout << "Call Discovered" << std::endl;
195                 g_provider = provider;
196                 responseCon.notify_all();
197             });
198
199     NSStartConsumer(cfg);
200
201     std::unique_lock< std::mutex > lock{ mutexForCondition };
202     responseCon.wait_for(lock, g_waitForResponse);
203
204 }
205
206 TEST_F(NotificationConsumerTest, DiscoverProviderWithNonAccepterWhenRescan)
207 {
208     g_providerSimul.setAccepter((int)NSSelector::NS_SELECTION_CONSUMER);
209     mocks.ExpectCallFunc(NSProviderChangedCallback).Do(
210             [this](NSProvider * provider, NSProviderState)
211             {
212                 std::cout << "Call Discovered" << std::endl;
213                 g_provider = provider;
214                 std::cout << g_provider->providerId << std::endl;
215                 responseCon.notify_all();
216             });
217
218     NSRescanProvider();
219
220     std::unique_lock< std::mutex > lock{ mutexForCondition };
221     responseCon.wait_for(lock, g_waitForResponse);
222
223 //    NSStopConsumer();
224 }
225
226 TEST_F(NotificationConsumerTest, ExpectSubscribeSuccess)
227 {
228 //    mocks.ExpectCallFunc(NSSubscriptionAcceptedCallback).Do(
229 //            [](NSProvider * )
230 //            {
231 //                std::cout << "Income Accepted subscription : " << std::endl;
232 //            });
233
234     NSResult ret = NSSubscribe(g_provider);
235     std::unique_lock< std::mutex > lock{ mutexForCondition };
236     responseCon.wait_for(lock, g_waitForResponse);
237
238     EXPECT_EQ(NS_OK, ret);
239 }
240
241 TEST_F(NotificationConsumerTest, ExpectReceiveNotification)
242 {
243     uint64_t id = 10;
244     std::string title = "title";
245     std::string msg = "msg";
246
247     mocks.ExpectCallFunc(NSNotificationReceivedCallbackEmpty).Do(
248             [](NSMessage * message)
249             {
250                 std::cout << "Income Notification : " << message->messageId << std::endl;
251             });
252
253     g_providerSimul.notifyMessage(id, title, msg);
254
255     std::unique_lock< std::mutex > lock{ mutexForCondition };
256     responseCon.wait_for(lock, g_waitForResponse);
257
258     NSStopConsumer();
259 }
260
261 TEST_F(NotificationConsumerTest, ExpectReceiveNotificationWithAccepterisProvider)
262 {
263     uint64_t id = 11;
264     std::string title = "title";
265     std::string msg = "msg";
266
267     g_providerSimul.setAccepter((int)NSSelector::NS_SELECTION_PROVIDER);
268
269     NSStartConsumer(cfg);
270     {
271         std::unique_lock< std::mutex > lock{ mutexForCondition };
272         responseCon.wait_for(lock, g_waitForResponse);
273     }
274
275     mocks.ExpectCallFunc(NSNotificationReceivedCallbackEmpty).Do(
276             [](NSMessage * message)
277             {
278                 std::cout << "Income Notification : " << message->messageId << std::endl;
279             });
280
281     g_providerSimul.notifyMessage(id, title, msg);
282
283     std::unique_lock< std::mutex > lock{ mutexForCondition };
284     responseCon.wait_for(lock, g_waitForResponse);
285
286 //    g_providerSimul.deleteNotificationResource();
287 //    NSStopConsumer();
288 }
289
290 TEST_F(NotificationConsumerTest, ExpectCallbackReadCheckWhenProviderNotifySync)
291 {
292     uint64_t id = 12;
293     std::string title = "title";
294     std::string msg = "msg";
295
296     NSSyncType type = NS_SYNC_DELETED;
297
298     mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
299             [](NSMessage * message)
300             {
301                 std::cout << "Income Notification : " << message->messageId << std::endl;
302             });
303
304     mocks.ExpectCallFunc(NSSyncCallbackEmpty).Do(
305             [& type](NSSyncInfo * sync)
306             {
307                 std::cout << "Income SyncInfo : " << sync->messageId
308                         << ", State : " << sync->state << std::endl;
309                 type = sync->state;
310
311             });
312
313     g_providerSimul.notifyMessage(id, title, msg);
314     {
315         std::unique_lock< std::mutex > lock{ mutexForCondition };
316         responseCon.wait_for(lock, g_waitForResponse);
317     }
318
319     g_providerSimul.sendRead(id);
320     {
321         std::unique_lock< std::mutex > lock{ mutexForCondition };
322         responseCon.wait_for(lock, g_waitForResponse);
323     }
324
325 //    g_providerSimul.deleteNotificationResource();
326 //    NSStopConsumer();
327
328     EXPECT_EQ(NS_SYNC_READ, type);
329 }
330
331 TEST_F(NotificationConsumerTest, ExpectCallbackDismissCheckWhenProviderNotifySync)
332 {
333     uint64_t id = 13;
334     std::string title = "title";
335     std::string msg = "msg";
336
337     NSSyncType type = NS_SYNC_READ;
338
339     mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
340             [](NSMessage * message)
341             {
342                 std::cout << "Income Notification : " << message->messageId << std::endl;
343             });
344
345     mocks.ExpectCallFunc(NSSyncCallbackEmpty).Do(
346             [& type](NSSyncInfo * sync)
347             {
348                 std::cout << "Income Notification : " << sync->messageId
349                         << ", State : " << sync->state << std::endl;
350                 type = sync->state;
351
352             });
353
354     g_providerSimul.notifyMessage(id, title, msg);
355     {
356         std::unique_lock< std::mutex > lock{ mutexForCondition };
357         responseCon.wait_for(lock, g_waitForResponse);
358     }
359
360     g_providerSimul.sendDismiss(id);
361     {
362         std::unique_lock< std::mutex > lock{ mutexForCondition };
363         responseCon.wait_for(lock, g_waitForResponse);
364     }
365
366 //    g_providerSimul.deleteNotificationResource();
367 //    NSStopConsumer();
368
369     EXPECT_EQ(NS_SYNC_DELETED, type);
370 }
371
372 TEST_F(NotificationConsumerTest, ExpectCallbackReadCheckWhenConsumerPostSync)
373 {
374     uint64_t id = 14;
375     std::string title = "title";
376     std::string msg = "msg";
377
378     NSSyncType type = NS_SYNC_DELETED;
379
380     mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
381             [](NSMessage * message)
382             {
383                 std::cout << "Income Notification : " << message->messageId << std::endl;
384                 NSConsumerSendSyncInfo(message->providerId, message->messageId, NS_SYNC_READ);
385                 std::unique_lock< std::mutex > lock{ mutexForCondition };
386                 responseCon.wait_for(lock, g_waitForResponse);
387             });
388
389     mocks.ExpectCallFunc(NSSyncCallbackEmpty).Do(
390             [& type](NSSyncInfo * sync)
391             {
392                 std::cout << "Income Notification : " << sync->messageId
393                         << ", State : " << sync->state << std::endl;
394                 type = sync->state;
395
396             });
397
398     g_providerSimul.notifyMessage(id, title, msg);
399     {
400         std::unique_lock< std::mutex > lock{ mutexForCondition };
401         responseCon.wait_for(lock, g_waitForResponse);
402     }
403
404 //    g_providerSimul.deleteNotificationResource();
405 //    NSStopConsumer();
406
407     EXPECT_EQ(NS_SYNC_READ, type);
408 }
409
410 TEST_F(NotificationConsumerTest, ExpectCallbackDismissCheckWhenConsumerPostSync)
411 {
412     uint64_t id = 15;
413     std::string title = "title";
414     std::string msg = "msg";
415
416     NSSyncType type = NS_SYNC_READ;
417
418     mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
419             [](NSMessage * message)
420             {
421                 std::cout << "Income Notification : " << message->messageId << std::endl;
422                 NSConsumerSendSyncInfo(message->providerId, message->messageId, NS_SYNC_DELETED);
423                 std::unique_lock< std::mutex > lock{ mutexForCondition };
424                 responseCon.wait_for(lock, g_waitForResponse);
425             });
426
427     mocks.ExpectCallFunc(NSSyncCallbackEmpty).Do(
428             [& type](NSSyncInfo * sync)
429             {
430                 std::cout << "Income Notification : " << sync->messageId
431                         << ", State : " << sync->state << std::endl;
432                 type = sync->state;
433
434             });
435
436     g_providerSimul.notifyMessage(id, title, msg);
437     {
438         std::unique_lock< std::mutex > lock{ mutexForCondition };
439         responseCon.wait_for(lock, g_waitForResponse);
440     }
441
442     EXPECT_EQ(NS_SYNC_DELETED, type);
443 }
444
445 TEST_F(NotificationConsumerTest, ExpectUnsubscribeSuccess)
446 {
447     NSResult ret = NSUnsubscribe(g_provider);
448     std::unique_lock< std::mutex > lock{ mutexForCondition };
449     responseCon.wait_for(lock, g_waitForResponse);
450
451     g_providerSimul.deleteNotificationResource();
452     NSStopConsumer();
453
454     EXPECT_EQ(NS_OK, ret);
455 }