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"
23 #include "OCResource.h"
25 #include "RCSRemoteResourceObject.h"
26 #include "RCSDiscoveryManager.h"
27 #include "RCSResourceObject.h"
28 #include "RCSAddress.h"
29 #include "RCSRequest.h"
31 #include <condition_variable>
34 using namespace OIC::Service;
37 constexpr char RESOURCEURI[]{ "/a/TemperatureSensor" };
38 constexpr char RESOURCETYPE[]{ "resource.type" };
39 constexpr char RESOURCEINTERFACE[]{ "oic.if.baseline" };
41 constexpr char ATTR_KEY[]{ "Temperature" };
42 constexpr int ATTR_VALUE{ 0 };
44 constexpr int DEFAULT_WAITING_TIME_IN_MILLIS = 3000;
46 void getRemoteAttributesCallback(const RCSResourceAttributes&, int) {}
47 void setRemoteAttributesCallback(const RCSResourceAttributes&, int) {}
48 void setRemoteRepresentationCallback(const HeaderOpts&, const RCSRepresentation&, int) {}
49 void resourceStateChanged(ResourceState) { }
50 void cacheUpdatedCallback(const RCSResourceAttributes&, int) {}
52 class RemoteResourceObjectTest: public TestWithMock
55 RCSResourceObject::Ptr server;
56 RCSRemoteResourceObject::Ptr object;
64 void Wait(int waitingTime = DEFAULT_WAITING_TIME_IN_MILLIS)
66 std::unique_lock< std::mutex > lock{ mutex };
67 cond.wait_for(lock, std::chrono::milliseconds{ waitingTime });
73 TestWithMock::SetUp();
77 WaitUntilDiscovered();
79 ASSERT_NE(object, nullptr);
84 TestWithMock::TearDown();
86 // This method is to make sure objects disposed.
87 WaitForPtrBeingUnique();
93 server = RCSResourceObject::Builder(RESOURCEURI, RESOURCETYPE, RESOURCEINTERFACE).build();
94 server->setAttribute(ATTR_KEY, ATTR_VALUE);
97 void WaitUntilDiscovered()
99 for (int i=0; i<10 && !object; ++i)
101 auto discoveryTask = RCSDiscoveryManager::getInstance()->discoverResourceByType(
102 RCSAddress::multicast(), RESOURCETYPE,
103 std::bind(&RemoteResourceObjectTest::resourceDiscovered, this,
104 std::placeholders::_1));
106 discoveryTask->cancel();
110 void WaitForPtrBeingUnique()
112 while((object && !object.unique()) || (server && !server.unique()))
114 std::this_thread::sleep_for(std::chrono::milliseconds{ 100 });
118 void resourceDiscovered(RCSRemoteResourceObject::Ptr resourceObject)
120 object = resourceObject;
126 std::condition_variable cond;
130 TEST_F(RemoteResourceObjectTest, GetRemoteAttributesDoesNotAllowEmptyFunction)
132 ASSERT_THROW(object->getRemoteAttributes({ }), RCSInvalidParameterException);
135 TEST_F(RemoteResourceObjectTest, GetRemoteAttributesGetsAttributesOfServer)
137 mocks.ExpectCallFunc(getRemoteAttributesCallback).Match(
138 [this](const RCSResourceAttributes& attrs, int)
140 RCSResourceObject::LockGuard lock{ server };
141 return attrs == server->getAttributes();
143 ).Do([this](const RCSResourceAttributes&, int){ Proceed(); });
145 object->getRemoteAttributes(getRemoteAttributesCallback);
150 TEST_F(RemoteResourceObjectTest, SetRemoteAttributesDoesNotAllowEmptyFunction)
152 ASSERT_THROW(object->setRemoteAttributes({ }, { }), RCSInvalidParameterException);
155 TEST_F(RemoteResourceObjectTest, SetRemoteAttributesSetsAttributesOfServer)
157 constexpr int newValue = ATTR_VALUE + 1;
158 RCSResourceAttributes newAttrs;
159 newAttrs[ATTR_KEY] = newValue;
161 mocks.ExpectCallFunc(setRemoteAttributesCallback).
162 Do([this](const RCSResourceAttributes&, int){ Proceed(); });
164 object->setRemoteAttributes(newAttrs, setRemoteAttributesCallback);
167 ASSERT_EQ(newValue, server->getAttributeValue(ATTR_KEY).get<int>());
170 TEST_F(RemoteResourceObjectTest, SetRemoteRepresentationDoesNotAllowEmptyFunction)
172 RCSQueryParams queryParams;
173 RCSRepresentation rcsRep;
174 ASSERT_THROW(object->set(queryParams, rcsRep, {}), RCSInvalidParameterException);
177 TEST_F(RemoteResourceObjectTest, SetRemoteRepresentationSetsRepresentationOfServer)
179 RCSRepresentation rcsRep;
180 RCSQueryParams queryParams;
181 constexpr int newValue = ATTR_VALUE + 1;
182 RCSResourceAttributes newAttrs;
183 newAttrs[ATTR_KEY] = newValue;
185 rcsRep.setAttributes(newAttrs);
187 mocks.ExpectCallFunc(setRemoteRepresentationCallback).
188 Do([this](const HeaderOpts&, const RCSRepresentation&, int){ Proceed(); });
190 object->set(queryParams, rcsRep, setRemoteRepresentationCallback);
193 ASSERT_EQ(newValue, server->getAttributeValue(ATTR_KEY).get<int>());
196 TEST_F(RemoteResourceObjectTest, QueryParamsForGetWillBePassedToBase)
201 virtual RCSGetResponse handle(const RCSRequest&, RCSResourceAttributes&) = 0;
202 virtual ~CustomHandler() {}
205 constexpr char PARAM_KEY[] { "aKey" };
206 constexpr char VALUE[] { "value" };
208 object->get(RCSQueryParams().setResourceInterface(RESOURCEINTERFACE).setResourceType(RESOURCETYPE).
209 put(PARAM_KEY, VALUE),
210 [](const HeaderOpts&, const RCSRepresentation&, int){});
212 auto mockHandler = mocks.Mock< CustomHandler >();
214 mocks.ExpectCall(mockHandler, CustomHandler::handle).
215 Match([](const RCSRequest& request, RCSResourceAttributes&)
217 return request.getInterface() == RESOURCEINTERFACE &&
218 request.getQueryParams().at(PARAM_KEY) == VALUE;
221 Do([this](const RCSRequest&, RCSResourceAttributes&)
224 return RCSGetResponse::defaultAction();
228 server->setGetRequestHandler(std::bind(&CustomHandler::handle, mockHandler,
229 std::placeholders::_1, std::placeholders::_2));
234 TEST_F(RemoteResourceObjectTest, MonitoringIsNotStartedByDefault)
236 ASSERT_FALSE(object->isMonitoring());
239 TEST_F(RemoteResourceObjectTest, StartMonitoringThrowsIfFunctionIsEmpty)
241 ASSERT_THROW(object->startMonitoring({ }), RCSInvalidParameterException);
244 TEST_F(RemoteResourceObjectTest, IsMonitoringReturnsTrueAfterStartMonitoring)
246 object->startMonitoring(resourceStateChanged);
248 ASSERT_TRUE(object->isMonitoring());
251 TEST_F(RemoteResourceObjectTest, StartMonitoringThrowsIfTryingToStartAgain)
253 object->startMonitoring(resourceStateChanged);
255 ASSERT_THROW(object->startMonitoring(resourceStateChanged), RCSBadRequestException);
258 TEST_F(RemoteResourceObjectTest, DefaultStateIsNone)
260 ASSERT_EQ(ResourceState::NONE, object->getState());
263 TEST_F(RemoteResourceObjectTest, CachingIsNotStartedByDefault)
265 ASSERT_FALSE(object->isCaching());
268 TEST_F(RemoteResourceObjectTest, IsCachingReturnsTrueAfterStartCaching)
270 object->startCaching(cacheUpdatedCallback);
272 ASSERT_TRUE(object->isCaching());
275 TEST_F(RemoteResourceObjectTest, StartCachingThrowsIfTryingToStartAgain)
277 object->startCaching(cacheUpdatedCallback);
279 ASSERT_THROW(object->startCaching(), RCSBadRequestException);
282 TEST_F(RemoteResourceObjectTest, DefaultCacheStateIsNone)
284 ASSERT_EQ(CacheState::NONE, object->getCacheState());
287 TEST_F(RemoteResourceObjectTest, CacheStateIsUnreadyAfterStartCaching)
289 object->startCaching();
291 ASSERT_EQ(CacheState::UNREADY, object->getCacheState());
294 TEST_F(RemoteResourceObjectTest, CacheStateIsReadyAfterCacheUpdated)
296 mocks.ExpectCallFunc(cacheUpdatedCallback).
297 Do([this](const RCSResourceAttributes&, int){ Proceed(); });
299 object->startCaching(cacheUpdatedCallback);
302 ASSERT_EQ(CacheState::READY, object->getCacheState());
305 TEST_F(RemoteResourceObjectTest, IsCachedAvailableReturnsTrueWhenCacheIsReady)
307 mocks.ExpectCallFunc(cacheUpdatedCallback).
308 Do([this](const RCSResourceAttributes&, int){ Proceed(); });
310 object->startCaching(cacheUpdatedCallback);
313 ASSERT_TRUE(object->isCachedAvailable());
316 TEST_F(RemoteResourceObjectTest, DISABLED_CacheUpdatedCallbackBeCalledWheneverCacheUpdated)
318 mocks.OnCallFunc(cacheUpdatedCallback).
319 Do([this](const RCSResourceAttributes&, int){ Proceed(); });
320 object->startCaching(cacheUpdatedCallback);
323 mocks.ExpectCallFunc(cacheUpdatedCallback).
324 Do([this](const RCSResourceAttributes&, int){ Proceed(); });
326 server->setAttribute(ATTR_KEY, ATTR_VALUE + 1);
331 TEST_F(RemoteResourceObjectTest, DISABLED_CacheUpdatedCallbackBeCalledWithUpdatedAttributes)
333 constexpr int newValue = ATTR_VALUE + 1;
335 mocks.OnCallFunc(cacheUpdatedCallback).
336 Do([this](const RCSResourceAttributes&, int){ Proceed(); });
337 object->startCaching(cacheUpdatedCallback);
340 mocks.ExpectCallFunc(cacheUpdatedCallback).
341 Match([this](const RCSResourceAttributes& attrs, int){
342 return attrs.at(ATTR_KEY) == newValue;
344 Do([this](const RCSResourceAttributes&, int){ Proceed(); });
346 server->setAttribute(ATTR_KEY, newValue);
351 TEST_F(RemoteResourceObjectTest, GetCachedAttributesThrowsIfCachingIsNotStarted)
353 ASSERT_THROW(object->getCachedAttributes(), RCSBadRequestException);
356 TEST_F(RemoteResourceObjectTest, CachedAttributesHasSameAttributesWithServer)
358 mocks.OnCallFunc(cacheUpdatedCallback).
359 Do([this](const RCSResourceAttributes&, int){ Proceed(); });
360 object->startCaching(cacheUpdatedCallback);
363 RCSResourceObject::LockGuard lock{ server };
365 ASSERT_EQ(object->getCachedAttributes(), server->getAttributes());
368 TEST_F(RemoteResourceObjectTest, GetCachedAttributeThrowsIfCachingIsNotStarted)
370 ASSERT_THROW(object->getCachedAttribute(ATTR_KEY), RCSBadRequestException);
373 TEST_F(RemoteResourceObjectTest, GetCachedAttributeThrowsIfKeyIsInvalid)
375 mocks.OnCallFunc(cacheUpdatedCallback).
376 Do([this](const RCSResourceAttributes&, int){ Proceed(); });
377 object->startCaching(cacheUpdatedCallback);
380 ASSERT_THROW(object->getCachedAttribute(""), RCSInvalidKeyException);
383 TEST_F(RemoteResourceObjectTest, HasSameUriWithServer)
385 EXPECT_EQ(RESOURCEURI, object->getUri());
388 TEST_F(RemoteResourceObjectTest, HasSameTypeWithServer)
390 EXPECT_EQ(RESOURCETYPE, object->getTypes()[0]);
393 TEST_F(RemoteResourceObjectTest, HasSameInterfaceWithServer)
395 EXPECT_EQ(RESOURCEINTERFACE, object->getInterfaces()[0]);
398 TEST_F(RemoteResourceObjectTest, GetValidOCResourceTest)
400 std::shared_ptr<OC::OCResource> ocRes = RCSRemoteResourceObject::toOCResource(object);
402 EXPECT_NE(nullptr, ocRes);
404 EXPECT_EQ(RESOURCEURI, ocRes->uri());