Merge "Merge remote-tracking branch 'origin/master' into notification-service" into...
[platform/upstream/iotivity.git] / service / easy-setup / mediator / richsdk / unittests / ESMediatorTest.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 "ESEnrolleeSimulator.h"
30 #include "escommon.h"
31 #include "ESRichCommon.h"
32 #include "EasySetup.h"
33 #include "RemoteEnrollee.h"
34
35 #include "ESEnrolleeCommon.h"
36 #include "easysetup.h"
37
38 #include "ocrandom.h"
39 #include "cainterface.h"
40 #include "OCPlatform.h"
41
42 #define PROV_RESOURCE_TYPE "ocf.wk.prov"
43
44 using namespace OC;
45 using namespace OIC::Service;
46
47 namespace
48 {
49     std::atomic_bool g_isStartedStack(false);
50
51     std::chrono::milliseconds g_waitForResponse(1000);
52
53     std::condition_variable responseCon;
54     std::mutex mutexForCondition;
55
56     ESEnrolleeSimulator g_enrolleeSimul;
57     std::shared_ptr<RemoteEnrollee> g_remoteEnrollee;
58 }
59
60 class TestWithMock: public testing::Test
61 {
62 public:
63     MockRepository mocks;
64
65 protected:
66     virtual ~TestWithMock() noexcept(noexcept(std::declval<Test>().~Test()))
67     {
68     }
69
70     virtual void TearDown()
71     {
72         try
73         {
74             mocks.VerifyAll();
75         }
76         catch (...)
77         {
78             mocks.reset();
79             throw;
80         }
81     }
82 };
83
84 class EasysetupMediatorTest : public TestWithMock
85 {
86 public:
87     std::shared_ptr<OC::OCResource> m_enrolleeResource;
88
89 public:
90     EasysetupMediatorTest() = default;
91     ~EasysetupMediatorTest() = default;
92
93     std::shared_ptr<OC::OCResource> CreateNotProvResource()
94     {
95         OCConnectivityType connectivityType = CT_DEFAULT;
96         std::vector<std::string> types = {"ocf.wk.notprov"};
97         std::vector<std::string> ifaces = {DEFAULT_INTERFACE};
98
99         return OCPlatform::constructResourceObject("coap://192.168.1.2:5000",
100                                                    "/NotProvisioningResURI",
101                                                    connectivityType,
102                                                    false,
103                                                    types,
104                                                    ifaces);
105     }
106
107     void discoverRemoteEnrollee()
108     {
109         std::string uri = std::string("/oic/res?rt=") + PROV_RESOURCE_TYPE;
110         OC::OCPlatform::findResource("", uri,
111                 OCConnectivityType::CT_DEFAULT,
112                 std::bind(&EasysetupMediatorTest::discoverRemoteEnrolleeCb,
113                             this, std::placeholders::_1));
114
115         std::unique_lock< std::mutex > lock{ mutexForCondition };
116         responseCon.wait_for(lock, g_waitForResponse);
117     }
118
119 protected:
120     void SetUp()
121     {
122         TestWithMock::SetUp();
123         if (g_isStartedStack == false)
124         {
125             if (OCInit(NULL, 0, OC_CLIENT_SERVER) != OC_STACK_OK)
126             {
127                 printf("OCStack init error!!\n");
128                 return;
129             }
130             g_enrolleeSimul.initEnrollee();
131             g_isStartedStack = true;
132         }
133     }
134
135     void TearDown()
136     {
137         TestWithMock::TearDown();
138     }
139
140 private:
141     bool isValidResourceToTest(std::shared_ptr<OC::OCResource> resource)
142     {
143         if((resource->connectivityType() & CT_ADAPTER_TCP) == CT_ADAPTER_TCP)
144         {
145             return false;
146         }
147
148         CAEndpoint_t *tempInfo = NULL;
149         uint32_t tempSize = 0;
150
151         CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
152         if (CA_STATUS_OK != res || NULL == tempInfo || 0 >= tempSize)
153         {
154             free(tempInfo);
155             return false;
156         }
157
158         for (uint32_t index = 0; index  < tempSize; index++)
159         {
160             if (CA_ADAPTER_IP == tempInfo[index].adapter)
161             {
162                 if(resource->host().find(tempInfo[index].addr) != std::string::npos &&
163                     resource->host().find(std::to_string(tempInfo[index].port).c_str()) != std::string::npos)
164                 {
165                     return true;
166                 }
167             }
168         }
169
170         return false;
171     }
172
173     void discoverRemoteEnrolleeCb(std::shared_ptr<OC::OCResource> resource)
174     {
175         if(!isValidResourceToTest(resource))
176         {
177             return ;
178         }
179
180         if(!resource->getResourceTypes().at(0).compare(PROV_RESOURCE_TYPE))
181         {
182             m_enrolleeResource = resource;
183         }
184     }
185 };
186
187 TEST_F(EasysetupMediatorTest, createremoteenrolleeFailedWithNotProvResource)
188 {
189     auto remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(CreateNotProvResource());
190
191     EXPECT_EQ(nullptr, remoteEnrollee);
192 }
193
194 TEST_F(EasysetupMediatorTest, createremoteenrolleeSucceedWithProvResource)
195 {
196     discoverRemoteEnrollee();
197     g_remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(m_enrolleeResource);
198
199     ASSERT_NE(nullptr, g_remoteEnrollee);
200 }
201
202 class GetConfigurationTest : public EasysetupMediatorTest
203 {
204 public:
205     GetConfigurationTest() = default;
206     ~GetConfigurationTest() = default;
207
208     static void onGetConfigurationCb(shared_ptr< GetConfigurationStatus > /*status*/)
209     {
210     }
211
212 protected:
213     void SetUp()
214     {
215         TestWithMock::SetUp();
216     }
217
218     void TearDown()
219     {
220         TestWithMock::TearDown();
221     }
222 };
223
224 TEST_F(GetConfigurationTest, ThrowExceptionWhenGetConfigurationFailedByCallbackIsNull)
225 {
226     EXPECT_ANY_THROW(g_remoteEnrollee->getConfiguration(nullptr));
227 }
228
229 TEST_F(GetConfigurationTest, GetConfigurationSucceed)
230 {
231     bool isWellConstructed = false;
232
233     g_enrolleeSimul.setDeviceProperty();
234
235     mocks.ExpectCallFunc(onGetConfigurationCb).Do(
236         [&isWellConstructed](std::shared_ptr< GetConfigurationStatus > status)
237         {
238             if(status->getESResult() == ES_OK)
239             {
240                 EnrolleeConf conf = status->getEnrolleeConf();
241                 if(!conf.getWiFiModes().empty())
242                 {
243                     if(conf.getWiFiModes().at(0) == WIFI_11G &&
244                         conf.getWiFiFreq() == WIFI_5G &&
245                         !strcmp(conf.getDeviceName().c_str(), "Test Device") &&
246                         !strcmp(conf.getModelNumber().c_str(), "Test Model Number"))
247                     {
248                         isWellConstructed = true;
249                     }
250                     cout << "getDeviceName : " << conf.getDeviceName().c_str() << endl;
251                     cout << "getModelNumber : " << conf.getModelNumber().c_str() << endl;
252                 }
253             }
254         });
255
256     g_remoteEnrollee->getConfiguration(onGetConfigurationCb);
257
258     std::unique_lock< std::mutex > lock{ mutexForCondition };
259     responseCon.wait_for(lock, g_waitForResponse);
260
261     EXPECT_TRUE(isWellConstructed);
262 }
263
264 class GetStatusTest : public EasysetupMediatorTest
265 {
266
267 public:
268     GetStatusTest() = default;
269     ~GetStatusTest() = default;
270
271     static void onGetStatusCb(shared_ptr< GetEnrolleeStatus > /*status*/)
272     {
273     }
274
275 protected:
276     void SetUp()
277     {
278         TestWithMock::SetUp();
279     }
280
281     void TearDown()
282     {
283         TestWithMock::TearDown();
284     }
285 };
286
287 TEST_F(GetStatusTest, ThrowExceptionWhenGetStatusFailedByCallbackIsNull)
288 {
289     EXPECT_ANY_THROW(g_remoteEnrollee->getStatus(nullptr));
290 }
291
292 TEST_F(GetStatusTest, GetStatusSucceed)
293 {
294     g_enrolleeSimul.setESState();
295     g_enrolleeSimul.setESErrorCode();
296
297     bool isWellConstructed = false;
298     mocks.ExpectCallFunc(onGetStatusCb).Do(
299         [&isWellConstructed](std::shared_ptr< GetEnrolleeStatus > status)
300         {
301             if(status->getESResult() == ES_OK)
302             {
303                 EnrolleeStatus enrolleeStatus = status->getEnrolleeStatus();
304
305                 if(enrolleeStatus.getProvStatus() == ES_STATE_CONNECTED_TO_ENROLLER &&
306                    enrolleeStatus.getLastErrCode() == ES_ERRCODE_NO_INTERNETCONNECTION)
307                 {
308                     isWellConstructed = true;
309                 }
310             }
311         });
312
313     g_remoteEnrollee->getStatus(onGetStatusCb);
314
315     std::unique_lock< std::mutex > lock{ mutexForCondition };
316     responseCon.wait_for(lock, g_waitForResponse);
317
318     EXPECT_TRUE(isWellConstructed);
319 }
320
321 class ProvisionDevicePropertiesTest : public EasysetupMediatorTest
322 {
323
324 public:
325     ProvisionDevicePropertiesTest() = default;
326     ~ProvisionDevicePropertiesTest() = default;
327
328     static void deviceProvisioningStatusCb(
329                                             shared_ptr< DevicePropProvisioningStatus > /*status*/)
330     {
331     }
332
333 protected:
334     void SetUp()
335     {
336         TestWithMock::SetUp();
337     }
338
339     void TearDown()
340     {
341         TestWithMock::TearDown();
342     }
343 };
344
345 TEST_F(ProvisionDevicePropertiesTest,
346           ThrowExceptionWhenProvisionDeviceProperiesFailedByCallbackIsNull)
347 {
348     DeviceProp devProp;
349     devProp.setWiFiProp("Iotivity_SSID", "Iotivity_PWD", WPA2_PSK, TKIP_AES);
350     devProp.setDevConfProp("korean", "Korea", "Location");
351
352     EXPECT_ANY_THROW(g_remoteEnrollee->provisionDeviceProperties(devProp, nullptr));
353 }
354
355 TEST_F(ProvisionDevicePropertiesTest,
356           ThrowExceptionWhenProvisionDeviceProperiesFailedWithoutSSID)
357 {
358     DeviceProp devProp;
359     devProp.setWiFiProp("", "Iotivity_PWD", WPA2_PSK, TKIP_AES);
360     devProp.setDevConfProp("korean", "Korea", "Location");
361     EXPECT_ANY_THROW(g_remoteEnrollee->provisionDeviceProperties(devProp,
362                                                                  deviceProvisioningStatusCb));
363 }
364
365 TEST_F(ProvisionDevicePropertiesTest,
366           ProvisionDeviceProperiesSucceed)
367 {
368     DeviceProp devProp;
369     devProp.setWiFiProp("Iotivity_SSID", "Iotivity_PWD", WPA2_PSK, TKIP_AES);
370     devProp.setDevConfProp("korean", "Korea", "Location");
371
372     int cntForReceivedCallbackWithSuccess = 0;
373
374     mocks.OnCallFunc(deviceProvisioningStatusCb).Do(
375         [&cntForReceivedCallbackWithSuccess]
376         (std::shared_ptr< DevicePropProvisioningStatus > status)
377         {
378             if(status->getESResult() == ES_OK)
379             {
380                cntForReceivedCallbackWithSuccess++;
381             }
382
383         });
384
385     g_remoteEnrollee->provisionDeviceProperties(devProp, deviceProvisioningStatusCb);
386
387     std::unique_lock< std::mutex > lock{ mutexForCondition };
388     responseCon.wait_for(lock, g_waitForResponse);
389
390     EXPECT_EQ(cntForReceivedCallbackWithSuccess, 1);
391 }
392
393 class ProvisionCloudPropertiesTest : public EasysetupMediatorTest
394 {
395
396 public:
397     ProvisionCloudPropertiesTest() = default;
398     ~ProvisionCloudPropertiesTest() = default;
399
400     static void cloudPropProvStatusCb(shared_ptr< CloudPropProvisioningStatus > /*status*/)
401     {
402     }
403
404 protected:
405     void SetUp()
406     {
407         TestWithMock::SetUp();
408     }
409
410     void TearDown()
411     {
412         TestWithMock::TearDown();
413     }
414 };
415
416 TEST_F(ProvisionCloudPropertiesTest,
417           ThrowExceptionWhenProvisionCloudPropertiesFailedByCallbackIsNull)
418 {
419     CloudProp cloudProp;
420     cloudProp.setCloudProp("authCode", "authProvider", "ciServer");
421     cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
422
423     EXPECT_ANY_THROW(g_remoteEnrollee->provisionCloudProperties(cloudProp, nullptr));
424 }
425
426 TEST_F(ProvisionCloudPropertiesTest,
427           ThrowExceptionWhenProvisionCloudPropertiesFailedWithoutAuthCode)
428 {
429     CloudProp cloudProp;
430     cloudProp.setCloudProp("", "authProvider", "ciServer");
431     cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
432     EXPECT_ANY_THROW(g_remoteEnrollee->provisionCloudProperties(cloudProp,
433                                                                 cloudPropProvStatusCb));
434 }
435
436 TEST_F(ProvisionCloudPropertiesTest,
437           ThrowExceptionWhenProvisionCloudPropertiesFailedWithoutAuthProvider)
438 {
439     CloudProp cloudProp;
440     cloudProp.setCloudProp("authCode", "", "ciServer");
441     cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
442     EXPECT_ANY_THROW(g_remoteEnrollee->provisionCloudProperties(cloudProp,
443                                                                 cloudPropProvStatusCb));
444 }
445
446 TEST_F(ProvisionCloudPropertiesTest,
447           ThrowExceptionWhenProvisionCloudPropertiesFailedWithoutCIServer)
448 {
449     CloudProp cloudProp;
450     cloudProp.setCloudProp("authCode", "authProvider", "");
451     cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
452     EXPECT_ANY_THROW(g_remoteEnrollee->provisionCloudProperties(cloudProp,
453                                                                 cloudPropProvStatusCb));
454 }
455
456 TEST_F(ProvisionCloudPropertiesTest, ProvisionCloudPropertiesSucceed)
457 {
458     CloudProp cloudProp;
459     cloudProp.setCloudProp("authCode", "authProvider", "ciServer");
460     cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
461
462     int cntForReceivedCallbackWithSuccess = 0;
463
464     mocks.OnCallFunc(cloudPropProvStatusCb).Do(
465         [& cntForReceivedCallbackWithSuccess](std::shared_ptr< CloudPropProvisioningStatus > status)
466         {
467             // Will called twice
468             if(status->getESResult() == ES_OK)
469             {
470                cntForReceivedCallbackWithSuccess++;
471             }
472         });
473
474     g_remoteEnrollee->provisionCloudProperties(cloudProp, cloudPropProvStatusCb);
475
476     std::unique_lock< std::mutex > lock{ mutexForCondition };
477     responseCon.wait_for(lock, g_waitForResponse);
478
479     EXPECT_EQ(cntForReceivedCallbackWithSuccess, 2);
480
481     ESTerminateEnrollee();
482 }