2 Copyright (C) 2012 Intel Corporation
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.
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.
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
21 #include <boost/assert.hpp>
22 #include <boost/lexical_cast.hpp>
25 //#include <json-glib/json-glib.h>
26 #include <listplusplus.h>
27 #include <vehicleproperty.h>
28 #include <abstractpropertytype.h>
30 #include "timestamp.h"
31 #include "testplugin.h"
32 #include <jsonhelper.h>
34 #define __SMALLFILE__ std::string(__FILE__).substr(std::string(__FILE__).rfind("/")+1)
35 AbstractRoutingEngine *m_re;
37 #define TEST(success) DebugOut(0) << "Testing " << ""#success"" << endl; g_assert((success));
38 const std::string TestProptertyName1 = "TestPropertyName1";
39 const std::string TestProptertyName2 = "TestPropertyName2";
41 //std::list<ObdPid*> Obd2Amb::supportedPidsList;
43 void testBooleanToStringFromString()
45 BasicPropertyType<bool> boolean(true);
46 std::string isTrue = boolean.toString();
47 boolean.fromString(boolean.toString());
48 std::string isTrue2 = boolean.toString();
50 TEST(isTrue == isTrue2);
53 bool beginsWith(std::string a, std::string b)
55 return (a.compare(0, b.length(), b) == 0);
59 * Tests Core's methods:
62 * * sourcesForProperty
66 bool TestPlugin::testCoreSetSupported()
68 PropertyList supported(routingEngine->supported());
69 TEST(contains(supported, TestProptertyName1) == false);
76 routingEngine->updateSupported(m_supportedProperties, PropertyList(), this);
78 TEST(routingEngine->getPropertyInfo(TestProptertyName1, uuid()).isValid() == true);
79 Zone::ZoneList zones(routingEngine->getPropertyInfo(TestProptertyName1, uuid()).zones());
80 TEST(contains(zones, Zone::LeftSide) == true);
82 supported = routingEngine->supported();
83 TEST(contains(supported, TestProptertyName1) == true);
84 TEST(contains(supported, TestProptertyName2) == true);
85 TEST(contains(supported, VehicleProperty::ClutchStatus) == false);
87 std::vector<std::string> sources = routingEngine->sourcesForProperty(TestProptertyName1);
88 TEST(contains(sources,uuid()) == true);
90 TEST(routingEngine->getPropertyInfo(TestProptertyName2, uuid()).isValid() == true);
91 zones = routingEngine->getPropertyInfo(TestProptertyName2, uuid()).zones();
92 TEST(contains(zones, Zone::FrontSide) == true);
98 * Tests Core's methods:
101 * * sourcesForProperty
102 * * subscribeToProperty - 2 versions
103 * * unsubscribeToProperty
106 bool TestPlugin::testSubscription()
108 int oldSubscriptionsToSupportedCounter = subscriptionsToSupportedCounter;
109 int oldSubscriptionsToUnsupportedCounter = subscriptionsToUnsupportedCounter;
110 int oldUnsubscriptionsToSupportedCounter= unsubscriptionsToSupportedCounter;
111 int oldUnsubscriptionsToUnsupportedCounter = unsubscriptionsToUnsupportedCounter;
113 // ! subscription works without having sink registered ! so there is no need to test
114 // routingEngine->registerSink(this) and routingEngine->unregisterSink(this)
115 routingEngine->unregisterSink(this);
116 routingEngine->registerSink(this);
118 // VehicleProperty::ClutchStatus doesn't exist
119 TEST(routingEngine->subscribeToProperty(VehicleProperty::ClutchStatus, uuid(), this) == false);
120 TEST(oldSubscriptionsToSupportedCounter == subscriptionsToSupportedCounter);
121 TEST(oldSubscriptionsToUnsupportedCounter == subscriptionsToUnsupportedCounter);
123 // TestProptertyName1 exists in our testplugin
124 TEST(routingEngine->subscribeToProperty(TestProptertyName1, uuid(), this) == true);
125 TEST(++oldSubscriptionsToSupportedCounter == subscriptionsToSupportedCounter);
126 TEST(oldSubscriptionsToUnsupportedCounter == subscriptionsToUnsupportedCounter);
128 TEST(routingEngine->subscribeToProperty(TestProptertyName1, "", this) == false);
129 TEST(oldSubscriptionsToSupportedCounter == subscriptionsToSupportedCounter);
130 TEST(oldSubscriptionsToUnsupportedCounter == subscriptionsToUnsupportedCounter);
132 // "other" source means no subscription callback in our plugin
133 TEST(routingEngine->subscribeToProperty(TestProptertyName1, "other", this) == false);
134 TEST(oldSubscriptionsToSupportedCounter == subscriptionsToSupportedCounter);
135 TEST(oldSubscriptionsToUnsupportedCounter == subscriptionsToUnsupportedCounter);
137 // we have subscribed TestProptertyName1 and not subscribed TestProptertyName2
138 int oldSupportedPropertyChanges = supportedPropertyChanges;
139 int oldPropertyChanges = propertyChanges;
141 AbstractPropertyType* value = new BasicPropertyType<int>(TestProptertyName1, 22);
142 value->priority = AbstractPropertyType::Instant;
143 routingEngine->updateProperty(value, "");
144 TEST(oldSupportedPropertyChanges == supportedPropertyChanges);
145 TEST(oldPropertyChanges == propertyChanges);
146 routingEngine->updateProperty(value, uuid());
147 TEST(++oldSupportedPropertyChanges == supportedPropertyChanges);
148 TEST(++oldPropertyChanges == propertyChanges);
151 value = new BasicPropertyType<short>(TestProptertyName2, 255);
152 value->priority = AbstractPropertyType::Instant;
153 routingEngine->updateProperty(value, "");
154 TEST(oldSupportedPropertyChanges == supportedPropertyChanges);
155 TEST(oldPropertyChanges == propertyChanges);
156 routingEngine->updateProperty(value, uuid());
157 TEST(oldSupportedPropertyChanges == supportedPropertyChanges);
158 TEST(oldPropertyChanges == propertyChanges);
161 value = new BasicPropertyType<bool>(VehicleProperty::ClutchStatus, true);
162 value->priority = AbstractPropertyType::Instant;
163 routingEngine->updateSupported({VehicleProperty::ClutchStatus},PropertyList(), this);
165 class TestSink : public AbstractSink
168 TestSink(AbstractRoutingEngine* engine, map<string, string> config) : AbstractSink(engine, config) {}
169 virtual const string uuid() { return "other"; }
170 virtual void propertyChanged(AbstractPropertyType *value){ ++propertyChanges; }
171 virtual void supportedChanged(const PropertyList & supportedProperties){};
173 int propertyChanges = 0;
176 //some other sink is subscribed, not this plug-in!
177 TestSink anotherSink(routingEngine, {});
178 TEST(routingEngine->subscribeToProperty(VehicleProperty::ClutchStatus, &anotherSink) == true);
179 TEST(oldSubscriptionsToSupportedCounter == subscriptionsToSupportedCounter);
180 TEST(++oldSubscriptionsToUnsupportedCounter == subscriptionsToUnsupportedCounter);
181 routingEngine->updateProperty(value, uuid());// uuid() != "other" no sink notified
182 TEST(anotherSink.propertyChanges == 1);// one update
183 TEST(oldSupportedPropertyChanges == supportedPropertyChanges);// no updates
184 TEST(oldPropertyChanges == propertyChanges);// no updates
185 TEST(routingEngine->unsubscribeToProperty(VehicleProperty::ClutchStatus, &anotherSink) == true);
186 routingEngine->updateSupported(PropertyList(),{VehicleProperty::ClutchStatus}, this);
187 TEST(oldUnsubscriptionsToSupportedCounter == unsubscriptionsToSupportedCounter);
188 TEST(++oldUnsubscriptionsToUnsupportedCounter == unsubscriptionsToUnsupportedCounter);
191 /// test lamba subscription:
193 TEST (routingEngine->subscribeToProperty(VehicleProperty::VehicleSpeed,[](AbstractPropertyType* value)
195 DebugOut(0)<<"lamba subscriptions work!"<<endl;
199 /// change vehiclespeed to trigger subscribe above
202 s.push_back(VehicleProperty::VehicleSpeed);
204 routingEngine->updateSupported(s, PropertyList(), this);
205 VehicleProperty::VehicleSpeedType speed(10);
206 speed.priority = AbstractPropertyType::Instant;
208 routingEngine->updateProperty(&speed,uuid());
209 routingEngine->updateSupported(PropertyList(), s, this);
215 // VehicleProperty::ClutchStatus doesn't exist
216 TEST(routingEngine->unsubscribeToProperty(VehicleProperty::ClutchStatus, this) == false);
217 TEST(oldUnsubscriptionsToSupportedCounter == unsubscriptionsToSupportedCounter);
218 TEST(oldUnsubscriptionsToUnsupportedCounter == unsubscriptionsToUnsupportedCounter);
220 // TestProptertyName1 exists in our testplugin
221 // subscribed 2x, lets try to unsubscribe 3x
222 // we should get only one unsubscription callback
223 TEST(routingEngine->unsubscribeToProperty(TestProptertyName1, this) == true);
224 TEST(routingEngine->unsubscribeToProperty(TestProptertyName1, this) == false);
225 TEST(routingEngine->unsubscribeToProperty(TestProptertyName1, this) == false);
226 TEST(++oldUnsubscriptionsToSupportedCounter == unsubscriptionsToSupportedCounter);
227 TEST(oldUnsubscriptionsToUnsupportedCounter == unsubscriptionsToUnsupportedCounter);
229 // TestProptertyName2 not subscribed
230 TEST(routingEngine->unsubscribeToProperty(TestProptertyName2, this) == false);;
231 TEST(oldUnsubscriptionsToSupportedCounter == unsubscriptionsToSupportedCounter);
232 TEST(oldUnsubscriptionsToUnsupportedCounter == unsubscriptionsToUnsupportedCounter);
237 bool testListPlusPlus()
239 std::map<std::string, int> theMap;
243 TEST(amb::containsKey(theMap, "1"));
244 TEST(!amb::containsKey(theMap, "bar"));
246 std::vector<int> list;
251 TEST(contains(list, 2));
253 TEST(!contains(list, 2));
258 Complex(int a, int b): foo(a), bar(b) {}
263 Complex complex1(1, 2);
265 Complex complex2(2, 2);
267 std::vector<Complex> complexList;
268 complexList.push_back(complex1);
269 complexList.push_back(complex2);
271 TEST(contains(complexList, complex1, [](auto a, auto b) { return a.foo == b.foo && a.bar == b.bar; }));
276 void testJsonHelper()
281 bool TestPlugin::testSetAndGet()
283 bool replySuccess(false);
285 std::string replySignalName("");
287 // Invalid request test
288 AsyncSetPropertyRequest requestInvalid;
289 requestInvalid.timeout = 0;
290 AsyncPropertyReply* reply = routingEngine->setProperty(requestInvalid);
291 TEST(reply == nullptr);
293 requestInvalid.property = "NotExists";
294 requestInvalid.completed = [&](AsyncPropertyReply* reply)
296 replySuccess = reply->success;
297 replyError = reply->error;
301 reply = routingEngine->setProperty(requestInvalid);
303 TEST(replySuccess == false);
304 TEST(replyError == -1);
306 AsyncSetPropertyRequest request;
308 request.property = TestProptertyName1;
309 request.zoneFilter = Zone::LeftSide;
310 request.value = VehicleProperty::getPropertyTypeForPropertyNameValue(request.property, "1");
311 request.completed = requestInvalid.completed;
313 reply = routingEngine->setProperty(request);
314 delete request.value;
315 request.value = nullptr;
317 TEST(replySuccess == true);
318 TEST(replyError == AsyncPropertyReply::NoError);
321 bool TestPlugin::testCoreUpdateSupported()
323 bool success = false;
326 toAdd.push_back(VehicleProperty::ClutchStatus);
328 routingEngine->updateSupported(toAdd, PropertyList(), this);
330 PropertyList supported = routingEngine->supported();
332 success = contains(supported,VehicleProperty::ClutchStatus);
334 PropertyList toRemove = toAdd;
336 routingEngine->updateSupported(PropertyList(),toRemove, this);
338 supported = routingEngine->supported();
340 success &= !contains(supported,VehicleProperty::ClutchStatus);
345 void TestPlugin::setConfiguration(map<string, string> config)
347 // //Config has been passed, let's start stuff up.
350 TestPlugin::TestPlugin(AbstractRoutingEngine *re, map<string, string> config)
351 : AbstractSource(re, config),
352 m_supportedProperties({TestProptertyName1, TestProptertyName2}),
353 subscriptionsToSupportedCounter(0),
354 subscriptionsToUnsupportedCounter(0),
355 unsubscriptionsToSupportedCounter(0),
356 unsubscriptionsToUnsupportedCounter(0),
358 supportedPropertyChanges(0)
361 DebugOut(0) << "Capabilities: " << endl;
363 for(auto prop : VehicleProperty::capabilities())
365 DebugOut(0) << prop << endl;
368 DebugOut() << "Testing Core::setSupported... " << endl;
369 testCoreSetSupported();
371 DebugOut() << "Testing MapPropertyType... " << endl;
372 MapPropertyType<BasicPropertyType<Door::Status>> propmap("Something");
373 MapPropertyType<BasicPropertyType<Door::Status>> propmaptwo("SomethingElse");
374 propmap.append("hi", Door::Ajar);
375 GVariant *var = propmap.toVariant();
376 gsize dictsize = g_variant_n_children(var);
377 //DebugOut() << var << endl;
378 propmaptwo.fromVariant(var);
380 g_assert(propmaptwo.toString() == propmap.toString());
383 propmap.fromString(propmaptwo.toString());
385 DebugOut() << "Testing map string equivalency: " << propmaptwo.toString() << "==" << propmap.toString() << endl;
387 g_assert(propmaptwo.toString() == propmap.toString());
389 DebugOut() << "Testing ListPropertyType... " << endl;
390 VehicleProperty::TripMetersType* tfirst = new VehicleProperty::TripMetersType();
391 VehicleProperty::TripMetersType* tsecond = new VehicleProperty::TripMetersType();
395 tsecond->fromVariant(tfirst->toVariant());
397 GVariant* testGVSVariant = g_variant_new("i", 9);
398 TEST(GVS<int>::value(testGVSVariant) == 9);
400 TEST (tfirst->toString() == tsecond->toString());
402 testBooleanToStringFromString();
404 TEST (testCoreUpdateSupported());
410 TEST(testListPlusPlus());
415 TestPlugin::~TestPlugin()
417 DebugOut() << "TestPlugin Destructor called!!!"<<endl;
420 PropertyList TestPlugin::supported()
422 return m_supportedProperties;
425 int TestPlugin::supportedOperations()
430 extern "C" void create(AbstractRoutingEngine* routingengine, map<string, string> config)
432 new TestPlugin(routingengine, config);
434 const string TestPlugin::uuid()
436 return "f77af740-f1f8-11e1-aff1-0800200c9a66";
438 void TestPlugin::subscribeToPropertyChanges(VehicleProperty::Property property)
440 if(contains(m_supportedProperties, property))
441 ++subscriptionsToSupportedCounter;
443 ++subscriptionsToUnsupportedCounter;
447 void TestPlugin::unsubscribeToPropertyChanges(VehicleProperty::Property property)
449 if(contains(m_supportedProperties, property))
450 ++unsubscriptionsToSupportedCounter;
452 ++unsubscriptionsToUnsupportedCounter;
456 void TestPlugin::getPropertyAsync(AsyncPropertyReply *reply)
461 AsyncPropertyReply *TestPlugin::setProperty(AsyncSetPropertyRequest request )
463 AsyncPropertyReply* reply = new AsyncPropertyReply (request);
464 reply->success = true;
465 reply->error = AsyncPropertyReply::NoError;
467 reply->completed(reply);
471 PropertyInfo TestPlugin::getPropertyInfo(const VehicleProperty::Property &property)
473 if(!contains(m_supportedProperties, property))
474 return PropertyInfo::invalid();
476 if(property == TestProptertyName1){
477 return PropertyInfo(10, {Zone::LeftSide});
479 else if(property == TestProptertyName2){
480 return PropertyInfo(30, {Zone::FrontSide});
483 return PropertyInfo(60, {Zone::None});
487 void TestPlugin::propertyChanged(AbstractPropertyType *value)
490 if(value && contains(m_supportedProperties, value->name))
491 supportedPropertyChanges++;