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