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"
26 #include <condition_variable>
30 using namespace OIC::Service;
33 constexpr char RESOURCEURI[]{ "/a/TemperatureSensor" };
34 constexpr char RESOURCETYPE[]{ "Resource.Hosting" };
35 constexpr char RESOURCEINTERFACE[]{ "oic.if.baseline" };
37 constexpr char ATTR_KEY[]{ "Temperature" };
38 constexpr int ATTR_VALUE{ 0 };
40 constexpr int DEFAULT_WAITING_TIME_IN_MILLIS = 3000;
42 void getRemoteAttributesCallback(const RCSResourceAttributes&) {}
43 void setRemoteAttributesCallback(const RCSResourceAttributes&) {}
44 void resourceStateChanged(ResourceState) { }
45 void cacheUpdatedCallback(const RCSResourceAttributes&) {}
47 class RemoteResourceObjectTest: public TestWithMock
50 RCSResourceObject::Ptr server;
51 RCSRemoteResourceObject::Ptr object;
52 std::shared_ptr< bool > finished;
60 void Wait(int waitingTime = DEFAULT_WAITING_TIME_IN_MILLIS)
62 std::unique_lock< std::mutex > lock{ mutex };
63 cond.wait_for(lock, std::chrono::milliseconds{ waitingTime });
69 TestWithMock::SetUp();
71 finished = std::make_shared< bool >(false);
75 WaitUntilDiscovered();
80 TestWithMock::TearDown();
82 // This method is to make sure objects disposed.
83 WaitForPtrBeingUnique();
91 server = RCSResourceObject::Builder(RESOURCEURI, RESOURCETYPE, RESOURCEINTERFACE).build();
92 server->setAttribute(ATTR_KEY, ATTR_VALUE);
97 std::lock_guard<std::mutex> lock{ mutexForObject };
98 return object == nullptr;
101 void WaitUntilDiscovered()
103 while (checkObject())
105 RCSDiscoveryManager::getInstance()->discoverResource(RCSAddress::multicast(),
106 "/oic/res?rt=Resource.Hosting", std::bind(resourceDiscovered, this, finished,
107 std::placeholders::_1));
113 void WaitForPtrBeingUnique()
115 while((object && !object.unique()) || (server && !server.unique()))
117 std::this_thread::sleep_for(std::chrono::milliseconds{ 100 });
121 // This callback is to protect crash from crashes caused by delayed callbacks
122 static void resourceDiscovered(RemoteResourceObjectTest* test,
123 std::shared_ptr< bool > finished, RCSRemoteResourceObject::Ptr resourceObject)
125 if (*finished) return;
128 std::lock_guard< std::mutex > lock{ test->mutexForObject };
130 if (test->object) return;
132 test->object = resourceObject;
139 std::condition_variable cond;
141 std::mutex mutexForObject;
144 TEST_F(RemoteResourceObjectTest, GetRemoteAttributesDoesNotAllowEmptyFunction)
146 ASSERT_THROW(object->getRemoteAttributes({ }), InvalidParameterException);
149 TEST_F(RemoteResourceObjectTest, GetRemoteAttributesGetsAttributesOfServer)
151 mocks.ExpectCallFunc(getRemoteAttributesCallback).Match(
152 [this](const RCSResourceAttributes& attrs)
154 RCSResourceObject::LockGuard lock{ server };
155 return attrs == server->getAttributes();
157 ).Do([this](const RCSResourceAttributes&){ Proceed(); });
159 object->getRemoteAttributes(getRemoteAttributesCallback);
164 TEST_F(RemoteResourceObjectTest, SetRemoteAttributesDoesNotAllowEmptyFunction)
166 ASSERT_THROW(object->setRemoteAttributes({ }, { }), InvalidParameterException);
169 TEST_F(RemoteResourceObjectTest, SetRemoteAttributesSetsAttributesOfServer)
171 constexpr int newValue = ATTR_VALUE + 1;
172 RCSResourceAttributes newAttrs;
173 newAttrs[ATTR_KEY] = newValue;
175 mocks.ExpectCallFunc(setRemoteAttributesCallback).
176 Do([this](const RCSResourceAttributes&){ Proceed(); });
178 object->setRemoteAttributes(newAttrs, setRemoteAttributesCallback);
181 ASSERT_EQ(newValue, server->getAttributeValue(ATTR_KEY));
184 TEST_F(RemoteResourceObjectTest, MonitoringIsNotStartedByDefault)
186 ASSERT_FALSE(object->isMonitoring());
189 TEST_F(RemoteResourceObjectTest, StartMonitoringThrowsIfFunctionIsEmpty)
191 ASSERT_THROW(object->startMonitoring({ }), InvalidParameterException);
194 TEST_F(RemoteResourceObjectTest, IsMonitoringReturnsTrueAfterStartMonitoring)
196 object->startMonitoring(resourceStateChanged);
198 ASSERT_TRUE(object->isMonitoring());
201 TEST_F(RemoteResourceObjectTest, StartMonitoringThrowsIfTryingToStartAgain)
203 object->startMonitoring(resourceStateChanged);
205 ASSERT_THROW(object->startMonitoring(resourceStateChanged), BadRequestException);
208 TEST_F(RemoteResourceObjectTest, DefaultStateIsNone)
210 ASSERT_EQ(ResourceState::NONE, object->getState());
213 TEST_F(RemoteResourceObjectTest, CachingIsNotStartedByDefault)
215 ASSERT_FALSE(object->isCaching());
218 TEST_F(RemoteResourceObjectTest, IsCachingReturnsTrueAfterStartCaching)
220 object->startCaching(cacheUpdatedCallback);
222 ASSERT_TRUE(object->isCaching());
225 TEST_F(RemoteResourceObjectTest, StartCachingThrowsIfTryingToStartAgain)
227 object->startCaching(cacheUpdatedCallback);
229 ASSERT_THROW(object->startCaching(), BadRequestException);
232 TEST_F(RemoteResourceObjectTest, DefaultCacheStateIsNone)
234 ASSERT_EQ(CacheState::NONE, object->getCacheState());
237 TEST_F(RemoteResourceObjectTest, CacheStateIsUnreadyAfterStartCaching)
239 object->startCaching();
241 ASSERT_EQ(CacheState::UNREADY, object->getCacheState());
244 TEST_F(RemoteResourceObjectTest, CacheStateIsReadyAfterCacheUpdated)
246 mocks.ExpectCallFunc(cacheUpdatedCallback).
247 Do([this](const RCSResourceAttributes&){ Proceed(); });
249 object->startCaching(cacheUpdatedCallback);
252 ASSERT_EQ(CacheState::READY, object->getCacheState());
255 TEST_F(RemoteResourceObjectTest, IsCachedAvailableReturnsTrueWhenCacheIsReady)
257 mocks.ExpectCallFunc(cacheUpdatedCallback).
258 Do([this](const RCSResourceAttributes&){ Proceed(); });
260 object->startCaching(cacheUpdatedCallback);
263 ASSERT_TRUE(object->isCachedAvailable());
266 TEST_F(RemoteResourceObjectTest, DISABLED_CacheUpdatedCallbackBeCalledWheneverCacheUpdated)
268 mocks.OnCallFunc(cacheUpdatedCallback).
269 Do([this](const RCSResourceAttributes&){ Proceed(); });
270 object->startCaching(cacheUpdatedCallback);
273 mocks.ExpectCallFunc(cacheUpdatedCallback).
274 Do([this](const RCSResourceAttributes&){ Proceed(); });
276 server->setAttribute(ATTR_KEY, ATTR_VALUE + 1);
281 TEST_F(RemoteResourceObjectTest, DISABLED_CacheUpdatedCallbackBeCalledWithUpdatedAttributes)
283 constexpr int newValue = ATTR_VALUE + 1;
285 mocks.OnCallFunc(cacheUpdatedCallback).
286 Do([this](const RCSResourceAttributes&){ Proceed(); });
287 object->startCaching(cacheUpdatedCallback);
290 mocks.ExpectCallFunc(cacheUpdatedCallback).
291 Match([this](const RCSResourceAttributes& attrs){
292 return attrs.at(ATTR_KEY) == newValue;
294 Do([this](const RCSResourceAttributes&){ Proceed(); });
296 server->setAttribute(ATTR_KEY, newValue);
301 TEST_F(RemoteResourceObjectTest, GetCachedAttributesThrowsIfCachingIsNotStarted)
303 ASSERT_THROW(object->getCachedAttributes(), BadRequestException);
306 TEST_F(RemoteResourceObjectTest, CachedAttributesHasSameAttributesWithServer)
308 mocks.OnCallFunc(cacheUpdatedCallback).
309 Do([this](const RCSResourceAttributes&){ Proceed(); });
310 object->startCaching(cacheUpdatedCallback);
313 RCSResourceObject::LockGuard lock{ server };
315 ASSERT_EQ(object->getCachedAttributes(), server->getAttributes());
318 TEST_F(RemoteResourceObjectTest, GetCachedAttributeThrowsIfCachingIsNotStarted)
320 ASSERT_THROW(object->getCachedAttribute(ATTR_KEY), BadRequestException);
323 TEST_F(RemoteResourceObjectTest, GetCachedAttributeThrowsIfKeyIsInvalid)
325 mocks.OnCallFunc(cacheUpdatedCallback).
326 Do([this](const RCSResourceAttributes&){ Proceed(); });
327 object->startCaching(cacheUpdatedCallback);
330 ASSERT_THROW(object->getCachedAttribute(""), InvalidKeyException);
333 TEST_F(RemoteResourceObjectTest, HasSameUriWithServer)
335 EXPECT_EQ(RESOURCEURI, object->getUri());
338 TEST_F(RemoteResourceObjectTest, HasSameTypeWithServer)
340 EXPECT_EQ(RESOURCETYPE, object->getTypes()[0]);
343 TEST_F(RemoteResourceObjectTest, HasSameInterfaceWithServer)
345 EXPECT_EQ(RESOURCEINTERFACE, object->getInterfaces()[0]);