ef6611f6b981fef7cca0eac7f80fcb348ad816c8
[platform/upstream/iotivity.git] / service / easy-setup / enrollee / unittests / ESEnrolleeTest.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 "ESMediatorSimulator.h"
30 #include "easysetup.h"
31
32 using namespace OC;
33
34 namespace
35 {
36     std::atomic_bool g_isStartedStack(false);
37
38     std::chrono::milliseconds g_waitForResponse(1000);
39
40     std::condition_variable responseCon;
41     std::mutex mutexForCondition;
42
43     ESMediatorSimulator g_mediatorSimul;
44 }
45
46 class TestWithMock: public testing::Test
47 {
48 public:
49     MockRepository mocks;
50
51 protected:
52     virtual ~TestWithMock() noexcept(noexcept(std::declval<Test>().~Test()))
53     {
54     }
55
56     virtual void TearDown()
57     {
58         try
59         {
60             mocks.VerifyAll();
61         }
62         catch (...)
63         {
64             mocks.reset();
65             throw;
66         }
67     }
68 };
69
70 class EasysetupEnrolleeTest : public TestWithMock
71 {
72 public:
73     EasysetupEnrolleeTest() = default;
74     ~EasysetupEnrolleeTest() = default;
75
76     static void discoveredResource(std::shared_ptr<OC::OCResource>)
77     {
78         std::cout << __func__ << std::endl;
79     }
80
81     static void onGetStatus(std::shared_ptr< GetEnrolleeStatus >)
82     {
83         std::cout << __func__ << std::endl;
84     }
85
86     static void onGetConfiguration(std::shared_ptr< GetConfigurationStatus >)
87     {
88         std::cout << __func__ << std::endl;
89     }
90
91     static void onGetWifiRsrc(const OCRepresentation& )
92     {
93         std::cout << __func__ << std::endl;
94     }
95
96     static void onGetCloudRsrc(const OCRepresentation& )
97     {
98         std::cout << __func__ << std::endl;
99     }
100
101     static void onGetDeviceConf(const OCRepresentation& )
102     {
103         std::cout << __func__ << std::endl;
104     }
105
106     static void onPutRequest(const OCRepresentation& )
107     {
108         std::cout << __func__ << std::endl;
109     }
110
111     static void deviceProvisioningStatusCallback(std::shared_ptr< DevicePropProvisioningStatus >)
112     {
113         std::cout << __func__ << std::endl;
114     }
115
116     static void cloudProvisioningStatusCallback(std::shared_ptr< CloudPropProvisioningStatus >)
117     {
118         std::cout << __func__ << std::endl;
119     }
120
121     static void WiFiProvCbInApp(ESWiFiProvData *)
122     {
123         std::cout << __func__ << std::endl;
124     }
125
126     static void DevConfProvCbInApp(ESDevConfProvData *)
127     {
128         std::cout << __func__ << std::endl;
129     }
130
131     static void CloudDataCbInApp(ESCloudProvData *)
132     {
133         std::cout << __func__ << std::endl;
134     }
135
136     ESResult startEnrollee()
137     {
138         ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFI_RESOURCE |
139                                                     ES_CLOUD_RESOURCE |
140                                                     ES_DEVCONF_RESOURCE);
141         ESProvisioningCallbacks callbacks;
142         callbacks.WiFiProvCb = &EasysetupEnrolleeTest::WiFiProvCbInApp;
143         callbacks.DevConfProvCb = &EasysetupEnrolleeTest::DevConfProvCbInApp;
144         callbacks.CloudDataProvCb = &EasysetupEnrolleeTest::CloudDataCbInApp;
145
146         return ESInitEnrollee(false, resourcemMask, callbacks);
147     }
148
149     ESResult startEnrolleeWithInvalidRsrcMask()
150     {
151         ESProvisioningCallbacks callbacks;
152         callbacks.WiFiProvCb = &EasysetupEnrolleeTest::WiFiProvCbInApp;
153         callbacks.DevConfProvCb = &EasysetupEnrolleeTest::DevConfProvCbInApp;
154         callbacks.CloudDataProvCb = &EasysetupEnrolleeTest::CloudDataCbInApp;
155
156         return ESInitEnrollee(false, (ESResourceMask)0, callbacks);
157     }
158
159     ESResult setDeviceProperty()
160     {
161         ESDeviceProperty deviceProperty = {
162             {{WIFI_11G, WiFi_EOF}, WIFI_5G}, {"Test Device", "Test Model Number"}
163         };
164
165         return ESSetDeviceProperty(&deviceProperty);
166     }
167
168     ESResult setCallabckForUserDataNULL()
169     {
170         return ESSetCallbackForUserdata(NULL, NULL);
171     }
172
173 protected:
174
175     void SetUp()
176     {
177         TestWithMock::SetUp();
178
179         if (g_isStartedStack == false)
180         {
181             if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
182             {
183                 printf("OCStack init error!!\n");
184                 return;
185             }
186
187             g_isStartedStack = true;
188         }
189     }
190
191     void TearDown()
192     {
193         TestWithMock::TearDown();
194     }
195
196 };
197
198 TEST_F(EasysetupEnrolleeTest, ESInitEnrolleeSuccess)
199 {
200     ESResult ret = startEnrollee();
201     EXPECT_EQ(ret, ES_OK);
202     ESTerminateEnrollee();
203 }
204
205 TEST_F(EasysetupEnrolleeTest, ESInitEnrolleeFailedInvalidRsrcMask)
206 {
207     ESResult ret = startEnrolleeWithInvalidRsrcMask();
208     EXPECT_EQ(ret, ES_ERROR);
209     ESTerminateEnrollee();
210 }
211
212 TEST_F(EasysetupEnrolleeTest, ESInitEnrolleeFailedByWiFiCbIsNull)
213 {
214     ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFI_RESOURCE |
215                                                     ES_CLOUD_RESOURCE |
216                                                     ES_DEVCONF_RESOURCE);
217     ESProvisioningCallbacks callbacks;
218     callbacks.WiFiProvCb = NULL;
219     callbacks.DevConfProvCb = &EasysetupEnrolleeTest::DevConfProvCbInApp;
220     callbacks.CloudDataProvCb = &EasysetupEnrolleeTest::CloudDataCbInApp;
221
222     ESResult ret = ESInitEnrollee(false, resourcemMask, callbacks);
223     EXPECT_EQ(ret, ES_ERROR);
224     ESTerminateEnrollee();
225 }
226
227 TEST_F(EasysetupEnrolleeTest, ESInitEnrolleeFailedByDevConfCbIsNull)
228 {
229     ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFI_RESOURCE |
230                                                     ES_CLOUD_RESOURCE |
231                                                     ES_DEVCONF_RESOURCE);
232     ESProvisioningCallbacks callbacks;
233     callbacks.WiFiProvCb = &EasysetupEnrolleeTest::WiFiProvCbInApp;
234     callbacks.DevConfProvCb = NULL;
235     callbacks.CloudDataProvCb = &EasysetupEnrolleeTest::CloudDataCbInApp;
236
237     ESResult ret = ESInitEnrollee(false, resourcemMask, callbacks);
238     EXPECT_EQ(ret, ES_ERROR);
239     ESTerminateEnrollee();
240 }
241
242 TEST_F(EasysetupEnrolleeTest, ESInitEnrolleeFailedByCloudCbIsNull)
243 {
244     ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFI_RESOURCE |
245                                                     ES_CLOUD_RESOURCE |
246                                                     ES_DEVCONF_RESOURCE);
247     ESProvisioningCallbacks callbacks;
248     callbacks.WiFiProvCb = &EasysetupEnrolleeTest::WiFiProvCbInApp;
249     callbacks.DevConfProvCb = &EasysetupEnrolleeTest::DevConfProvCbInApp;
250     callbacks.CloudDataProvCb = NULL;
251
252     ESResult ret = ESInitEnrollee(false, resourcemMask, callbacks);
253     EXPECT_EQ(ret, ES_ERROR);
254     ESTerminateEnrollee();
255 }
256
257 TEST_F(EasysetupEnrolleeTest, FindProvisioningResourceAtEnrolleeWithSuccess)
258 {
259     mocks.ExpectCallFunc(discoveredResource).Do(
260         [](std::shared_ptr<OC::OCResource> resource)
261         {
262             try
263             {
264                 std::cout<<"DISCOVERED Resource:"<<std::endl;
265                 // Get the resource host address
266                 std::string uri = resource->uri();
267                 std::cout << "\tURI of the resource: " << uri << std::endl;
268             } catch (OCException &e)
269             {
270                 std::cout << e.reason() << std::endl;
271             }
272
273         });
274
275     ESResult ret = startEnrollee();
276
277     g_mediatorSimul.discoverRemoteEnrollee(discoveredResource);
278
279     std::unique_lock< std::mutex > lock{ mutexForCondition };
280     responseCon.wait_for(lock, g_waitForResponse);
281
282     EXPECT_EQ(ret, ES_OK);
283
284     ESTerminateEnrollee();
285 }
286
287 TEST_F(EasysetupEnrolleeTest, SetDevicePropertyWithSuccess)
288 {
289     ESResult ret = startEnrollee();
290     ret = setDeviceProperty();
291     EXPECT_EQ(ret, ES_OK);
292     ESTerminateEnrollee();
293 }
294
295 TEST_F(EasysetupEnrolleeTest, SetProvStatusWithSuccess)
296 {
297     ESResult ret = startEnrollee();
298     ret = ESSetState(ES_STATE_CONNECTED_TO_ENROLLER);
299     EXPECT_EQ(ret, ES_OK);
300     ESTerminateEnrollee();
301 }
302
303 TEST_F(EasysetupEnrolleeTest, SetErrorCodeWithSuccess)
304 {
305     ESResult ret = startEnrollee();
306     ret = ESSetErrorCode(ES_ERRCODE_PW_WRONG);
307     EXPECT_EQ(ret, ES_OK);
308     ESTerminateEnrollee();
309 }
310
311 TEST_F(EasysetupEnrolleeTest, DevicePropertyIsWellConstructedInResponsePayload)
312 {
313     bool isWellConstructed = false;
314     mocks.ExpectCallFunc(onGetConfiguration).Do(
315         [& isWellConstructed](std::shared_ptr< GetConfigurationStatus > status)
316         {
317             if(status->getESResult() == ES_OK)
318             {
319                 EnrolleeConf conf = status->getEnrolleeConf();
320                 if(conf.getWiFiModes().at(0) == WIFI_11G &&
321                     conf.getWiFiFreq() == WIFI_5G &&
322                     !strcmp(conf.getDeviceName().c_str(), "Test Device"))
323                 {
324                     isWellConstructed = true;
325                 }
326             }
327         });
328     ESResult ret = startEnrollee();
329     ret = setDeviceProperty();
330
331     g_mediatorSimul.getConfiguration(onGetConfiguration);
332
333     std::unique_lock< std::mutex > lock{ mutexForCondition };
334     responseCon.wait_for(lock, g_waitForResponse);
335
336     EXPECT_EQ(ret, ES_OK);
337
338     ESTerminateEnrollee();
339 }
340
341 TEST_F(EasysetupEnrolleeTest, ProvisioningPropertiesIsWellConstructedInResponsePayload)
342 {
343     bool isWellConstructed = false;
344     mocks.ExpectCallFunc(onGetStatus).Do(
345         [& isWellConstructed](std::shared_ptr< GetEnrolleeStatus > status)
346         {
347             if(status->getESResult() == ES_OK)
348             {
349                 EnrolleeStatus enrolleeStatus = status->getEnrolleeStatus();
350
351
352                 if(enrolleeStatus.getProvStatus() == ES_STATE_CONNECTED_TO_ENROLLER &&
353                    enrolleeStatus.getLastErrCode() == ES_ERRCODE_NO_INTERNETCONNECTION)
354                 {
355                     isWellConstructed = true;
356                 }
357             }
358         });
359     ESResult ret = startEnrollee();
360     ret = setDeviceProperty();
361     ret = ESSetState(ES_STATE_CONNECTED_TO_ENROLLER);
362     ret = ESSetErrorCode(ES_ERRCODE_NO_INTERNETCONNECTION);
363
364     g_mediatorSimul.getStatus(onGetStatus);
365
366     std::unique_lock< std::mutex > lock{ mutexForCondition };
367     responseCon.wait_for(lock, g_waitForResponse);
368
369     EXPECT_EQ(ret, ES_OK);
370
371     ESTerminateEnrollee();
372 }
373
374 TEST_F(EasysetupEnrolleeTest, WiFiAndDevConfProperiesProvisionedWithSuccess)
375 {
376     int cntForReceivedCallbackWithSuccess = 0;
377
378     mocks.OnCallFunc(deviceProvisioningStatusCallback).Do(
379         [& cntForReceivedCallbackWithSuccess](std::shared_ptr< DevicePropProvisioningStatus > status)
380         {
381             if(status->getESResult() == ES_OK)
382                cntForReceivedCallbackWithSuccess++;
383         });
384
385     mocks.OnCallFunc(WiFiProvCbInApp).Do(
386         [& cntForReceivedCallbackWithSuccess](ESWiFiProvData *data)
387         {
388             if(!strcmp(data->ssid, "Iotivity_SSID") &&
389                 !strcmp(data->pwd, "Iotivity_PWD") &&
390                 data->authtype == WPA2_PSK &&
391                 data->enctype == TKIP_AES)
392             {
393                 cntForReceivedCallbackWithSuccess++;
394             }
395         });
396     mocks.OnCallFunc(DevConfProvCbInApp).Do(
397         [& cntForReceivedCallbackWithSuccess](ESDevConfProvData *data)
398         {
399             if(!strcmp(data->language, "korean") &&
400                 !strcmp(data->country, "Korea"))
401             {
402                 cntForReceivedCallbackWithSuccess++;
403             }
404         });
405
406     startEnrollee();
407
408     g_mediatorSimul.provisionDeviceProperties(deviceProvisioningStatusCallback);
409
410     std::unique_lock< std::mutex > lock{ mutexForCondition };
411     responseCon.wait_for(lock, g_waitForResponse);
412
413     EXPECT_EQ(cntForReceivedCallbackWithSuccess, 3);
414
415     ESTerminateEnrollee();
416 }
417
418 TEST_F(EasysetupEnrolleeTest, CloudServerProperiesProvisionedWithSuccess)
419 {
420     int cntForReceivedCallbackWithSuccess = 0;
421
422     mocks.OnCallFunc(cloudProvisioningStatusCallback).Do(
423         [& cntForReceivedCallbackWithSuccess](std::shared_ptr< CloudPropProvisioningStatus > status)
424         {
425             // Will called twice
426             if(status->getESResult() == ES_OK || status->getESResult() == ES_FOUND_ENROLLEE)
427             {
428                cntForReceivedCallbackWithSuccess++;
429             }
430         });
431
432     mocks.OnCallFunc(CloudDataCbInApp).Do(
433         [& cntForReceivedCallbackWithSuccess](ESCloudProvData *data)
434         {
435             if(!strcmp(data->authCode, "authCode") &&
436                 !strcmp(data->authProvider, "authProvider") &&
437                 !strcmp(data->ciServer, "ciServer"))
438             {
439                 cntForReceivedCallbackWithSuccess++;
440             }
441         });
442
443     startEnrollee();
444
445     g_mediatorSimul.provisionCloudProperties(cloudProvisioningStatusCallback);
446
447     std::unique_lock< std::mutex > lock{ mutexForCondition };
448     responseCon.wait_for(lock, g_waitForResponse);
449
450     EXPECT_EQ(cntForReceivedCallbackWithSuccess, 3);
451
452     ESTerminateEnrollee();
453 }
454
455 TEST_F(EasysetupEnrolleeTest, GetWifiRsrcTest)
456 {
457     bool isRepFlag = false;
458     mocks.ExpectCallFunc(onGetWifiRsrc).Do(
459         [& isRepFlag](const OCRepresentation& /*rep*/)
460         {
461
462             isRepFlag = true;
463         });
464
465     ESResult ret = startEnrollee();
466     g_mediatorSimul.getWifiRsrc(onGetWifiRsrc);
467
468     std::unique_lock< std::mutex > lock{ mutexForCondition };
469     responseCon.wait_for(lock, g_waitForResponse);
470
471     EXPECT_EQ(ret, ES_OK);
472
473     ESTerminateEnrollee();
474 }
475
476 TEST_F(EasysetupEnrolleeTest, GetCloudRsrcTest)
477 {
478     bool isRepFlag = false;
479     mocks.ExpectCallFunc(onGetCloudRsrc).Do(
480         [& isRepFlag](const OCRepresentation& /*rep*/)
481         {
482             isRepFlag = true;
483         });
484
485     ESResult ret = startEnrollee();
486     g_mediatorSimul.getCloudRsrc(onGetCloudRsrc);
487
488     std::unique_lock< std::mutex > lock{ mutexForCondition };
489     responseCon.wait_for(lock, g_waitForResponse);
490
491     EXPECT_EQ(ret, ES_OK);
492
493     ESTerminateEnrollee();
494 }
495
496 TEST_F(EasysetupEnrolleeTest, GetDevConfTest)
497 {
498     bool isRepFlag = false;
499     mocks.ExpectCallFunc(onGetDeviceConf).Do(
500         [& isRepFlag](const OCRepresentation& /*rep*/)
501         {
502             isRepFlag = true;
503         });
504
505     ESResult ret = startEnrollee();
506     ret = setDeviceProperty();
507
508     g_mediatorSimul.getDevConfiguration(onGetDeviceConf);
509
510     std::unique_lock< std::mutex > lock{ mutexForCondition };
511     responseCon.wait_for(lock, g_waitForResponse);
512
513     EXPECT_EQ(ret, ES_OK);
514
515     ESTerminateEnrollee();
516 }
517
518 TEST_F(EasysetupEnrolleeTest, PutRequestTest)
519 {
520     bool isRepFlag = false;
521     mocks.ExpectCallFunc(onPutRequest).Do(
522         [& isRepFlag](const OCRepresentation& /*rep*/)
523         {
524             isRepFlag = true;
525         });
526
527     ESResult ret = startEnrollee();
528
529     g_mediatorSimul.putProvRsrc(onPutRequest);
530
531     std::unique_lock< std::mutex > lock{ mutexForCondition };
532     responseCon.wait_for(lock, g_waitForResponse);
533
534     EXPECT_EQ(ret, ES_OK);
535
536     ESTerminateEnrollee();
537 }
538
539 TEST_F(EasysetupEnrolleeTest, ESSetCallabckForUserDataFailed)
540 {
541     ESResult ret = setCallabckForUserDataNULL();
542     EXPECT_EQ(ret, ES_ERROR);
543     ESTerminateEnrollee();
544 }