Skip to content
This repository was archived by the owner on Aug 5, 2022. It is now read-only.

Commit 49c3d81

Browse files
committed
Merge pull request #330 from krocard/add-functional-test-for-element-handle
Add functional tests for element handle Test the following ElementHandle apis: - `getMappingData` - `{s,g}etAsXML` with Raw and Hex format
2 parents 3d58c6f + 19c1c5d commit 49c3d81

File tree

12 files changed

+160
-81
lines changed

12 files changed

+160
-81
lines changed

parameter/ConfigurableElement.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -275,18 +275,19 @@ bool CConfigurableElement::setSettingsAsBytes(const std::vector<uint8_t> &bytes,
275275
return true;
276276
}
277277

278-
void CConfigurableElement::getListOfElementsWithMapping(
279-
std::list<const CConfigurableElement *> &configurableElementPath) const
278+
std::list<const CConfigurableElement *> CConfigurableElement::getConfigurableElementContext() const
280279
{
281-
// Check parent
282-
const CElement *pParent = getParent();
283-
if (isOfConfigurableElementType(pParent)) {
280+
std::list<const CConfigurableElement *> configurableElementPath;
284281

285-
const CConfigurableElement *pConfigurableElement =
286-
static_cast<const CConfigurableElement *>(pParent);
282+
const CElement *element = this;
283+
while (element != nullptr and isOfConfigurableElementType(element)) {
284+
auto configurableElement = static_cast<const CConfigurableElement *>(element);
287285

288-
pConfigurableElement->getListOfElementsWithMapping(configurableElementPath);
286+
configurableElementPath.push_back(configurableElement);
287+
element = element->getParent();
289288
}
289+
290+
return configurableElementPath;
290291
}
291292

292293
// Used for simulation and virtual subsystems

parameter/ConfigurableElement.h

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -133,22 +133,11 @@ class PARAMETER_EXPORT CConfigurableElement : public CElement
133133
bool setSettingsAsBytes(const std::vector<uint8_t> &bytes,
134134
CParameterAccessContext &parameterAccessContext) const;
135135

136-
/**
137-
* Get the list of all the ancestors that have a mapping.
138-
*
139-
* The mapping is represented as a std::string of all the mapping data (key:value) defined in
140-
* the
141-
* context of the element.
142-
* In this class, the method is generic and calls its parent getListOfElementsWithMappings(...)
143-
* method.
144-
*
145-
* @param[in:out] configurableElementPath List of all the ConfigurableElements found
146-
* that have a mapping. Elements are added at the end of the list, so the root Element will be
147-
* the last one.
136+
/** @return List of all ConfigurableElements that have a mapping relevant in this context.
137+
* Ie: return self and CConfigurableElement ancestor of this node.
148138
*
149139
*/
150-
virtual void getListOfElementsWithMapping(
151-
std::list<const CConfigurableElement *> &configurableElementPath) const;
140+
std::list<const CConfigurableElement *> getConfigurableElementContext() const;
152141

153142
// Used for simulation and virtual subsystems
154143
virtual void setDefaultValues(CParameterAccessContext &parameterAccessContext) const;

parameter/ElementHandle.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,16 @@ bool ElementHandle::getMappingData(const string &strKey, string &strValue) const
116116
{
117117
const std::string *pStrValue;
118118

119-
if (!mElement.getMappingData(strKey, pStrValue)) {
120-
return false;
121-
}
119+
// Seach for the key in self and ancestors
120+
auto elements = mElement.getConfigurableElementContext();
122121

123-
strValue = *pStrValue;
124-
return true;
122+
for (auto *element : elements)
123+
if (element->getMappingData(strKey, pStrValue)) {
124+
strValue = *pStrValue;
125+
return true;
126+
}
127+
128+
return false;
125129
}
126130

127131
bool ElementHandle::getStructureAsXML(std::string &xmlSettings, std::string &error) const

parameter/InstanceConfigurableElement.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -114,19 +114,6 @@ bool CInstanceConfigurableElement::map(IMapper &mapper, std::string &strError)
114114
return true;
115115
}
116116

