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&, int) {}
43 void setRemoteAttributesCallback(const RCSResourceAttributes&, int) {}
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();
77 ASSERT_NE(object, nullptr);
82 TestWithMock::TearDown();
84 // This method is to make sure objects disposed.
85 WaitForPtrBeingUnique();
93 server = RCSResourceObject::Builder(RESOURCEURI, RESOURCETYPE, RESOURCEINTERFACE).build();
94 server->setAttribute(ATTR_KEY, ATTR_VALUE);
99 std::lock_guard<std::mutex> lock{ mutexForObject };
100 return object == nullptr;
103 void WaitUntilDiscovered()
105 for (int i=0; i<10 && checkObject(); ++i)
107 const std::string uri = "/oic/res";
108 const std::string type = "Resource.Hosting";
109 auto discoveryTask = RCSDiscoveryManager::getInstance()->discoverResourceByType(
110 RCSAddress::multicast(), uri, type, std::bind(resourceDiscovered, this, finished,
111 std::placeholders::_1));
116 void WaitForPtrBeingUnique()
118 while((object && !object.unique()) || (server && !server.unique()))
120 std::this_thread::sleep_for(std::chrono::milliseconds{ 100 });
124 // This callback is to protect crash from crashes caused by delayed callbacks
125 static void resourceDiscovered(RemoteResourceObjectTest* test,
126 std::shared_ptr< bool > finished, RCSRemoteResourceObject::Ptr resourceObject)
128 if (*finished) return;
131 std::lock_guard< std::mutex > lock{ test->mutexForObject };
133 if (test->object) return;
135 test->object = resourceObject;
142 std::condition_variable cond;
144 std::mutex mutexForObject;
147 TEST_F(RemoteResourceObjectTest, GetRemoteAttributesDoesNotAllowEmptyFunction)
149 ASSERT_THROW(object->getRemoteAttributes({ }), InvalidParameterException);
152 TEST_F(RemoteResourceObjectTest, GetRemoteAttributesGetsAttributesOfServer)
154 mocks.ExpectCallFunc(getRemoteAttributesCallback).Match(
155 [this](const RCSResourceAttributes& attrs, int)
157 RCSResourceObject::LockGuard lock{ server };
158 return attrs == server->getAttributes();
160 ).Do([this](const RCSResourceAttributes&, int){ Proceed(); });
162 object->getRemoteAttributes(getRemoteAttributesCallback);
167 TEST_F(RemoteResourceObjectTest, SetRemoteAttributesDoesNotAllowEmptyFunction)
169 ASSERT_THROW(object->setRemoteAttributes({ }, { }), InvalidParameterException);
172 TEST_F(RemoteResourceObjectTest, SetRemoteAttributesSetsAttributesOfServer)
174 constexpr int newValue = ATTR_VALUE + 1;
175 RCSResourceAttributes newAttrs;
176 newAttrs[ATTR_KEY] = newValue;
178 mocks.ExpectCallFunc(setRemoteAttributesCallback).
179 Do([this](const RCSResourceAttributes&, int){ Proceed(); });
181 object->setRemoteAttributes(newAttrs, setRemoteAttributesCallback);
184 ASSERT_EQ(newValue, server->getAttributeValue(ATTR_KEY));
187 TEST_F(RemoteResourceObjectTest, MonitoringIsNotStartedByDefault)
189 ASSERT_FALSE(object->isMonitoring());
192 TEST_F(RemoteResourceObjectTest, StartMonitoringThrowsIfFunctionIsEmpty)
194 ASSERT_THROW(object->startMonitoring({ }), InvalidParameterException);
197 TEST_F(RemoteResourceObjectTest, IsMonitoringReturnsTrueAfterStartMonitoring)
199 object->startMonitoring(resourceStateChanged);
201 ASSERT_TRUE(object->isMonitoring());
204 TEST_F(RemoteResourceObjectTest, StartMonitoringThrowsIfTryingToStartAgain)
206 object->startMonitoring(resourceStateChanged);
208 ASSERT_THROW(object->startMonitoring(resourceStateChanged), BadRequestException);
211 TEST_F(RemoteResourceObjectTest, DefaultStateIsNone)
213 ASSERT_EQ(ResourceState::NONE, object->getState());
216 TEST_F(RemoteResourceObjectTest, CachingIsNotStartedByDefault)
218 ASSERT_FALSE(object->isCaching());
221 TEST_F(RemoteResourceObjectTest, IsCachingReturnsTrueAfterStartCaching)
223 object->startCaching(cacheUpdatedCallback);
225 ASSERT_TRUE(object->isCaching());
228 TEST_F(RemoteResourceObjectTest, StartCachingThrowsIfTryingToStartAgain)
230 object->startCaching(cacheUpdatedCallback);
232 ASSERT_THROW(object->startCaching(), BadRequestException);
235 TEST_F(RemoteResourceObjectTest, DefaultCacheStateIsNone)
237 ASSERT_EQ(CacheState::NONE, object->getCacheState());
240 TEST_F(RemoteResourceObjectTest, CacheStateIsUnreadyAfterStartCaching)
242 object->startCaching();
244 ASSERT_EQ(CacheState::UNREADY, object->getCacheState());
247 TEST_F(RemoteResourceObjectTest, CacheStateIsReadyAfterCacheUpdated)
249 mocks.ExpectCallFunc(cacheUpdatedCallback).
250 Do([this](const RCSResourceAttributes&){ Proceed(); });
252 object->startCaching(cacheUpdatedCallback);
255 ASSERT_EQ(CacheState::READY, object->getCacheState());
258 TEST_F(RemoteResourceObjectTest, IsCachedAvailableReturnsTrueWhenCacheIsReady)
260 mocks.ExpectCallFunc(cacheUpdatedCallback).
261 Do([this](const RCSResourceAttributes&){ Proceed(); });
263 object->startCaching(cacheUpdatedCallback);
266 ASSERT_TRUE(object->isCachedAvailable());
269 TEST_F(RemoteResourceObjectTest, DISABLED_CacheUpdatedCallbackBeCalledWheneverCacheUpdated)
271 mocks.OnCallFunc(cacheUpdatedCallback).
272 Do([this](const RCSResourceAttributes&){ Proceed(); });
273 object->startCaching(cacheUpdatedCallback);
276 mocks.ExpectCallFunc(cacheUpdatedCallback).
277 Do([this](const RCSResourceAttributes&){ Proceed(); });
279 server->setAttribute(ATTR_KEY, ATTR_VALUE + 1);
284 TEST_F(RemoteResourceObjectTest, DISABLED_CacheUpdatedCallbackBeCalledWithUpdatedAttributes)
286 constexpr int newValue = ATTR_VALUE + 1;
288 mocks.OnCallFunc(cacheUpdatedCallback).
289 Do([this](const RCSResourceAttributes&){ Proceed(); });
290 object->startCaching(cacheUpdatedCallback);
293 mocks.ExpectCallFunc(cacheUpdatedCallback).
294 Match([this](const RCSResourceAttributes& attrs){
295 return attrs.at(ATTR_KEY) == newValue;
297 Do([this](const RCSResourceAttributes&){ Proceed(); });
299 server->setAttribute(ATTR_KEY, newValue);
304 TEST_F(RemoteResourceObjectTest, GetCachedAttributesThrowsIfCachingIsNotStarted)
306 ASSERT_THROW(object->getCachedAttributes(), BadRequestException);
309 TEST_F(RemoteResourceObjectTest, CachedAttributesHasSameAttributesWithServer)
311 mocks.OnCallFunc(cacheUpdatedCallback).
312 Do([this](const RCSResourceAttributes&){ Proceed(); });
313 object->startCaching(cacheUpdatedCallback);
316 RCSResourceObject::LockGuard lock{ server };
318 ASSERT_EQ(object->getCachedAttributes(), server->getAttributes());
321 TEST_F(RemoteResourceObjectTest, GetCachedAttributeThrowsIfCachingIsNotStarted)
323 ASSERT_THROW(object->getCachedAttribute(ATTR_KEY), BadRequestException);
326 TEST_F(RemoteResourceObjectTest, GetCachedAttributeThrowsIfKeyIsInvalid)
328 mocks.OnCallFunc(cacheUpdatedCallback).
329 Do([this](const RCSResourceAttributes&){ Proceed(); });
330 object->startCaching(cacheUpdatedCallback);
333 ASSERT_THROW(object->getCachedAttribute(""), InvalidKeyException);
336 TEST_F(RemoteResourceObjectTest, HasSameUriWithServer)
338 EXPECT_EQ(RESOURCEURI, object->getUri());
341 TEST_F(RemoteResourceObjectTest, HasSameTypeWithServer)
343 EXPECT_EQ(RESOURCETYPE, object->getTypes()[0]);
346 TEST_F(RemoteResourceObjectTest, HasSameInterfaceWithServer)
348 EXPECT_EQ(RESOURCEINTERFACE, object->getInterfaces()[0]);