reverted varianttype
[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
69         //
70         // CALL setSupported
71         //
72
73         // valid call
74         routingEngine->updateSupported(m_supportedProperties, PropertyList(), this);
75
76         TEST(routingEngine->getPropertyInfo(TestProptertyName1, uuid()).isValid() == true);
77         Zone::ZoneList zones(routingEngine->getPropertyInfo(TestProptertyName1, uuid()).zones());
78         TEST(contains(zones, Zone::LeftSide) == true);
79
80         supported = routingEngine->supported();
81         TEST(contains(supported, TestProptertyName1) == true);
82         TEST(contains(supported, TestProptertyName2) == true);
83         TEST(contains(supported, VehicleProperty::ClutchStatus) == false);
84
85         std::vector<std::string> sources = routingEngine->sourcesForProperty(TestProptertyName1);
86         TEST(contains(sources,uuid()) == true);
87
88         TEST(routingEngine->getPropertyInfo(TestProptertyName2, uuid()).isValid() == true);
89         zones = routingEngine->getPropertyInfo(TestProptertyName2, uuid()).zones();
90         TEST(contains(zones, Zone::FrontSide) == true);
91
92         return true;
93 }
94
95 /**
96  * Tests Core's methods:
97  * * unregisterSink
98  * * registerSink
99  * * sourcesForProperty
100  * * subscribeToProperty - 2 versions
101  * * unsubscribeToProperty
102  */
103
104 bool TestPlugin::testSubscription()
105 {
106         int oldSubscriptionsToSupportedCounter = subscriptionsToSupportedCounter;
107         int oldSubscriptionsToUnsupportedCounter = subscriptionsToUnsupportedCounter;
108         int oldUnsubscriptionsToSupportedCounter= unsubscriptionsToSupportedCounter;
109         int oldUnsubscriptionsToUnsupportedCounter = unsubscriptionsToUnsupportedCounter;
110
111         // ! subscription works without having sink registered ! so there is no need to test
112         // routingEngine->registerSink(this) and routingEngine->unregisterSink(this)
113         routingEngine->unregisterSink(this);
114         routingEngine->registerSink(this);
115
116         // VehicleProperty::ClutchStatus doesn't exist
117         TEST(routingEngine->subscribeToProperty(VehicleProperty::ClutchStatus, uuid(), this) == false);
118         TEST(oldSubscriptionsToSupportedCounter == subscriptionsToSupportedCounter);
119         TEST(oldSubscriptionsToUnsupportedCounter == subscriptionsToUnsupportedCounter);
120
121         // TestProptertyName1 exists in our testplugin
122         TEST(routingEngine->subscribeToProperty(TestProptertyName1, uuid(), this) == true);
123         TEST(++oldSubscriptionsToSupportedCounter == subscriptionsToSupportedCounter);
124         TEST(oldSubscriptionsToUnsupportedCounter == subscriptionsToUnsupportedCounter);
125
126         TEST(routingEngine->subscribeToProperty(TestProptertyName1, "", this) == false);
127         TEST(oldSubscriptionsToSupportedCounter == subscriptionsToSupportedCounter);
128         TEST(oldSubscriptionsToUnsupportedCounter == subscriptionsToUnsupportedCounter);
129
130         // "other" source means no subscription callback in our plugin
131         TEST(routingEngine->subscribeToProperty(TestProptertyName1, "other", this) == false);
132         TEST(oldSubscriptionsToSupportedCounter == subscriptionsToSupportedCounter);
133         TEST(oldSubscriptionsToUnsupportedCounter == subscriptionsToUnsupportedCounter);
134
135         // we have subscribed TestProptertyName1 and not subscribed TestProptertyName2
136         int oldSupportedPropertyChanges = supportedPropertyChanges;
137         int oldPropertyChanges = propertyChanges;
138
139         AbstractPropertyType* value = new BasicPropertyType<int>(TestProptertyName1, 22);
140         value->priority = AbstractPropertyType::Instant;
141         routingEngine->updateProperty(value, "");
142         TEST(oldSupportedPropertyChanges == supportedPropertyChanges);
143         TEST(oldPropertyChanges == propertyChanges);
144         routingEngine->updateProperty(value, uuid());
145         TEST(++oldSupportedPropertyChanges == supportedPropertyChanges);
146         TEST(++oldPropertyChanges == propertyChanges);
147         delete value;
148
149         value = new BasicPropertyType<short>(TestProptertyName2, 255);
150         value->priority = AbstractPropertyType::Instant;
151         routingEngine->updateProperty(value, "");
152         TEST(oldSupportedPropertyChanges == supportedPropertyChanges);
153         TEST(oldPropertyChanges == propertyChanges);
154         routingEngine->updateProperty(value, uuid());
155         TEST(oldSupportedPropertyChanges == supportedPropertyChanges);
156         TEST(oldPropertyChanges == propertyChanges);
157         delete value;
158
159         value = new BasicPropertyType<bool>(VehicleProperty::ClutchStatus, true);
160         value->priority = AbstractPropertyType::Instant;
161         routingEngine->updateSupported({VehicleProperty::ClutchStatus},PropertyList(), this);
162
163         class TestSink : public AbstractSink
164         {
165         public:
166                 TestSink(AbstractRoutingEngine* engine, map<string, string> config) : AbstractSink(engine, config) {}
167                 virtual const string uuid() { return "other"; }
168                 virtual void propertyChanged(AbstractPropertyType *value){ ++propertyChanges; }
169                 virtual void supportedChanged(const PropertyList & supportedProperties){};
170
171                 int propertyChanges = 0;
172         };
173
174         //some other sink is subscribed, not this plug-in!
175         TestSink anotherSink(routingEngine, {});
176         TEST(routingEngine->subscribeToProperty(VehicleProperty::ClutchStatus, &anotherSink) == true);
177         TEST(oldSubscriptionsToSupportedCounter == subscriptionsToSupportedCounter);
178         TEST(++oldSubscriptionsToUnsupportedCounter == subscriptionsToUnsupportedCounter);
179         routingEngine->updateProperty(value, uuid());// uuid() != "other" no sink notified
180         TEST(anotherSink.propertyChanges == 1);// one update
181         TEST(oldSupportedPropertyChanges == supportedPropertyChanges);// no updates
182         TEST(oldPropertyChanges == propertyChanges);// no updates
183         TEST(routingEngine->unsubscribeToProperty(VehicleProperty::ClutchStatus, &anotherSink) == true);
184         routingEngine->updateSupported(PropertyList(),{VehicleProperty::ClutchStatus}, this);
185         TEST(oldUnsubscriptionsToSupportedCounter == unsubscriptionsToSupportedCounter);
186         TEST(++oldUnsubscriptionsToUnsupportedCounter == unsubscriptionsToUnsupportedCounter);
187
188
189         /// test lamba subscription:
190
191         TEST (routingEngine->subscribeToProperty(VehicleProperty::VehicleSpeed,[](AbstractPropertyType* value)
192         {
193                 DebugOut(0)<<"lamba subscriptions work!"<<endl;
194                 TEST(value);
195         }) > 0);
196
197         /// change vehiclespeed to trigger subscribe above
198
199         PropertyList s;
200         s.push_back(VehicleProperty::VehicleSpeed);
201
202         routingEngine->updateSupported(s, PropertyList(), this);
203         VehicleProperty::VehicleSpeedType speed(10);
204         speed.priority = AbstractPropertyType::Instant;
205
206         routingEngine->updateProperty(&speed,uuid());
207         routingEngine->updateSupported(PropertyList(), s, this);
208
209         delete value;
210
211         // unsubscription
212
213         // VehicleProperty::ClutchStatus doesn't exist
214         TEST(routingEngine->unsubscribeToProperty(VehicleProperty::ClutchStatus, this) == false);
215         TEST(oldUnsubscriptionsToSupportedCounter == unsubscriptionsToSupportedCounter);
216         TEST(oldUnsubscriptionsToUnsupportedCounter == unsubscriptionsToUnsupportedCounter);
217
218         // TestProptertyName1 exists in our testplugin
219         // subscribed 2x, lets try to unsubscribe 3x
220         // we should get only one unsubscription callback
221         TEST(routingEngine->unsubscribeToProperty(TestProptertyName1, this) == true);
222         TEST(routingEngine->unsubscribeToProperty(TestProptertyName1, this) == false);
223         TEST(routingEngine->unsubscribeToProperty(TestProptertyName1, this) == false);
224         TEST(++oldUnsubscriptionsToSupportedCounter == unsubscriptionsToSupportedCounter);
225         TEST(oldUnsubscriptionsToUnsupportedCounter == unsubscriptionsToUnsupportedCounter);
226
227         // TestProptertyName2 not subscribed
228         TEST(routingEngine->unsubscribeToProperty(TestProptertyName2, this) == false);;
229         TEST(oldUnsubscriptionsToSupportedCounter == unsubscriptionsToSupportedCounter);
230         TEST(oldUnsubscriptionsToUnsupportedCounter == unsubscriptionsToUnsupportedCounter);
231
232         return true;
233 }
234
235 bool TestPlugin::testSetAndGet()
236 {
237         bool replySuccess(false);
238         int replyError(-1);
239         std::string replySignalName("");
240
241         // Invalid request test
242         AsyncSetPropertyRequest requestInvalid;
243         requestInvalid.timeout = 0;
244         AsyncPropertyReply* reply = routingEngine->setProperty(requestInvalid);
245         TEST(reply == nullptr);
246
247         requestInvalid.property = "NotExists";
248         requestInvalid.completed = [&](AsyncPropertyReply* reply)
249         {
250                 replySuccess = reply->success;
251                 replyError = reply->error;
252                 delete reply;
253         };
254
255         reply = routingEngine->setProperty(requestInvalid);
256
257         TEST(replySuccess == false);
258         TEST(replyError == -1);
259
260         AsyncSetPropertyRequest request;
261         request.timeout = 0;
262         request.property = TestProptertyName1;
263         request.zoneFilter = Zone::LeftSide;
264         request.value = VehicleProperty::getPropertyTypeForPropertyNameValue(request.property, "1");
265         request.completed = requestInvalid.completed;
266
267         reply = routingEngine->setProperty(request);
268         delete request.value;
269         request.value = nullptr;
270
271         TEST(replySuccess == true);
272         TEST(replyError == AsyncPropertyReply::NoError);
273 }
274
275 bool TestPlugin::testCoreUpdateSupported()
276 {
277         bool success = false;
278
279         PropertyList toAdd;
280         toAdd.push_back(VehicleProperty::ClutchStatus);
281
282         routingEngine->updateSupported(toAdd,PropertyList(), this);
283
284         PropertyList supported = routingEngine->supported();
285
286         success = contains(supported,VehicleProperty::ClutchStatus);
287
288         PropertyList toRemove = toAdd;
289
290         routingEngine->updateSupported(PropertyList(),toRemove, this);
291
292         supported = routingEngine->supported();
293
294         success &= !contains(supported,VehicleProperty::ClutchStatus);
295
296         return success;
297 }
298
299 void TestPlugin::setConfiguration(map<string, string> config)
300 {
301         //      //Config has been passed, let's start stuff up.
302 }
303
304 TestPlugin::TestPlugin(AbstractRoutingEngine *re, map<string, string> config)
305         : AbstractSource(re, config),
306           m_supportedProperties({TestProptertyName1, TestProptertyName2}),
307           subscriptionsToSupportedCounter(0),
308           subscriptionsToUnsupportedCounter(0),
309           unsubscriptionsToSupportedCounter(0),
310           unsubscriptionsToUnsupportedCounter(0),
311           propertyChanges(0),
312           supportedPropertyChanges(0)
313 {
314
315         DebugOut(0) << "Capabilities: " << endl;
316
317         for(auto prop : VehicleProperty::capabilities())
318         {
319                 DebugOut(0) << prop << endl;
320         }
321
322         DebugOut() << "Testing Core::setSupported... " << endl;
323         testCoreSetSupported();
324
325         DebugOut() << "Testing MapPropertyType... " << endl;
326         MapPropertyType<BasicPropertyType<Zone::Type>,BasicPropertyType<Door::Status>> propmap("something");
327         MapPropertyType<BasicPropertyType<Zone::Type>,BasicPropertyType<Door::Status>> propmaptwo("something");
328         propmap.append(Zone::RearLeft,Door::Ajar);
329         GVariant *var = propmap.toVariant();
330         gsize dictsize = g_variant_n_children(var);
331         //DebugOut() << var << endl;
332         propmaptwo.fromVariant(var);
333
334         g_assert(propmaptwo.toString() == propmap.toString());
335
336         DebugOut() << "Testing ListPropertyType... " << endl;
337         VehicleProperty::TripMetersType* tfirst = new VehicleProperty::TripMetersType();
338         VehicleProperty::TripMetersType* tsecond = new VehicleProperty::TripMetersType();
339         BasicPropertyType<uint16_t> v1(0);
340         BasicPropertyType<uint16_t> v2(5);
341         BasicPropertyType<uint16_t> v3(10);
342         tfirst->append(v1);
343         tfirst->append(v2);
344         tfirst->append(v3);
345         tsecond->fromVariant(tfirst->toVariant());
346
347         GVariant* testGVSVariant = g_variant_new("i", 9);
348         TEST(GVS<int>::value(testGVSVariant) == 9);
349
350         TEST (tfirst->toString() == tsecond->toString());
351
352         testBooleanToStringFromString();
353
354         TEST (testCoreUpdateSupported());
355
356         testSubscription();
357
358         testSetAndGet();
359 }
360
361 TestPlugin::~TestPlugin()
362 {
363         DebugOut() << "TestPlugin Destructor called!!!"<<endl;
364 }
365
366 PropertyList TestPlugin::supported()
367 {
368         return m_supportedProperties;
369 }
370
371 int TestPlugin::supportedOperations()
372 {
373         return Get | Set;
374 }
375
376 extern "C" void create(AbstractRoutingEngine* routingengine, map<string, string> config)
377 {
378         new TestPlugin(routingengine, config);
379 }
380 const string TestPlugin::uuid()
381 {
382         return "f77af740-f1f8-11e1-aff1-0800200c9a66";
383 }
384 void TestPlugin::subscribeToPropertyChanges(VehicleProperty::Property property)
385 {
386         if(contains(m_supportedProperties, property))
387                 ++subscriptionsToSupportedCounter;
388         else
389                 ++subscriptionsToUnsupportedCounter;
390 }
391
392
393 void TestPlugin::unsubscribeToPropertyChanges(VehicleProperty::Property property)
394 {
395         if(contains(m_supportedProperties, property))
396                 ++unsubscriptionsToSupportedCounter;
397         else
398                 ++unsubscriptionsToUnsupportedCounter;
399 }
400
401
402 void TestPlugin::getPropertyAsync(AsyncPropertyReply *reply)
403 {
404
405 }
406
407 AsyncPropertyReply *TestPlugin::setProperty(AsyncSetPropertyRequest request )
408 {
409         AsyncPropertyReply* reply = new AsyncPropertyReply (request);
410         reply->success = true;
411         reply->error = AsyncPropertyReply::NoError;
412         if(reply->completed)
413                 reply->completed(reply);
414         return reply;
415 }
416
417 PropertyInfo TestPlugin::getPropertyInfo(const VehicleProperty::Property &property)
418 {
419         if(!contains(m_supportedProperties, property))
420                 return PropertyInfo::invalid();
421
422         if(property == TestProptertyName1){
423                 return PropertyInfo(10, {Zone::LeftSide});
424         }
425         else if(property == TestProptertyName2){
426                 return PropertyInfo(30, {Zone::FrontSide});
427         }
428         else{
429                 return PropertyInfo(60, {Zone::None});
430         }
431 }
432
433 void TestPlugin::propertyChanged(AbstractPropertyType *value)
434 {
435         ++propertyChanges;
436         if(value && contains(m_supportedProperties, value->name))
437                 supportedPropertyChanges++;
438
439 }