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 "RCSResourceObject.h"
24 #include "RCSRequest.h"
25 #include "RCSSeparateResponse.h"
26 #include "InterfaceHandler.h"
27 #include "ResourceAttributesConverter.h"
29 #include "OCPlatform.h"
32 using namespace std::placeholders;
34 using namespace OIC::Service;
37 typedef OCStackResult (*registerResource)(OCResourceHandle&, string&, const string&, const string&,
38 EntityHandler, uint8_t );
40 typedef OCStackResult (*NotifyAllObservers)(OCResourceHandle);
42 constexpr char RESOURCE_URI[]{ "a/test" };
43 constexpr char RESOURCE_TYPE[]{ "resourcetype" };
44 constexpr char KEY[]{ "key" };
45 constexpr char CUSTOM_INTERFACE[]{ "oic.if.custom" };
46 constexpr int VALUE{ 100 };
48 TEST(ResourceObjectBuilderCreateTest, ThrowIfUriIsInvalid)
50 ASSERT_THROW(RCSResourceObject::Builder("", "", "").build(), RCSPlatformException);
53 class ResourceObjectBuilderTest: public TestWithMock
58 TestWithMock::SetUp();
60 mocks.OnCallFuncOverload(static_cast< registerResource >(OCPlatform::registerResource))
65 TEST_F(ResourceObjectBuilderTest, RegisterResourceWhenCallCreate)
67 mocks.ExpectCallFuncOverload(static_cast< registerResource >(OCPlatform::registerResource))
70 RCSResourceObject::Builder(RESOURCE_URI, RESOURCE_TYPE, "").build();
73 TEST_F(ResourceObjectBuilderTest, ResourceServerHasPropertiesSetByBuilder)
75 auto serverResource = RCSResourceObject::Builder(RESOURCE_URI, RESOURCE_TYPE, "").
76 setDiscoverable(false).setObservable(true).build();
78 EXPECT_FALSE(serverResource->isDiscoverable());
79 EXPECT_TRUE(serverResource->isObservable());
82 TEST_F(ResourceObjectBuilderTest, ResourceServerHasAttrsSetByBuilder)
84 RCSResourceAttributes attrs;
87 auto serverResource = RCSResourceObject::Builder(RESOURCE_URI, RESOURCE_TYPE, "").
88 setAttributes(attrs).build();
90 RCSResourceObject::LockGuard lock{ serverResource, RCSResourceObject::AutoNotifyPolicy::NEVER };
91 EXPECT_EQ(attrs, serverResource->getAttributes());
94 TEST_F(ResourceObjectBuilderTest, TypesAddedInBuilderWillBeBound)
97 mocks.OnCallFunc(OCPlatform::bindTypeToResource).Do(
98 [&count](const OCResourceHandle&, const std::string&)
105 auto serverResource = RCSResourceObject::Builder(RESOURCE_URI, RESOURCE_TYPE, "").
106 addType("1").addType("2").build();
111 TEST_F(ResourceObjectBuilderTest, InterfaceAddedInBuilderWillBeBound)
114 mocks.OnCallFunc(OCPlatform::bindInterfaceToResource).Do(
115 [&count](const OCResourceHandle&, const std::string&)
122 auto serverResource = RCSResourceObject::Builder(RESOURCE_URI, RESOURCE_TYPE, "").
123 addInterface("1").addInterface("2").build();
128 class ResourceObjectTest: public TestWithMock
131 RCSResourceObject::Ptr server;
136 TestWithMock::SetUp();
140 server = RCSResourceObject::Builder(RESOURCE_URI, RESOURCE_TYPE, "").build();
142 initResourceObject();
145 virtual void initMocks()
147 mocks.OnCallFuncOverload(static_cast< registerResource >(OCPlatform::registerResource)).
150 mocks.OnCallFunc(OCPlatform::unregisterResource).Return(OC_STACK_OK);
153 virtual void initResourceObject() {
154 server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::NEVER);
158 TEST_F(ResourceObjectTest, AccessAttributesWithLock)
161 RCSResourceObject::LockGuard lock{ server };
162 auto& attr = server->getAttributes();
166 ASSERT_EQ(VALUE, server->getAttribute<int>(KEY));
169 TEST_F(ResourceObjectTest, ThrowIfTryToAccessAttributesWithoutGuard)
171 ASSERT_THROW(server->getAttributes(), NoLockException);
174 TEST_F(ResourceObjectTest, SettingAttributesWithinGuardDoesntCauseDeadLock)
177 RCSResourceObject::LockGuard guard{ server };
178 server->setAttribute(KEY, VALUE);
181 ASSERT_EQ(VALUE, server->getAttribute<int>(KEY));
184 TEST_F(ResourceObjectTest, SettingNestedAttributesIsSameToGettingNestedAttributes)
186 RCSResourceAttributes lightAttributes;
188 lightAttributes["red"]=50;
189 lightAttributes["blue"]=100;
190 lightAttributes["green"]=150;
192 server->setAttribute(KEY, lightAttributes);
194 ASSERT_EQ(lightAttributes, server->getAttribute<RCSResourceAttributes>(KEY));
197 TEST_F(ResourceObjectTest, SettingNestedVectorAttributesIsSameToGettingNestedVectorAttributes)
199 vector<int> arr11 = {0,1}, arr12 = {4,5}, arr13 ={7,8};
200 vector<vector<int>> arr21 = { arr11, arr12 }, arr22 = { arr12, arr13 };
201 vector<vector<vector<int>>> arr31={ arr21, arr22 };
203 server->setAttribute(KEY, arr31);
205 ASSERT_EQ(arr31, server->getAttributeValue(KEY));
208 TEST_F(ResourceObjectTest, ThrowIfResourceToBindIsInvalid)
210 ASSERT_THROW(server->bindResource(server), RCSInvalidParameterException);
213 TEST_F(ResourceObjectTest, ThrowIfBindResourceFailed)
215 mocks.OnCallFunc(OCBindResource).Return(OC_STACK_ERROR);
217 ASSERT_THROW(server->bindResource(
218 RCSResourceObject::Builder("a/temp", RESOURCE_TYPE, "").build()), RCSPlatformException);
221 TEST_F(ResourceObjectTest, ThrowIfResourceToUnbindIsInvalid)
223 ASSERT_THROW(server->unbindResource(server), RCSInvalidParameterException);
226 TEST_F(ResourceObjectTest, BoundResourceCanBeRetrieved)
228 mocks.OnCallFunc(OCBindResource).Return(OC_STACK_OK);
230 auto boundResource = RCSResourceObject::Builder("a/temp", RESOURCE_TYPE, "").build();
231 server->bindResource(boundResource);
233 ASSERT_EQ(boundResource, server->getBoundResources()[0]);
237 class AutoNotifyTest: public ResourceObjectTest
242 mocks.OnCallFuncOverload(static_cast< NotifyAllObservers >(
243 OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
246 virtual void initResourceObject() {
251 TEST_F(AutoNotifyTest, DefalutAutoNotifyPolicyIsUpdated)
253 ASSERT_EQ(RCSResourceObject::AutoNotifyPolicy::UPDATED, server->getAutoNotifyPolicy());
256 TEST_F(AutoNotifyTest, AutoNotifyPolicyCanBeSet)
258 server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::NEVER);
260 ASSERT_EQ(RCSResourceObject::AutoNotifyPolicy::NEVER, server->getAutoNotifyPolicy());
263 TEST_F(AutoNotifyTest, WithUpdatedPolicy_NeverBeNotifiedIfAttributeIsNotChanged)
265 server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
266 server->setAttribute(KEY, VALUE);
268 mocks.NeverCallFuncOverload(static_cast< NotifyAllObservers >(
269 OC::OCPlatform::notifyAllObservers));
271 server->setAttribute(KEY, VALUE);
274 TEST_F(AutoNotifyTest, WithUpdatedPolicy_WillBeNotifiedIfAttributeIsChanged)
276 server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
277 server->setAttribute(KEY, VALUE);
279 mocks.ExpectCallFuncOverload(static_cast< NotifyAllObservers >(
280 OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
282 server->setAttribute(KEY, VALUE + 1);
285 TEST_F(AutoNotifyTest, WithUpdatedPolicy_WillBeNotifiedIfValueIsAdded)
287 constexpr char newKey[]{ "newKey" };
288 server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
290 mocks.ExpectCallFuncOverload(static_cast< NotifyAllObservers >(
291 OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
293 server->setAttribute(newKey, VALUE);
296 TEST_F(AutoNotifyTest, WithNeverPolicy_NeverBeNotifiedEvenIfAttributeIsChanged)
298 server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::NEVER);
300 mocks.NeverCallFuncOverload(static_cast< NotifyAllObservers >(
301 OC::OCPlatform::notifyAllObservers));
303 RCSResourceObject::LockGuard lock{ server };
304 server->setAttribute(KEY, VALUE);
307 TEST_F(AutoNotifyTest, WithUpdatePolicy_WillBeNotifiedIfAttributeIsDeleted)
309 server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
310 server->setAttribute(KEY, VALUE);
312 mocks.ExpectCallFuncOverload(static_cast< NotifyAllObservers >(
313 OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
315 server->removeAttribute(KEY);
318 class AutoNotifyWithGuardTest: public AutoNotifyTest
322 TEST_F(AutoNotifyWithGuardTest, GuardFollowsServerPolicyByDefault)
324 server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::UPDATED);
326 mocks.ExpectCallFuncOverload(static_cast< NotifyAllObservers >(
327 OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
329 RCSResourceObject::LockGuard guard{ server };
330 server->setAttribute(KEY, VALUE);
333 TEST_F(AutoNotifyWithGuardTest, GuardCanOverridePolicy)
335 server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::ALWAYS);
337 mocks.NeverCallFuncOverload(static_cast< NotifyAllObservers >(
338 OC::OCPlatform::notifyAllObservers));
340 RCSResourceObject::LockGuard guard{ server, RCSResourceObject::AutoNotifyPolicy::NEVER };
341 server->getAttributes()[KEY] = VALUE;
344 TEST_F(AutoNotifyWithGuardTest, GuardInvokesNotifyWhenDestroyed)
346 server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::NEVER);
348 mocks.ExpectCallFuncOverload(static_cast< NotifyAllObservers >(
349 OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
352 RCSResourceObject::LockGuard guard{ server, RCSResourceObject::AutoNotifyPolicy::ALWAYS };
353 server->setAttribute(KEY, VALUE);
356 mocks.NeverCallFuncOverload(static_cast< NotifyAllObservers >(
357 OC::OCPlatform::notifyAllObservers)).Return(OC_STACK_OK);
359 server->setAttribute(KEY, VALUE);
362 class ResourceObjectHandlingRequestTest: public ResourceObjectTest
365 EntityHandler handler;
367 static constexpr OCRequestHandle fakeRequestHandle =
368 reinterpret_cast<OCRequestHandle>(0x1234);
369 static constexpr OCResourceHandle fakeResourceHandle =
370 reinterpret_cast<OCResourceHandle>(0x4321);
373 OCResourceRequest::Ptr createRequest(OCMethod method = OC_REST_GET, OCRepresentation ocRep =
374 OCRepresentation{}, const string& interface="")
376 auto request = make_shared<OCResourceRequest>();
378 OCEntityHandlerRequest ocEntityHandlerRequest;
379 memset(&ocEntityHandlerRequest, 0, sizeof(OCEntityHandlerRequest));
380 OC::MessageContainer mc;
382 mc.addRepresentation(ocRep);
384 ocEntityHandlerRequest.requestHandle = fakeRequestHandle;
385 ocEntityHandlerRequest.resource = fakeResourceHandle;
386 ocEntityHandlerRequest.method = method;
387 ocEntityHandlerRequest.payload = reinterpret_cast<OCPayload*>(mc.getPayload());
389 if(!interface.empty())
391 const string query = string("if=" + interface);
392 ocEntityHandlerRequest.query = const_cast<char *> (query.c_str());
395 formResourceRequest(OC_REQUEST_FLAG, &ocEntityHandlerRequest, request);
401 OCStackResult registerResourceFake(OCResourceHandle&, string&, const string&,
402 const string&, EntityHandler handler, uint8_t)
404 this->handler = handler;
410 mocks.OnCallFuncOverload(
411 static_cast<registerResource>(OCPlatform::registerResource)).Do(
412 bind(&ResourceObjectHandlingRequestTest::registerResourceFake,
413 this, _1, _2, _3, _4, _5, _6));
414 mocks.OnCallFunc(OCPlatform::unregisterResource).Return(OC_STACK_OK);
418 TEST_F(ResourceObjectHandlingRequestTest, CallSendResponseWhenReceiveRequest)
420 mocks.ExpectCallFunc(OCPlatform::sendResponse).Return(OC_STACK_OK);
422 ASSERT_EQ(OC_EH_OK, handler(createRequest()));
425 TEST_F(ResourceObjectHandlingRequestTest, ReturnErrorCodeWhenSendResponseFailed)
427 mocks.ExpectCallFunc(OCPlatform::sendResponse).Return(OC_STACK_ERROR);
429 ASSERT_EQ(OC_EH_ERROR, handler(createRequest()));
432 TEST_F(ResourceObjectHandlingRequestTest, SendResponseWithSameHandlesPassedByRequest)
434 mocks.ExpectCallFunc(OCPlatform::sendResponse).Match(
435 [](const shared_ptr<OCResourceResponse> response)
437 return response->getRequestHandle() == fakeRequestHandle &&
438 response->getResourceHandle() == fakeResourceHandle;
440 ).Return(OC_STACK_OK);
442 ASSERT_EQ(OC_EH_OK, handler(createRequest()));
445 TEST_F(ResourceObjectHandlingRequestTest, SendResponseWithRCSResponseResults)
447 constexpr int errorCode{ 1999 };
449 server->setGetRequestHandler(
450 [](const RCSRequest&, RCSResourceAttributes&) -> RCSGetResponse
452 return RCSGetResponse::create(errorCode);
456 mocks.ExpectCallFunc(OCPlatform::sendResponse).Match(
457 [](const shared_ptr<OCResourceResponse> response)
459 return response->getErrorCode() == errorCode;
461 ).Return(OC_STACK_OK);
463 ASSERT_EQ(OC_EH_OK, handler(createRequest()));
466 TEST_F(ResourceObjectHandlingRequestTest, SendSetResponseWithCustomAttrs)
468 constexpr int errorCode{ 1999 };
469 constexpr char value[]{ "VALUE" };
471 server->setSetRequestHandler(
472 [](const RCSRequest&, RCSResourceAttributes&) -> RCSSetResponse
474 RCSResourceAttributes attrs;
476 return RCSSetResponse::create(attrs, errorCode);
480 mocks.ExpectCallFunc(OCPlatform::sendResponse).Match(
481 [](const shared_ptr<OCResourceResponse> response)
483 return value == response->getResourceRepresentation()[KEY].getValue<std::string>()
484 && response->getErrorCode() == errorCode;
486 ).Return(OC_STACK_OK);
488 ASSERT_EQ(OC_EH_OK, handler(createRequest(OC_REST_POST)));
491 TEST_F(ResourceObjectHandlingRequestTest, SeparateResponseIsSlowResponse)
493 server->setGetRequestHandler(
494 [](const RCSRequest&, RCSResourceAttributes&) -> RCSGetResponse
496 return RCSGetResponse::separate();
500 ASSERT_EQ(OC_EH_SLOW, handler(createRequest()));
503 TEST_F(ResourceObjectHandlingRequestTest, SetMethodOfSeparateResponseInvokesSendResponse)
506 server->setGetRequestHandler(
507 [&aRequest](const RCSRequest& request, RCSResourceAttributes&) -> RCSGetResponse
510 return RCSGetResponse::separate();
513 handler(createRequest(OC_REST_GET));
515 mocks.ExpectCallFunc(OCPlatform::sendResponse).Return(OC_STACK_OK);
517 RCSSeparateResponse(aRequest).set();
520 TEST_F(ResourceObjectHandlingRequestTest, SetMethodOfSeparateResponseThrowsIfTheResourceIsDestroyed)
523 server->setGetRequestHandler(
524 [&aRequest](const RCSRequest& request, RCSResourceAttributes&) -> RCSGetResponse
527 return RCSGetResponse::separate();
530 handler(createRequest(OC_REST_GET));
532 RCSSeparateResponse resp(aRequest);
536 EXPECT_THROW(resp.set(), RCSBadRequestException);
539 static bool checkResponse(const OCRepresentation& ocRep, const RCSResourceAttributes& rcsAttr,
540 const std::vector<std::string>& interfaces,
541 const std::vector<std::string>& resourceTypes, const std::string& resourceUri)
543 return resourceUri == ocRep.getUri() &&
544 interfaces == ocRep.getResourceInterfaces() &&
545 resourceTypes == ocRep.getResourceTypes() &&
546 rcsAttr == ResourceAttributesConverter::fromOCRepresentation(ocRep);
549 static bool compareResponse(const OCRepresentation& ocRep1, const OCRepresentation& ocRep2)
551 return ocRep1.getUri() == ocRep2.getUri() &&
552 ocRep1.getResourceInterfaces() == ocRep2.getResourceInterfaces() &&
553 ocRep1.getResourceTypes() == ocRep2.getResourceTypes() &&
554 ResourceAttributesConverter::fromOCRepresentation(ocRep1) ==
555 ResourceAttributesConverter::fromOCRepresentation(ocRep2);
558 class ResourceObjectInterfaceHandlerTest: public ResourceObjectHandlingRequestTest
561 void initServer(vector<string> interfaces,
562 const std::string& defaultInterface = BASELINE_INTERFACE)
564 auto initBuilder = RCSResourceObject::Builder(RESOURCE_URI, RESOURCE_TYPE,
567 for(const auto& itf : interfaces)
569 initBuilder.addInterface(itf);
572 RCSResourceAttributes rcsAttr;
574 initBuilder.setAttributes(rcsAttr);
575 initBuilder.setDefaultInterface(defaultInterface);
577 server = initBuilder.build();
578 server->setAutoNotifyPolicy(RCSResourceObject::AutoNotifyPolicy::NEVER);
579 server->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::ACCEPTANCE);
586 TestWithMock::SetUp();
593 ResourceObjectHandlingRequestTest::initMocks();
595 mocks.OnCallFunc(OCPlatform::bindInterfaceToResource).Return(OC_STACK_OK);
599 TEST_F(ResourceObjectInterfaceHandlerTest, GetResponseForBaselineContainsAllPropertiesOfServer)
601 initServer({BASELINE_INTERFACE});
603 OCRepresentation ocRep;
605 mocks.ExpectCallFunc(OCPlatform::sendResponse).Match(
606 [=](const shared_ptr<OCResourceResponse> response)
608 RCSResourceObject::LockGuard guard{ server };
610 return checkResponse(response->getResourceRepresentation(),
611 server->getAttributes(), server->getInterfaces(), server->getTypes(),
615 ).Return(OC_STACK_OK);
617 handler(createRequest(OC_REST_GET, ocRep, BASELINE_INTERFACE));
620 TEST_F(ResourceObjectInterfaceHandlerTest, SetResponseForActuatorContainsOnlyRequestedAttributes)
622 initServer({ACTUATOR_INTERFACE});
624 OCRepresentation ocRep;
627 mocks.ExpectCallFunc(OCPlatform::sendResponse).Match(
628 [&ocRep](const shared_ptr<OCResourceResponse> response)
630 return checkResponse(response->getResourceRepresentation(),
631 ResourceAttributesConverter::fromOCRepresentation(ocRep), {}, {}, "");
633 ).Return(OC_STACK_OK);
635 handler(createRequest(OC_REST_POST, ocRep, ACTUATOR_INTERFACE));
638 TEST_F(ResourceObjectInterfaceHandlerTest, SetResponseForBaselineContainsAppliedAttributes)
640 initServer({BASELINE_INTERFACE});
642 OCRepresentation ocRep;
643 ocRep["NEWKEY"] = std::string("NEWVALUE");
645 mocks.ExpectCallFunc(OCPlatform::sendResponse).Match(
646 [=](const shared_ptr<OCResourceResponse> response)
648 RCSResourceObject::LockGuard guard{ server };
650 return checkResponse(response->getResourceRepresentation(),
651 server->getAttributes(), server->getInterfaces(), server->getTypes(),
654 ).Return(OC_STACK_OK);
656 handler(createRequest(OC_REST_POST, ocRep, BASELINE_INTERFACE));
659 TEST_F(ResourceObjectInterfaceHandlerTest, GetResponseForCustomEqualsResponseForDefault)
661 initServer({CUSTOM_INTERFACE});
663 OCRepresentation ocRep;
664 OCRepresentation repArray[2];
667 mocks.OnCallFunc(OCPlatform::sendResponse).Do(
668 [&repArray, &cnt](const shared_ptr<OCResourceResponse> response)
670 repArray[cnt++] = response->getResourceRepresentation();
675 handler(createRequest(OC_REST_GET, ocRep, CUSTOM_INTERFACE));
676 handler(createRequest(OC_REST_GET, ocRep, server->getDefaultInterface()));
679 EXPECT_TRUE(compareResponse(repArray[0], repArray[1]));
682 TEST_F(ResourceObjectInterfaceHandlerTest, SetRequestForSensorGotNoHandler)
684 initServer({SENSOR_INTERFACE});
686 OCRepresentation ocRep;
689 EXPECT_EQ(OC_EH_ERROR, handler(createRequest(OC_REST_POST, ocRep, SENSOR_INTERFACE)));
692 TEST_F(ResourceObjectInterfaceHandlerTest, ThrowIfDefaultInterfaceIsInvalid)
694 auto builder = RCSResourceObject::Builder(RESOURCE_URI, RESOURCE_TYPE, BASELINE_INTERFACE);
696 ASSERT_THROW(builder.setDefaultInterface(ACTUATOR_INTERFACE), RCSBadRequestException);
699 TEST_F(ResourceObjectInterfaceHandlerTest, SettingDefaultInterfaceEqualsGetDefaultInterface)
701 initServer({SENSOR_INTERFACE}, BASELINE_INTERFACE);
703 EXPECT_EQ(BASELINE_INTERFACE, server->getDefaultInterface());
708 class SetRequestHandlerPolicyTest: public ResourceObjectHandlingRequestTest
711 typedef OCStackResult (*SendResponse)(std::shared_ptr<OCResourceResponse>);
714 OCRepresentation createOCRepresentation()
716 OCRepresentation ocRep;
723 ResourceObjectHandlingRequestTest::initMocks();
724 mocks.OnCallFunc(OCPlatform::sendResponse).Return(OC_STACK_OK);
728 TEST_F(SetRequestHandlerPolicyTest, DefalutSetRequestHandlerPolicyIsNever)
730 ASSERT_EQ(RCSResourceObject::SetRequestHandlerPolicy::NEVER,
731 server->getSetRequestHandlerPolicy());
734 TEST_F(SetRequestHandlerPolicyTest, SetRequestHandlerPolicyCanBeSet)
736 server->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::ACCEPTANCE);
738 ASSERT_EQ(RCSResourceObject::SetRequestHandlerPolicy::ACCEPTANCE,
739 server->getSetRequestHandlerPolicy());
742 TEST_F(SetRequestHandlerPolicyTest, WithNeverPolicy_DeniedIfKeyIsNew)
744 server->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::NEVER);
746 handler(createRequest(OC_REST_POST, createOCRepresentation()));
748 RCSResourceObject::LockGuard guard{ server };
749 ASSERT_FALSE(server->getAttributes().contains(KEY));
752 TEST_F(SetRequestHandlerPolicyTest, WithAcceptancePolicy_AcceptedEvenIfKeyIsNew)
754 server->setSetRequestHandlerPolicy(RCSResourceObject::SetRequestHandlerPolicy::ACCEPTANCE);
756 handler(createRequest(OC_REST_POST, createOCRepresentation()));
758 RCSResourceObject::LockGuard guard{ server };
759 ASSERT_TRUE(server->getAttributes().contains(KEY));
764 class ResourceObjectSynchronizationTest: public ResourceObjectHandlingRequestTest
768 static void withLock(RCSResourceObject::Ptr serverResource, int count)
770 for (int i=0; i<count; ++i)
772 RCSResourceObject::LockGuard lock{ serverResource };
774 auto& attrs = serverResource->getAttributes();
776 attrs[KEY] = attrs[KEY].get<int>() + 1;
780 static void withSetter(RCSResourceObject::Ptr serverResource, int count)
782 for (int i=0; i<count; ++i)
784 RCSResourceObject::LockGuard lock{ serverResource };
786 serverResource->setAttribute(KEY, serverResource->getAttribute<int>(KEY) + 1);
791 TEST_F(ResourceObjectSynchronizationTest, MultipleAccessToServerResource)
794 vector<thread> threads;
796 server->setAttribute(KEY, 0);
798 for (int i = 20; i >= 0; --i) {
799 int count = 5000 + i * 100;
800 threads.push_back(thread { withLock, server, count });
804 for (int i = 20; i >= 0; --i) {
805 int count = 5000 + i * 100;
806 threads.push_back(thread { withSetter, server, count });
810 for (auto& t : threads)
815 ASSERT_EQ(expected, server->getAttribute<int>(KEY));
818 TEST_F(ResourceObjectSynchronizationTest, MultipleAccessToServerResourceWithRequests)
821 vector<thread> threads;
823 mocks.OnCallFunc(OCPlatform::sendResponse).Return(OC_STACK_OK);
825 server->setAttribute(KEY, 0);
827 for (int i = 20; i >= 0; --i) {
828 int count = 5000 + i * 100;
829 threads.push_back(thread{ withLock, server, count });
833 for (int i = 20; i >= 0; --i) {
834 int count = 5000 + i * 100;
835 threads.push_back(thread{ withSetter, server, count });
839 threads.push_back(thread{
842 for (int i=0; i<10000; ++i)
844 if (i % 5 == 0) handler(createRequest(OC_REST_OBSERVE));
845 handler(createRequest((i & 1) ? OC_REST_GET : OC_REST_POST));
850 for (auto& t : threads)
855 ASSERT_EQ(expected, server->getAttribute<int>(KEY));
860 class AttributeUpdatedListenerTest: public ResourceObjectHandlingRequestTest
863 typedef OCStackResult (*SendResponse)(std::shared_ptr<OCResourceResponse>);
866 OCRepresentation createOCRepresentation(void)
868 OCRepresentation ocRep;
876 ResourceObjectHandlingRequestTest::SetUp();
877 mocks.OnCallFunc(OCPlatform::sendResponse).Return(OC_STACK_OK);
879 server->setAttribute(KEY, 0);
883 class AttributeUpdatedListener
886 virtual void onUpdated(const OIC::Service::RCSResourceAttributes::Value&,
887 const OIC::Service::RCSResourceAttributes::Value&)=0;
889 virtual ~AttributeUpdatedListener() {}
893 TEST_F(AttributeUpdatedListenerTest, RemoveListenerReturnsFalseIfListenerIsNotAdded)
895 ASSERT_FALSE(server->removeAttributeUpdatedListener(KEY));
898 TEST_F(AttributeUpdatedListenerTest, RemoveListenerReturnsTrueIfListenerIsAdded)
900 auto listener = mocks.Mock< AttributeUpdatedListener >();
902 server->addAttributeUpdatedListener(KEY,
903 std::bind(&AttributeUpdatedListener::onUpdated, listener, _1, _2));
905 ASSERT_TRUE(server->removeAttributeUpdatedListener(KEY));
908 TEST_F(AttributeUpdatedListenerTest, AddListenerRunsAddedFunction)
910 auto listener = mocks.Mock< AttributeUpdatedListener >();
912 server->addAttributeUpdatedListener(KEY,
913 std::bind(&AttributeUpdatedListener::onUpdated, listener, _1, _2));
915 mocks.ExpectCall(listener, AttributeUpdatedListener::onUpdated);
917 handler(createRequest(OC_REST_POST, createOCRepresentation()));
920 TEST_F(AttributeUpdatedListenerTest, ListenerWithSameKeyOverridesPreviousOne)
922 auto first = mocks.Mock< AttributeUpdatedListener >();
923 auto second = mocks.Mock< AttributeUpdatedListener >();
925 mocks.NeverCall(first, AttributeUpdatedListener::onUpdated);
926 mocks.ExpectCall(second, AttributeUpdatedListener::onUpdated);
928 server->addAttributeUpdatedListener(KEY,
929 std::bind(&AttributeUpdatedListener::onUpdated, first, _1, _2));
930 server->addAttributeUpdatedListener(KEY,
931 std::bind(&AttributeUpdatedListener::onUpdated, second, _1, _2));
933 handler(createRequest(OC_REST_POST, createOCRepresentation()));
936 TEST_F(AttributeUpdatedListenerTest, RemovedListenerNotBeInvoked)
938 auto listener = mocks.Mock< AttributeUpdatedListener >();
939 server->addAttributeUpdatedListener(KEY,
940 std::bind(&AttributeUpdatedListener::onUpdated, listener, _1, _2));
942 mocks.NeverCall(listener, AttributeUpdatedListener::onUpdated);
944 server->removeAttributeUpdatedListener(KEY);
946 handler(createRequest(OC_REST_POST, createOCRepresentation()));