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