Merge branch 'notification-service'
[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 deviceProvisioningStatusCallback(std::shared_ptr< DevicePropProvisioningStatus >)
92     {
93         std::cout << __func__ << std::endl;
94     }
95
96     static void cloudProvisioningStatusCallback(std::shared_ptr< CloudPropProvisioningStatus >)
97     {
98         std::cout << __func__ << std::endl;
99     }
100
101     static void WiFiProvCbInApp(ESWiFiProvData *)
102     {
103         std::cout << __func__ << std::endl;
104     }
105
106     static void DevConfProvCbInApp(ESDevConfProvData *)
107     {
108         std::cout << __func__ << std::endl;
109     }
110
111     static void CloudDataCbInApp(ESCloudProvData *)
112     {
113         std::cout << __func__ << std::endl;
114     }
115
116     ESResult startEnrollee()
117     {
118         ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFI_RESOURCE |
119                                                     ES_CLOUD_RESOURCE |
120                                                     ES_DEVCONF_RESOURCE);
121         ESProvisioningCallbacks callbacks;
122         callbacks.WiFiProvCb = &EasysetupEnrolleeTest::WiFiProvCbInApp;
123         callbacks.DevConfProvCb = &EasysetupEnrolleeTest::DevConfProvCbInApp;
124         callbacks.CloudDataProvCb = &EasysetupEnrolleeTest::CloudDataCbInApp;
125
126         return ESInitEnrollee(false, resourcemMask, callbacks);
127     }
128
129     ESResult setDeviceProperty()
130     {
131         ESDeviceProperty deviceProperty = {
132             {{WIFI_11G, WiFi_EOF}, WIFI_5G}, {"Test Device"}
133         };
134
135         return ESSetDeviceProperty(&deviceProperty);
136     }
137
138 protected:
139
140     void SetUp()
141     {
142         TestWithMock::SetUp();
143
144         if (g_isStartedStack == false)
145         {
146             if (OCInit(NULL, 0, OC_SERVER) != OC_STACK_OK)
147             {
148                 printf("OCStack init error!!\n");
149                 return;
150             }
151
152             g_isStartedStack = true;
153         }
154     }
155
156     void TearDown()
157     {
158         TestWithMock::TearDown();
159     }
160
161 };
162
163 TEST_F(EasysetupEnrolleeTest, ESInitEnrolleeSuccess)
164 {
165     ESResult ret = startEnrollee();
166     EXPECT_EQ(ret, ES_OK);
167     ESTerminateEnrollee();
168 }
169
170 TEST_F(EasysetupEnrolleeTest, ESInitEnrolleeFailedByWiFiCbIsNull)
171 {
172     ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFI_RESOURCE |
173                                                     ES_CLOUD_RESOURCE |
174                                                     ES_DEVCONF_RESOURCE);
175     ESProvisioningCallbacks callbacks;
176     callbacks.WiFiProvCb = NULL;
177     callbacks.DevConfProvCb = &EasysetupEnrolleeTest::DevConfProvCbInApp;
178     callbacks.CloudDataProvCb = &EasysetupEnrolleeTest::CloudDataCbInApp;
179
180     ESResult ret = ESInitEnrollee(false, resourcemMask, callbacks);
181     EXPECT_EQ(ret, ES_ERROR);
182     ESTerminateEnrollee();
183 }
184
185 TEST_F(EasysetupEnrolleeTest, ESInitEnrolleeFailedByDevConfCbIsNull)
186 {
187     ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFI_RESOURCE |
188                                                     ES_CLOUD_RESOURCE |
189                                                     ES_DEVCONF_RESOURCE);
190     ESProvisioningCallbacks callbacks;
191     callbacks.WiFiProvCb = &EasysetupEnrolleeTest::WiFiProvCbInApp;
192     callbacks.DevConfProvCb = NULL;
193     callbacks.CloudDataProvCb = &EasysetupEnrolleeTest::CloudDataCbInApp;
194
195     ESResult ret = ESInitEnrollee(false, resourcemMask, callbacks);
196     EXPECT_EQ(ret, ES_ERROR);
197     ESTerminateEnrollee();
198 }
199
200 TEST_F(EasysetupEnrolleeTest, ESInitEnrolleeFailedByCloudCbIsNull)
201 {
202     ESResourceMask resourcemMask = (ESResourceMask)(ES_WIFI_RESOURCE |
203                                                     ES_CLOUD_RESOURCE |
204                                                     ES_DEVCONF_RESOURCE);
205     ESProvisioningCallbacks callbacks;
206     callbacks.WiFiProvCb = &EasysetupEnrolleeTest::WiFiProvCbInApp;
207     callbacks.DevConfProvCb = &EasysetupEnrolleeTest::DevConfProvCbInApp;
208     callbacks.CloudDataProvCb = NULL;
209
210     ESResult ret = ESInitEnrollee(false, resourcemMask, callbacks);
211     EXPECT_EQ(ret, ES_ERROR);
212     ESTerminateEnrollee();
213 }
214
215 TEST_F(EasysetupEnrolleeTest, FindProvisioningResourceAtEnrolleeWithSuccess)
216 {
217     mocks.ExpectCallFunc(discoveredResource).Do(
218         [](std::shared_ptr<OC::OCResource> resource)
219         {
220             try
221             {
222                 std::cout<<"DISCOVERED Resource:"<<std::endl;
223                 // Get the resource host address
224                 std::string uri = resource->uri();
225                 std::cout << "\tURI of the resource: " << uri << std::endl;
226             } catch (OCException &e)
227             {
228                 std::cout << e.reason() << std::endl;
229             }
230
231         });
232
233     ESResult ret = startEnrollee();
234
235     g_mediatorSimul.discoverRemoteEnrollee(discoveredResource);
236
237     std::unique_lock< std::mutex > lock{ mutexForCondition };
238     responseCon.wait_for(lock, g_waitForResponse);
239
240     EXPECT_EQ(ret, ES_OK);
241
242     ESTerminateEnrollee();
243 }
244
245 TEST_F(EasysetupEnrolleeTest, SetDevicePropertyWithSuccess)
246 {
247     ESResult ret = startEnrollee();
248     ret = setDeviceProperty();
249     EXPECT_EQ(ret, ES_OK);
250     ESTerminateEnrollee();
251 }
252
253 TEST_F(EasysetupEnrolleeTest, SetProvStatusWithSuccess)
254 {
255     ESResult ret = startEnrollee();
256     ret = ESSetState(ES_STATE_CONNECTED_TO_ENROLLER);
257     EXPECT_EQ(ret, ES_OK);
258     ESTerminateEnrollee();
259 }
260
261 TEST_F(EasysetupEnrolleeTest, SetErrorCodeWithSuccess)
262 {
263     ESResult ret = startEnrollee();
264     ret = ESSetErrorCode(ES_ERRCODE_PW_WRONG);
265     EXPECT_EQ(ret, ES_OK);
266     ESTerminateEnrollee();
267 }
268
269 TEST_F(EasysetupEnrolleeTest, DevicePropertyIsWellConstructedInResponsePayload)
270 {
271     bool isWellConstructed = false;
272     mocks.ExpectCallFunc(onGetConfiguration).Do(
273         [& isWellConstructed](std::shared_ptr< GetConfigurationStatus > status)
274         {
275             if(status->getESResult() == ES_OK)
276             {
277                 EnrolleeConf conf = status->getEnrolleeConf();
278                 if(conf.getWiFiModes().at(0) == WIFI_11G &&
279                     conf.getWiFiFreq() == WIFI_5G &&
280                     !strcmp(conf.getDeviceName().c_str(), "Test Device"))
281                 {
282                     isWellConstructed = true;
283                 }
284             }
285         });
286     ESResult ret = startEnrollee();
287     ret = setDeviceProperty();
288
289     g_mediatorSimul.getConfiguration(onGetConfiguration);
290
291     std::unique_lock< std::mutex > lock{ mutexForCondition };
292     responseCon.wait_for(lock, g_waitForResponse);
293
294     EXPECT_EQ(ret, ES_OK);
295
296     ESTerminateEnrollee();
297 }
298
299 TEST_F(EasysetupEnrolleeTest, ProvisioningPropertiesIsWellConstructedInResponsePayload)
300 {
301     bool isWellConstructed = false;
302     mocks.ExpectCallFunc(onGetStatus).Do(
303         [& isWellConstructed](std::shared_ptr< GetEnrolleeStatus > status)
304         {
305             if(status->getESResult() == ES_OK)
306             {
307                 EnrolleeStatus enrolleeStatus = status->getEnrolleeStatus();
308
309
310                 if(enrolleeStatus.getProvStatus() == ES_STATE_CONNECTED_TO_ENROLLER &&
311                    enrolleeStatus.getLastErrCode() == ES_ERRCODE_NO_INTERNETCONNECTION)
312                 {
313                     isWellConstructed = true;
314                 }
315             }
316         });
317     ESResult ret = startEnrollee();
318     ret = setDeviceProperty();
319     ret = ESSetState(ES_STATE_CONNECTED_TO_ENROLLER);
320     ret = ESSetErrorCode(ES_ERRCODE_NO_INTERNETCONNECTION);
321
322     g_mediatorSimul.getStatus(onGetStatus);
323
324     std::unique_lock< std::mutex > lock{ mutexForCondition };
325     responseCon.wait_for(lock, g_waitForResponse);
326
327     EXPECT_EQ(ret, ES_OK);
328
329     ESTerminateEnrollee();
330 }
331
332 TEST_F(EasysetupEnrolleeTest, WiFiAndDevConfProperiesProvisionedWithSuccess)
333 {
334     int cntForReceivedCallbackWithSuccess = 0;
335
336     mocks.OnCallFunc(deviceProvisioningStatusCallback).Do(
337         [& cntForReceivedCallbackWithSuccess](std::shared_ptr< DevicePropProvisioningStatus > status)
338         {
339             if(status->getESResult() == ES_OK)
340                cntForReceivedCallbackWithSuccess++;
341         });
342
343     mocks.OnCallFunc(WiFiProvCbInApp).Do(
344         [& cntForReceivedCallbackWithSuccess](ESWiFiProvData *data)
345         {
346             if(!strcmp(data->ssid, "Iotivity_SSID") &&
347                 !strcmp(data->pwd, "Iotivity_PWD") &&
348                 data->authtype == WPA2_PSK &&
349                 data->enctype == TKIP_AES)
350             {
351                 cntForReceivedCallbackWithSuccess++;
352             }
353         });
354     mocks.OnCallFunc(DevConfProvCbInApp).Do(
355         [& cntForReceivedCallbackWithSuccess](ESDevConfProvData *data)
356         {
357             if(!strcmp(data->language, "korean") &&
358                 !strcmp(data->country, "Korea"))
359             {
360                 cntForReceivedCallbackWithSuccess++;
361             }
362         });
363
364     startEnrollee();
365
366     g_mediatorSimul.provisionDeviceProperties(deviceProvisioningStatusCallback);
367
368     std::unique_lock< std::mutex > lock{ mutexForCondition };
369     responseCon.wait_for(lock, g_waitForResponse);
370
371     EXPECT_EQ(cntForReceivedCallbackWithSuccess, 3);
372
373     ESTerminateEnrollee();
374 }
375
376 TEST_F(EasysetupEnrolleeTest, CloudServerProperiesProvisionedWithSuccess)
377 {
378     int cntForReceivedCallbackWithSuccess = 0;
379
380     mocks.OnCallFunc(cloudProvisioningStatusCallback).Do(
381         [& cntForReceivedCallbackWithSuccess](std::shared_ptr< CloudPropProvisioningStatus > status)
382         {
383             // Will called twice
384             if(status->getESResult() == ES_OK)
385             {
386                cntForReceivedCallbackWithSuccess++;
387             }
388         });
389
390     mocks.OnCallFunc(CloudDataCbInApp).Do(
391         [& cntForReceivedCallbackWithSuccess](ESCloudProvData *data)
392         {
393             if(!strcmp(data->authCode, "authCode") &&
394                 !strcmp(data->authProvider, "authProvider") &&
395                 !strcmp(data->ciServer, "ciServer"))
396             {
397                 cntForReceivedCallbackWithSuccess++;
398             }
399         });
400
401     startEnrollee();
402
403     g_mediatorSimul.provisionCloudProperties(cloudProvisioningStatusCallback);
404
405     std::unique_lock< std::mutex > lock{ mutexForCondition };
406     responseCon.wait_for(lock, g_waitForResponse);
407
408     EXPECT_EQ(cntForReceivedCallbackWithSuccess, 3);
409
410     ESTerminateEnrollee();
411 }
412
413