fixed zone issue
[profile/ivi/automotive-message-broker.git] / plugins / testplugin / testplugin.cpp
1 /*
2         Copyright (C) 2012  Intel Corporation
3
4         This library is free software; you can redistribute it and/or
5         modify it under the terms of the GNU Lesser General Public
6         License as published by the Free Software Foundation; either
7         version 2.1 of the License, or (at your option) any later version.
8
9         This library is distributed in the hope that it will be useful,
10         but WITHOUT ANY WARRANTY; without even the implied warranty of
11         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12         Lesser General Public License for more details.
13
14         You should have received a copy of the GNU Lesser General Public
15         License along with this library; if not, write to the Free Software
16         Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18
19
20 #include <iostream>
21 #include <boost/assert.hpp>
22 #include <boost/lexical_cast.hpp>
23 #include <glib.h>
24 #include <sstream>
25 //#include <json-glib/json-glib.h>
26 #include <listplusplus.h>
27 #include <vehicleproperty.h>
28 #include <abstractpropertytype.h>
29 #include "debugout.h"
30 #include "timestamp.h"
31 #include "testplugin.h"
32 #define __SMALLFILE__ std::string(__FILE__).substr(std::string(__FILE__).rfind("/")+1)
33 AbstractRoutingEngine *m_re;
34
35 #define TEST(success)   g_assert((success));
36 const std::string TestProptertyName1 = "TestPropertyName1";
37 const std::string TestProptertyName2 = "TestPropertyName2";
38
39 //std::list<ObdPid*> Obd2Amb::supportedPidsList;
40
41 void testBooleanToStringFromString()
42 {
43         BasicPropertyType<bool> boolean(true);
44         std::string isTrue = boolean.toString();
45         boolean.fromString(boolean.toString());
46         std::string isTrue2 = boolean.toString();
47
48         g_assert(isTrue == isTrue2);
49 }
50
51 bool beginsWith(std::string a, std::string b)
52 {
53         return (a.compare(0, b.length(), b) == 0);
54 }
55
56 /**
57  * Tests Core's methods:
58  * * setSupported
59  * * supported
60  * * sourcesForProperty
61  * * getPropertyInfo
62  */
63
64 bool TestPlugin::testCoreSetSupported()
65 {
66         PropertyList supported(routingEngine->supported());
67         TEST(contains(supported,TestProptertyName1) == false);
68         std::vector<std::string> sources(routingEngine->sourcesForProperty(TestProptertyName1));
69         TEST(contains(sources,uuid()) == false);
70
71         // if we were registered in Core, it will ask us and we will return it valid, but we haven't registered yet
72         TEST(routingEngine->getPropertyInfo(TestProptertyName1, uuid()).isValid() == false);
73
74         //
75         // CALL setSupported
76         //
77         routingEngine->updateSupported(m_supportedProperties, PropertyList(), nullptr);// invalid input
78         TEST(routingEngine->getPropertyInfo(TestProptertyName1, uuid()).isValid() == false);
79
80         // valid call
81         routingEngine->updateSupported(m_supportedProperties, PropertyList(), this);// we are register as source from now
82
83         TEST(routingEngine->getPropertyInfo(TestProptertyName1, uuid()).isValid() == true);
84         Zone::ZoneList zones(routingEngine->getPropertyInfo(TestProptertyName1, uuid()).zones());
85         TEST(contains(zones, Zone::LeftSide) == true);
86
87         supported = routingEngine->supported();
88         TEST(contains(supported,TestProptertyName1) == true);
89         TEST(contains(supported,TestProptertyName2) == true);
90         TEST(contains(supported,VehicleProperty::ClutchStatus) == false);
91
92         sources = routingEngine->sourcesForProperty(TestProptertyName1);
93         TEST(contains(sources,uuid()) == true);
94
95         TEST(routingEngine->getPropertyInfo(TestProptertyName2, uuid()).isValid() == true);
96         zones = routingEngine->getPropertyInfo(TestProptertyName2, uuid()).zones();
97         TEST(contains(zones,Zone::FrontSide) == true);
98
99         return true;
100 }
101
102 /**
103  * Tests Core's methods:
104  * * unregisterSink
105  * * registerSink
106  * * sourcesForProperty
107  * * subscribeToProperty - 2 versions
108  * * unsubscribeToProperty
109  */
110
111 bool TestPlugin::testSubscription()
112 {
113         int oldSubscriptionsToSupportedCounter = subscriptionsToSupportedCounter;
114         int oldSubscriptionsToUnsupportedCounter = subscriptionsToUnsupportedCounter;
115         int oldUnsubscriptionsToSupportedCounter= unsubscriptionsToSupportedCounter;
116         int oldUnsubscriptionsToUnsupportedCounter = unsubscriptionsToUnsupportedCounter;
117
118         // ! subscription works without having sink registered ! so there is no need to test
119         // routingEngine->registerSink(this) and routingEngine->unregisterSink(this)
120         routingEngine->unregisterSink(this);
121         routingEngine->registerSink(this);
122
123         // VehicleProperty::ClutchStatus doesn't exist
124         TEST(routingEngine->subscribeToProperty(VehicleProperty::ClutchStatus, uuid(), this) == false);
125         TEST(oldSubscriptionsToSupportedCounter == subscriptionsToSupportedCounter);
126         TEST(oldSubscriptionsToUnsupportedCounter == subscriptionsToUnsupportedCounter);
127
128         // TestProptertyName1 exists in our testplugin
129         TEST(routingEngine->subscribeToProperty(TestProptertyName1, uuid(), this) == true);
130         TEST(++oldSubscriptionsToSupportedCounter == subscriptionsToSupportedCounter);
131         TEST(oldSubscriptionsToUnsupportedCounter == subscriptionsToUnsupportedCounter);
132
133         TEST(routingEngine->subscribeToProperty(TestProptertyName1, "", this) == false);
134         TEST(oldSubscriptionsToSupportedCounter == subscriptionsToSupportedCounter);
135         TEST(oldSubscriptionsToUnsupportedCounter == subscriptionsToUnsupportedCounter);
136
137         // "other" source means no subscription callback in our plugin
138         TEST(routingEngine->subscribeToProperty(TestProptertyName1, "other", this) == false);
139         TEST(oldSubscriptionsToSupportedCounter == subscriptionsToSupportedCounter);
140         TEST(oldSubscriptionsToUnsupportedCounter == subscriptionsToUnsupportedCounter);
141
142         // we have subscribed TestProptertyName1 and not subscribed TestProptertyName2
143         int oldSupportedPropertyChanges = supportedPropertyChanges;
144         int oldPropertyChanges = propertyChanges;
145
146         AbstractPropertyType* value = new BasicPropertyType<int>(TestProptertyName1, 22);
147         value->priority = AbstractPropertyType::Instant;
148         routingEngine->updateProperty(value, "");
149         TEST(oldSupportedPropertyChanges == supportedPropertyChanges);
150         TEST(oldPropertyChanges == propertyChanges);
151         routingEngine->updateProperty(value, uuid());
152         TEST(++oldSupportedPropertyChanges == supportedPropertyChanges);
153         TEST(++oldPropertyChanges == propertyChanges);
154         delete value;
155
156         value = new BasicPropertyType<short>(TestProptertyName2, 255);
157         value->priority = AbstractPropertyType::Instant;
158         routingEngine->updateProperty(value, "");
159         TEST(oldSupportedPropertyChanges == supportedPropertyChanges);
160         TEST(oldPropertyChanges == propertyChanges);
161         routingEngine->updateProperty(value, uuid());
162         TEST(oldSupportedPropertyChanges == supportedPropertyChanges);
163         TEST(oldPropertyChanges == propertyChanges);
164         delete value;
165
166         value = new BasicPropertyType<bool>(VehicleProperty::ClutchStatus, true);
167         value->priority = AbstractPropertyType::Instant;
168         routingEngine->updateSupported({VehicleProperty::ClutchStatus},PropertyList(), this);
169
170         class TestSink : public AbstractSink
171         {
172         public:
173                 TestSink(AbstractRoutingEngine* engine, map<string, string> config) : AbstractSink(engine, config) {}
174                 virtual const string uuid() { return "other"; }
175                 virtual void propertyChanged(AbstractPropertyType *value){ ++propertyChanges; }
176                 virtual void supportedChanged(const PropertyList & supportedProperties){};
177
178                 int propertyChanges = 0;
179         };
180
181         //some other sink is subscribed, not this plug-in!
182         TestSink anotherSink(routingEngine, {});
183         TEST(routingEngine->subscribeToProperty(VehicleProperty::ClutchStatus, &anotherSink) == true);
184         TEST(oldSubscriptionsToSupportedCounter == subscriptionsToSupportedCounter);
185         TEST(++oldSubscriptionsToUnsupportedCounter == subscriptionsToUnsupportedCounter);
186         routingEngine->updateProperty(value, uuid());// uuid() != "other" no sink notified
187         TEST(anotherSink.propertyChanges == 1);// one update
188         TEST(oldSupportedPropertyChanges == supportedPropertyChanges);// no updates
189         TEST(oldPropertyChanges == propertyChanges);// no updates
190         TEST(routingEngine->unsubscribeToProperty(VehicleProperty::ClutchStatus, &anotherSink) == true);
191         routingEngine->updateSupported(PropertyList(),{VehicleProperty::ClutchStatus}, this);
192         TEST(oldUnsubscriptionsToSupportedCounter == unsubscriptionsToSupportedCounter);
193         TEST(++oldUnsubscriptionsToUnsupportedCounter == unsubscriptionsToUnsupportedCounter);
194
195
196         /// test lamba subscription:
197
198         TEST (routingEngine->subscribeToProperty(VehicleProperty::VehicleSpeed,[](AbstractPropertyType* value)
199         {
200                 DebugOut(0)<<"lamba subscriptions work!"<<endl;
201                 TEST(value);
202         }) > 0);
203
204         /// change vehiclespeed to trigger subscribe above
205
206         PropertyList s;
207         s.push_back(VehicleProperty::VehicleSpeed);
208
209         routingEngine->updateSupported(s, PropertyList(), this);
210         VehicleProperty::VehicleSpeedType speed(10);
211         speed.priority = AbstractPropertyType::Instant;
212
213         routingEngine->updateProperty(&speed,uuid());
214         routingEngine->updateSupported(PropertyList(), s, this);
215
216         delete value;
217
218         // unsubscription
219
220         // VehicleProperty::ClutchStatus doesn't exist
221         TEST(routingEngine->unsubscribeToProperty(VehicleProperty::ClutchStatus, this) == false);
222         TEST(oldUnsubscriptionsToSupportedCounter == unsubscriptionsToSupportedCounter);
223         TEST(oldUnsubscriptionsToUnsupportedCounter == unsubscriptionsToUnsupportedCounter);
224
225         // TestProptertyName1 exists in our testplugin
226         // subscribed 2x, lets try to unsubscribe 3x
227         // we should get only one unsubscription callback
228         TEST(routingEngine->unsubscribeToProperty(TestProptertyName1, this) == true);
229         TEST(routingEngine->unsubscribeToProperty(TestProptertyName1, this) == false);
230         TEST(routingEngine->unsubscribeToProperty(TestProptertyName1, this) == false);
231         TEST(++oldUnsubscriptionsToSupportedCounter == unsubscriptionsToSupportedCounter);
232         TEST(oldUnsubscriptionsToUnsupportedCounter == unsubscriptionsToUnsupportedCounter);
233
234         // TestProptertyName2 not subscribed
235         TEST(routingEngine->unsubscribeToProperty(TestProptertyName2, this) == false);;
236         TEST(oldUnsubscriptionsToSupportedCounter == unsubscriptionsToSupportedCounter);
237         TEST(oldUnsubscriptionsToUnsupportedCounter == unsubscriptionsToUnsupportedCounter);
238
239         return true;
240 }
241
242 bool TestPlugin::testSetAndGet()
243 {
244         bool replySuccess(false);
245         int replyError(-1);
246         std::string replySignalName("");
247
248         // Invalid request test
249         AsyncSetPropertyRequest requestInvalid;
250         requestInvalid.timeout = 0;
251         AsyncPropertyReply* reply = routingEngine->setProperty(requestInvalid);
252         TEST(reply == nullptr);
253
254         requestInvalid.property = "NotExists";
255         requestInvalid.completed = [&](AsyncPropertyReply* reply)
256         {
257                 replySuccess = reply->success;
258                 replyError = reply->error;
259                 delete reply;
260         };
261
262         reply = routingEngine->setProperty(requestInvalid);
263
264         TEST(replySuccess == false);
265         TEST(replyError == -1);
266
267         AsyncSetPropertyRequest request;
268         request.timeout = 0;
269         request.property = TestProptertyName1;
270         request.zoneFilter = Zone::LeftSide;
271         request.value = VehicleProperty::getPropertyTypeForPropertyNameValue(request.property, "1");
272         request.completed = requestInvalid.completed;
273
274         reply = routingEngine->setProperty(request);
275         delete request.value;
276         request.value = nullptr;
277
278         TEST(replySuccess == true);
279         TEST(replyError == AsyncPropertyReply::NoError);
280 }
281
282 bool TestPlugin::testCoreUpdateSupported()
283 {
284         bool success = false;
285
286         PropertyList toAdd;
287         toAdd.push_back(VehicleProperty::ClutchStatus);
288
289         routingEngine->updateSupported(toAdd,PropertyList(), this);
290
291         PropertyList supported = routingEngine->supported();
292
293         success = contains(supported,VehicleProperty::ClutchStatus);
294
295         PropertyList toRemove = toAdd;
296
297         routingEngine->updateSupported(PropertyList(),toRemove, this);
298
299         supported = routingEngine->supported();
300
301         success &= !contains(supported,VehicleProperty::ClutchStatus);
302
303         return success;
304 }
305
306 void TestPlugin::setConfiguration(map<string, string> config)
307 {
308         //      //Config has been passed, let's start stuff up.
309 }
310
311 TestPlugin::TestPlugin(AbstractRoutingEngine *re, map<string, string> config)
312         : AbstractSource(re, config),
313           m_supportedProperties({TestProptertyName1, TestProptertyName2}),
314           subscriptionsToSupportedCounter(0),
315           subscriptionsToUnsupportedCounter(0),
316           unsubscriptionsToSupportedCounter(0),
317           unsubscriptionsToUnsupportedCounter(0),
318           propertyChanges(0),
319           supportedPropertyChanges(0)
320 {
321
322         DebugOut(0) << "Capabilities: " << endl;
323
324         for(auto prop : VehicleProperty::capabilities())
325         {
326                 DebugOut(0) << prop << endl;
327         }
328
329         DebugOut() << "Testing Core::setSupported... " << endl;
330         testCoreSetSupported();
331
332         DebugOut() << "Testing MapPropertyType... " << endl;
333         MapPropertyType<BasicPropertyType<Zone::Type>,BasicPropertyType<Door::Status>> propmap("something");
334         MapPropertyType<BasicPropertyType<Zone::Type>,BasicPropertyType<Door::Status>> propmaptwo("something");
335         propmap.append(Zone::RearLeft,Door::Ajar);
336         GVariant *var = propmap.toVariant();
337         gsize dictsize = g_variant_n_children(var);
338         //DebugOut() << var << endl;
339         propmaptwo.fromVariant(var);
340
341         g_assert(propmaptwo.toString() == propmap.toString());
342
343         DebugOut() << "Testing ListPropertyType... " << endl;
344         VehicleProperty::TripMetersType* tfirst = new VehicleProperty::TripMetersType();
345         VehicleProperty::TripMetersType* tsecond = new VehicleProperty::TripMetersType();
346         BasicPropertyType<uint16_t> v1(0);
347         BasicPropertyType<uint16_t> v2(5);
348         BasicPropertyType<uint16_t> v3(10);
349         tfirst->append(v1);
350         tfirst->append(v2);
351         tfirst->append(v3);
352         tsecond->fromVariant(tfirst->toVariant());
353
354         g_assert (tfirst->toString() == tsecond->toString());
355
356         testBooleanToStringFromString();
357
358         g_assert (testCoreUpdateSupported());
359
360         testSubscription();
361
362         testSetAndGet();
363 }
364
365 TestPlugin::~TestPlugin()
366 {
367         DebugOut() << "TestPlugin Destructor called!!!"<<endl;
368 }
369
370 PropertyList TestPlugin::supported()
371 {
372         return m_supportedProperties;
373 }
374
375 int TestPlugin::supportedOperations()
376 {
377         return Get | Set;
378 }
379
380 extern "C" AbstractSource * create(AbstractRoutingEngine* routingengine, map<string, string> config)
381 {
382         return new TestPlugin(routingengine, config);
383
384 }
385 const string TestPlugin::uuid()
386 {
387         return "f77af740-f1f8-11e1-aff1-0800200c9a66";
388 }
389 void TestPlugin::subscribeToPropertyChanges(VehicleProperty::Property property)
390 {
391         if(contains(m_supportedProperties, property))
392                 ++subscriptionsToSupportedCounter;
393         else
394                 ++subscriptionsToUnsupportedCounter;
395 }
396
397
398 void TestPlugin::unsubscribeToPropertyChanges(VehicleProperty::Property property)
399 {
400         if(contains(m_supportedProperties, property))
401                 ++unsubscriptionsToSupportedCounter;
402         else
403                 ++unsubscriptionsToUnsupportedCounter;
404 }
405
406
407 void TestPlugin::getPropertyAsync(AsyncPropertyReply *reply)
408 {
409
410 }
411
412 AsyncPropertyReply *TestPlugin::setProperty(AsyncSetPropertyRequest request )
413 {
414         AsyncPropertyReply* reply = new AsyncPropertyReply (request);
415         reply->success = true;
416         reply->error = AsyncPropertyReply::NoError;
417         if(reply->completed)
418                 reply->completed(reply);
419         return reply;
420 }
421
422 PropertyInfo TestPlugin::getPropertyInfo(const VehicleProperty::Property &property)
423 {
424         if(!contains(m_supportedProperties, property))
425                 return PropertyInfo::invalid();
426
427         if(property == TestProptertyName1){
428                 return PropertyInfo(10, {Zone::LeftSide});
429         }
430         else if(property == TestProptertyName2){
431                 return PropertyInfo(30, {Zone::FrontSide});
432         }
433         else{
434                 return PropertyInfo(60, {Zone::None});
435         }
436 }
437
438 void TestPlugin::propertyChanged(AbstractPropertyType *value)
439 {
440         ++propertyChanges;
441         if(value && contains(m_supportedProperties, value->name))
442                 supportedPropertyChanges++;
443
444 }