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