ddl/test/mapping/src/tester_mapping.cpp
2019-12-12 14:41:47 +01:00

1605 lines
No EOL
70 KiB
C++

/**
* @file
* Implementation of the tester for Mapping
*
* @copyright
* @verbatim
Copyright @ 2017 Audi Electronics Venture GmbH. All rights reserved.
This Source Code Form is subject to the terms of the Mozilla
Public License, v. 2.0. If a copy of the MPL was not distributed
with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular file, then
You may include the notice in a location (such as a LICENSE file in a
relevant directory) where a recipient would be likely to look for such a notice.
You may add additional accurate notices of copyright ownership.
@endverbatim
*/
#include <memory> //std::unique_ptr<>
#include <ddl.h>
#include "a_util/result/error_def.h"
#include <gtest/gtest.h>
#include "../../_common/adtf_compat.h"
#include "../../_common/compat.h"
using namespace mapping::oo;
using namespace mapping::rt;
using namespace ddl;
_MAKE_RESULT(-5, ERR_INVALID_ARG)
_MAKE_RESULT(-11, ERR_INVALID_FILE)
_MAKE_RESULT(-20, ERR_NOT_FOUND)
_MAKE_RESULT(-40, ERR_INVALID_STATE)
_MAKE_RESULT(-42, ERR_INVALID_TYPE)
ddl::DDLDescription* LoadDDL(const std::string& strDDLFile)
{
std::string strDDL;
if (a_util::filesystem::readTextFile(strDDLFile, strDDL) != a_util::filesystem::OK)
{
return NULL;
}
ddl::DDLImporter oImp;
if (a_util::result::isFailed(oImp.setXML(strDDL)))
{
return NULL;
}
if (a_util::result::isFailed(oImp.createNew()))
{
return NULL;
}
return oImp.getDDL();
}
/**
* @detail This test creates an empty configuration.
*/
TEST(cTesterMapping,
TestEmptyConfig)
{
TEST_REQ("FEPSDK-283");
std::unique_ptr<ddl::DDLDescription> poDDL(LoadDDL("files/test.description"));
MapConfiguration oConfig(poDDL.get());
ASSERT_EQ(oConfig.getHeader().getAuthor() , a_util::system::getCurrentUserName());
ASSERT_EQ(oConfig.getHeader().getCreationDate() , oConfig.getHeader().getModificationDate());
ASSERT_EQ(oConfig.getHeader().getLanguageVersion() , "1.00");
ASSERT_TRUE(oConfig.getSourceList().empty());
ASSERT_TRUE(oConfig.getTargetList().empty());
ASSERT_TRUE(oConfig.getTransformationList().empty());
// test setDescription for reset
ASSERT_EQ(a_util::result::SUCCESS, oConfig.setDescription(NULL));
// test load from not existing file
ASSERT_EQ(oConfig.loadFromFile("blubb") , ERR_INVALID_FILE);
}
/**
* @detail This test creates a configuration and loads a map file.
*/
TEST(cTesterMapping,
TestLoadMapSuccessConfig)
{
TEST_REQ("FEPSDK-283");
std::unique_ptr<ddl::DDLDescription> poDDL(LoadDDL("files/test.description"));
MapConfiguration oConfig(poDDL.get());
a_util::xml::DOM oDom;
ASSERT_TRUE(oDom.load("files/base.map"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.loadFromDOM(oDom));
// Verify header
ASSERT_EQ(oConfig.getHeader().getAuthor() , "ASAP");
ASSERT_EQ(oConfig.getHeader().getCreationDate() , "2016-Mar-22");
ASSERT_EQ(oConfig.getHeader().getLanguageVersion() , "1.00");
ASSERT_EQ(oConfig.getHeader().getModificationDate() , "2016-Mar-22");
// Verify source list
ASSERT_EQ(oConfig.getSourceList().size() , 4);
ASSERT_TRUE(oConfig.getSource("Light"));
ASSERT_TRUE(oConfig.getSource("Wiper"));
ASSERT_TRUE(oConfig.getSource("AALA"));
ASSERT_TRUE(oConfig.getSource("Additional"));
ASSERT_EQ(oConfig.getSource("Light")->getType() , "tFEP_Driver_LightControl");
ASSERT_EQ(oConfig.getSource("Wiper")->getType() , "tFEP_Driver_WiperControl");
ASSERT_EQ(oConfig.getSource("AALA")->getType() , "tFEP_Driver_AalaControl");
ASSERT_EQ(oConfig.getSource("Additional")->getType() , "tFEP_Driver_AdditionalControl");
// Verify target list
ASSERT_EQ(oConfig.getTargetList().size() , 1);
ASSERT_TRUE(oConfig.getTarget("Signal"));
ASSERT_EQ(oConfig.getTarget("Signal")->getType() , "tFEP_Driver_DriverCtrl");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList().size() , 13);
// Verify assignment list
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[0].getConstant() , "42");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[0].getTo() , "f64SimTime");
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[0].getSource().empty());
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[0].getFrom().empty());
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[0].getTransformation().empty());
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[1].getConstant().empty());
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[1].getTo() , "sAalaControl");
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[1].getFrom().empty());
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[1].getSource() , "AALA");
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[1].getTransformation().empty());
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[2].getConstant().empty());
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[2].getTo() , "sWiperControl");
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[2].getFrom().empty());
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[2].getSource() , "Wiper");
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[2].getTransformation().empty());
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[3].getConstant().empty());
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[3].getTo() , "ui8Spare1[0]");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[3].getFrom() , "ui8Spare1[3]");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[3].getSource() , "Light");
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[3].getTransformation().empty());
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[4].getConstant().empty());
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[4].getTo() , "ui8Spare1[1]");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[4].getFrom() , "ui8Spare1[2]");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[4].getSource() , "Light");
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[4].getTransformation().empty());
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[5].getConstant().empty());
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[5].getTo() , "ui8Spare1[2]");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[5].getFrom() , "ui8Spare1[1]");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[5].getSource() , "Light");
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[5].getTransformation().empty());
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[6].getConstant().empty());
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[6].getTo() , "ui8Spare1[3]");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[6].getFrom() , "ui8Spare1[0]");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[6].getSource() , "Light");
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[6].getTransformation().empty());
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[7].getConstant().empty());
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[7].getTo() , "ui32ValidityMask");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[7].getFrom() , "ui32ValidityMask");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[7].getSource() , "Additional");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[7].getTransformation() , "polynom2");
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[8].getConstant().empty());
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[8].getTo() , "sLightControl.eLightState");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[8].getFrom() , "eLightState");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[8].getSource() , "Light");
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[8].getTransformation().empty());
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[9].getConstant().empty());
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[9].getTo() , "ui32VehicleId");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[9].getFunction() , "simulation_time");
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[9].getSource().empty());
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[9].getTransformation().empty());
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[10].getConstant().empty());
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[10].getTo() , "sLongitudinal.f32ThrottlePedal");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[10].getFunction() , "trigger_counter");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[10].getModulo() , "10");
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[10].getTransformation().empty());
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[11].getConstant().empty());
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[11].getTo() , "sLightControl.bIndicatorLeft");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[11].getFunction() , "received");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[11].getSource() , "Light");
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[11].getTransformation().empty());
ASSERT_TRUE(oConfig.getTarget("Signal")->getAssignmentList()[12].getConstant().empty());
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[12].getTo() , "eGear");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[12].getFrom() , "eFrontState");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[12].getSource() , "Wiper");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList()[12].getTransformation() , "table1");
// Verify referenced sources list
ASSERT_EQ(oConfig.getTarget("Signal")->getReferencedSources().size() , 4);
// Verify trigger list
ASSERT_EQ(oConfig.getTarget("Signal")->getTriggerList().size() , 3);
ASSERT_TRUE(oConfig.getTarget("Signal")->getTriggerList()[0]);
const MapPeriodicTrigger* p =
dynamic_cast<const MapPeriodicTrigger*>(oConfig.getTarget("Signal")->getTriggerList()[0]);
ASSERT_TRUE(p);
ASSERT_EQ(p->getPeriod() , 10);
ASSERT_TRUE(oConfig.getTarget("Signal")->getTriggerList()[1]);
const MapSignalTrigger* s =
dynamic_cast<const MapSignalTrigger*>(oConfig.getTarget("Signal")->getTriggerList()[1]);
ASSERT_TRUE(s);
ASSERT_EQ(s->getVariable() , "Light");
ASSERT_TRUE(oConfig.getTarget("Signal")->getTriggerList()[2]);
const MapDataTrigger* d =
dynamic_cast<const MapDataTrigger*>(oConfig.getTarget("Signal")->getTriggerList()[2]);
ASSERT_TRUE(d);
ASSERT_EQ(d->getSource() , "Light");
ASSERT_EQ(d->getVariable() , "ui8Spare1[3]");
ASSERT_EQ(d->getOperator() , "less_than");
ASSERT_EQ(d->getValue() , 2);
// Verify transformation list
ASSERT_EQ(oConfig.getTransformationList().size() , 3);
ASSERT_TRUE(oConfig.getTransformation("polynom1"));
const MapPolynomTransformation* t =
dynamic_cast<const MapPolynomTransformation*>(oConfig.getTransformation("polynom1"));
ASSERT_TRUE(t);
ASSERT_EQ(t->getA() , 1);
ASSERT_EQ(t->getB() , 1.7);
ASSERT_EQ(t->getC() , 2);
ASSERT_EQ(t->getD() , 1.1);
ASSERT_EQ(t->getE() , 0);
ASSERT_TRUE(oConfig.getTransformation("polynom2"));
t = dynamic_cast<const MapPolynomTransformation*>(oConfig.getTransformation("polynom2"));
ASSERT_TRUE(t);
ASSERT_EQ(t->getA() , 2);
ASSERT_EQ(t->getB() , 1);
ASSERT_EQ(t->getC() , 0);
ASSERT_EQ(t->getD() , 0);
ASSERT_EQ(t->getE() , 0);
ASSERT_TRUE(oConfig.getTransformation("table1"));
const MapEnumTableTransformation* tEnum =
dynamic_cast<const MapEnumTableTransformation*>(oConfig.getTransformation("table1"));
ASSERT_TRUE(tEnum);
ASSERT_EQ(tEnum->getDefault() , 3);
std::map< int64_t, int64_t > oConvList = tEnum->getConversions();
ASSERT_EQ(oConvList.size() , 5);
ASSERT_EQ(oConvList[0] , 4);
ASSERT_EQ(oConvList[1] , 5);
ASSERT_EQ(oConvList[2] , 6);
ASSERT_EQ(oConvList[3] , 7);
ASSERT_EQ(oConvList[4] , 4);
}
/**
* @detail Test Configuration to load erroneous Map Files.
*/
TEST(cTesterMapping,
TestLoadMapFailConfig)
{
TEST_REQ("FEPSDK-283");
std::unique_ptr<ddl::DDLDescription> poDDL(LoadDDL("files/test.description"));
MapConfiguration oConfig(poDDL.get());
a_util::xml::DOM oDom;
for (int i = 0; i <= 40; ++i)
{
oDom = a_util::xml::DOM();
ASSERT_TRUE(oDom.load(a_util::strings::format("files/nok%d.map", i)));
a_util::result::Result nRes = oConfig.loadFromDOM(oDom);
//tMapErrorList list = oConfig.getErrorList();
//LOG_INFO(list.Join(','));
ASSERT_TRUE(a_util::result::isFailed(nRes)) <<
a_util::strings::format("%d should have failed but didn't", i).c_str();
}
// nok0.map -> <from> and <constant> attributes set at the same time for <assignment> to 'f64SimTime'
// nok1.map -> Missing 'from' or 'constant' attribute for assignment element
// nok2.map -> Missing 'to' attribute for <assignment> element
// nok3.map -> Missing <language_version>, <author>, <date_creation>, <date_change> or <description> element in header
// nok4.map -> Missing or empty name attribute for <source> element
// nok5.map -> Missing or empty type attribute for <source> element
// nok6.map -> Missing name attribute for <target> element
// nok7.map -> Missing type attribute for <target> element
// nok8.map -> Missing <mapping> root element
// nok9.map -> Missing <header> element
// nok10.map -> Redefinition of source 'Light'
// nok11.map -> Unknown source type 'tBullshit'
// nok12.map -> Redefinition of target or name reuse of source 'Signal'
// nok13.map -> Unknown target type 'tBullshit'
// nok14.map -> Empty or non-numeric constant 'true'
// nok15.map -> Target element referenced by 'to' unknown or invalid: 'bullshit'
// nok16.map -> Assignment references unknown source: 'Bullshit'
// nok17.map -> Source element referenced by 'from' unknown or invalid: 'AALA.nBullshit'
// nok18.map -> Destination element is assigned repeatedly: ui8Spare1[0]
// nok19.map -> Structure <assignment> 'sLightControl' overwrites previous element <assignment> in <target> 'Signal'
// nok20.map -> Element <assignment> 'sLightControl.eLightState' overwrites previous structure <assignment> in <target> 'Signal'
// nok21.map -> Unknown transformation: 'bullshit'
// nok22.map -> Incompatible types in <assignment>: struct->other struct
// nok23.map -> Incompatible types in <assignment>: struct->primitive
// nok24.map -> Incompatible types in <assignment>: primitive->struct
// nok25.map -> Incompatible types in <assignment>: array->array with other size
// nok26.map -> Missing <to> attribute for an <assignment>
// nok27.map -> <from> attribute empty for <assignment> to 'f64SimTime'
// nok28.map -> Missing <trigger> type attribute
// nok29.map -> Invalid period attribute for periodic trigger (expected positive integer)
// nok30.map -> Missing unit attribute for periodic trigger
// nok31.map -> Invalid element type in <target> 'Signal': 'tigger'
// nok32.map -> Invalid coefficient attribute 'b' for polynomial transformation 'polynom2' (expected number),
// Invalid coefficient attribute 'd' for polynomial transformation 'polynom2' (expected number)
// nok33.map -> Dynamic target elements are not allowed: 'f64DynamicArray' in <target> 'DynSignal'
// nok34.map -> Incompatible types for <assignment> to 'ui8Spare1[0]' in <target> 'Signal'
// nok35.map -> <function> should be of type 'simulation_time()', 'trigger_counter([Modulo])' or 'received([Signal])' for <assignment> to 'ui32VehicleId'
// nok36.map -> <function> of type 'simulation_time()' takes no argument for <assignment> to 'ui32VehicleId'
// nok37.map -> <function> of type'received([Signal])' has no argument for <assignment> to 'ui32VehicleId'
// nok38.map -> Missing variable attribute for signal trigger
// nok39.map -> Variable attribute for data trigger should be a signal element (expected [Signal].[Element]),Invalid operator attribute for data trigger
//(expected less_than, greater_than, less_than_equal, greater_than_equal, equal or not_equal),Invalid value attribute for data trigger (expected floating point value)
// nok40.map -> <to> attribute 'GS' for <conversion> in <transformation> 'table1' should be a element of 'tFEP_Driver_GearSelection' <enumeration>
}
/**
* @detail Test Configuration to merge Map Files
*/
TEST(cTesterMapping,
TestMergeMapsSuccessConfig)
{
TEST_REQ("FEPSDK-283");
std::unique_ptr<ddl::DDLDescription> poDDL(LoadDDL("files/test.description"));
MapConfiguration oConfig(poDDL.get());
a_util::xml::DOM oDom;
ASSERT_TRUE(oDom.load("files/base.map"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.loadFromDOM(oDom));
oDom = a_util::xml::DOM();
ASSERT_TRUE(oDom.load("files/merge.map"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.loadFromDOM(oDom, MapConfiguration::mc_merge_mapping));
// Verify that new signal was added in target list
ASSERT_EQ(oConfig.getTargetList().size() , 2);
ASSERT_TRUE(oConfig.getTarget("Signal2"));
ASSERT_EQ(oConfig.getTarget("Signal2")->getType() , "tFEP_Driver_LateralControl");
ASSERT_EQ(oConfig.getTarget("Signal2")->getAssignmentList().size() , 2);
ASSERT_TRUE(oConfig.getTarget("Signal2")->getAssignmentList()[0].getConstant().empty());
ASSERT_EQ(oConfig.getTarget("Signal2")->getAssignmentList()[0].getFrom() , "ui32ValidityMask");
ASSERT_EQ(oConfig.getTarget("Signal2")->getAssignmentList()[0].getSource() , "Light");
ASSERT_EQ(oConfig.getTarget("Signal2")->getAssignmentList()[0].getTo() , "f32SteeringWheel");
ASSERT_EQ(oConfig.getTarget("Signal2")->getAssignmentList()[0].getTransformation() , "polynom2");
ASSERT_EQ(oConfig.getTarget("Signal2")->getAssignmentList()[1].getConstant() , "21");
ASSERT_TRUE(oConfig.getTarget("Signal2")->getAssignmentList()[1].getFrom().empty());
ASSERT_TRUE(oConfig.getTarget("Signal2")->getAssignmentList()[1].getSource().empty());
ASSERT_EQ(oConfig.getTarget("Signal2")->getAssignmentList()[1].getTo() , "ui32ValidityMask");
ASSERT_TRUE(oConfig.getTarget("Signal2")->getAssignmentList()[1].getTransformation().empty());
// this tests a regression where setting a ddl description would clear the complete configuration
ASSERT_EQ(a_util::result::SUCCESS, oConfig.setDescription(poDDL.get()));
ASSERT_EQ(oConfig.getTargetList().size() , 2);
// load ddl that doesn't contain the target signal lateralcontrol
// so the mapping config should be cleared
std::unique_ptr<ddl::DDLDescription> poBadDDL(LoadDDL
("files/test_without_lateralcontrol_signal.description"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.setDescription(poBadDDL.get()));
ASSERT_EQ(oConfig.getTargetList().size() , 0);
}
/**
* @detail Test Configuration to merge conflicting Map Files
*/
TEST(cTesterMapping,
TestMergeMapsFailConfig)
{
TEST_REQ("FEPSDK-283");
std::unique_ptr<ddl::DDLDescription> poDDL(LoadDDL("files/test.description"));
MapConfiguration oConfig(poDDL.get());
a_util::xml::DOM oDom;
ASSERT_TRUE(oDom.load("files/base.map"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.loadFromDOM(oDom));
for (int i = 0; i <= 4; ++i)
{
oDom = a_util::xml::DOM();
ASSERT_TRUE(oDom.load(a_util::strings::format("files/nok_merge%d.map", i)));
a_util::result::Result nRes = oConfig.loadFromDOM(oDom, MapConfiguration::mc_merge_mapping);
//tMapErrorList list = oConfig.getErrorList();
//LOG_INFO(list.Join(','));
ASSERT_TRUE(a_util::result::isFailed(nRes)) <<
a_util::strings::format("%d should have failed but didn't", i).c_str();
}
// nok_merge0.map -> Trying to merge conflicting source definition for 'Light'
// nok_merge1.map -> Trying to merge conflicting target definition for 'Signal'
// nok_merge2.map -> Trying to merge conflicting transformation definition for 'polynom1'
// nok_merge3.map -> Trying to merge conflicting target definition for 'Signal'
// nok_merge4.map -> Trying to merge conflicting transformation definition for 'table1'
}
/**
* @detail Test load then write configuration
*/
TEST(cTesterMapping,
TestReadWriteMapFile)
{
TEST_REQ("CDPKGDDL-28");
std::unique_ptr<ddl::DDLDescription> poDDL(LoadDDL("files/test.description"));
MapConfiguration oConfig(poDDL.get());
a_util::xml::DOM oDom;
ASSERT_TRUE(oDom.load("files/base.map"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.loadFromDOM(oDom));
a_util::xml::DOM oNewDom;
ASSERT_EQ(a_util::result::SUCCESS, oConfig.writeToDOM(oNewDom));
ASSERT_EQ(oNewDom.getRoot().getName() , oDom.getRoot().getName());
ASSERT_EQ(oNewDom.getRoot().getChildren().size() , oDom.getRoot().getChildren().size());
//Verify sources
a_util::xml::DOMElement oSrcsEl = oDom.getRoot().getChild("sources");
a_util::xml::DOMElement oNewSrcsEl = oNewDom.getRoot().getChild("sources");
ASSERT_TRUE(!oSrcsEl.isNull() && !oNewSrcsEl.isNull());
a_util::xml::DOMElementList oOldChildren = oSrcsEl.getChildren();
a_util::xml::DOMElementList oNewChildren = oNewSrcsEl.getChildren();
ASSERT_TRUE(oOldChildren.size() == oNewChildren.size());
a_util::xml::DOMElementList::const_iterator itSrcNew = oNewChildren.begin();
for( a_util::xml::DOMElementList::const_iterator itSrc = oOldChildren.begin();
itSrc != oOldChildren.end(); itSrc++, itSrcNew++)
{
ASSERT_EQ(itSrc->getName() , itSrcNew->getName());
ASSERT_EQ(itSrc->getAttributes() , itSrcNew->getAttributes());
ASSERT_EQ(itSrc->getChildren().size() , itSrcNew->getChildren().size());
}
//Verify targets
a_util::xml::DOMElement oTrgsEl = oDom.getRoot().getChild("targets");
a_util::xml::DOMElement oNewTrgsEl = oNewDom.getRoot().getChild("targets");
ASSERT_TRUE(!oTrgsEl.isNull() && !oNewTrgsEl.isNull());
ASSERT_TRUE(oTrgsEl.getChildren().size() == oNewTrgsEl.getChildren().size());
a_util::xml::DOMElement oTrgEl = oTrgsEl.getChild("target");
a_util::xml::DOMElement oNewTrgEl = oNewTrgsEl.getChild("target");
ASSERT_TRUE(!oTrgEl.isNull() && !oNewTrgEl.isNull());
oOldChildren = oTrgEl.getChildren();
oNewChildren = oNewTrgEl.getChildren();
ASSERT_TRUE(oOldChildren.size() == oNewChildren.size());
a_util::xml::DOMElementList::const_iterator itNewTrg = oNewChildren.begin();
for( a_util::xml::DOMElementList::const_iterator itTrg = oOldChildren.begin();
itTrg != oOldChildren.end(); itTrg++, itNewTrg++)
{
ASSERT_EQ(itTrg->getName() , itNewTrg->getName());
ASSERT_EQ(itTrg->getAttributes() , itNewTrg->getAttributes());
ASSERT_EQ(itTrg->getChildren().size() , itNewTrg->getChildren().size());
}
//Verify transformations
a_util::xml::DOMElement oTrfEl = oDom.getRoot().getChild("transformations");
a_util::xml::DOMElement oNewTrfEl = oNewDom.getRoot().getChild("transformations");
ASSERT_TRUE(!oTrfEl.isNull() && !oNewTrfEl.isNull());
oOldChildren = oTrfEl.getChildren();
oNewChildren = oNewTrfEl.getChildren();
ASSERT_TRUE(oOldChildren.size() == oNewChildren.size());
a_util::xml::DOMElementList::const_iterator itTrfNew = oNewChildren.begin();
for( a_util::xml::DOMElementList::const_iterator itTrg = oOldChildren.begin();
itTrg != oOldChildren.end(); itTrg++, itTrfNew++)
{
ASSERT_TRUE(itTrg->getName() == itTrfNew->getName());
ASSERT_TRUE(itTrg->getAttribute("name") == itTrfNew->getAttribute("name"));
if(itTrg->getName() == "polynomial")
{
char c = 'a';
a_util::result::Result res = a_util::result::SUCCESS;
for (int i = 0; i < 5; ++i, ++c)
{
a_util::xml::DOMAttributes oldAttrs = itTrg->getAttributes();
a_util::xml::DOMAttributes::const_iterator itAttr = oldAttrs.find(std::string(1, c));
a_util::xml::DOMAttributes newAttrs = itTrfNew->getAttributes();
a_util::xml::DOMAttributes::const_iterator itAttrNew = newAttrs.find(std::string(1, c));
if (itAttr != oldAttrs.end() && itAttrNew != newAttrs.end())
{
ASSERT_TRUE(a_util::strings::toDouble(itAttr->second) == a_util::strings::toDouble(itAttrNew->second));
}
}
}
else
{
a_util::xml::DOMAttributes oldAttrs = itTrg->getAttributes();
a_util::xml::DOMAttributes newAttrs = itTrfNew->getAttributes();
a_util::xml::DOMAttributes::const_iterator itAttrNew = newAttrs.begin();
for(a_util::xml::DOMAttributes::const_iterator itAttr = oldAttrs.begin();
itAttr != oldAttrs.end(); itAttr++, itAttrNew++)
{
ASSERT_TRUE(itAttr->second == itAttrNew->second);
}
ASSERT_TRUE(itTrg->getChildren().size() == itTrfNew->getChildren().size());
}
}
// Write to file
ASSERT_EQ(a_util::result::SUCCESS, oConfig.writeToFile("files/generated_base.map"));
ASSERT_TRUE(a_util::filesystem::remove("files/generated_base.map"));
}
/**
* @detail Test to write a simple map configuration
*/
TEST(cTesterMapping,
TestWriteSimpleMapConfig)
{
TEST_REQ("CDPKGDDL-28");
std::unique_ptr<ddl::DDLDescription> poDDL(LoadDDL("files/test.description"));
MapConfiguration oConfig(poDDL.get());
// set header description
std::string strDesc = "New description";
ASSERT_EQ(a_util::result::SUCCESS, oConfig.setHeaderDescription(strDesc));
// add Transformation
ASSERT_EQ(a_util::result::SUCCESS, oConfig.addTransformation("poly1", "polynomial"));
MapPolynomTransformation *pPolyTrf = dynamic_cast<MapPolynomTransformation*>(oConfig.getTransformation("poly1"));
ASSERT_TRUE(pPolyTrf);
std::string strCoefs[5] = {"2","1.34","","0","1e-7"};
ASSERT_EQ(a_util::result::SUCCESS, pPolyTrf->setCoefficients(strCoefs));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.addTransformation("enum1", "enum_table"));
MapEnumTableTransformation *pEnumTrf = dynamic_cast<MapEnumTableTransformation*>(oConfig.getTransformation("enum1"));
ASSERT_TRUE(pEnumTrf);
ASSERT_EQ(a_util::result::SUCCESS, pEnumTrf->setEnums("tFEP_Driver_LightState", "tFEP_Driver_WiperState"));
ASSERT_EQ(a_util::result::SUCCESS, pEnumTrf->setDefault("WS_OnStandard"));
ASSERT_EQ(a_util::result::SUCCESS, pEnumTrf->addConversion("LS_Auto", "WS_OnStandard"));
ASSERT_EQ(a_util::result::SUCCESS, pEnumTrf->addConversion("LS_Parking", "WS_Off"));
ASSERT_EQ(a_util::result::SUCCESS, pEnumTrf->addConversion("LS_OnHighBeam", "WS_Auto"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.addTarget("target1", "tFEP_Driver_LongitudinalControl"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.addTarget("target2", "tFEP_Driver_WiperControl"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.addSource("source1", "tFEP_Driver_LateralControl"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.addSource("source2", "tFEP_Driver_LightControl"));
// set constant
MapAssignment oAssign1("f32ThrottlePedal");
ASSERT_EQ(a_util::result::SUCCESS, oAssign1.setConstant("12"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.getTarget("target1")->addAssignment(oAssign1));
ASSERT_EQ(oConfig.getTarget("target1")->getAssignmentList()[0].getConstant() , "12");
// set connection with polynomial trasnformation
MapAssignment oAssign2("f32BrakePedal");
ASSERT_EQ(a_util::result::SUCCESS, oAssign2.connect("source1.f32SteeringWheel"));
ASSERT_EQ(a_util::result::SUCCESS, oAssign2.setTransformation("poly1"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.getTarget("target1")->addAssignment(oAssign2));
ASSERT_EQ(oConfig.getTarget("target1")->getAssignmentList()[1].getFrom() , "f32SteeringWheel");
ASSERT_EQ(oConfig.getTarget("target1")->getAssignmentList()[1].getSource() , "source1");
// set connection with enum trasnformation
MapAssignment oAssignEnum("eFrontState");
ASSERT_EQ(a_util::result::SUCCESS, oAssignEnum.connect("source2.eLightState"));
ASSERT_EQ(a_util::result::SUCCESS, oAssignEnum.setTransformation("enum1"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.getTarget("target2")->addAssignment(oAssignEnum));
ASSERT_EQ(oConfig.getTarget("target2")->getAssignmentList()[0].getFrom() , "eLightState");
ASSERT_EQ(oConfig.getTarget("target2")->getAssignmentList()[0].getSource() , "source2");
// set SimulationTime function
MapAssignment oAssign3("f32ClutchPedal");
ASSERT_EQ(a_util::result::SUCCESS, oAssign3.setSimulationTimeFunction());
ASSERT_EQ(a_util::result::SUCCESS, oConfig.getTarget("target1")->addAssignment(oAssign3));
ASSERT_EQ(oConfig.getTarget("target1")->getAssignmentList()[2].getFunction() , "simulation_time");
ASSERT_TRUE(oConfig.getTarget("target1")->getAssignmentList()[2].getSource().empty());
// set TriggerCounter function
MapAssignment oAssign4("f32AccelTarget");
ASSERT_EQ(a_util::result::SUCCESS, oAssign4.setTriggerCounterFunction("5"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.getTarget("target1")->addAssignment(oAssign4));
ASSERT_EQ(oConfig.getTarget("target1")->getAssignmentList()[3].getFunction() , "trigger_counter");
ASSERT_EQ(oConfig.getTarget("target1")->getAssignmentList()[3].getModulo() , "5");
// set Received function
MapAssignment oAssign5("ui32ValidityMask");
ASSERT_EQ(a_util::result::SUCCESS, oAssign5.setReceivedFunction("source1"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.getTarget("target1")->addAssignment(oAssign5));
ASSERT_EQ(oConfig.getTarget("target1")->getAssignmentList()[4].getFunction() , "received");
ASSERT_EQ(oConfig.getTarget("target1")->getAssignmentList()[4].getSource() , "source1");
// set Triggers
MapPeriodicTrigger* pPTrigger = new MapPeriodicTrigger(&oConfig);
ASSERT_EQ(a_util::result::SUCCESS, pPTrigger->setPeriod("10","s"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.getTarget("target1")->addTrigger(pPTrigger));
ASSERT_TRUE(oConfig.getTarget("target1")->getTriggerList()[0]->isEqual(*pPTrigger));
MapSignalTrigger* pSTrigger = new MapSignalTrigger(&oConfig);
ASSERT_EQ(a_util::result::SUCCESS, pSTrigger->setVariable("source1"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.getTarget("target1")->addTrigger(pSTrigger));
ASSERT_TRUE(oConfig.getTarget("target1")->getTriggerList()[1]->isEqual(*pSTrigger));
MapDataTrigger* pDTrigger = new MapDataTrigger(&oConfig);
ASSERT_EQ(a_util::result::SUCCESS, pDTrigger->setComparison("source1.f32SteeringWheel", "less_than", "1"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.getTarget("target1")->addTrigger(pDTrigger));
ASSERT_TRUE(oConfig.getTarget("target1")->getTriggerList()[2]->isEqual(*pDTrigger));
// Write in file
ASSERT_EQ(a_util::result::SUCCESS, oConfig.writeToFile("files/generated_simple.map"));
ASSERT_TRUE(a_util::filesystem::remove("files/generated_simple.map"));
}
/**
* @detail Test fail to add erroneous elements
*/
TEST(cTesterMapping,
TestWriteMapFailConfig)
{
TEST_REQ("CDPKGDDL-28");
std::unique_ptr<ddl::DDLDescription> poDDL(LoadDDL("files/test.description"));
MapConfiguration oConfig(poDDL.get());
/**
* Signals
**/
ASSERT_EQ(oConfig.addTarget("target", "") , ERR_INVALID_TYPE);
ASSERT_EQ(oConfig.addSource("source", "nothing") , ERR_INVALID_TYPE);
ASSERT_EQ(oConfig.getSourceList().size() , 0);
ASSERT_EQ(oConfig.getTargetList().size() , 0);
/**
* Create basis mapping
**/
ASSERT_EQ(a_util::result::SUCCESS, oConfig.addTarget("target1", "tFEP_Driver_LongitudinalControl"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.addSource("source1", "tFEP_Driver_LateralControl"));
MapAssignment oAssign1("f32ThrottlePedal");
ASSERT_EQ(a_util::result::SUCCESS, oAssign1.setConstant("12"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.getTarget("target1")->addAssignment(oAssign1));
/**
* Transformations
**/
MapPolynomTransformation *pPolyTrf = new MapPolynomTransformation(&oConfig, "poly1");
// Coefficient not float
std::string strCoefs[5] = {"not_a_float","1.34","","0","1e-7"};
ASSERT_EQ(pPolyTrf->setCoefficients(strCoefs) , ERR_INVALID_ARG);
MapEnumTableTransformation *pEnumTrf = new MapEnumTableTransformation(&oConfig, "enum1");
// Enum does not exist
ASSERT_EQ(pEnumTrf->setEnums("not_an_enum", "tFEP_Driver_WiperState") , ERR_INVALID_TYPE);
ASSERT_EQ(pEnumTrf->setDefault("WS_OnStandard") , ERR_INVALID_TYPE);
ASSERT_EQ(pEnumTrf->addConversion("LS_Auto", "WS_OnStandard") , ERR_INVALID_TYPE);
// Default does not exist
ASSERT_EQ(a_util::result::SUCCESS, pEnumTrf->setEnums("tFEP_Driver_LightState", "tFEP_Driver_WiperState"));
ASSERT_EQ(pEnumTrf->setDefault("not_in_enum") , ERR_INVALID_TYPE);
ASSERT_EQ(a_util::result::SUCCESS, pEnumTrf->addConversion("LS_Auto", "WS_OnStandard"));
// Enum element does not exist
ASSERT_EQ(a_util::result::SUCCESS, pEnumTrf->setEnums("tFEP_Driver_LightState", "tFEP_Driver_WiperState"));
ASSERT_EQ(a_util::result::SUCCESS, pEnumTrf->setDefault("WS_OnStandard"));
ASSERT_EQ(pEnumTrf->addConversion("not_in_enum", "WS_OnStandard") , ERR_INVALID_TYPE);
delete pEnumTrf;
delete pPolyTrf;
/**
* Assignments
**/
//Target does not exist
ASSERT_FALSE(oConfig.getTarget("not_a_target"));
// set same elements twice
ASSERT_EQ(oConfig.addTarget("target1", "tFEP_Driver_LongitudinalControl") , ERR_INVALID_ARG);
ASSERT_EQ(oConfig.addSource("target1", "tFEP_Driver_DriverCtrl") , ERR_INVALID_ARG);
ASSERT_EQ(oConfig.getTarget("target1")->addAssignment(oAssign1) , ERR_INVALID_ARG);
ASSERT_EQ(oConfig.getSourceList().size() , 1);
ASSERT_EQ(oConfig.getTargetList().size() , 1);
ASSERT_EQ(oConfig.getTarget("target1")->getAssignmentList().size() , 1);
// set bad assignments
MapAssignment oAssignEmpty;
ASSERT_EQ(oConfig.getTarget("target1")->addAssignment(oAssignEmpty) , ERR_INVALID_ARG);
ASSERT_EQ(oConfig.getErrorList().size() , 1);
ASSERT_EQ(oConfig.getTarget("target1")->getAssignmentList().size() , 1);
MapAssignment oAssign2("f32BrakePedal");
ASSERT_EQ(oConfig.getTarget("target1")->addAssignment(oAssign2) , ERR_INVALID_ARG);
ASSERT_EQ(oConfig.getErrorList().size() , 1);
ASSERT_EQ(oConfig.getTarget("target1")->getAssignmentList().size() , 1);
ASSERT_EQ(a_util::result::SUCCESS, oAssign2.connect("source1.nothing"));
ASSERT_EQ(oConfig.getTarget("target1")->addAssignment(oAssign2) , ERR_INVALID_TYPE);
ASSERT_EQ(oConfig.getErrorList().size() , 1);
ASSERT_EQ(oConfig.getTarget("target1")->getAssignmentList().size() , 1);
ASSERT_EQ(a_util::result::SUCCESS, oAssign2.setConstant("text"));
ASSERT_EQ(oConfig.getTarget("target1")->addAssignment(oAssign2) , ERR_INVALID_ARG);
ASSERT_EQ(oConfig.getErrorList().size() , 1);
ASSERT_EQ(oConfig.getTarget("target1")->getAssignmentList().size() , 1);
ASSERT_EQ(a_util::result::SUCCESS, oAssign2.setReceivedFunction("nothing"));
ASSERT_EQ(oConfig.getTarget("target1")->addAssignment(oAssign2) , ERR_INVALID_ARG);
ASSERT_EQ(oConfig.getErrorList().size() , 1);
ASSERT_EQ(oConfig.getTarget("target1")->getAssignmentList().size() , 1);
// Transformation does not exist
ASSERT_EQ(a_util::result::SUCCESS, oAssign2.connect("source1.f32SteeringWheel"));
ASSERT_EQ(a_util::result::SUCCESS, oAssign2.setTransformation("not_a_transformation"));
ASSERT_EQ(oConfig.getTarget("target1")->addAssignment(oAssign2) , ERR_INVALID_ARG);
ASSERT_EQ(oConfig.getErrorList().size() , 1);
ASSERT_EQ(oConfig.getTarget("target1")->getAssignmentList().size() , 1);
/**
* Triggers
**/
// Period is not a number
MapPeriodicTrigger* pPTrigger = new MapPeriodicTrigger(&oConfig);
ASSERT_EQ(pPTrigger->setPeriod("10s","s") , ERR_INVALID_ARG);
// Variable is not in source list
MapSignalTrigger* pSTrigger = new MapSignalTrigger(&oConfig);
ASSERT_EQ(pSTrigger->setVariable("not_a_source") , ERR_INVALID_ARG);
ASSERT_EQ(oConfig.getTarget("target1")->addTrigger(pSTrigger) , ERR_INVALID_ARG);
// Variable not an element
MapDataTrigger* pDTrigger = new MapDataTrigger(&oConfig);
ASSERT_EQ(pDTrigger->setComparison("source1.not_an_element", "less_than", "1") , ERR_INVALID_TYPE);
ASSERT_EQ(oConfig.getTarget("target1")->addTrigger(pDTrigger) , ERR_INVALID_TYPE);
// No trigger added
ASSERT_EQ(oConfig.getTarget("target1")->getTriggerList().size() , 0);
/**
* Remove dll
**/
oConfig.modifyDescription(NULL);
ASSERT_EQ(a_util::result::SUCCESS, oAssign2.setConstant("12"));
ASSERT_EQ(oConfig.getTarget("target1")->addAssignment(oAssign2) , ERR_INVALID_STATE);
delete pDTrigger;
delete pSTrigger;
delete pPTrigger;
}
/**
* @detail Test load files partially when ddl not complete is
*/
TEST(cTesterMapping,
TestLoadMapPartiallyConfig)
{
TEST_REQ("CDPKGDDL-28");
MapConfiguration oConfig;
a_util::xml::DOM oDom;
ASSERT_TRUE(oDom.load("files/base.map"));
ASSERT_NE(a_util::result::SUCCESS, oConfig.loadPartiallyFromDOM(oDom));
// Verify source list
ASSERT_EQ(oConfig.getSourceList().size() , 4);
ASSERT_TRUE(oConfig.getSource("Light"));
ASSERT_TRUE(oConfig.getSource("Wiper"));
ASSERT_TRUE(oConfig.getSource("AALA"));
ASSERT_TRUE(oConfig.getSource("Additional"));
ASSERT_EQ(oConfig.getSource("Light")->getType() , "tFEP_Driver_LightControl");
ASSERT_EQ(oConfig.getSource("Wiper")->getType() , "tFEP_Driver_WiperControl");
ASSERT_EQ(oConfig.getSource("AALA")->getType() , "tFEP_Driver_AalaControl");
ASSERT_EQ(oConfig.getSource("Additional")->getType() , "tFEP_Driver_AdditionalControl");
ASSERT_FALSE(oConfig.getSource("Light")->isValid());
ASSERT_FALSE(oConfig.getSource("Wiper")->isValid());
ASSERT_FALSE(oConfig.getSource("AALA")->isValid());
ASSERT_FALSE(oConfig.getSource("Additional")->isValid());
// Verify target list
ASSERT_EQ(oConfig.getTargetList().size() , 1);
ASSERT_TRUE(oConfig.getTarget("Signal"));
ASSERT_EQ(oConfig.getTarget("Signal")->getType() , "tFEP_Driver_DriverCtrl");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList().size() , 13);
ASSERT_FALSE(oConfig.getTarget("Signal")->isValid());
// Cannot write incomplete mapping
ASSERT_NE(a_util::result::SUCCESS, oConfig.writeToFile("files/generated_never_base.map"));
// set valid DDL
std::unique_ptr<ddl::DDLDescription> poDDL(LoadDDL("files/test.description"));
oConfig.modifyDescription(poDDL.get());
// Verify source list
ASSERT_TRUE(oConfig.getSource("Light")->isValid());
ASSERT_TRUE(oConfig.getSource("Wiper")->isValid());
ASSERT_TRUE(oConfig.getSource("AALA")->isValid());
ASSERT_TRUE(oConfig.getSource("Additional")->isValid());
// Verify target list
ASSERT_EQ(oConfig.getTargetList().size() , 1);
ASSERT_TRUE(oConfig.getTarget("Signal"));
ASSERT_EQ(oConfig.getTarget("Signal")->getType() , "tFEP_Driver_DriverCtrl");
ASSERT_EQ(oConfig.getTarget("Signal")->getAssignmentList().size() , 13);
ASSERT_TRUE(oConfig.getTarget("Signal")->isValid());
ASSERT_EQ(a_util::result::SUCCESS, oConfig.writeToFile("files/generated_partially_base.map"));
ASSERT_TRUE(a_util::filesystem::remove("files/generated_partially_base.map"));
}
/**
* @detail Test to modify a mapping
*/
TEST(cTesterMapping,
TestModifyMapConfig)
{
TEST_REQ("CDPKGDDL-28");
std::unique_ptr<ddl::DDLDescription> poDDL(LoadDDL("files/test.description"));
MapConfiguration oConfig(poDDL.get());
a_util::xml::DOM oDom;
ASSERT_TRUE(oDom.load("files/base.map"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.loadFromDOM(oDom));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.getSource("Light")->setName("new_Light"));
ASSERT_TRUE(oConfig.getSource("new_Light"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.getSource("Additional")->setType("tFEP_Driver_LateralControl"));
ASSERT_EQ(oConfig.getSource("Additional")->getType() , "tFEP_Driver_LateralControl");
ASSERT_EQ(a_util::result::SUCCESS, oConfig.getTarget("Signal")->setName("new_Signal"));
ASSERT_TRUE(oConfig.getTarget("new_Signal"));
ASSERT_EQ(a_util::result::SUCCESS, oConfig.writeToFile("files/generated_modified_base.map"));
ASSERT_TRUE(a_util::filesystem::remove("files/generated_modified_base.map"));
// Modify target type, mapping is not valid anymore
ASSERT_EQ(oConfig.getTarget("new_Signal")->setType("tFEP_Driver_LateralControl") , ERR_INVALID_TYPE);
ASSERT_EQ(oConfig.getTarget("new_Signal")->getType() , "tFEP_Driver_LateralControl");
const MapAssignmentList lst = oConfig.getTarget("new_Signal")->getAssignmentList();
for(MapAssignmentList::const_iterator it = lst.begin(); it != lst.end(); it++)
{
if(it->getTo() == "ui32ValidityMask")
{
ASSERT_TRUE(it->isValid());
}
else
{
ASSERT_FALSE(it->isValid());
}
}
}
/// stripped down version of the internal helper class fep::cDDLManager used below
class TestDDLManager
{
ddl::DDLDescription* m_poDDL;
public:
TestDDLManager() : m_poDDL(NULL)
{
m_poDDL = DDLDescription::createDefault();
}
~TestDDLManager()
{
delete m_poDDL;
m_poDDL = NULL;
}
a_util::result::Result loadDDLFile(const std::string& strFile)
{
std::string strDDL;
if (a_util::filesystem::readTextFile(strFile, strDDL) != a_util::filesystem::OK)
{
return ERR_INVALID_FILE;
}
ddl::DDLImporter oImp;
a_util::result::Result nRes = oImp.setXML(strDDL);
if (a_util::result::isOk(nRes))
{
nRes = oImp.createNew();
}
if (a_util::result::isFailed(nRes))
{
nRes = ERR_INVALID_ARG;
}
if (a_util::result::isOk(nRes))
{
delete m_poDDL;
m_poDDL = oImp.getDDL();
}
return nRes;
}
a_util::result::Result ResolveType(const std::string& strType, std::string& strDestination) const
{
a_util::result::Result nRes = a_util::result::SUCCESS;
if (strType.empty())
{
nRes = ERR_NOT_FOUND;
}
if (a_util::result::isOk(nRes))
{
nRes = ERR_NOT_FOUND;
// since the DDL resolver searches units, datatypes, structs and streams
// we need to make sure first that the type is a struct - since only them are supported
DDLComplexVec vecStructs = m_poDDL->getStructs();
DDLComplexIt itStruct =
std::find_if(vecStructs.begin(), vecStructs.end(), DDLCompareFunctor<>(strType));
if (itStruct != vecStructs.end())
{
DDLResolver oDDLResolver;
oDDLResolver.setTargetName(strType);
if (a_util::result::isOk(oDDLResolver.visitDDL(m_poDDL)))
{
strDestination = oDDLResolver.getResolvedXML();
nRes = a_util::result::SUCCESS;
}
}
}
return nRes;
}
const ddl::DDLDescription& getDDL() const
{
return *m_poDDL;
}
};
/// Test class that drives the mapping engine in a standalone fashion
/// It also provides easy access to source and target buffers to make the test easy to read
#pragma warning(disable: 4355)
class MappingDriver : private IMappingEnvironment
{
struct Signal
{
std::string strName;
std::string strType;
ISignalListener* pListener;
};
struct sPeriodicWrapper
{
a_util::system::Timer oTimer;
mapping::rt::IPeriodicListener* pListener;
sPeriodicWrapper() : pListener(NULL) {}
void TimerFunc()
{
pListener->onTimer(a_util::system::getCurrentMicroseconds());
}
};
typedef std::map<mapping::rt::IPeriodicListener*, sPeriodicWrapper*> tPeriodicWrappers;
TestDDLManager m_oManager;
MapConfiguration m_oConfig;
MappingEngine m_oEngine;
std::map<std::string, Signal> mapSources;
std::map<std::string, a_util::memory::shared_ptr<ddl::StaticCodec> > mapSourceCoders;
std::map<std::string, Target::MemoryBuffer> mapSourceBuffers;
std::map<std::string, a_util::memory::shared_ptr<ddl::StaticCodec> > mapTargetCoders;
std::map<std::string, Target::MemoryBuffer> mapTargetBuffers;
std::map<std::string, handle_t> mapTargetHandle;
std::map<handle_t, std::string> mapHandleTarget;
tPeriodicWrappers m_mapPeriodicWrappers;
public:
MappingDriver(const std::string& strDDL, const std::string& strMapping) : m_oEngine(*this)
{
setup(strDDL, strMapping);
}
~MappingDriver()
{
m_oEngine.stop();
m_oEngine.unmapAll();
mapSourceCoders.clear();
mapTargetCoders.clear();
}
void setup(const std::string& strDDL, const std::string& strMapping)
{
// setup engine
ASSERT_EQ(a_util::result::SUCCESS, m_oManager.loadDDLFile(strDDL));
ASSERT_EQ(a_util::result::SUCCESS, m_oConfig.setDescription(&m_oManager.getDDL()));
ASSERT_EQ(a_util::result::SUCCESS, m_oConfig.loadFromFile(strMapping, MapConfiguration::mc_load_mapping));
ASSERT_EQ(a_util::result::SUCCESS, m_oEngine.setConfiguration(m_oConfig));
}
void addTarget(const std::string& strTarget)
{
ASSERT_EQ(mapTargetCoders.find(strTarget) , mapTargetCoders.end());
// map target
ASSERT_EQ(a_util::result::SUCCESS, m_oEngine.Map(strTarget, mapTargetHandle[strTarget]));
mapHandleTarget[mapTargetHandle[strTarget]] = strTarget;
const MapTarget* pTarget = m_oConfig.getTarget(strTarget);
// create source buffers and coders
const MapSourceNameList& lstSources = pTarget->getReferencedSources();
for (MapSourceNameList::const_iterator it = lstSources.begin(); it != lstSources.end(); ++it)
{
const MapSource* pMapSource = m_oConfig.getSource(*it);
if(mapSourceCoders.find(std::string(pMapSource->getName())) == mapSourceCoders.end())
{
std::string strSourceDesc;
ASSERT_EQ(a_util::result::SUCCESS, m_oManager.ResolveType(pMapSource->getType(), strSourceDesc));
ddl::CodecFactory oFac(pMapSource->getType().c_str(), strSourceDesc.c_str());
ASSERT_EQ(a_util::result::SUCCESS, oFac.isValid());
Target::MemoryBuffer& oSourceBuffer = mapSourceBuffers[pMapSource->getName()];
oSourceBuffer.resize(oFac.getStaticBufferSize(), 0);
mapSourceCoders.insert(std::make_pair(std::string(pMapSource->getName()),
a_util::memory::shared_ptr<ddl::StaticCodec>(new ddl::StaticCodec(
oFac.makeStaticCodecFor(&oSourceBuffer[0], oSourceBuffer.size())))));
}
}
// create target buffer and coder
std::string strTargetDesc;
ASSERT_EQ(a_util::result::SUCCESS, m_oManager.ResolveType(pTarget->getType(), strTargetDesc));
ddl::CodecFactory oFac(pTarget->getType().c_str(), strTargetDesc.c_str());
ASSERT_EQ(a_util::result::SUCCESS, oFac.isValid());
Target::MemoryBuffer& oTargetBuffer = mapTargetBuffers[strTarget];
oTargetBuffer.resize(oFac.getStaticBufferSize(), 0);
mapTargetCoders.insert(std::make_pair(strTarget, a_util::memory::shared_ptr<ddl::StaticCodec>(new ddl::StaticCodec(
oFac.makeStaticCodecFor(&oTargetBuffer[0], oTargetBuffer.size())))));
ddl::StaticCodec& oTargetCoder = *mapTargetCoders[strTarget];
}
void resetEngine()
{
// reset engine
ASSERT_EQ(a_util::result::SUCCESS, m_oEngine.reset());
}
void startEngine()
{
// start engine
ASSERT_EQ(a_util::result::SUCCESS, m_oEngine.start());
}
void stopEngine()
{
// start engine
ASSERT_EQ(a_util::result::SUCCESS, m_oEngine.stop());
}
bool targetHasTriggers(const std::string& signal_name)
{
// look for trigger
handle_t target_handle = mapTargetHandle[signal_name];
return m_oEngine.hasTriggers(target_handle);
}
ddl::StaticCodec& getTargetCoder(const std::string& strTarget)
{
return *mapTargetCoders[strTarget];
}
ddl::StaticCodec& getSourceCoder(const std::string& strSource)
{
return *mapSourceCoders[strSource];
}
a_util::result::Result sendSourceBuffer(const std::string& strSource)
{
Target::MemoryBuffer& oSourceBuf = mapSourceBuffers[strSource];
return mapSources[strSource].pListener->onSampleReceived(&oSourceBuf[0], oSourceBuf.size());
}
a_util::result::Result receiveTargetBuffer(const std::string& strTarget)
{
Target::MemoryBuffer& oTargetBuffer = mapTargetBuffers[strTarget];
handle_t hTargetHandle = mapTargetHandle[strTarget];
return m_oEngine.getCurrentData(hTargetHandle, &oTargetBuffer[0], oTargetBuffer.size());
}
private:
a_util::result::Result registerSource(const char* strSourceName, const char* strTypeName,
ISignalListener* pListener, handle_t& hHandle)
{
Signal sig;
sig.strName = strSourceName;
sig.strType = strTypeName;
sig.pListener = pListener;
mapSources[strSourceName] = sig;
hHandle = (handle_t)&mapSources[strSourceName];
return a_util::result::SUCCESS;
}
a_util::result::Result unregisterSource(handle_t hHandle)
{ // dont care
return a_util::result::SUCCESS;
}
a_util::result::Result sendTarget(handle_t hTarget, const void* pData,
size_t szSize, timestamp_t tmTimeStamp)
{
if(szSize == mapTargetBuffers[mapHandleTarget[hTarget]].size())
{
a_util::memory::copy(&mapTargetBuffers[mapHandleTarget[hTarget]][0], szSize, pData, szSize);
}
return a_util::result::SUCCESS;
}
a_util::result::Result targetMapped(const char* strTargetName,
const char* strTargetType, handle_t hTarget, size_t szTargetType)
{
return a_util::result::SUCCESS;
}
a_util::result::Result targetUnmapped(const char* strTargetName, handle_t hTarget)
{
return a_util::result::SUCCESS;
}
a_util::result::Result resolveType(const char* strTypeName, const char*& strTypeDescription)
{
resolveTypeTest(strTypeName, strTypeDescription);
return a_util::result::SUCCESS;
}
void resolveTypeTest(const char* strTypeName, const char*& strTypeDescription)
{
static std::string strDesc;
ASSERT_EQ(a_util::result::SUCCESS, m_oManager.ResolveType(strTypeName, strDesc));
strTypeDescription = strDesc.c_str();
}
timestamp_t getTime() const
{
return a_util::system::getCurrentMicroseconds();
}
a_util::result::Result registerPeriodicTimer(timestamp_t tmPeriod_us, mapping::rt::IPeriodicListener* pListener)
{
sPeriodicWrapper* pWrap = new sPeriodicWrapper;
pWrap->pListener = pListener;
m_mapPeriodicWrappers[pListener] = pWrap;
pWrap->oTimer.setPeriod(tmPeriod_us + 1000);
pWrap->oTimer.setCallback(&sPeriodicWrapper::TimerFunc, *pWrap);
pWrap->oTimer.start();
return a_util::result::SUCCESS;
}
a_util::result::Result unregisterPeriodicTimer(timestamp_t tmPeriod_us, mapping::rt::IPeriodicListener* pListener)
{
tPeriodicWrappers::iterator it = m_mapPeriodicWrappers.find(pListener);
delete it->second;
m_mapPeriodicWrappers.erase(it);
return a_util::result::SUCCESS;
}
};
/**
* @detail Test Engine with default values
*/
TEST(cTesterMapping,
TestDefaultEngine)
{
TEST_REQ("FEPSDK-278");
MappingDriver base_test("files/engine.description", "files/engine_default.map");
base_test.addTarget("OutSignal");
base_test.startEngine();
ddl::StaticCodec& oTarget = base_test.getTargetCoder("OutSignal");
// Target in engine_default.map has no triggers
ASSERT_EQ(false, base_test.targetHasTriggers("OutSignal"));
// copy target buffer initially
base_test.receiveTargetBuffer("OutSignal");
a_util::variant::Variant var;
// test ddl defaults
ASSERT_EQ(ddl::access_element::get_value(oTarget, "i8Val").asInt8() , 42);
// test mapping contants defaults
ASSERT_EQ(ddl::access_element::get_value(oTarget, "i16Val").asInt16() , 3);
ASSERT_EQ(ddl::access_element::get_value(oTarget, "enumValDef").asInt16() , 60);
// test mapping contants defaults in structure
ASSERT_EQ(ddl::access_element::get_value(oTarget, "structMinimal.i8Val").asInt8() , 4);
}
/**
* @detail Test Engine for direct assignments
*/
TEST(cTesterMapping,
TestDirectMappingEngine)
{
TEST_REQ("FEPSDK-278");
MappingDriver base_test("files/engine.description", "files/engine_directmapping.map");
base_test.addTarget("OutSignal");
base_test.addTarget("OutSignal2");
base_test.startEngine();
ddl::StaticCodec& oTarget = base_test.getTargetCoder("OutSignal");
ddl::StaticCodec& oTarget2 = base_test.getTargetCoder("OutSignal2");
ddl::StaticCodec& oSource1 = base_test.getSourceCoder("MinimalSignal");
ddl::StaticCodec& oSource2 = base_test.getSourceCoder("InSignal");
ddl::StaticCodec& oSource3 = base_test.getSourceCoder("MinimalSignal2");
// Targets in engine_directmapping.map have no triggers
ASSERT_EQ(false, base_test.targetHasTriggers("OutSignal"));
ASSERT_EQ(false, base_test.targetHasTriggers("OutSignal2"));
bool bVal = false;
int8_t i8Val = 0;
int16_t i16Val = 0;
int32_t i32Val = 0;
int64_t i64Val = 0;
uint8_t ui8Val = 0;
uint16_t ui16Val = 0;
uint32_t ui32Val = 0;
uint64_t ui64Val = 0;
float f32Val = 0;
// Test mapping input with same type
i32Val = 42;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource1, "i32Val", a_util::variant::Variant(i32Val)));
base_test.sendSourceBuffer("MinimalSignal");
base_test.receiveTargetBuffer("OutSignal");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "i32Val").asInt32() , 42);
// Test mapping input with different type
f32Val = 42;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource1, "f32Val", a_util::variant::Variant(f32Val)));
base_test.sendSourceBuffer("MinimalSignal");
base_test.receiveTargetBuffer("OutSignal");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "i64Val").asInt64() , 42);
// Test mapping input array element with same type
f32Val = 1;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "f32Ary[0]", a_util::variant::Variant(f32Val)));
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "f32Ary[0]").asFloat() , 1);
// Test mapping input array element with different type
i32Val = 1;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource1, "i32Val", a_util::variant::Variant(i32Val)));
base_test.sendSourceBuffer("MinimalSignal");
base_test.receiveTargetBuffer("OutSignal");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "f32Ary[1]").asFloat() , 1);
// Test mapping enum
i16Val = 3;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "enumVal", a_util::variant::Variant(i16Val)));
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "enumVal").asInt16() , 3);
// Test mapping input structure element with same type
i16Val = 5;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource1, "i16Val", a_util::variant::Variant(i16Val)));
base_test.sendSourceBuffer("MinimalSignal");
base_test.receiveTargetBuffer("OutSignal");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "structMinimal.i16Val").asInt16() , 5);
// Test mapping input structure element with same type
i32Val = 5;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "structMinimal.i32Val", a_util::variant::Variant(i32Val)));
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "structMinimal.i32Val").asInt32() , 5);
// Test mapping input structure element with different type
ui32Val = 5;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "structMinimal.ui32Val", a_util::variant::Variant(ui32Val)));
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "structMinimal.i64Val").asInt64() , 5);
// Test mapping input structure with same type
i16Val = 15;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource1, "i16Val", a_util::variant::Variant(i16Val)));
base_test.sendSourceBuffer("MinimalSignal");
base_test.receiveTargetBuffer("OutSignal");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "structMinimalAry[0].i16Val").asInt16() , 15);
/**
* Test second Target
**/
base_test.receiveTargetBuffer("OutSignal2");
// test ddl defaults
ASSERT_EQ(ddl::access_element::get_value(oTarget2, "i8Val").asInt8() , 42);
// test mapping contants defaults
ASSERT_EQ(ddl::access_element::get_value(oTarget2, "i16Val").asInt16() , 3);
// Test mapping input structure with same type
i16Val = 15;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource3, "i16Val", a_util::variant::Variant(i16Val)));
base_test.sendSourceBuffer("MinimalSignal2");
base_test.receiveTargetBuffer("OutSignal2");
ASSERT_EQ(ddl::access_element::get_value(oTarget2, "structMinimalAry[0].i16Val").asInt16() , 15);
}
/**
* @detail Test Engine for assignments with transformation
*/
TEST(cTesterMapping,
TestTransformationsEngine)
{
TEST_REQ("FEPSDK-278");
MappingDriver base_test("files/engine.description", "files/engine_transformations.map");
base_test.addTarget("OutSignal");
base_test.addTarget("OutSignal2");
base_test.startEngine();
ddl::StaticCodec& oTarget = base_test.getTargetCoder("OutSignal");
ddl::StaticCodec& oTarget2 = base_test.getTargetCoder("OutSignal2");
ddl::StaticCodec& oSource1 = base_test.getSourceCoder("MinimalSignal");
ddl::StaticCodec& oSource2 = base_test.getSourceCoder("InSignal");
// Targets in engine_transformations.map have no triggers
ASSERT_EQ(false, base_test.targetHasTriggers("OutSignal"));
ASSERT_EQ(false, base_test.targetHasTriggers("OutSignal2"));
// Sources also have no triggers
ASSERT_EQ(false, base_test.targetHasTriggers("InSignal"));
ASSERT_EQ(false, base_test.targetHasTriggers("MinimalSignal"));
bool bVal = false;
int8_t i8Val = 0;
int16_t i16Val = 0;
int32_t i32Val = 0;
int64_t i64Val = 0;
uint8_t ui8Val = 0;
uint16_t ui16Val = 0;
uint32_t ui32Val = 0;
uint64_t ui64Val = 0;
float f32Val = 0;
// Test mapping input with same type and transformation
ui8Val = 4;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource1, "ui8Val", a_util::variant::Variant(ui8Val)));
base_test.sendSourceBuffer("MinimalSignal");
base_test.receiveTargetBuffer("OutSignal");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "ui8Val").asUInt8() , 6);
// Test mapping input with different type and transformation
f32Val = 4;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource1, "f32Val", a_util::variant::Variant(f32Val)));
base_test.sendSourceBuffer("MinimalSignal");
base_test.receiveTargetBuffer("OutSignal");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "ui16Val").asUInt16() , 6);
// Test mapping input array with same type with transformation
i8Val = 4;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "i8Ary[0]", a_util::variant::Variant(i8Val)));
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "i8Ary[9]", a_util::variant::Variant(i8Val)));
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "i8Ary[0]").asInt8() , 6);
ASSERT_EQ(ddl::access_element::get_value(oTarget, "i8Ary[9]").asInt8() , 6);
/**
* Test second Target
**/
base_test.receiveTargetBuffer("OutSignal2");
// Test mapping input with different type and transformation
f32Val = 4;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource1, "f32Val", a_util::variant::Variant(f32Val)));
base_test.sendSourceBuffer("MinimalSignal");
base_test.receiveTargetBuffer("OutSignal2");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "ui16Val").asUInt16() , 6);
// Test mapping input array with different type with transformation
f32Val = 4;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "f32Ary[0]", a_util::variant::Variant(f32Val)));
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "f32Ary[9]", a_util::variant::Variant(f32Val)));
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal2");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "i8Ary[0]").asInt8() , 6);
ASSERT_EQ(ddl::access_element::get_value(oTarget, "i8Ary[9]").asInt8() , 6);
// Test enum to enum transformation with same enum type
// Test conversion
i16Val = 20;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "enumVal", a_util::variant::Variant(i16Val)));
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal2");
ASSERT_EQ(ddl::access_element::get_value(oTarget2, "enumVal").asInt16() , 10);
i16Val = 40;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "enumVal", a_util::variant::Variant(i16Val)));
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal2");
ASSERT_EQ(ddl::access_element::get_value(oTarget2, "enumVal").asInt16() , 40);
i16Val = 50;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "enumVal", a_util::variant::Variant(i16Val)));
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal2");
ASSERT_EQ(ddl::access_element::get_value(oTarget2, "enumVal").asInt16() , 40);
i16Val = 10;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "enumVal", a_util::variant::Variant(i16Val)));
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal2");
ASSERT_EQ(ddl::access_element::get_value(oTarget2, "enumVal").asInt16() , 10);
i16Val = 29;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "enumVal", a_util::variant::Variant(i16Val)));
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal2");
ASSERT_EQ(ddl::access_element::get_value(oTarget2, "enumVal").asInt16() , 34);
i16Val = 52;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "enumVal", a_util::variant::Variant(i16Val)));
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal2");
ASSERT_EQ(ddl::access_element::get_value(oTarget2, "enumVal").asInt16() , 35);
// Test Default
i16Val = 60;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "enumVal", a_util::variant::Variant(i16Val)));
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal2");
ASSERT_EQ(ddl::access_element::get_value(oTarget2, "enumVal").asInt16() , 0);
// Test enum to enum transformation with different enum types
i16Val = 20;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "enumVal", a_util::variant::Variant(i16Val)));
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal2");
ASSERT_EQ(ddl::access_element::get_value(oTarget2, "enumVal2").asInt32() , 1);
i16Val = 40;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "enumVal", a_util::variant::Variant(i16Val)));
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal2");
ASSERT_EQ(ddl::access_element::get_value(oTarget2, "enumVal2").asInt32() , 2);
i16Val = 60;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource2, "enumVal", a_util::variant::Variant(i16Val)));
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal2");
ASSERT_EQ(ddl::access_element::get_value(oTarget2, "enumVal2").asInt32() , 3);
}
/**
* @detail Test Engine for macro assignments
*/
TEST(cTesterMapping,
TestMacrosEngine)
{
TEST_REQ("FEPSDK-278");
MappingDriver base_test("files/engine.description", "files/engine_macros.map");
base_test.addTarget("OutSignal");
base_test.startEngine();
ddl::StaticCodec& oTarget = base_test.getTargetCoder("OutSignal");
ddl::StaticCodec& oSource1 = base_test.getSourceCoder("MinimalSignal");
ddl::StaticCodec& oSource2 = base_test.getSourceCoder("InSignal");
// Target in engine_macros.map has triggers
ASSERT_EQ(true, base_test.targetHasTriggers("OutSignal"));
bool bVal = false;
uint32_t ui32Val = 0;
uint64_t ui64Val = 0;
// Test mapping with simulation_time
for (int i = 0; i < 10; ++i)
{
timestamp_t tmTime = a_util::system::getCurrentMicroseconds();
base_test.receiveTargetBuffer("OutSignal");
ASSERT_TRUE(ddl::access_element::get_value(oTarget, "ui64Val").asUInt64() >= (uint64_t)tmTime);
}
// Test mapping with trigger_counter
// Trigger three times
base_test.sendSourceBuffer("InSignal");
base_test.sendSourceBuffer("InSignal");
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "ui32Val").asUInt32() , 3);
/**
* Test Reset Engine
**/
base_test.stopEngine();
base_test.resetEngine();
base_test.startEngine();
// Test mapping with trigger_counter
base_test.receiveTargetBuffer("OutSignal");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "ui32Val").asUInt32() , 0);
base_test.sendSourceBuffer("InSignal");
base_test.receiveTargetBuffer("OutSignal");
ASSERT_EQ(ddl::access_element::get_value(oTarget, "ui32Val").asUInt32() , 1);
// Test received Boolean
ASSERT_FALSE(ddl::access_element::get_value(oTarget, "bVal").asBool());
base_test.sendSourceBuffer("MinimalSignal");
base_test.receiveTargetBuffer("OutSignal");
ASSERT_TRUE(ddl::access_element::get_value(oTarget, "bVal").asBool());
}
/**
* @detail Test Engine for triggers
*/
TEST(cTesterMapping,
TestTriggersEngine)
{
TEST_REQ("FEPSDK-278");
MappingDriver base_test("files/engine.description", "files/engine_triggers.map");
base_test.addTarget("OutSignal3");
base_test.startEngine();
ddl::StaticCodec& oTarget3 = base_test.getTargetCoder("OutSignal3");
ddl::StaticCodec& oSource1 = base_test.getSourceCoder("MinimalSignal");
ddl::StaticCodec& oSource2 = base_test.getSourceCoder("InSignal");
// You can guess if engine_triggers.map contains triggers
ASSERT_EQ(true, base_test.targetHasTriggers("OutSignal3"));
base_test.receiveTargetBuffer("OutSignal3");
ASSERT_EQ(ddl::access_element::get_value(oTarget3, "ui32Val").asUInt32(), 0 % 5);
// Test signal Trigger
base_test.sendSourceBuffer("InSignal");
ASSERT_EQ(ddl::access_element::get_value(oTarget3, "ui32Val").asUInt32(), 1 % 5);
// Test data Trigger
int32_t i32Val = -42;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource1, "i32Val", a_util::variant::Variant(i32Val)));
base_test.sendSourceBuffer("MinimalSignal"); // fires not_equal, less_than and less_than_equal
ASSERT_EQ(ddl::access_element::get_value(oTarget3, "ui32Val").asUInt32(), 4 % 5);
i32Val = -1;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource1, "i32Val", a_util::variant::Variant(i32Val)));
base_test.sendSourceBuffer("MinimalSignal"); // fires equal, not_equal, less_than and less_than_equal
ASSERT_EQ(ddl::access_element::get_value(oTarget3, "ui32Val").asUInt32(), 8 % 5);
i32Val = 42;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource1, "i32Val", a_util::variant::Variant(i32Val)));
base_test.sendSourceBuffer("MinimalSignal"); // fires not_equal, greater_than and greater_than_equal
ASSERT_EQ(ddl::access_element::get_value(oTarget3, "ui32Val").asUInt32(), 11 % 5);
i32Val = 3;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource1, "i32Val", a_util::variant::Variant(i32Val)));
base_test.sendSourceBuffer("MinimalSignal"); // fires not_equal and less_than_equal
ASSERT_EQ(ddl::access_element::get_value(oTarget3, "ui32Val").asUInt32(), 13 % 5);
i32Val = 4;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource1, "i32Val", a_util::variant::Variant(i32Val)));
base_test.sendSourceBuffer("MinimalSignal"); // fires not_equal and greater_than_equal
ASSERT_EQ(ddl::access_element::get_value(oTarget3, "ui32Val").asUInt32(), 15 % 5);
i32Val = 2;
ASSERT_EQ(a_util::result::SUCCESS, ddl::access_element::set_value(oSource1, "i32Val", a_util::variant::Variant(i32Val)));
base_test.sendSourceBuffer("MinimalSignal"); // fires less_than and less_than_equal
ASSERT_EQ(ddl::access_element::get_value(oTarget3, "ui32Val").asUInt32(), 17 % 5);
}