Merge remote-tracking branch 'origin/master' into notification-service
[platform/upstream/iotivity.git] / service / notification / unittest / NSProviderTest.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 "NSProviderInterface.h"
30 #include "NSConsumerSimulator.h"
31 #include "NSCommon.h"
32
33 namespace
34 {
35     std::atomic_bool g_isStartedStack(false);
36
37     std::chrono::milliseconds g_waitForResponse(500);
38
39     std::condition_variable responseCon;
40     std::mutex mutexForCondition;
41
42     NSConsumerSimulator g_consumerSimul;
43     char * g_consumerID;
44     char g_title[100];
45     char g_body[100];
46     char g_sourceName[100];
47 }
48
49 class TestWithMock: public testing::Test
50 {
51 public:
52     MockRepository mocks;
53
54 protected:
55     virtual ~TestWithMock() noexcept(noexcept(std::declval<Test>().~Test())) {}
56
57     virtual void TearDown() {
58         try
59         {
60             mocks.VerifyAll();
61         }
62         catch (...)
63         {
64             mocks.reset();
65             throw;
66         }
67     }
68 };
69
70 class NotificationProviderTest : public TestWithMock
71 {
72 public:
73     NotificationProviderTest() = default;
74     ~NotificationProviderTest() = default;
75
76     static void NSRequestedSubscribeCallbackEmpty(NSConsumer *)
77     {
78         std::cout << __func__ << std::endl;
79     }
80
81     static void NSSyncCallbackEmpty(NSSyncInfo *)
82     {
83         std::cout << __func__ << std::endl;
84     }
85
86     static void NSMessageCallbackFromConsumerEmpty(
87             const int &, const std::string &, const std::string &, const std::string &)
88     {
89         std::cout << __func__ << std::endl;
90     }
91
92     static void NSSyncCallbackFromConsumerEmpty(int, int)
93     {
94         std::cout << __func__ << std::endl;
95     }
96
97 protected:
98
99     void SetUp()
100     {
101         TestWithMock::SetUp();
102
103         if (g_isStartedStack == false)
104         {
105             OC::PlatformConfig cfg
106             {
107                 OC::ServiceType::InProc,
108                 OC::ModeType::Both,
109                 "0.0.0.0",
110                 0,
111                 OC::QualityOfService::HighQos
112             };
113             OC::OCPlatform::Configure(cfg);
114
115             try
116             {
117                 OC::OCPlatform::stopPresence();
118             }
119             catch (...)
120             {
121
122             }
123
124             g_isStartedStack = true;
125
126             strncpy(g_title, "Title", strlen("Title"));
127             strncpy(g_body, "ContentText", strlen("ContentText"));
128             strncpy(g_sourceName, "OIC", strlen("OIC"));
129         }
130
131     }
132
133     void TearDown()
134     {
135         TestWithMock::TearDown();
136     }
137
138 };
139
140 TEST_F(NotificationProviderTest, StartProviderPositiveWithNSPolicyTrue)
141 {
142     NSProviderConfig config;
143     config.subRequestCallback = NSRequestedSubscribeCallbackEmpty;
144     config.syncInfoCallback = NSSyncCallbackEmpty;
145     config.subControllability = true;
146     config.userInfo = NULL;
147
148     NSResult ret = NSStartProvider(config);
149
150     std::unique_lock< std::mutex > lock{ mutexForCondition };
151     responseCon.wait_for(lock, g_waitForResponse);
152
153     EXPECT_EQ(ret, NS_OK);
154 }
155
156 TEST_F(NotificationProviderTest, StopProviderPositive)
157 {
158     NSResult ret = NSStopProvider();
159
160     std::unique_lock< std::mutex > lock{ mutexForCondition };
161     responseCon.wait_for(lock, g_waitForResponse);
162
163     EXPECT_EQ(ret, NS_OK);
164 }
165
166 TEST_F(NotificationProviderTest, StartProviderPositiveWithNSPolicyFalse)
167 {
168     NSProviderConfig config;
169     config.subRequestCallback = NSRequestedSubscribeCallbackEmpty;
170     config.syncInfoCallback = NSSyncCallbackEmpty;
171     config.subControllability = false;
172     config.userInfo = NULL;
173
174     NSResult ret = NSStartProvider(config);
175
176     std::unique_lock< std::mutex > lock{ mutexForCondition };
177     responseCon.wait_for(lock, std::chrono::milliseconds(3000));
178     g_consumerSimul.findProvider();
179
180     responseCon.wait_for(lock, std::chrono::milliseconds(3000));
181     NSStopProvider();
182     EXPECT_EQ(ret, NS_OK);
183 }
184
185 TEST_F(NotificationProviderTest, ExpectCallbackWhenReceiveSubscribeRequestWithAccepterProvider)
186 {
187     g_consumerID = NULL;
188     mocks.OnCallFunc(NSRequestedSubscribeCallbackEmpty).Do(
189             [](NSConsumer * consumer)
190             {
191                 std::cout << "NSRequestedSubscribeCallback" << std::endl;
192                 g_consumerID = strdup(consumer->consumerId);
193                 responseCon.notify_all();
194             });
195
196     NSProviderConfig config;
197     config.subRequestCallback = NSRequestedSubscribeCallbackEmpty;
198     config.syncInfoCallback = NSSyncCallbackEmpty;
199     config.subControllability = true;
200     config.userInfo = NULL;
201
202     NSStartProvider(config);
203
204     {
205         std::unique_lock< std::mutex > lock{ mutexForCondition };
206         responseCon.wait_for(lock, g_waitForResponse);
207     }
208
209     g_consumerSimul.setCallback(NSMessageCallbackFromConsumerEmpty,
210             NSSyncCallbackFromConsumerEmpty);
211     g_consumerSimul.findProvider();
212
213     std::unique_lock< std::mutex > lock{ mutexForCondition };
214     responseCon.wait_for(lock, std::chrono::milliseconds(1000));
215
216     EXPECT_NE((void*)g_consumerID, (void*)NULL);
217 }
218
219 TEST_F(NotificationProviderTest, NeverCallNotifyOnConsumerByAcceptIsFalse)
220 {
221     bool expectTrue = true;
222     int msgID;
223
224     mocks.OnCallFunc(NSMessageCallbackFromConsumerEmpty).Do(
225             [& expectTrue, &msgID](const int &id, const std::string&, const std::string&, const std::string&)
226             {
227                 if (id == msgID)
228                 {
229                     std::cout << "This function never call" << std::endl;
230                     expectTrue = false;
231                 }
232             });
233
234     NSAcceptSubscription(g_consumerID, false);
235
236     NSMessage * msg = NSCreateMessage();
237     msgID = (int)msg->messageId;
238     msg->title = g_title;
239     msg->contentText = g_body;
240     msg->sourceName = g_sourceName;
241
242     NSSendMessage(msg);
243     {
244         std::unique_lock< std::mutex > lock{ mutexForCondition };
245         responseCon.wait_for(lock, g_waitForResponse);
246     }
247
248     std::unique_lock< std::mutex > lock{ mutexForCondition };
249     responseCon.wait_for(lock, std::chrono::milliseconds(1000));
250
251     EXPECT_EQ(expectTrue, true);
252
253     NSAcceptSubscription(g_consumerID, true);
254 }
255
256 TEST_F(NotificationProviderTest, ExpectCallNotifyOnConsumerByAcceptIsTrue)
257 {
258     int msgID;
259
260     mocks.ExpectCallFunc(NSMessageCallbackFromConsumerEmpty).Do(
261             [&msgID](const int &id, const std::string&, const std::string&, const std::string&)
262             {
263                 std::cout << "id : " << id << std::endl;
264                 if (id == msgID)
265                 {
266                     std::cout << "ExpectCallNotifyOnConsumerByAcceptIsTrue" << std::endl;
267                     responseCon.notify_all();
268                 }
269             });
270
271     NSAcceptSubscription(g_consumerID, true);
272
273     NSMessage * msg = NSCreateMessage();
274     msgID = (int)msg->messageId;
275     msg->title = g_title;
276     msg->contentText = g_body;
277     msg->sourceName = g_sourceName;
278     NSSendMessage(msg);
279
280     std::unique_lock< std::mutex > lock{ mutexForCondition };
281     responseCon.wait(lock);
282 }
283
284 TEST_F(NotificationProviderTest, ExpectCallbackSyncOnReadToConsumer)
285 {
286     int id;
287
288     mocks.ExpectCallFunc(NSSyncCallbackFromConsumerEmpty).Do(
289             [& id](int & type, int &syncId)
290             {
291         std::cout << "NSSyncCallbackEmpty" << std::endl;
292                 if (syncId == id &&
293                         type == NS_SYNC_READ)
294                 {
295                     std::cout << "ExpectCallbackSyncOnReadFromConsumer" << std::endl;
296                     responseCon.notify_all();
297                 }
298             });
299
300     NSMessage * msg = NSCreateMessage();
301     id = (int)msg->messageId;
302     msg->title = g_title;
303     msg->contentText = g_body;
304     msg->sourceName = g_sourceName;
305
306     NSProviderSendSyncInfo(msg->messageId, NS_SYNC_READ);
307     std::unique_lock< std::mutex > lock{ mutexForCondition };
308     responseCon.wait_for(lock, std::chrono::milliseconds(5000));
309 }
310
311 TEST_F(NotificationProviderTest, ExpectCallbackSyncOnReadFromConsumer)
312 {
313     int type = NS_SYNC_READ;
314     int id;
315     mocks.ExpectCallFunc(NSSyncCallbackEmpty).Do(
316             [& id](NSSyncInfo * sync)
317             {
318                 std::cout << "NSSyncCallbackEmpty" << std::endl;
319                 if ((int)sync->messageId == id && sync->state == NS_SYNC_READ)
320                 {
321                     std::cout << "ExpectCallbackSyncOnReadFromConsumer" << std::endl;
322                     responseCon.notify_all();
323                 }
324             });
325
326     NSMessage * msg = NSCreateMessage();
327     id = (int)msg->messageId;
328     msg->title = g_title;
329     msg->contentText = g_body;
330     msg->sourceName = g_sourceName;
331
332     g_consumerSimul.syncToProvider(type, id, msg->providerId);
333     std::unique_lock< std::mutex > lock{ mutexForCondition };
334     responseCon.wait_for(lock, std::chrono::milliseconds(5000));
335 }
336
337 TEST_F(NotificationProviderTest, ExpectEqualAddedTopicsAndRegisteredTopics)
338 {
339     std::string str("TEST1");
340     std::string str2("TEST2");
341     NSProviderRegisterTopic(str.c_str());
342     NSProviderRegisterTopic(str2.c_str());
343
344     bool isSame = true;
345     NSTopicLL * topics = NSProviderGetTopics();
346
347     if(!topics)
348     {
349         printf("topic is NULL\n");
350         isSame = false;
351     }
352     else
353     {
354         NSTopicLL * iter = topics;
355         std::string compStr(iter->topicName);
356         std::string compStr2(iter->next->topicName);
357
358         printf("str = %s, compStr = %s\n", str.c_str(), iter->topicName);
359         printf("str2 = %s, compStr2 = %s\n", str2.c_str(), iter->next->topicName);
360
361         if(str.compare(compStr) == 0 && str2.compare(compStr2) == 0)
362         {
363             isSame = true;
364         }
365     }
366
367     EXPECT_EQ(isSame, true);
368 }
369
370 TEST_F(NotificationProviderTest, ExpectEqualUnregisteredTopicsAndRegisteredTopics)
371 {
372     std::string str("TEST1");
373     std::string str2("TEST2");
374     NSProviderRegisterTopic(str.c_str());
375     NSProviderRegisterTopic(str2.c_str());
376     NSProviderUnregisterTopic(str2.c_str());
377
378     bool isSame = true;
379     NSTopicLL * topics = NSProviderGetTopics();
380
381     if(!topics)
382     {
383         printf("topic is NULL\n");
384         isSame = false;
385     }
386     else
387     {
388         NSTopicLL * iter = topics;
389         std::string compStr(iter->topicName);
390
391         printf("str = %s, compStr = %s\n", str.c_str(), iter->topicName);
392
393         if(str.compare(compStr) == 0)
394         {
395             isSame = true;
396         }
397     }
398
399     EXPECT_EQ(isSame, true);
400 }
401
402 TEST_F(NotificationProviderTest, CancelObserves)
403 {
404     bool ret = g_consumerSimul.cancelObserves();
405
406     std::unique_lock< std::mutex > lock{ mutexForCondition };
407     responseCon.wait_for(lock, std::chrono::milliseconds(5000));
408
409     EXPECT_EQ(ret, true);
410 }