replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / service / notification / cpp-wrapper / unittest / NSConsumerServiceTest.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 "NSUtils.h"
32 #include "NSSyncInfo.h"
33 #include "NSMessage.h"
34 #include "NSMediaContents.h"
35 #include "NSConsumerService.h"
36
37 #include "NSProviderServiceSimulator.h"
38
39 namespace
40 {
41     NSProviderSimulator g_providerSimul;
42     std::shared_ptr<OIC::Service::NSProvider> g_provider;
43
44     std::atomic_bool g_isStartedStack(false);
45
46     std::chrono::milliseconds g_waitForResponse(1000);
47
48     std::condition_variable responseCon;
49     std::mutex mutexForCondition;
50
51     enum class NSSelector
52     {
53         NS_SELECTION_CONSUMER = 0,
54         NS_SELECTION_PROVIDER = 1
55     };
56
57 }
58
59 class TestWithMock: public testing::Test
60 {
61     public:
62         MockRepository mocks;
63
64     protected:
65         virtual ~TestWithMock() noexcept(noexcept(std::declval<Test>().~Test()))
66         {
67
68         }
69
70         virtual void TearDown()
71         {
72             try
73             {
74                 mocks.VerifyAll();
75             }
76             catch (...)
77             {
78                 mocks.reset();
79                 throw;
80             }
81         }
82 };
83
84 class NotificationServiceConsumerTest : public TestWithMock
85 {
86     public:
87         NotificationServiceConsumerTest() = default;
88         ~NotificationServiceConsumerTest() = default;
89
90         static void ProviderDiscoveredCallbackEmpty( std::shared_ptr<OIC::Service::NSProvider> )
91         {
92             std::cout << __func__ << std::endl;
93         }
94
95         static void NotificationReceivedCallbackEmpty( OIC::Service::NSMessage )
96         {
97             std::cout << __func__ << std::endl;
98         }
99
100         static void SyncCallbackEmpty(OIC::Service::NSSyncInfo)
101         {
102             std::cout << __func__ << std::endl;
103         }
104
105         static void FoundResourceEmpty(std::shared_ptr< OC::OCResource >)
106         {
107             std::cout << __func__ << std::endl;
108         }
109
110         static void ProviderChangedCallbackEmpty( OIC::Service::NSProviderState )
111         {
112             std::cout << __func__ << std::endl;
113         }
114
115     protected:
116
117         void SetUp()
118         {
119             TestWithMock::SetUp();
120
121             if (g_isStartedStack == false)
122             {
123                 OC::PlatformConfig cfg
124                 {
125                     OC::ServiceType::InProc,
126                     OC::ModeType::Both,
127                     "0.0.0.0",
128                     0,
129                     OC::QualityOfService::LowQos
130                 };
131                 OC::OCPlatform::Configure(cfg);
132
133                 try
134                 {
135                     OC::OCPlatform::stopPresence();
136                 }
137                 catch (...)
138                 {
139
140                 }
141
142                 g_isStartedStack = true;
143             }
144
145         }
146
147         void TearDown()
148         {
149             TestWithMock::TearDown();
150         }
151
152 };
153
154 TEST_F(NotificationServiceConsumerTest, StartConsumerPositive)
155 {
156     OIC::Service::NSConsumerService::getInstance()->start(ProviderDiscoveredCallbackEmpty);
157 }
158
159 TEST_F(NotificationServiceConsumerTest, StopConsumerPositive)
160 {
161     OIC::Service::NSConsumerService::getInstance()->stop();
162 }
163
164 TEST_F(NotificationServiceConsumerTest, DiscoverProviderWithNonAccepterWhenStartedConsumerFirst)
165 {
166     mocks.ExpectCallFunc(ProviderDiscoveredCallbackEmpty).Do(
167         [this]( std::shared_ptr<OIC::Service::NSProvider> provider)
168     {
169         std::cout << "Call Discovered" << std::endl;
170         std::cout << provider->getProviderId() << std::endl;
171         responseCon.notify_all();
172     });
173
174     OIC::Service::NSConsumerService::getInstance()->start(ProviderDiscoveredCallbackEmpty);
175
176     g_providerSimul.setAccepter((int)NSSelector::NS_SELECTION_CONSUMER);
177     g_providerSimul.createNotificationResource();
178
179     std::unique_lock< std::mutex > lock { mutexForCondition };
180     responseCon.wait_for(lock, g_waitForResponse);
181
182     OIC::Service::NSConsumerService::getInstance()->stop();
183     g_providerSimul.deleteNotificationResource();
184 }
185
186 TEST_F(NotificationServiceConsumerTest, DiscoverProviderWithNonAccepterWhenStartedConsumerAfter)
187 {
188     g_providerSimul.setAccepter((int)NSSelector::NS_SELECTION_CONSUMER);
189     g_providerSimul.createNotificationResource();
190     {
191         std::unique_lock< std::mutex > lock { mutexForCondition };
192         responseCon.wait_for(lock, g_waitForResponse);
193     }
194
195     mocks.ExpectCallFunc(ProviderDiscoveredCallbackEmpty).Do(
196         [this]( std::shared_ptr<OIC::Service::NSProvider> provider)
197     {
198         std::cout << "Call Discovered" << std::endl;
199         g_provider = provider;
200         std::cout << g_provider->getProviderId() << std::endl;
201         responseCon.notify_all();
202     });
203
204     OIC::Service::NSConsumerService::getInstance()->start(ProviderDiscoveredCallbackEmpty);
205
206     std::unique_lock< std::mutex > lock { mutexForCondition };
207     responseCon.wait_for(lock, g_waitForResponse);
208
209     ASSERT_NE(nullptr, g_provider) << "error: discovery failure";
210
211 }
212
213 TEST_F(NotificationServiceConsumerTest, DiscoverProviderWithNonAccepterWhenRescan)
214 {
215     g_providerSimul.setAccepter((int)NSSelector::NS_SELECTION_CONSUMER);
216     mocks.OnCallFunc(ProviderDiscoveredCallbackEmpty).Do(
217         [this]( std::shared_ptr<OIC::Service::NSProvider> provider)
218     {
219         std::cout << "Call Discovered" << std::endl;
220         g_provider = provider;
221         std::cout << g_provider->getProviderId() << std::endl;
222         responseCon.notify_all();
223     });
224
225     OIC::Service::NSConsumerService::getInstance()->rescanProvider();
226
227     std::unique_lock< std::mutex > lock { mutexForCondition };
228     responseCon.wait_for(lock, g_waitForResponse);
229 }
230
231 TEST_F(NotificationServiceConsumerTest, ExpectSubscribeSuccess)
232 {
233     OIC::Service::NSProviderState revState = OIC::Service::NSProviderState::DENY;
234     mocks.OnCallFunc(ProviderChangedCallbackEmpty).Do(
235         [this, & revState](OIC::Service::NSProviderState state)
236     {
237         std::cout << "Income Accepted subscription : " << std::endl;
238         revState = state;
239         responseCon.notify_all();
240     });
241
242     ASSERT_NE(nullptr, g_provider) << "error: discovery failure";
243
244     g_provider->setListener( (OIC::Service::NSProvider::ProviderStateCallback)
245                              ProviderChangedCallbackEmpty,
246                              (OIC::Service::NSProvider::MessageReceivedCallback)NotificationReceivedCallbackEmpty,
247                              (OIC::Service::NSProvider::SyncInfoReceivedCallback)SyncCallbackEmpty);
248     if (!g_provider->isSubscribed())
249     {
250         g_provider->subscribe();
251     }
252     std::unique_lock< std::mutex > lock { mutexForCondition };
253     responseCon.wait_for(lock, g_waitForResponse);
254     EXPECT_EQ(OIC::Service::NSProviderState::ALLOW, revState);
255 }
256
257 TEST_F(NotificationServiceConsumerTest, ExpectReceiveNotification)
258 {
259     uint64_t id = 10;
260     std::string title = "title";
261     std::string msg = "msg";
262
263     mocks.ExpectCallFunc(NotificationReceivedCallbackEmpty).Do(
264         [this]( OIC::Service::NSMessage message)
265     {
266         std::cout << "Income Notification : " << message.getMessageId() << std::endl;
267         responseCon.notify_all();
268     });
269
270     g_providerSimul.notifyMessage(id, title, msg);
271
272     std::unique_lock< std::mutex > lock { mutexForCondition };
273     responseCon.wait_for(lock, g_waitForResponse);
274
275     OIC::Service::NSConsumerService::getInstance()->stop();
276 }
277
278 TEST_F(NotificationServiceConsumerTest, DiscoverProviderWithAccepterisProvider)
279 {
280     g_providerSimul.setAccepter((int)NSSelector::NS_SELECTION_PROVIDER);
281
282     mocks.ExpectCallFunc(ProviderDiscoveredCallbackEmpty).Do(
283         [this]( std::shared_ptr<OIC::Service::NSProvider> provider)
284     {
285         std::cout << "Call Discovered" << std::endl;
286         g_provider = provider;
287         g_provider->setListener( (OIC::Service::NSProvider::ProviderStateCallback)
288                                  ProviderChangedCallbackEmpty,
289                                  (OIC::Service::NSProvider::MessageReceivedCallback)NotificationReceivedCallbackEmpty,
290                                  (OIC::Service::NSProvider::SyncInfoReceivedCallback)SyncCallbackEmpty);
291         if (!g_provider->isSubscribed())
292         {
293             g_provider->subscribe();
294         }
295         std::cout << g_provider->getProviderId() << std::endl;
296         responseCon.notify_all();
297     });
298
299
300     OIC::Service::NSConsumerService::getInstance()->start(ProviderDiscoveredCallbackEmpty);
301     std::unique_lock< std::mutex > lock { mutexForCondition };
302     responseCon.wait_for(lock, g_waitForResponse);
303 }
304
305 TEST_F(NotificationServiceConsumerTest, ExpectReceiveNotificationWithAccepterisProvider)
306 {
307     uint64_t id = 11;
308     std::string title = "title";
309     std::string msg = "msg";
310     uint64_t revId = 1;
311
312     mocks.OnCallFunc(NotificationReceivedCallbackEmpty).Do(
313         [this, & id, & revId](OIC::Service::NSMessage message)
314     {
315         std::cout << "Income Notification : " << message.getMessageId() << std::endl;
316         revId =  message.getMessageId();
317         responseCon.notify_all();
318     });
319
320     g_providerSimul.notifyMessage(id, title, msg);
321
322     std::unique_lock< std::mutex > lock { mutexForCondition };
323     responseCon.wait_for(lock, g_waitForResponse);
324
325     EXPECT_EQ(id, revId);
326 }
327
328 TEST_F(NotificationServiceConsumerTest, ExpectCallbackReadCheckWhenProviderNotifySync)
329 {
330     uint64_t id = 12;
331     std::string title = "title";
332     std::string msg = "msg";
333     OIC::Service::NSSyncInfo::NSSyncType type = OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED;
334
335     mocks.OnCallFunc(NotificationReceivedCallbackEmpty).Do(
336         [this]( OIC::Service::NSMessage message)
337     {
338         std::cout << "Income Notification : " << message.getMessageId() << std::endl;
339     });
340
341     mocks.OnCallFunc(SyncCallbackEmpty).Do(
342         [& type, this](OIC::Service::NSSyncInfo sync)
343     {
344         std::cout << "Income SyncInfo : " << sync.getMessageId()
345                   << ", State : " << (int) sync.getState() << std::endl;
346         type = sync.getState();
347         responseCon.notify_all();
348     });
349
350     g_providerSimul.notifyMessage(id, title, msg);
351     {
352         std::unique_lock< std::mutex > lock { mutexForCondition };
353         responseCon.wait_for(lock, g_waitForResponse);
354     }
355
356     g_providerSimul.sendRead(id);
357     {
358         std::unique_lock< std::mutex > lock { mutexForCondition };
359         responseCon.wait_for(lock, g_waitForResponse);
360     }
361
362     EXPECT_EQ(OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ, type);
363 }
364
365 TEST_F(NotificationServiceConsumerTest, ExpectCallbackDismissCheckWhenProviderNotifySync)
366 {
367     uint64_t id = 13;
368     std::string title = "title";
369     std::string msg = "msg";
370     OIC::Service::NSSyncInfo::NSSyncType type = OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ;
371
372     mocks.OnCallFunc(NotificationReceivedCallbackEmpty).Do(
373         [this]( OIC::Service::NSMessage message)
374     {
375         std::cout << "Income Notification : " << message.getMessageId() << std::endl;
376     });
377
378     mocks.OnCallFunc(SyncCallbackEmpty).Do(
379         [& type, this](OIC::Service::NSSyncInfo sync)
380     {
381         std::cout << "Income Notification : " << sync.getMessageId()
382                   << ", State : " << (int) sync.getState() << std::endl;
383         type = sync.getState();
384         responseCon.notify_all();
385     });
386
387     g_providerSimul.notifyMessage(id, title, msg);
388     {
389         std::unique_lock< std::mutex > lock { mutexForCondition };
390         responseCon.wait_for(lock, g_waitForResponse);
391     }
392
393     g_providerSimul.sendDismiss(id);
394     {
395         std::unique_lock< std::mutex > lock { mutexForCondition };
396         responseCon.wait_for(lock, g_waitForResponse);
397     }
398
399     EXPECT_EQ(OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED, type);
400 }
401
402 TEST_F(NotificationServiceConsumerTest, ExpectCallbackReadCheckWhenConsumerPostSync)
403 {
404     uint64_t id = 14;
405     std::string title = "title";
406     std::string msg = "msg";
407     OIC::Service::NSSyncInfo::NSSyncType type = OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED;
408
409     ASSERT_NE(nullptr, g_provider) << "error: discovery failure";
410
411     mocks.OnCallFunc(NotificationReceivedCallbackEmpty).Do(
412         [this]( OIC::Service::NSMessage message)
413     {
414         std::cout << "Income Notification : " << message.getMessageId() << std::endl;
415         g_provider->sendSyncInfo(message.getMessageId(),
416                                  OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ);
417         std::unique_lock< std::mutex > lock { mutexForCondition };
418         responseCon.wait_for(lock, g_waitForResponse);
419     });
420
421     mocks.OnCallFunc(SyncCallbackEmpty).Do(
422         [& type, this](OIC::Service::NSSyncInfo sync)
423     {
424         std::cout << "Income Notification : " << sync.getMessageId()
425                   << ", State : " << (int) sync.getState() << std::endl;
426         type = sync.getState();
427         responseCon.notify_all();
428     });
429
430     g_providerSimul.notifyMessage(id, title, msg);
431     {
432         std::unique_lock< std::mutex > lock { mutexForCondition };
433         responseCon.wait_for(lock, g_waitForResponse);
434     }
435
436     EXPECT_EQ(OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ, type);
437 }
438
439 TEST_F(NotificationServiceConsumerTest, ExpectCallbackDismissCheckWhenConsumerPostSync)
440 {
441     uint64_t id = 15;
442     std::string title = "title";
443     std::string msg = "msg";
444     OIC::Service::NSSyncInfo::NSSyncType type = OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_READ;
445
446     ASSERT_NE(nullptr, g_provider) << "error: discovery failure";
447
448     mocks.OnCallFunc(NotificationReceivedCallbackEmpty).Do(
449         [this]( OIC::Service::NSMessage message)
450     {
451         std::cout << "Income Notification : " << message.getMessageId() << std::endl;
452         g_provider->sendSyncInfo(message.getMessageId(),
453                                  OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED);
454         std::unique_lock< std::mutex > lock { mutexForCondition };
455         responseCon.wait_for(lock, g_waitForResponse);
456     });
457
458     mocks.OnCallFunc(SyncCallbackEmpty).Do(
459         [& type, this](OIC::Service::NSSyncInfo sync)
460     {
461         std::cout << "Income Notification : " << sync.getMessageId()
462                   << ", State : " << (int) sync.getState() << std::endl;
463         type = sync.getState();
464         responseCon.notify_all();
465     });
466
467     g_providerSimul.notifyMessage(id, title, msg);
468     {
469         std::unique_lock< std::mutex > lock { mutexForCondition };
470         responseCon.wait_for(lock, g_waitForResponse);
471     }
472
473     EXPECT_EQ(OIC::Service::NSSyncInfo::NSSyncType::NS_SYNC_DELETED, type);
474 }
475
476 TEST_F(NotificationServiceConsumerTest, ExpectGetProviderSuccessWithValidProviderId)
477 {
478     ASSERT_NE(nullptr, g_provider) << "error: discovery failure";
479
480     std::shared_ptr<OIC::Service::NSProvider> provider =
481         OIC::Service::NSConsumerService::getInstance()->getProvider(
482             g_provider->getProviderId());
483     int ret = strcmp(provider->getProviderId().c_str(), g_provider->getProviderId().c_str());
484     EXPECT_EQ(0, ret);
485 }
486
487 TEST_F(NotificationServiceConsumerTest, ExpectGetProviderSuccessWithInvalidProviderId)
488 {
489     std::shared_ptr<OIC::Service::NSProvider> provider =
490         OIC::Service::NSConsumerService::getInstance()->getProvider(
491             "123456789012345678901234567890123457");
492     bool res = (provider == nullptr);
493     EXPECT_EQ(res, 1);
494 }
495
496 TEST_F(NotificationServiceConsumerTest, ExpectCallbackTopicUpdated)
497 {
498     OIC::Service::NSProviderState revState = OIC::Service::NSProviderState::STOPPED;
499     mocks.OnCallFunc(ProviderChangedCallbackEmpty).Do(
500         [this, & revState](OIC::Service::NSProviderState state)
501     {
502         std::cout << "Income Changed Callback : " << (int)state << std::endl;
503         revState = state;
504         responseCon.notify_all();
505     });
506
507     NSProviderSimulator::NS_TopicList topics;
508     topics.push_back("1");
509     topics.push_back("2");
510     topics.push_back("3");
511
512     g_providerSimul.setTopics(topics);
513
514     std::unique_lock< std::mutex > lock{ mutexForCondition };
515     responseCon.wait_for(lock, g_waitForResponse);
516
517     EXPECT_EQ(OIC::Service::NSProviderState::TOPIC, revState);
518 }
519
520 TEST_F(NotificationServiceConsumerTest, ExpectEQTopicList)
521 {
522     bool isSame = true;
523
524     NSProviderSimulator::NS_TopicList topics;
525     topics.push_back("1");
526     topics.push_back("2");
527     topics.push_back("3");
528
529     ASSERT_NE(nullptr, g_provider) << "error: discovery failure";
530
531     auto  retTopic = g_provider->getTopicList()->getTopicsList();
532     auto it1 = retTopic.begin();
533     auto it2 = topics.begin();
534     while ( it1 != retTopic.end() || it2 != topics.end() )
535     {
536         if ((*it1).getTopicName() !=  *it2)
537         {
538             isSame = false; break;
539         }
540         it1++; it2++;
541     }
542
543
544     EXPECT_EQ(true, isSame);
545 }
546
547 TEST_F(NotificationServiceConsumerTest, ExpectFailUpdateTopicOnConsumer)
548 {
549     ASSERT_NE(nullptr, g_provider) << "error: discovery failure";
550
551     auto retTopic = g_provider->getTopicList();
552     for (auto it : retTopic->getTopicsList())
553     {
554         std::cout << "Topic Name: " << it.getTopicName() << std::endl;
555         std::cout << "state : " << (int) it.getState() << std::endl;
556         it.setState(OIC::Service::NSTopic::NSTopicState::SUBSCRIBED);
557     }
558     OIC::Service::NSResult ret = g_provider->updateTopicList(retTopic);
559     std::cout << "ret : " << (int) ret << std::endl;
560
561     EXPECT_EQ(OIC::Service::NSResult::ERROR, ret);
562 }
563
564
565 TEST_F(NotificationServiceConsumerTest, ExpectCallbackDeletedProvider)
566 {
567     OIC::Service::NSProviderState type = OIC::Service::NSProviderState::ALLOW;
568     mocks.OnCallFunc(ProviderChangedCallbackEmpty).Do(
569         [& type, this](OIC::Service::NSProviderState state)
570     {
571         std::cout << "Income Changed Callback : " << std::endl;
572         type = state;
573     });
574
575     g_providerSimul.deleteNotificationResource();
576
577     std::unique_lock< std::mutex > lock { mutexForCondition };
578     responseCon.wait_for(lock, g_waitForResponse);
579
580     EXPECT_EQ(type, OIC::Service::NSProviderState::STOPPED);
581     OIC::Service::NSConsumerService::getInstance()->stop();
582 }