1 //******************************************************************
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
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
11 // http://www.apache.org/licenses/LICENSE-2.0
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.
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
21 #include "UnitTestHelper.h"
22 #include "RCSRemoteResourceObject.h"
23 #include "RCSDiscoveryManager.h"
24 #include "RCSResourceObject.h"
25 #include "PrimitiveResource.h"
29 using namespace OIC::Service;
32 constexpr char RESOURCEURI[]{ "/a/TemperatureSensor" };
33 constexpr char RESOURCETYPE[]{ "Resource.Hosting" };
34 constexpr char RESOURCEINTERFACE[]{ "oic.if.baseline" };
36 constexpr char ATTR_KEY[]{ "Temperature" };
37 constexpr int ATTR_VALUE{ 0 };
39 constexpr int DEFAULT_WAITING_TIME_IN_MILLIS = 3000;
41 void getRemoteAttributesCallback(const RCSResourceAttributes&) {}
42 void setRemoteAttributesCallback(const RCSResourceAttributes&) {}
43 void resourceStateChanged(ResourceState) { }
44 void cacheUpdatedCallback(const RCSResourceAttributes&) {}
46 class RemoteResourceObjectTest: public TestWithMock
49 RCSResourceObject::Ptr server;
50 RCSRemoteResourceObject::Ptr object;
51 std::shared_ptr< bool > finished;
59 void Wait(int waitingTime = DEFAULT_WAITING_TIME_IN_MILLIS)
61 std::unique_lock< std::mutex > lock{ mutex };
62 cond.wait_for(lock, std::chrono::milliseconds{ waitingTime });
68 TestWithMock::SetUp();
70 finished = std::make_shared< bool >(false);
74 WaitUntilDiscovered();
79 TestWithMock::TearDown();
81 // This method is to make sure objects disposed.
82 WaitForPtrBeingUnique();
90 server = RCSResourceObject::Builder(RESOURCEURI, RESOURCETYPE, RESOURCEINTERFACE).build();
91 server->setAttribute(ATTR_KEY, ATTR_VALUE);
96 std::lock_guard<std::mutex> lock{ mutexForObject };
97 return object == nullptr;
100 void WaitUntilDiscovered()
102 while (checkObject())
104 RCSDiscoveryManager::getInstance()->discoverResource(RCSAddress::multicast(),
105 "/oic/res?rt=Resource.Hosting", std::bind(resourceDiscovered, this, finished,
106 std::placeholders::_1));
112 void WaitForPtrBeingUnique()
114 while((object && !object.unique()) || (server && !server.unique()))
116 std::this_thread::sleep_for(std::chrono::milliseconds{ 100 });
120 // This callback is to protect crash from crashes caused by delayed callbacks
121 static void resourceDiscovered(RemoteResourceObjectTest* test,
122 std::shared_ptr< bool > finished, RCSRemoteResourceObject::Ptr resourceObject)
124 if (*finished) return;
127 std::lock_guard< std::mutex > lock{ test->mutexForObject };
129 if (test->object) return;
131 test->object = resourceObject;
138 std::condition_variable cond;
140 std::mutex mutexForObject;
143 TEST_F(RemoteResourceObjectTest, GetRemoteAttributesDoesNotAllowEmptyFunction)
145 ASSERT_THROW(object->getRemoteAttributes({ }), InvalidParameterException);
148 TEST_F(RemoteResourceObjectTest, GetRemoteAttributesGetsAttributesOfServer)
150 mocks.ExpectCallFunc(getRemoteAttributesCallback).Match(
151 [this](const RCSResourceAttributes& attrs)
153 RCSResourceObject::LockGuard lock{ server };
154 return attrs == server->getAttributes();
156 ).Do([this](const RCSResourceAttributes&){ Proceed(); });
158 object->getRemoteAttributes(getRemoteAttributesCallback);
163 TEST_F(RemoteResourceObjectTest, SetRemoteAttributesDoesNotAllowEmptyFunction)
165 ASSERT_THROW(object->setRemoteAttributes({ }, { }), InvalidParameterException);
168 TEST_F(RemoteResourceObjectTest, SetRemoteAttributesSetsAttributesOfServer)
170 constexpr int newValue = ATTR_VALUE + 1;
171 RCSResourceAttributes newAttrs;
172 newAttrs[ATTR_KEY] = newValue;
174 mocks.ExpectCallFunc(setRemoteAttributesCallback).
175 Do([this](const RCSResourceAttributes&){ Proceed(); });
177 object->setRemoteAttributes(newAttrs, setRemoteAttributesCallback);
180 ASSERT_EQ(newValue, server->getAttributeValue(ATTR_KEY));
183 TEST_F(RemoteResourceObjectTest, MonitoringIsNotStartedByDefault)
185 ASSERT_FALSE(object->isMonitoring());
188 TEST_F(RemoteResourceObjectTest, StartMonitoringThrowsIfFunctionIsEmpty)
190 ASSERT_THROW(object->startMonitoring({ }), InvalidParameterException);
193 TEST_F(RemoteResourceObjectTest, IsMonitoringReturnsTrueAfterStartMonitoring)
195 object->startMonitoring(resourceStateChanged);
197 ASSERT_TRUE(object->isMonitoring());
200 TEST_F(RemoteResourceObjectTest, StartMonitoringThrowsIfTryingToStartAgain)
202 object->startMonitoring(resourceStateChanged);
204 ASSERT_THROW(object->startMonitoring(resourceStateChanged), BadRequestException);
207 TEST_F(RemoteResourceObjectTest, DefaultStateIsNone)
209 ASSERT_EQ(ResourceState::NONE, object->getState());
212 TEST_F(RemoteResourceObjectTest, CachingIsNotStartedByDefault)
214 ASSERT_FALSE(object->isCaching());
217 TEST_F(RemoteResourceObjectTest, IsCachingReturnsTrueAfterStartCaching)
219 object->startCaching(cacheUpdatedCallback);
221 ASSERT_TRUE(object->isCaching());
224 TEST_F(RemoteResourceObjectTest, StartCachingThrowsIfTryingToStartAgain)
226 object->startCaching(cacheUpdatedCallback);
228 ASSERT_THROW(object->startCaching(), BadRequestException);
231 TEST_F(RemoteResourceObjectTest, DefaultCacheStateIsNone)
233 ASSERT_EQ(CacheState::NONE, object->getCacheState());
236 TEST_F(RemoteResourceObjectTest, CacheStateIsUnreadyAfterStartCaching)
238 object->startCaching();
240 ASSERT_EQ(CacheState::UNREADY, object->getCacheState());
243 TEST_F(RemoteResourceObjectTest, CacheStateIsReadyAfterCacheUpdated)
245 mocks.ExpectCallFunc(cacheUpdatedCallback).
246 Do([this](const RCSResourceAttributes&){ Proceed(); });
248 object->startCaching(cacheUpdatedCallback);
251 ASSERT_EQ(CacheState::READY, object->getCacheState());
254 TEST_F(RemoteResourceObjectTest, IsCachedAvailableReturnsTrueWhenCacheIsReady)
256 mocks.ExpectCallFunc(cacheUpdatedCallback).
257 Do([this](const RCSResourceAttributes&){ Proceed(); });
259 object->startCaching(cacheUpdatedCallback);
262 ASSERT_TRUE(object->isCachedAvailable());
265 TEST_F(RemoteResourceObjectTest, DISABLED_CacheUpdatedCallbackBeCalledWheneverCacheUpdated)
267 mocks.OnCallFunc(cacheUpdatedCallback).
268 Do([this](const RCSResourceAttributes&){ Proceed(); });
269 object->startCaching(cacheUpdatedCallback);
272 mocks.ExpectCallFunc(cacheUpdatedCallback).
273 Do([this](const RCSResourceAttributes&){ Proceed(); });
275 server->setAttribute(ATTR_KEY, ATTR_VALUE + 1);
280 TEST_F(RemoteResourceObjectTest, DISABLED_CacheUpdatedCallbackBeCalledWithUpdatedAttributes)
282 constexpr int newValue = ATTR_VALUE + 1;
284 mocks.OnCallFunc(cacheUpdatedCallback).
285 Do([this](const RCSResourceAttributes&){ Proceed(); });
286 object->startCaching(cacheUpdatedCallback);
289 mocks.ExpectCallFunc(cacheUpdatedCallback).
290 Match([this](const RCSResourceAttributes& attrs){
291 return attrs.at(ATTR_KEY) == newValue;
293 Do([this](const RCSResourceAttributes&){ Proceed(); });
295 server->setAttribute(ATTR_KEY, newValue);
300 TEST_F(RemoteResourceObjectTest, GetCachedAttributesThrowsIfCachingIsNotStarted)
302 ASSERT_THROW(object->getCachedAttributes(), BadRequestException);
305 TEST_F(RemoteResourceObjectTest, CachedAttributesHasSameAttributesWithServer)
307 mocks.OnCallFunc(cacheUpdatedCallback).
308 Do([this](const RCSResourceAttributes&){ Proceed(); });
309 object->startCaching(cacheUpdatedCallback);
312 RCSResourceObject::LockGuard lock{ server };
314 ASSERT_EQ(object->getCachedAttributes(), server->getAttributes());
317 TEST_F(RemoteResourceObjectTest, GetCachedAttributeThrowsIfCachingIsNotStarted)
319 ASSERT_THROW(object->getCachedAttribute(ATTR_KEY), BadRequestException);
322 TEST_F(RemoteResourceObjectTest, GetCachedAttributeThrowsIfKeyIsInvalid)
324 mocks.OnCallFunc(cacheUpdatedCallback).
325 Do([this](const RCSResourceAttributes&){ Proceed(); });
326 object->startCaching(cacheUpdatedCallback);
329 ASSERT_THROW(object->getCachedAttribute(""), InvalidKeyException);
332 TEST_F(RemoteResourceObjectTest, HasSameUriWithServer)
334 EXPECT_EQ(RESOURCEURI, object->getUri());
337 TEST_F(RemoteResourceObjectTest, HasSameTypeWithServer)
339 EXPECT_EQ(RESOURCETYPE, object->getTypes()[0]);
342 TEST_F(RemoteResourceObjectTest, HasSameInterfaceWithServer)
344 EXPECT_EQ(RESOURCEINTERFACE, object->getInterfaces()[0]);