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