Fix to prevent of crash on the unit test.
[platform/upstream/iotivity.git] / service / notification / unittest / NSConsumerTest2.cpp
1 //******************************************************************
2 //
3 // Copyright 2017 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
23 #include <list>
24 #include <condition_variable>
25 #include <mutex>
26 #include <chrono>
27
28 #include "OCPlatform.h"
29 #include "octypes.h"
30 #include "ocstack.h"
31 #include "ocpayload.h"
32 #include "cainterface.h"
33
34 #include "NSCommon.h"
35 #include "NSConsumerInterface.h"
36 #include "NSConsumerDiscovery.h"
37 #include "NSConsumerCommunication.h"
38 #include "NSConsumerInternalTaskController.h"
39
40 namespace
41 {
42     NSProvider * g_provider = NULL;
43     NSProvider_internal * g_provider_internal = NULL;
44
45     OCClientResponse * g_testResponse = NULL;
46     OCDevAddr * testAddr = NULL;
47
48     uint64_t revId = 0;
49     NSSyncType type = NS_SYNC_DELETED;
50     NSProviderState revState = NS_STOPPED;
51     NSProviderState expectedState = NS_STOPPED;
52
53     NSConsumerConfig cfg;
54
55     std::chrono::milliseconds g_waitForResponse(1000);
56
57     std::condition_variable messageReceive;
58     std::mutex messageReceiveLock;
59
60     std::condition_variable syncReceive;
61     std::mutex syncReceiveLock;
62
63     std::condition_variable providerChanged;
64     std::mutex providerChangedLock;
65
66     const std::string testProviderID = "123456789012345678901234567890123456";
67
68     static void NSNotificationReceivedCallback(NSMessage * message)
69         {
70         if (0 != testProviderID.compare(message->providerId))
71         {
72             NSRemoveMessage(message);
73             return;
74         }
75
76         std::cout << __func__ << std::endl;
77         std::cout << "Income Notification : " << message->messageId << std::endl;
78         revId = message->messageId;
79
80         NSRemoveMessage(message);
81         messageReceive.notify_all();
82     }
83
84     static void NSSyncCallback(NSSyncInfo * sync)
85     {
86         if (0 != testProviderID.compare(sync->providerId))
87         {
88             free(sync);
89             return;
90         }
91
92         std::cout << __func__ << std::endl;
93         std::cout << "Income SyncInfo : " << sync->messageId
94                 << ", State : " << sync->state << std::endl;
95         type = sync->state;
96
97         free(sync);
98         syncReceive.notify_all();
99     }
100
101     static void NSProviderChangedCallback(NSProvider * provider,  NSProviderState state)
102     {
103         if (0 != testProviderID.compare(provider->providerId))
104         {
105             NSRemoveProvider(provider);
106             return;
107         }
108
109         std::cout << __func__ << " " << state << std::endl;
110         std::cout << provider->providerId << std::endl;
111         if (g_provider)
112         {
113             NSRemoveProvider(g_provider);
114             g_provider = NULL;
115         }
116         g_provider = provider;
117
118         if (expectedState == state)
119         {
120             revState = state;
121             providerChanged.notify_all();
122         }
123     }
124     static FILE* client_open(const char * path, const char * mode)
125     {
126         if (0 == strcmp(path, OC_SECURITY_DB_DAT_FILE_NAME))
127         {
128             std::string file_name = "./oic_svr_db_ns.dat";
129             return fopen(file_name.c_str(), mode);
130         }
131         else
132         {
133             return fopen(path, mode);
134         }
135     }
136
137     OCDevAddr * getDevAddr()
138     {
139         CAEndpoint_t * ninfo = NULL;
140         size_t size = 0;
141         CAResult_t ret = CAGetNetworkInformation(&ninfo, &size);
142         if (ret != CA_STATUS_OK || size == 0)
143         {
144             return NULL;
145         }
146
147         OCDevAddr * addr =
148                 (OCDevAddr *)malloc(sizeof(OCDevAddr));
149         if (addr == NULL)
150         {
151             free(ninfo);
152             return NULL;
153         }
154         addr->adapter = (ninfo[0].adapter == CA_ALL_ADAPTERS) ? OC_ADAPTER_IP :
155                 (OCTransportAdapter) ninfo[0].adapter;
156         strncpy(addr->addr, ninfo[0].addr, sizeof(ninfo[0].addr));
157         addr->flags = (OCTransportFlags)ninfo[0].flags;
158         addr->ifindex = ninfo[0].ifindex;
159         addr->port = ninfo[0].port;
160         strncpy(addr->remoteId, ninfo[0].remoteId, 37);
161
162         free(ninfo);
163         ninfo = NULL;
164         return addr;
165     }
166
167     OCRepPayload * getDiscoverPayload()
168     {
169         OCRepPayload * payload = OCRepPayloadCreate();
170         EXPECT_NE((void *)NULL, payload);
171
172         std::string msgUri = "/notifiationTest/message";
173         std::string syncUri = "/notifiationTest/sync";
174         std::string topicUri = "/notifiationTest/topic";
175
176         bool getResult = OCRepPayloadSetPropBool(payload, NS_ATTRIBUTE_POLICY, false);
177         getResult &= OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, testProviderID.c_str());
178         getResult &= OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_MESSAGE, msgUri.c_str());
179         getResult &= OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_SYNC, syncUri.c_str());
180         getResult &= OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_TOPIC, topicUri.c_str());
181         if (getResult == false)
182         {
183             OCRepPayloadDestroy(payload);
184         }
185         EXPECT_EQ(true, getResult);
186
187         return payload;
188     }
189
190     OCRepPayload * getMsgPayload(uint64_t msgId)
191     {
192         OCRepPayload * payload = OCRepPayloadCreate();
193         EXPECT_NE((void *)NULL, payload);
194         bool getResult = OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, msgId);
195         getResult &= OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, testProviderID.c_str());
196         if (getResult == false)
197         {
198             OCRepPayloadDestroy(payload);
199         }
200         EXPECT_EQ(true, getResult);
201
202         return payload;
203     }
204
205     OCRepPayload * getSyncPayload(uint64_t msgId, int64_t state)
206     {
207         OCRepPayload * payload = OCRepPayloadCreate();
208         EXPECT_NE((void *)NULL, payload);
209         bool getResult = OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_MESSAGE_ID, msgId);
210         getResult &= OCRepPayloadSetPropString(payload, NS_ATTRIBUTE_PROVIDER_ID, testProviderID.c_str());
211         getResult &= OCRepPayloadSetPropInt(payload, NS_ATTRIBUTE_STATE, state);
212         if (getResult == false)
213         {
214             OCRepPayloadDestroy(payload);
215         }
216         EXPECT_EQ(true, getResult);
217
218         return payload;
219     }
220
221     OCRepPayload * getTopicPayload()
222     {
223         size_t dimensions[MAX_REP_ARRAY_DEPTH] = {3, 0, 0};
224         OCRepPayload ** topicList = (OCRepPayload **)malloc(sizeof(OCRepPayload *)*3);
225         EXPECT_NE((void *)NULL, topicList);
226         for (int i = 0; i < 3; ++i)
227         {
228             topicList[i] = OCRepPayloadCreate();
229             EXPECT_NE((void *)NULL, topicList[i]);
230
231             bool getResult = OCRepPayloadSetPropInt(topicList[i],
232                             NS_ATTRIBUTE_TOPIC_SELECTION, 1);
233             getResult &= OCRepPayloadSetPropString(topicList[i],
234                             NS_ATTRIBUTE_TOPIC_NAME, std::to_string(i+1).c_str());
235             EXPECT_EQ(true, getResult);
236         }
237
238         OCRepPayload * payload = OCRepPayloadCreate();
239         EXPECT_NE((void *)NULL, payload);
240         bool getResult = OCRepPayloadSetPropString(payload,
241                         NS_ATTRIBUTE_CONSUMER_ID, testProviderID.c_str());
242         getResult &= OCRepPayloadSetPropObjectArrayAsOwner(payload,
243                         NS_ATTRIBUTE_TOPIC_LIST, topicList, dimensions);
244         if (getResult == false)
245         {
246             OCRepPayloadDestroy(payload);
247         }
248         EXPECT_EQ(true, getResult);
249
250         return payload;
251     }
252
253     OCClientResponse * createResponse()
254     {
255         OCClientResponse * testResponse =
256                 (OCClientResponse *)malloc(sizeof(OCClientResponse));
257         EXPECT_NE((void *)NULL, testResponse);
258
259         std::string notiUri = "/notifiationTest";
260
261         testResponse->addr = testAddr;
262         testResponse->devAddr = *testAddr;
263         testResponse->connType = CT_ADAPTER_IP;
264         testResponse->identity.id_length = 37;
265         strncpy((char *)(testResponse->identity.id), testProviderID.c_str(), 37);
266         testResponse->numRcvdVendorSpecificHeaderOptions = 0;
267         testResponse->resourceUri = (char*)malloc(sizeof(char)*notiUri.size() + 1);
268         strncpy((char*)testResponse->resourceUri, notiUri.c_str(), notiUri.size()+1);
269         testResponse->result = OC_STACK_OK;
270         testResponse->sequenceNumber = 1;
271         testResponse->payload = NULL;
272
273         return testResponse;
274     }
275
276     NSProvider_internal * getProvider(OCDevAddr * addr)
277     {
278         if (addr == NULL)
279         {
280             return NULL;
281         }
282
283         NSProviderConnectionInfo * info =
284                 (NSProviderConnectionInfo *)malloc(sizeof(NSProviderConnectionInfo));
285         if (info == NULL)
286         {
287             free(addr);
288             return NULL;
289         }
290         info->isCloudConnection = false;
291         info->isSubscribing = false;
292         info->messageHandle = NULL;
293         info->syncHandle = NULL;
294         info->next = NULL;
295         info->addr = addr;
296
297         NSProvider_internal * provider =
298                 (NSProvider_internal *)malloc(sizeof(NSProvider_internal));
299         if (provider == NULL)
300         {
301             free(addr);
302             free(info);
303             return NULL;
304         }
305         provider->accessPolicy = NSSelector::NS_SELECTION_CONSUMER;
306         provider->state = NS_DISCOVERED;
307         strcpy(provider->providerId, testProviderID.c_str());
308         provider->messageUri = strdup("/notificationTest/message");
309         provider->syncUri = strdup("/notificationTest/sync");
310         provider->topicUri = strdup("/notificationTest/topic");
311         provider->topicLL = NULL;
312         provider->connection = info;
313
314         return provider;
315     }
316
317     void stackInit()
318     {
319         static OCPersistentStorage gps {client_open, fread, fwrite, fclose, unlink };
320         OC::PlatformConfig occfg
321         {
322             OC::ServiceType::InProc,
323             OC::ModeType::Both,
324             "0.0.0.0",
325             0,
326             OC::QualityOfService::LowQos,
327             &gps
328         };
329         OC::OCPlatform::Configure(occfg);
330
331         try
332         {
333             OC::OCPlatform::stopPresence();
334         }
335         catch (...)
336         {
337
338         }
339
340         testAddr = getDevAddr();
341         if (testAddr == NULL)
342         {
343             throw std::exception();
344         }
345     }
346     void stackTearDown()
347     {
348         if (testAddr)
349         {
350             free(testAddr);
351             testAddr = NULL;
352         }
353         if (g_provider)
354         {
355             NSRemoveProvider(g_provider);
356             g_provider = NULL;
357         }
358     }
359
360     void removeGlobalResponse()
361     {
362         if (g_testResponse)
363         {
364             free((void*)(g_testResponse->resourceUri));
365             free(g_testResponse);
366             g_testResponse = NULL;
367         }
368     }
369 }
370
371 TEST(NotificationConsumerTest, StartConsumerNegativeNonSetChangedCB)
372 {
373     cfg.changedCb = NULL;
374     cfg.messageCb = NSNotificationReceivedCallback;
375     cfg.syncInfoCb = NSSyncCallback;
376
377     EXPECT_EQ(NS_ERROR, NSStartConsumer(cfg));
378 }
379
380 TEST(NotificationConsumerTest, StartConsumerNegativeNonSetNotiReceiveCB)
381 {
382     cfg.changedCb = NSProviderChangedCallback;
383     cfg.messageCb = NULL;
384     cfg.syncInfoCb = NSSyncCallback;
385
386     EXPECT_EQ(NS_ERROR, NSStartConsumer(cfg));
387 }
388
389 TEST(NotificationConsumerTest, StartConsumerNegativeNonSetSyncCB)
390 {
391     cfg.changedCb = NSProviderChangedCallback;
392     cfg.messageCb = NSNotificationReceivedCallback;
393     cfg.syncInfoCb = NULL;
394
395     EXPECT_EQ(NS_ERROR, NSStartConsumer(cfg));
396 }
397
398 TEST(NotificationConsumerTest, StartConsumerPositive)
399 {
400
401     EXPECT_NO_THROW(stackInit());
402
403     cfg.changedCb = NSProviderChangedCallback;
404     cfg.messageCb = NSNotificationReceivedCallback;
405     cfg.syncInfoCb = NSSyncCallback;
406
407     EXPECT_EQ(NS_OK, NSStartConsumer(cfg));
408 }
409
410 TEST(NotificationConsumerTest, StopConsumerPositive)
411 {
412     EXPECT_EQ(NSStopConsumer(), NS_OK);
413 }
414
415 TEST(NotificationConsumerTest, StopConsumerNegative)
416 {
417     EXPECT_EQ(NSStopConsumer(), NS_ERROR);
418 }
419
420 TEST(NotificationConsumerTest, ExpectCallbackDiscovered)
421 {
422     cfg.changedCb = NSProviderChangedCallback;
423     cfg.messageCb = NSNotificationReceivedCallback;
424     cfg.syncInfoCb = NSSyncCallback;
425
426     NSStartConsumer(cfg);
427
428     revState = NS_STOPPED;
429     expectedState = NS_DISCOVERED;
430
431     g_testResponse = createResponse();
432     g_testResponse->payload = (OCPayload *)getDiscoverPayload();
433     NSIntrospectProvider(NULL, NULL, g_testResponse);
434
435     std::unique_lock< std::mutex > lock{ providerChangedLock };
436     providerChanged.wait_for(lock, g_waitForResponse);
437
438     OCRepPayloadDestroy((OCRepPayload *)g_testResponse->payload);
439     g_testResponse->payload = NULL;
440     removeGlobalResponse();
441
442     EXPECT_EQ(NS_DISCOVERED, revState);
443 }
444
445 TEST(NotificationConsumerTest, ExpectCallbackAllow)
446 {
447     revState = NS_STOPPED;
448     expectedState = NS_ALLOW;
449
450     g_testResponse = createResponse();
451     g_testResponse->payload = (OCPayload *)getMsgPayload(NS_ALLOW);
452     NSConsumerMessageListener(NULL,NULL, g_testResponse);
453
454     std::unique_lock< std::mutex > lock{ providerChangedLock };
455     providerChanged.wait_for(lock, g_waitForResponse);
456
457     OCRepPayloadDestroy((OCRepPayload *)g_testResponse->payload);
458     g_testResponse->payload = NULL;
459     removeGlobalResponse();
460
461     EXPECT_EQ(NS_ALLOW, revState);
462 }
463
464 TEST(NotificationConsumerTest, ExpectReceiveNotification)
465 {
466     uint64_t id = 100;
467
468     g_testResponse = createResponse();
469     g_testResponse->payload = (OCPayload *)getMsgPayload(id);
470     NSConsumerMessageListener(NULL,NULL, g_testResponse);
471
472     std::unique_lock< std::mutex > lock{ messageReceiveLock };
473     messageReceive.wait_for(lock, g_waitForResponse);
474
475     OCRepPayloadDestroy((OCRepPayload *)g_testResponse->payload);
476     g_testResponse->payload = NULL;
477     removeGlobalResponse();
478
479     EXPECT_EQ(id, revId);
480 }
481
482 TEST(NotificationConsumerTest, ExpectReceiveSyncInfo)
483 {
484     uint64_t id = 100;
485     type = NS_SYNC_DELETED;
486
487     g_testResponse = createResponse();
488     g_testResponse->payload = (OCPayload *)getSyncPayload(id, NS_SYNC_READ);
489     NSConsumerSyncInfoListener(NULL,NULL, g_testResponse);
490
491     std::unique_lock< std::mutex > lock{ syncReceiveLock };
492     syncReceive.wait_for(lock, g_waitForResponse);
493
494     OCRepPayloadDestroy((OCRepPayload *)g_testResponse->payload);
495     g_testResponse->payload = NULL;
496     removeGlobalResponse();
497
498     EXPECT_EQ(NS_SYNC_READ, type);
499 }
500
501 TEST(NotificationConsumerTest, ExpectSuccessSendSyncInfo)
502 {
503     uint64_t id = 100;
504     type = NS_SYNC_READ;
505
506     auto ret = NSConsumerSendSyncInfo(g_provider->providerId, id, NS_SYNC_DELETED);
507
508     EXPECT_EQ(NS_OK, ret);
509 }
510
511 TEST(NotificationConsumerTest, GetValidProvider)
512 {
513     NSProvider * provider = NSConsumerGetProvider(g_provider->providerId);
514     EXPECT_NE((void *)NULL, provider);
515     NSRemoveProvider(provider);
516 }
517
518 TEST(NotificationConsumerTest, GetInvalidProvider)
519 {
520     NSProvider * provider = NSConsumerGetProvider(NULL);
521     EXPECT_EQ((void *)NULL, provider);
522 }
523
524 TEST(NotificationConsumerTest, ExpectGetTopicListIsNULL)
525 {
526     NSTopicLL * currentTopics = NSConsumerGetTopicList(g_provider->providerId);
527     EXPECT_EQ(NULL, currentTopics);
528
529     if (currentTopics)
530     {
531         NSRemoveTopicLL(currentTopics);
532     }
533 }
534
535 TEST(NotificationConsumerTest, ExpectCallbackTopicUpdated)
536 {
537     revState = NS_STOPPED;
538
539     g_testResponse = createResponse();
540     g_testResponse->payload = (OCPayload *)getTopicPayload();
541     g_provider_internal = getProvider(testAddr);
542     NSIntrospectTopic((void *)g_provider_internal, NULL, g_testResponse);
543
544     expectedState = NS_TOPIC;
545     std::unique_lock< std::mutex > lock{ providerChangedLock };
546     providerChanged.wait_for(lock, g_waitForResponse);
547
548     EXPECT_EQ(NS_TOPIC, revState);
549
550     OCRepPayloadDestroy((OCRepPayload *)g_testResponse->payload);
551     g_testResponse->payload = NULL;
552     removeGlobalResponse();
553
554     expectedState = NS_STOPPED;
555 }
556
557 TEST(NotificationConsumerTest, ExpectEQTopicList)
558 {
559     bool isSame = true;
560
561     typedef std::list<std::string> TesttopicList;
562     TesttopicList topics;
563     topics.push_back("1");
564     topics.push_back("2");
565     topics.push_back("3");
566
567     NSTopicLL * retTopic = NSConsumerGetTopicList(g_provider_internal->providerId);
568     EXPECT_NE((void *)NULL, (void *)retTopic);
569
570     NSTopicLL * iter = retTopic;
571     std::for_each (topics.begin(), topics.end(),
572             [this, & iter, & isSame](const std::string & str)
573             {
574                 isSame &= (str == std::string(iter->topicName));
575                 iter = iter->next;
576             });
577
578     NSRemoveTopicLL(retTopic);
579
580     EXPECT_EQ(true, isSame);
581 }
582
583 TEST(NotificationConsumerTest, ExpectSuccessUpdateTopicOnConsumer)
584 {
585     NSTopicLL * retTopic = NSConsumerGetTopicList(g_provider_internal->providerId);
586
587     NSTopicLL * iter = retTopic;
588     for (; iter; iter = iter->next)
589     {
590         iter->state = NS_TOPIC_SUBSCRIBED;
591     }
592     NSResult ret = NSConsumerUpdateTopicList(g_provider_internal->providerId, retTopic);
593
594     NSRemoveTopicLL(retTopic);
595
596     EXPECT_EQ(NS_OK, ret);
597 }
598
599 TEST(NotificationConsumerTest, ExpectUnsubscribeSuccess)
600 {
601     revState = NS_DENY;
602     NSResult ret = NSUnsubscribe(g_provider_internal->providerId);
603
604     expectedState = NS_STOPPED;
605     std::unique_lock< std::mutex > lock{ providerChangedLock };
606     providerChanged.wait_for(lock, g_waitForResponse);
607
608     EXPECT_EQ(NS_STOPPED, revState);
609     EXPECT_EQ(NS_OK, ret);
610 }
611
612 TEST(NotificationConsumerTest, ExpectUnsubscribeWithPresenceStart)
613 {
614     g_testResponse = createResponse();
615     OCPresencePayload * payload = OCPresencePayloadCreate(1, 2, OC_PRESENCE_TRIGGER_CREATE, NULL);
616     EXPECT_NE((void *)NULL, payload);
617     g_testResponse->payload = (OCPayload *)payload;
618
619     auto ret = NSConsumerPresenceListener(NULL,NULL, g_testResponse);
620
621     EXPECT_EQ(OC_STACK_KEEP_TRANSACTION, ret);
622     OCPresencePayloadDestroy(payload);
623     removeGlobalResponse();
624 }
625
626 TEST(NotificationConsumerTest, ExpectUnsubscribeWithPresenceStop)
627 {
628     g_testResponse = createResponse();
629     OCPresencePayload * payload = OCPresencePayloadCreate(2, 2, OC_PRESENCE_TRIGGER_DELETE, NULL);
630     EXPECT_NE((void *)NULL, payload);
631     g_testResponse->payload = (OCPayload *)payload;
632
633     auto ret = NSConsumerPresenceListener(NULL,NULL, g_testResponse);
634
635     EXPECT_EQ(OC_STACK_KEEP_TRANSACTION, ret);
636     OCPresencePayloadDestroy(payload);
637
638     NSStopConsumer();
639
640     stackTearDown();
641 }