Imported Upstream version 1.0.0
[platform/upstream/iotivity.git] / service / resource-hosting / src / unittest / ResourceEncapsulationTestSimulator.h
1 //******************************************************************
2 //
3 // Copyright 2015 Samsung Electronics All Rights Reserved.
4 //
5 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
6 //
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
10 //
11 //      http://www.apache.org/licenses/LICENSE-2.0
12 //
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.
18 //
19 //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
20
21 #include <memory>
22 #include <mutex>
23 #include <atomic>
24 #include <condition_variable>
25
26 #include "UnitTestHelper.h"
27
28 #include "RCSDiscoveryManager.h"
29 #include "RCSRemoteResourceObject.h"
30 #include "RCSResourceAttributes.h"
31 #include "RCSAddress.h"
32
33 #include "RequestObject.h"
34
35 using namespace testing;
36 using namespace OIC::Service;
37
38 class ResourceEncapsulationTestSimulator
39         : public std::enable_shared_from_this<ResourceEncapsulationTestSimulator>
40 {
41 public:
42     typedef std::shared_ptr<ResourceEncapsulationTestSimulator> Ptr;
43
44     RCSResourceObject::Ptr server;
45     RCSRemoteResourceObject::Ptr remoteResource;
46
47 private:
48     std::mutex mutexForDiscovery;
49     std::unique_ptr<RCSDiscoveryManager::DiscoveryTask> discoveryTask;
50
51     std::string MULTICASTURI;
52     std::string HOSTED_RESOURCEURI;
53     std::string RESOURCEURI;
54     std::string RESOURCETYPE;
55     std::string RESOURCEINTERFACE;
56     std::string ATTR_KEY;
57     int ATTR_VALUE;
58
59 public:
60     ResourceEncapsulationTestSimulator()
61     :server(nullptr), remoteResource(nullptr),
62      mutexForDiscovery(),
63      MULTICASTURI("/oic/res"),
64      HOSTED_RESOURCEURI("/a/TempHumSensor"),
65      RESOURCEURI("/a/TempHumSensor/hosting"),
66      RESOURCETYPE("resource.hosting"),
67      RESOURCEINTERFACE("oic.if.baseline"),
68      ATTR_KEY("Temperature"),
69      ATTR_VALUE(0)
70     { }
71     ~ResourceEncapsulationTestSimulator()
72     { }
73
74 private:
75     void onDiscoveryResource_Impl(RCSRemoteResourceObject::Ptr resourceObject)
76     {
77         if (remoteResource != nullptr)
78         {
79             return;
80         }
81
82         if (RESOURCEURI.compare(resourceObject->getUri()) != 0)
83         {
84             return;
85         }
86
87         remoteResource = resourceObject;
88         mutexForDiscovery.unlock();
89     }
90
91     static void onDiscoveryResource(RCSRemoteResourceObject::Ptr resourceObject,
92             std::weak_ptr<ResourceEncapsulationTestSimulator> rPtr)
93     {
94         std::shared_ptr<ResourceEncapsulationTestSimulator> ptr = rPtr.lock();
95         if (ptr != nullptr)
96         {
97             ptr->onDiscoveryResource_Impl(resourceObject);
98         }
99     }
100     void waitForDiscovery()
101     {
102         std::chrono::milliseconds interval(100);
103         while(true)
104         {
105             if(mutexForDiscovery.try_lock())
106             {
107                 mutexForDiscovery.unlock();
108                 return;
109             }
110             std::this_thread::sleep_for(interval);
111         }
112     }
113     void WaitForPtrBeingUnique()
114     {
115         while((remoteResource && !remoteResource.unique()) || (server && !server.unique()))
116         {
117             std::this_thread::sleep_for(std::chrono::milliseconds{ 100 });
118         }
119     }
120
121 public:
122     void destroy()
123     {
124         if(server.use_count()) server.reset();
125         if(remoteResource.use_count()) remoteResource.reset();
126         WaitForPtrBeingUnique();
127     }
128     void defaultRunSimulator()
129     {
130         createResource();
131         discoveryResource();
132         waitForDiscovery();
133     }
134
135     void createResource()
136     {
137         server = RCSResourceObject::Builder(RESOURCEURI, RESOURCETYPE, RESOURCEINTERFACE)
138                 .setDiscoverable(true).setObservable(true).build();
139         server->setAttribute(ATTR_KEY, ATTR_VALUE);
140     }
141
142     void discoveryResource()
143     {
144         discoveryResource(RESOURCETYPE);
145     }
146
147     void discoveryResource(std::string & resourceType)
148     {
149         try
150         {
151             discoveryTask = RCSDiscoveryManager::getInstance()->discoverResourceByType(
152                     RCSAddress::multicast(), MULTICASTURI, resourceType,
153                     std::bind(onDiscoveryResource, std::placeholders::_1,
154                         std::weak_ptr<ResourceEncapsulationTestSimulator>(shared_from_this())));
155             mutexForDiscovery.lock();
156         }
157         catch(std::exception & e)
158         {
159             std::cout << "exception : " << e.what() << std::endl;
160         }
161     }
162
163     std::string getServerUri() const
164     {
165         return RESOURCEURI;
166     }
167
168     std::string getHostedServerUri() const
169     {
170         return HOSTED_RESOURCEURI;
171     }
172
173     RCSResourceObject::Ptr getResourceServer() const
174     {
175         return server;
176     }
177  
178     RCSRemoteResourceObject::Ptr getRemoteResource() const
179     {
180         return remoteResource;
181     }
182
183     void ChangeAttributeValue()
184     {
185         std::chrono::milliseconds interval(100);
186         if (server != nullptr)
187             server->setAttribute(ATTR_KEY, ATTR_VALUE + 10);
188         std::this_thread::sleep_for(interval);
189     }
190
191     void ChangeResourceState()
192     {
193         std::chrono::milliseconds interval(400);
194         if (server != nullptr)
195             server = nullptr;
196         std::this_thread::sleep_for(interval);
197     }
198 };