4cc18abb9f71ba9e43c2a1b81badeb54ed677b7f
[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 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> CreateNotProvResource()
92     {
93         OCConnectivityType connectivityType = CT_DEFAULT;
94         std::vector<std::string> types = {"oic.wk.notprov"};
95         std::vector<std::string> ifaces = {DEFAULT_INTERFACE};
96
97         return OCPlatform::constructResourceObject("coap://192.168.1.2:5000",
98                                                    "/NotProvisioningResURI",
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_PROV;
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_PROV))
179         {
180             m_enrolleeResource = resource;
181         }
182     }
183 };
184
185 TEST_F(EasysetupMediatorTest, createremoteenrolleeFailedWithNotProvResource)
186 {
187     auto remoteEnrollee = EasySetup::getInstance()->createRemoteEnrollee(CreateNotProvResource());
188
189     EXPECT_EQ(nullptr, remoteEnrollee);
190 }
191
192 TEST_F(EasysetupMediatorTest, createremoteenrolleeSucceedWithProvResource)
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                         !strcmp(conf.getModelNumber().c_str(), "Test Model Number"))
245                     {
246                         isWellConstructed = true;
247                     }
248                     cout << "getDeviceName : " << conf.getDeviceName().c_str() << endl;
249                     cout << "getModelNumber : " << conf.getModelNumber().c_str() << endl;
250                 }
251             }
252         });
253
254     g_remoteEnrollee->getConfiguration(onGetConfigurationCb);
255
256     std::unique_lock< std::mutex > lock{ mutexForCondition };
257     responseCon.wait_for(lock, g_waitForResponse);
258
259     EXPECT_TRUE(isWellConstructed);
260 }
261
262 class GetStatusTest : public EasysetupMediatorTest
263 {
264
265 public:
266     GetStatusTest() = default;
267     ~GetStatusTest() = default;
268
269     static void onGetStatusCb(shared_ptr< GetEnrolleeStatus > /*status*/)
270     {
271     }
272
273 protected:
274     void SetUp()
275     {
276         TestWithMock::SetUp();
277     }
278
279     void TearDown()
280     {
281         TestWithMock::TearDown();
282     }
283 };
284
285 TEST_F(GetStatusTest, ThrowExceptionWhenGetStatusFailedByCallbackIsNull)
286 {
287     EXPECT_ANY_THROW(g_remoteEnrollee->getStatus(nullptr));
288 }
289
290 TEST_F(GetStatusTest, GetStatusSucceed)
291 {
292     g_enrolleeSimul.setESState();
293     g_enrolleeSimul.setESErrorCode();
294
295     bool isWellConstructed = false;
296     mocks.ExpectCallFunc(onGetStatusCb).Do(
297         [&isWellConstructed](std::shared_ptr< GetEnrolleeStatus > status)
298         {
299             if(status->getESResult() == ES_OK)
300             {
301                 EnrolleeStatus enrolleeStatus = status->getEnrolleeStatus();
302
303                 if(enrolleeStatus.getProvStatus() == ES_STATE_CONNECTED_TO_ENROLLER &&
304                    enrolleeStatus.getLastErrCode() == ES_ERRCODE_NO_INTERNETCONNECTION)
305                 {
306                     isWellConstructed = true;
307                 }
308             }
309         });
310
311     g_remoteEnrollee->getStatus(onGetStatusCb);
312
313     std::unique_lock< std::mutex > lock{ mutexForCondition };
314     responseCon.wait_for(lock, g_waitForResponse);
315
316     EXPECT_TRUE(isWellConstructed);
317 }
318
319 class ProvisionDevicePropertiesTest : public EasysetupMediatorTest
320 {
321
322 public:
323     ProvisionDevicePropertiesTest() = default;
324     ~ProvisionDevicePropertiesTest() = default;
325
326     static void deviceProvisioningStatusCb(
327                                             shared_ptr< DevicePropProvisioningStatus > /*status*/)
328     {
329     }
330
331 protected:
332     void SetUp()
333     {
334         TestWithMock::SetUp();
335     }
336
337     void TearDown()
338     {
339         TestWithMock::TearDown();
340     }
341 };
342
343 TEST_F(ProvisionDevicePropertiesTest,
344           ThrowExceptionWhenProvisionDeviceProperiesFailedByCallbackIsNull)
345 {
346     DeviceProp devProp;
347     devProp.setWiFiProp("Iotivity_SSID", "Iotivity_PWD", WPA2_PSK, TKIP_AES);
348     devProp.setDevConfProp("korean", "Korea", "Location");
349
350     EXPECT_ANY_THROW(g_remoteEnrollee->provisionDeviceProperties(devProp, nullptr));
351 }
352
353 TEST_F(ProvisionDevicePropertiesTest,
354           ThrowExceptionWhenProvisionDeviceProperiesFailedWithoutSSID)
355 {
356     DeviceProp devProp;
357     devProp.setWiFiProp("", "Iotivity_PWD", WPA2_PSK, TKIP_AES);
358     devProp.setDevConfProp("korean", "Korea", "Location");
359     EXPECT_ANY_THROW(g_remoteEnrollee->provisionDeviceProperties(devProp,
360                                                                  deviceProvisioningStatusCb));
361 }
362
363 TEST_F(ProvisionDevicePropertiesTest,
364           ProvisionDeviceProperiesSucceed)
365 {
366     DeviceProp devProp;
367     devProp.setWiFiProp("Iotivity_SSID", "Iotivity_PWD", WPA2_PSK, TKIP_AES);
368     devProp.setDevConfProp("korean", "Korea", "Location");
369
370     int cntForReceivedCallbackWithSuccess = 0;
371
372     mocks.OnCallFunc(deviceProvisioningStatusCb).Do(
373         [&cntForReceivedCallbackWithSuccess]
374         (std::shared_ptr< DevicePropProvisioningStatus > status)
375         {
376             if(status->getESResult() == ES_OK)
377             {
378                cntForReceivedCallbackWithSuccess++;
379             }
380
381         });
382
383     g_remoteEnrollee->provisionDeviceProperties(devProp, deviceProvisioningStatusCb);
384
385     std::unique_lock< std::mutex > lock{ mutexForCondition };
386     responseCon.wait_for(lock, g_waitForResponse);
387
388     EXPECT_EQ(cntForReceivedCallbackWithSuccess, 1);
389 }
390
391 class ProvisionCloudPropertiesTest : public EasysetupMediatorTest
392 {
393
394 public:
395     ProvisionCloudPropertiesTest() = default;
396     ~ProvisionCloudPropertiesTest() = default;
397
398     static void cloudPropProvStatusCb(shared_ptr< CloudPropProvisioningStatus > /*status*/)
399     {
400     }
401
402 protected:
403     void SetUp()
404     {
405         TestWithMock::SetUp();
406     }
407
408     void TearDown()
409     {
410         TestWithMock::TearDown();
411     }
412 };
413
414 TEST_F(ProvisionCloudPropertiesTest,
415           ThrowExceptionWhenProvisionCloudPropertiesFailedByCallbackIsNull)
416 {
417     CloudProp cloudProp;
418     cloudProp.setCloudProp("authCode", "authProvider", "ciServer");
419     cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
420
421     EXPECT_ANY_THROW(g_remoteEnrollee->provisionCloudProperties(cloudProp, nullptr));
422 }
423
424 TEST_F(ProvisionCloudPropertiesTest,
425           ThrowExceptionWhenProvisionCloudPropertiesFailedWithoutAuthCode)
426 {
427     CloudProp cloudProp;
428     cloudProp.setCloudProp("", "authProvider", "ciServer");
429     cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
430     EXPECT_ANY_THROW(g_remoteEnrollee->provisionCloudProperties(cloudProp,
431                                                                 cloudPropProvStatusCb));
432 }
433
434 TEST_F(ProvisionCloudPropertiesTest,
435           ThrowExceptionWhenProvisionCloudPropertiesFailedWithoutAuthProvider)
436 {
437     CloudProp cloudProp;
438     cloudProp.setCloudProp("authCode", "", "ciServer");
439     cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
440     EXPECT_ANY_THROW(g_remoteEnrollee->provisionCloudProperties(cloudProp,
441                                                                 cloudPropProvStatusCb));
442 }
443
444 TEST_F(ProvisionCloudPropertiesTest,
445           ThrowExceptionWhenProvisionCloudPropertiesFailedWithoutCIServer)
446 {
447     CloudProp cloudProp;
448     cloudProp.setCloudProp("authCode", "authProvider", "");
449     cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
450     EXPECT_ANY_THROW(g_remoteEnrollee->provisionCloudProperties(cloudProp,
451                                                                 cloudPropProvStatusCb));
452 }
453
454 TEST_F(ProvisionCloudPropertiesTest, ProvisionCloudPropertiesSucceed)
455 {
456     CloudProp cloudProp;
457     cloudProp.setCloudProp("authCode", "authProvider", "ciServer");
458     cloudProp.setCloudID("f002ae8b-c42c-40d3-8b8d-1927c17bd1b3");
459
460     int cntForReceivedCallbackWithSuccess = 0;
461
462     mocks.OnCallFunc(cloudPropProvStatusCb).Do(
463         [& cntForReceivedCallbackWithSuccess](std::shared_ptr< CloudPropProvisioningStatus > status)
464         {
465             // Will called twice
466             if(status->getESResult() == ES_OK || status->getESResult() == ES_FOUND_ENROLLEE)
467             {
468                cntForReceivedCallbackWithSuccess++;
469             }
470         });
471
472     g_remoteEnrollee->provisionCloudProperties(cloudProp, cloudPropProvStatusCb);
473
474     std::unique_lock< std::mutex > lock{ mutexForCondition };
475     responseCon.wait_for(lock, g_waitForResponse);
476
477     EXPECT_EQ(cntForReceivedCallbackWithSuccess, 2);
478
479     ESTerminateEnrollee();
480 }