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