117-
void CInstanceConfigurableElement::getListOfElementsWithMapping(
118-
std::list<const CConfigurableElement *> &configurableElementPath) const
119-
{
120-
const CTypeElement *pTypeElement = getTypeElement();
121-
122-
if (pTypeElement && pTypeElement->hasMappingData()) {
123-
124-
configurableElementPath.push_back(this);
125-
}
126-
127-
base::getListOfElementsWithMapping(configurableElementPath);
128-
}
129-
130117
// Element properties
131118
void CInstanceConfigurableElement::showProperties(std::string &strResult) const
132119
{

parameter/InstanceConfigurableElement.h

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -92,22 +92,6 @@ class PARAMETER_EXPORT CInstanceConfigurableElement : public CConfigurableElemen
9292
// Array Length
9393
size_t getArrayLength() const;
9494

95-
/**
96-
* Get the list of all the ancestors that have a mapping.
97-
*
98-
* The mapping is represented as a std::string of all the mapping data (key:value) defined in
99-
* the
100-
* context of the element.
101-
* In this class, the method is generic and calls its parent getListOfElementsWithMappings(...)
102-
* method.
103-
*
104-
* @param[in:out] configurableElementPath List of all the ConfigurableElements found
105-
* that have a mapping. Elements are added at the end of the list, so the root Element will be
106-
* the last one.
107-
*/
108-
virtual void getListOfElementsWithMapping(
109-
std::list<const CConfigurableElement *> &configurableElementPath) const;
110-
11195
virtual void structureToXml(CXmlElement &xmlElement,
11296
CXmlSerializingContext &serializingContext) const;
11397

parameter/ParameterMgr.cpp

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1993,14 +1993,6 @@ bool CParameterMgr::accessParameterValue(const string &strPath, string &strValue
19931993
// User get parameter mapping
19941994
bool CParameterMgr::getParameterMapping(const string &strPath, string &strResult) const
19951995
{
1996-
CPathNavigator pathNavigator(strPath);
1997-
1998-
// Nagivate through system class
1999-
if (!pathNavigator.navigateThrough(getConstSystemClass()->getName(), strResult)) {
2000-
2001-
return false;
2002-
}
2003-
20041996
// Get the ConfigurableElement corresponding to strPath
20051997
const CConfigurableElement *pConfigurableElement = getConfigurableElement(strPath, strResult);
20061998
if (!pConfigurableElement) {
@@ -2009,8 +2001,7 @@ bool CParameterMgr::getParameterMapping(const string &strPath, string &strResult
20092001
}
20102002

20112003
// Find the list of the ancestors of the current ConfigurableElement that have a mapping
2012-
list<const CConfigurableElement *> configurableElementPath;
2013-
pConfigurableElement->getListOfElementsWithMapping(configurableElementPath);
2004+
auto configurableElementPath = pConfigurableElement->getConfigurableElementContext();
20142005

20152006
// Get the Subsystem containing the ConfigurableElement
20162007
const CSubsystem *pSubsystem = pConfigurableElement->getBelongingSubsystem();

parameter/include/ElementHandle.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,10 @@ class PARAMETER_EXPORT ElementHandle
9191

9292
std::vector<ElementHandle> getChildren();
9393

94-
/** Get Mapping Data
94+
/** Get mapping data of the element context
9595
*
96-
* Retrieve Mapping data associated to a given key if any
96+
* Retrieve mapping data associated to a given key if any.
97+
* If the key is not present in this element, query ancestors.
9798
*
9899
* @param[in] strKey the input mapping key
99100
* @param[out] strValue the resulting mapping value in case of success

test/functional-tests/Handle.cpp

Lines changed: 113 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,12 @@
4242
#include <libxml/tree.h>
4343

4444
#include <string>
45+
#include <list>
46+
47+
#include <stdlib.h>
4548

4649
using std::string;
50+
using std::list;
4751
using Bytes = std::vector<uint8_t>;
4852

4953
namespace parameterFramework
@@ -156,11 +160,21 @@ struct AllParamsPF : public ParameterFramework
156160
if (result != expected) {
157161
utility::TmpFile resultFile(result);
158162
utility::TmpFile expectedFile(expected);
159-
auto gitCommand = "git --no-pager diff --word-diff-regex='[^ <>]+' --color --no-index ";
160-
auto diffSuccess =
161-
system((gitCommand + resultFile.getPath() + ' ' + expectedFile.getPath()).c_str());
162-
if (diffSuccess != 0) {
163-
WARN("Failed to pretty-print the difference between actual and expected results.");
163+
string command = "git --no-pager diff --word-diff-regex='[^ <>]+'"
164+
" --color --no-index --exit-code " +
165+
resultFile.getPath() + ' ' + expectedFile.getPath();
166+
167+
// `system` return -1 or 127 on failure, the command error code otherwise
168+
// `git diff` return 1 if the files are the different (thanks to --exit-code)
169+
auto status = system(command.c_str());
170+
#ifdef WIFEXITED // Posix platform
171+
bool success = WIFEXITED(status) and WEXITSTATUS(status) == 1;
172+
#else
173+
bool success = status == 1;
174+
#endif
175+
if (not success) {
176+
WARN("Warning: Failed to pretty-print the difference between "
177+
"actual and expected results with `git diff'");
164178
}
165179
}
166180
}
@@ -363,6 +377,24 @@ static const char *testBasicSettingsXML = R"(
363377
<BitParameter Name="thirty_two">4294967295</BitParameter>
364378
</BitParameterBlock>
365379
)";
380+
static const char *testRawHexBasicSettingsXML = R"(
381+
<BooleanParameter Name="bool">0x1</BooleanParameter>
382+
<BooleanParameter Name="bool_array">0x0 0x1</BooleanParameter>
383+
<IntegerParameter Name="integer">0x0064</IntegerParameter>
384+
<IntegerParameter Name="integer_array">0xFFFFFFF6 0x00000000 0x00000008 0x0000000A</IntegerParameter>
385+
<FixedPointParameter ValueSpace="Raw" Name="fix_point">0x24000000</FixedPointParameter>
386+
<FixedPointParameter ValueSpace="Raw" Name="fix_point_array">0x72000000 0x0B000000 0xF0000000</FixedPointParameter>
387+
<EnumParameter Name="enum">five</EnumParameter>
388+
<EnumParameter Name="enum_array">eight min eight min</EnumParameter>
389+
<StringParameter Name="string">A string of 32 character.@@@@@@@</StringParameter>
390+
<BitParameterBlock Name="bit_block">
391+
<BitParameter Name="one">0x1</BitParameter>
392+
<BitParameter Name="two">0x2</BitParameter>
393+
<BitParameter Name="six">0xA</BitParameter>
394+
<BitParameter Name="sixteen">0x48</BitParameter>
395+
<BitParameter Name="thirty_two">0xFFFFFFFF</BitParameter>
396+
</BitParameterBlock>
397+
)";
366398

367399
SCENARIO_METHOD(SettingsTestPF, "Export and import XML settings", "[handler][settings][xml]")
368400
{
@@ -377,12 +409,26 @@ SCENARIO_METHOD(SettingsTestPF, "Export and import XML settings", "[handler][set
377409
checkXMLEq(basicParams.getAsXML(),
378410
mkBasicSettings(defaultBasicSettingsXML, "parameter_block"));
379411
}
380-
WHEN ("Importing basic parameter XML") {
381-
string testSettings = mkBasicSettings(testBasicSettingsXML, "parameter_block");
382-
CHECK_NOTHROW(basicParams.setAsXML(testSettings));
412+
string testSettings = mkBasicSettings(testBasicSettingsXML, "parameter_block");
413+
string rawTestSettings = mkBasicSettings(testRawHexBasicSettingsXML, "parameter_block");
414+
415+
auto checkExport = [&] {
383416
THEN ("Exported settings should be the ones imported") {
384417
checkXMLEq(basicParams.getAsXML(), testSettings);
385418
}
419+
THEN ("Exported raw settings should be the ones imported") {
420+
setRawValueSpace(true);
421+
setHexOutputFormat(true);
422+
checkXMLEq(basicParams.getAsXML(), rawTestSettings);
423+
}
424+
};
425+
WHEN ("Importing basic parameter XML") {
426+
CHECK_NOTHROW(basicParams.setAsXML(testSettings));
427+
checkExport();
428+
}
429+
WHEN ("Importing raw basic parameter XML") {
430+
CHECK_NOTHROW(basicParams.setAsXML(rawTestSettings));
431+
checkExport();
386432
}
387433
}
388434

@@ -497,4 +543,63 @@ SCENARIO_METHOD(SettingsTestPF, "Import basic params in one format, export in an
497543
}
498544
}
499545

546+
struct MappingPF : public ParameterFramework
547+
{
548+
MappingPF() : ParameterFramework{getConfig()} { REQUIRE_NOTHROW(start()); }
549+
550+
Config getConfig()
551+
{
552+
Config config;
553+
config.instances = "<BooleanParameter Name='bool' Mapping='bool_map'>";
554+
config.subsystemMapping = "subsystem_mapping";
555+
return config;
556+
}
557+
};
558+
559+
SCENARIO("Mapping handle access", "[handler][mapping]")
560+
{
561+
GIVEN ("A PF with mappings") {
562+
Config config;
563+
config.subsystemMapping = "rootK:rootV";
564+
config.components = "<ComponentType Name='componentType' Mapping='typeK:typeV' />";
565+
config.instances = "<BooleanParameter Name='param' Mapping='paramK:paramV' />"
566+
"<Component Name='component' Mapping='instanceK:instanceV' "
567+
" Type='componentType' />";
568+
ParameterFramework pf{config};
569+
REQUIRE_NOTHROW(pf.start());
570+
571+
struct TestVector
572+
{
573+
string path;
574+
list<string> valid;
575+
list<string> invalid;
576+
};
577+
list<TestVector> testVectors = {
578+
// clang-format off
579+
{"/test/test", {"root"}, {"param", "type", "instance"}},
580+
{"/test/test/param", {"root", "param"}, {"type", "instance"}},
581+
{"/test/test/component", {"root", "type", "instance"}, {"param"}}
582+
// clang-format on
583+
};
584+
585+
for (auto &test : testVectors) {
586+
GIVEN ("An element handle of " + test.path) {
587+
ElementHandle handle(pf, test.path);
588+
589+
for (auto &valid : test.valid) {
590+
THEN ("The following mapping should exist: " + valid) {
591+
CHECK(handle.getMappingData(valid + "K") == valid + "V");
592+
}
593+
}
594+
595+
for (auto &invalid : test.invalid) {
596+
THEN ("The following mapping should not exist: " + invalid) {
597+
CHECK_THROWS_AS(handle.getMappingData(invalid + "K"), Exception);
598+
}
599+
}
600+
}
601+
}
602+
}
603+
}
604+
500605
} // namespace parameterFramework

test/functional-tests/include/Config.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ struct Config
5050
(this->*member) = std::forward<T>(value);
5151
}
5252

53+
/** Mapping attribute of the test subsystem. */
54+
std::string subsystemMapping;
55+
5356
/** Instances of the test subsystem.
5457
*
5558
* Content of the configuration

test/functional-tests/include/ConfigFiles.hpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,11 @@ class ConfigFiles
4343
{
4444
public:
4545
ConfigFiles(const Config &config)
46-
: mStructureFile(format(mStructureTemplate, {{"type", config.subsystemType},
47-
{"instances", config.instances},
48-
{"components", config.components}})),
46+
: mStructureFile(
47+
format(mStructureTemplate, {{"type", config.subsystemType},
48+
{"instances", config.instances},
49+
{"components", config.components},
50+
{"subsystemMapping", config.subsystemMapping}})),
4951
mDomainsFile(format(mDomainsTemplate, {{"domains", config.domains}})),
5052
mConfigFile(format(mConfigTemplate, {{"structurePath", mStructureFile.getPath()},
5153
{"domainsPath", mDomainsFile.getPath()},
@@ -101,7 +103,7 @@ class ConfigFiles
101103
)";
102104
const char *mStructureTemplate = R"(<?xml version='1.0' encoding='UTF-8'?>
103105
<SystemClass Name='test'>
104-
<Subsystem Name='test' Type='{type}'>
106+
<Subsystem Name='test' Type='{type}' Mapping='{subsystemMapping}'>
105107
<ComponentLibrary>
106108
{components}
107109
</ComponentLibrary>

0 commit comments

Comments
 (0)