Merge remote-tracking branch 'origin/master' into notification-service
[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, StartConsumerNegativeNonSetChangedCB)
152 {
153     cfg.changedCb = NULL;
154     cfg.messageCb = NSNotificationReceivedCallbackEmpty;
155     cfg.syncInfoCb = NSSyncCallbackEmpty;
156
157     EXPECT_EQ(NS_ERROR, NSStartConsumer(cfg));
158     std::unique_lock< std::mutex > lock{ mutexForCondition };
159     responseCon.wait_for(lock, g_waitForResponse);
160 }
161
162 TEST_F(NotificationConsumerTest, StartConsumerNegativeNonSetNotiReceiveCB)
163 {
164     cfg.changedCb = NSProviderChangedCallback;
165     cfg.messageCb = NULL;
166     cfg.syncInfoCb = NSSyncCallbackEmpty;
167
168     EXPECT_EQ(NS_ERROR, NSStartConsumer(cfg));
169     std::unique_lock< std::mutex > lock{ mutexForCondition };
170     responseCon.wait_for(lock, g_waitForResponse);
171 }
172
173 TEST_F(NotificationConsumerTest, StartConsumerNegativeNonSetSyncCB)
174 {
175     cfg.changedCb = NSProviderChangedCallback;
176     cfg.messageCb = NSNotificationReceivedCallbackEmpty;
177     cfg.syncInfoCb = NULL;
178
179     EXPECT_EQ(NS_ERROR, NSStartConsumer(cfg));
180     std::unique_lock< std::mutex > lock{ mutexForCondition };
181     responseCon.wait_for(lock, g_waitForResponse);
182 }
183
184 TEST_F(NotificationConsumerTest, StartConsumerPositive)
185 {
186     cfg.changedCb = NSProviderChangedCallback;
187     cfg.messageCb = NSNotificationReceivedCallbackEmpty;
188     cfg.syncInfoCb = NSSyncCallbackEmpty;
189
190     EXPECT_EQ(NS_OK, NSStartConsumer(cfg));
191     std::unique_lock< std::mutex > lock{ mutexForCondition };
192     responseCon.wait_for(lock, g_waitForResponse);
193 }
194
195 TEST_F(NotificationConsumerTest, StopConsumerPositive)
196 {
197     EXPECT_EQ(NSStopConsumer(), NS_OK);
198 }
199
200 TEST_F(NotificationConsumerTest, StopConsumerNegative)
201 {
202     EXPECT_EQ(NSStopConsumer(), NS_ERROR);
203 }
204
205 TEST_F(NotificationConsumerTest, DiscoverProviderWithNonAccepterWhenStartedConsumerFirst)
206 {
207     NSProviderState revState = NS_STOPPED;
208     mocks.OnCallFunc(NSProviderChangedCallback).Do(
209             [this, & revState](NSProvider *, NSProviderState state)
210             {
211                 std::cout << "Call Discovered" << std::endl;
212                 revState = state;
213                 responseCon.notify_all();
214             });
215
216     NSStartConsumer(cfg);
217
218     g_providerSimul.setAccepter((int)NSSelector::NS_SELECTION_CONSUMER);
219     g_providerSimul.createNotificationResource();
220
221     std::unique_lock< std::mutex > lock{ mutexForCondition };
222     responseCon.wait_for(lock, g_waitForResponse);
223
224     NSStopConsumer();
225     g_providerSimul.deleteNotificationResource();
226
227     EXPECT_EQ(NS_DISCOVERED, revState);
228 }
229
230 TEST_F(NotificationConsumerTest, DiscoverProviderWithNonAccepterWhenStartedConsumerAfter)
231 {
232     g_providerSimul.setAccepter((int)NSSelector::NS_SELECTION_CONSUMER);
233     g_providerSimul.createNotificationResource();
234     {
235         std::unique_lock< std::mutex > lock{ mutexForCondition };
236         responseCon.wait_for(lock, g_waitForResponse);
237     }
238
239     NSProviderState revState = NS_STOPPED;
240     mocks.OnCallFunc(NSProviderChangedCallback).Do(
241             [this, & revState](NSProvider * provider, NSProviderState state)
242             {
243                 std::cout << "Call Discovered" << std::endl;
244
245                 g_provider = provider;
246                 revState = state;
247                 responseCon.notify_all();
248             });
249
250     NSStartConsumer(cfg);
251
252     std::unique_lock< std::mutex > lock{ mutexForCondition };
253     responseCon.wait_for(lock, g_waitForResponse);
254
255     EXPECT_EQ(NS_DISCOVERED, revState);
256 }
257
258 TEST_F(NotificationConsumerTest, DiscoverProviderWithNonAccepterWhenRescan)
259 {
260     g_providerSimul.setAccepter((int)NSSelector::NS_SELECTION_CONSUMER);
261     NSProviderState revState = NS_STOPPED;
262     mocks.OnCallFunc(NSProviderChangedCallback).Do(
263             [this, &revState](NSProvider * provider, NSProviderState state)
264             {
265                 std::cout << "Call Discovered" << std::endl;
266                 revState = state;
267                 g_provider = provider;
268                 std::cout << g_provider->providerId << std::endl;
269                 responseCon.notify_all();
270             });
271
272     NSRescanProvider();
273
274     std::unique_lock< std::mutex > lock{ mutexForCondition };
275     responseCon.wait_for(lock, g_waitForResponse);
276
277     EXPECT_EQ(NS_DISCOVERED, revState);
278 }
279
280 TEST_F(NotificationConsumerTest, ExpectSubscribeSuccess)
281 {
282     NSProviderState revState = NS_DENY;
283     mocks.OnCallFunc(NSProviderChangedCallback).Do(
284             [this, & revState](NSProvider * , NSProviderState state)
285             {
286                 std::cout << "Income Changed Callback : " << state << std::endl;
287                 revState = state;
288                 responseCon.notify_all();
289             });
290
291     NSResult ret = NSSubscribe(g_provider->providerId);
292     std::unique_lock< std::mutex > lock{ mutexForCondition };
293     responseCon.wait_for(lock, g_waitForResponse);
294
295     EXPECT_EQ(NS_ALLOW, revState);
296     EXPECT_EQ(NS_OK, ret);
297 }
298
299 TEST_F(NotificationConsumerTest, ExpectReceiveNotification)
300 {
301     uint64_t id = 10;
302     std::string title = "title";
303     std::string msg = "msg";
304
305     mocks.ExpectCallFunc(NSNotificationReceivedCallbackEmpty).Do(
306             [this](NSMessage * message)
307             {
308                 std::cout << "Income Notification : " << message->messageId << std::endl;
309             });
310
311     g_providerSimul.notifyMessage(id, title, msg);
312
313     std::unique_lock< std::mutex > lock{ mutexForCondition };
314     responseCon.wait_for(lock, g_waitForResponse);
315
316     NSStopConsumer();
317 }
318
319 TEST_F(NotificationConsumerTest, ExpectReceiveSubAllowWithAccepterisProvider)
320 {
321     g_providerSimul.setAccepter((int)NSSelector::NS_SELECTION_PROVIDER);
322     NSProviderState revState = NS_DENY;
323
324     mocks.OnCallFunc(NSProviderChangedCallback).Do(
325             [this, & revState](NSProvider * , NSProviderState state)
326             {
327                 std::cout << "Income Changed Callback : " << state << std::endl;
328                 revState = state;
329                 responseCon.notify_all();
330             });
331
332     NSStartConsumer(cfg);
333     std::unique_lock< std::mutex > lock{ mutexForCondition };
334     responseCon.wait_for(lock, g_waitForResponse);
335
336     EXPECT_EQ(NS_ALLOW, revState);
337 }
338
339 TEST_F(NotificationConsumerTest, ExpectReceiveNotificationWithAccepterisProvider)
340 {
341     uint64_t id = 11;
342     std::string title = "title";
343     std::string msg = "msg";
344     uint64_t revId = 1;
345
346     mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
347             [this, & id, & revId](NSMessage * message)
348             {
349                 std::cout << "Income Notification : " << message->messageId << std::endl;
350                 revId = message->messageId;
351             });
352
353     g_providerSimul.notifyMessage(id, title, msg);
354
355     std::unique_lock< std::mutex > lock{ mutexForCondition };
356     responseCon.wait_for(lock, g_waitForResponse);
357
358     EXPECT_EQ(id, revId);
359 }
360
361 TEST_F(NotificationConsumerTest, ExpectCallbackReadCheckWhenProviderNotifySync)
362 {
363     uint64_t id = 12;
364     std::string title = "title";
365     std::string msg = "msg";
366     NSSyncType type = NS_SYNC_DELETED;
367
368     mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
369             [this](NSMessage * message)
370             {
371                 std::cout << "Income Notification : " << message->messageId << std::endl;
372             });
373
374     mocks.OnCallFunc(NSSyncCallbackEmpty).Do(
375             [& type, this](NSSyncInfo * sync)
376             {
377                 std::cout << "Income SyncInfo : " << sync->messageId
378                         << ", State : " << sync->state << std::endl;
379                 type = sync->state;
380             });
381
382     g_providerSimul.notifyMessage(id, title, msg);
383     {
384         std::unique_lock< std::mutex > lock{ mutexForCondition };
385         responseCon.wait_for(lock, g_waitForResponse);
386     }
387
388     g_providerSimul.sendRead(id);
389     {
390         std::unique_lock< std::mutex > lock{ mutexForCondition };
391         responseCon.wait_for(lock, g_waitForResponse);
392     }
393
394     EXPECT_EQ(NS_SYNC_READ, type);
395 }
396
397 TEST_F(NotificationConsumerTest, ExpectCallbackDismissCheckWhenProviderNotifySync)
398 {
399     uint64_t id = 13;
400     std::string title = "title";
401     std::string msg = "msg";
402     NSSyncType type = NS_SYNC_READ;
403
404     mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
405             [this](NSMessage * message)
406             {
407                 std::cout << "Income Notification : " << message->messageId << std::endl;
408             });
409
410     mocks.OnCallFunc(NSSyncCallbackEmpty).Do(
411             [& type, this](NSSyncInfo * sync)
412             {
413                 std::cout << "Income Notification : " << sync->messageId
414                         << ", State : " << sync->state << std::endl;
415                 type = sync->state;
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.sendDismiss(id);
425     {
426         std::unique_lock< std::mutex > lock{ mutexForCondition };
427         responseCon.wait_for(lock, g_waitForResponse);
428     }
429
430     EXPECT_EQ(NS_SYNC_DELETED, type);
431 }
432
433 TEST_F(NotificationConsumerTest, ExpectCallbackReadCheckWhenConsumerPostSync)
434 {
435     uint64_t id = 14;
436     std::string title = "title";
437     std::string msg = "msg";
438     NSSyncType type = NS_SYNC_DELETED;
439
440     mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
441             [this](NSMessage * message)
442             {
443                 std::cout << "Income Notification : " << message->messageId << std::endl;
444                 NSConsumerSendSyncInfo(message->providerId, message->messageId, NS_SYNC_READ);
445                 std::unique_lock< std::mutex > lock{ mutexForCondition };
446                 responseCon.wait_for(lock, g_waitForResponse);
447             });
448
449     mocks.OnCallFunc(NSSyncCallbackEmpty).Do(
450             [& type, this](NSSyncInfo * sync)
451             {
452                 std::cout << "Income Notification : " << sync->messageId
453                         << ", State : " << sync->state << std::endl;
454                 type = sync->state;
455             });
456
457     g_providerSimul.notifyMessage(id, title, msg);
458     {
459         std::unique_lock< std::mutex > lock{ mutexForCondition };
460         responseCon.wait_for(lock, g_waitForResponse);
461     }
462
463     EXPECT_EQ(NS_SYNC_READ, type);
464 }
465
466 TEST_F(NotificationConsumerTest, ExpectCallbackDismissCheckWhenConsumerPostSync)
467 {
468     uint64_t id = 15;
469     std::string title = "title";
470     std::string msg = "msg";
471     NSSyncType state = NS_SYNC_READ;
472
473     mocks.OnCallFunc(NSNotificationReceivedCallbackEmpty).Do(
474             [this](NSMessage * message)
475             {
476                 std::cout << "Income Notification : " << message->messageId << std::endl;
477                 NSConsumerSendSyncInfo(message->providerId, message->messageId, NS_SYNC_DELETED);
478                 std::unique_lock< std::mutex > lock{ mutexForCondition };
479                 responseCon.wait_for(lock, g_waitForResponse);
480             });
481
482     mocks.OnCallFunc(NSSyncCallbackEmpty).Do(
483             [& state, this](NSSyncInfo * sync)
484             {
485                 std::cout << "Income Notification : " << sync->messageId
486                         << ", State : " << sync->state << std::endl;
487                 state = sync->state;
488             });
489
490     g_providerSimul.notifyMessage(id, title, msg);
491     {
492         std::unique_lock< std::mutex > lock{ mutexForCondition };
493         responseCon.wait_for(lock, g_waitForResponse);
494     }
495
496     EXPECT_EQ(NS_SYNC_DELETED, state);
497 //    g_providerSimul.deleteNotificationResource();
498 //    NSStopConsumer();
499 }
500
501 TEST_F(NotificationConsumerTest, ExpectCallbackDeletedProvider)
502 {
503     NSProviderState type = NS_ALLOW;
504     mocks.OnCallFunc(NSProviderChangedCallback).Do(
505             [& type, this](NSProvider * , NSProviderState state)
506             {
507                 std::cout << "Income Changed Callback : " << state << std::endl;
508                 //EXPECT_EQ(state, NS_STOPPED);
509                 type = state;
510                 responseCon.notify_all();
511             });
512
513     g_providerSimul.deleteNotificationResource();
514
515     std::unique_lock< std::mutex > lock{ mutexForCondition };
516     responseCon.wait_for(lock, g_waitForResponse);
517
518     EXPECT_EQ(type, NS_STOPPED);
519     NSStopConsumer();
520 }
521
522 //TEST_F(NotificationConsumerTest, ExpectUnsubscribeSuccess)
523 //{
524 //    NSResult ret = NSUnsubscribe(g_provider->providerId);
525 //    std::unique_lock< std::mutex > lock{ mutexForCondition };
526 //    responseCon.wait_for(lock, g_waitForResponse);
527 //
528 //    g_providerSimul.deleteNotificationResource();
529 //    NSStopConsumer();
530 //
531 //    EXPECT_EQ(NS_OK, ret);
532 //}