xref: /aosp_15_r20/external/parameter-framework/upstream/test/functional-tests/Handle.cpp (revision c33452fb792a5495ec310a9626f2638b053af5dd)
1*c33452fbSAndroid Build Coastguard Worker /*
2*c33452fbSAndroid Build Coastguard Worker  * Copyright (c) 2015, Intel Corporation
3*c33452fbSAndroid Build Coastguard Worker  * All rights reserved.
4*c33452fbSAndroid Build Coastguard Worker  *
5*c33452fbSAndroid Build Coastguard Worker  * Redistribution and use in source and binary forms, with or without modification,
6*c33452fbSAndroid Build Coastguard Worker  * are permitted provided that the following conditions are met:
7*c33452fbSAndroid Build Coastguard Worker  *
8*c33452fbSAndroid Build Coastguard Worker  * 1. Redistributions of source code must retain the above copyright notice, this
9*c33452fbSAndroid Build Coastguard Worker  * list of conditions and the following disclaimer.
10*c33452fbSAndroid Build Coastguard Worker  *
11*c33452fbSAndroid Build Coastguard Worker  * 2. Redistributions in binary form must reproduce the above copyright notice,
12*c33452fbSAndroid Build Coastguard Worker  * this list of conditions and the following disclaimer in the documentation and/or
13*c33452fbSAndroid Build Coastguard Worker  * other materials provided with the distribution.
14*c33452fbSAndroid Build Coastguard Worker  *
15*c33452fbSAndroid Build Coastguard Worker  * 3. Neither the name of the copyright holder nor the names of its contributors
16*c33452fbSAndroid Build Coastguard Worker  * may be used to endorse or promote products derived from this software without
17*c33452fbSAndroid Build Coastguard Worker  * specific prior written permission.
18*c33452fbSAndroid Build Coastguard Worker  *
19*c33452fbSAndroid Build Coastguard Worker  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20*c33452fbSAndroid Build Coastguard Worker  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21*c33452fbSAndroid Build Coastguard Worker  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22*c33452fbSAndroid Build Coastguard Worker  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23*c33452fbSAndroid Build Coastguard Worker  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24*c33452fbSAndroid Build Coastguard Worker  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25*c33452fbSAndroid Build Coastguard Worker  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26*c33452fbSAndroid Build Coastguard Worker  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27*c33452fbSAndroid Build Coastguard Worker  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28*c33452fbSAndroid Build Coastguard Worker  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29*c33452fbSAndroid Build Coastguard Worker  */
30*c33452fbSAndroid Build Coastguard Worker 
31*c33452fbSAndroid Build Coastguard Worker #include "Config.hpp"
32*c33452fbSAndroid Build Coastguard Worker #include "Test.hpp"
33*c33452fbSAndroid Build Coastguard Worker #include "Exception.hpp"
34*c33452fbSAndroid Build Coastguard Worker #include "TmpFile.hpp"
35*c33452fbSAndroid Build Coastguard Worker 
36*c33452fbSAndroid Build Coastguard Worker #include "ParameterFramework.hpp"
37*c33452fbSAndroid Build Coastguard Worker #include "ElementHandle.hpp"
38*c33452fbSAndroid Build Coastguard Worker 
39*c33452fbSAndroid Build Coastguard Worker #include <catch.hpp>
40*c33452fbSAndroid Build Coastguard Worker 
41*c33452fbSAndroid Build Coastguard Worker #include <libxml/parser.h>
42*c33452fbSAndroid Build Coastguard Worker #include <libxml/tree.h>
43*c33452fbSAndroid Build Coastguard Worker 
44*c33452fbSAndroid Build Coastguard Worker #include <string>
45*c33452fbSAndroid Build Coastguard Worker #include <list>
46*c33452fbSAndroid Build Coastguard Worker 
47*c33452fbSAndroid Build Coastguard Worker #include <stdlib.h>
48*c33452fbSAndroid Build Coastguard Worker 
49*c33452fbSAndroid Build Coastguard Worker using std::string;
50*c33452fbSAndroid Build Coastguard Worker using std::list;
51*c33452fbSAndroid Build Coastguard Worker using Bytes = std::vector<uint8_t>;
52*c33452fbSAndroid Build Coastguard Worker 
53*c33452fbSAndroid Build Coastguard Worker namespace parameterFramework
54*c33452fbSAndroid Build Coastguard Worker {
55*c33452fbSAndroid Build Coastguard Worker 
56*c33452fbSAndroid Build Coastguard Worker struct AllParamsPF : public ParameterFramework
57*c33452fbSAndroid Build Coastguard Worker {
AllParamsPFparameterFramework::AllParamsPF58*c33452fbSAndroid Build Coastguard Worker     AllParamsPF() : ParameterFramework{getConfig()} { REQUIRE_NOTHROW(start()); }
59*c33452fbSAndroid Build Coastguard Worker 
getBasicParamsparameterFramework::AllParamsPF60*c33452fbSAndroid Build Coastguard Worker     string getBasicParams()
61*c33452fbSAndroid Build Coastguard Worker     {
62*c33452fbSAndroid Build Coastguard Worker         string structure = R"(
63*c33452fbSAndroid Build Coastguard Worker             <BooleanParameter Name="bool" Description="bool"/>
64*c33452fbSAndroid Build Coastguard Worker             <BooleanParameter ArrayLength="2" Name="bool_array" Description="bool-array"/>
65*c33452fbSAndroid Build Coastguard Worker 
66*c33452fbSAndroid Build Coastguard Worker             <IntegerParameter Signed="false" Min="33" Max="123" Size="16" Name="integer"/>
67*c33452fbSAndroid Build Coastguard Worker             <IntegerParameter Signed="true" Min="-10" Max="10" Size="32" ArrayLength="4" Name="integer_array"/>
68*c33452fbSAndroid Build Coastguard Worker 
69*c33452fbSAndroid Build Coastguard Worker             <FixedPointParameter Size="32" Integral="3" Fractional="4" Name="fix_point"/>
70*c33452fbSAndroid Build Coastguard Worker             <FixedPointParameter Size="32" Integral="3" Fractional="4" ArrayLength="3" Name="fix_point_array"/>
71*c33452fbSAndroid Build Coastguard Worker 
72*c33452fbSAndroid Build Coastguard Worker             <EnumParameter Size="8" Name="enum">
73*c33452fbSAndroid Build Coastguard Worker                 <ValuePair Literal="min"  Numerical="-128"/>
74*c33452fbSAndroid Build Coastguard Worker                 <ValuePair Literal="five" Numerical="5"/>
75*c33452fbSAndroid Build Coastguard Worker                 <ValuePair Literal="max"  Numerical="127"/>
76*c33452fbSAndroid Build Coastguard Worker             </EnumParameter>
77*c33452fbSAndroid Build Coastguard Worker             <EnumParameter Size="16" ArrayLength="4" Name="enum_array">
78*c33452fbSAndroid Build Coastguard Worker                 <ValuePair Literal="eight"  Numerical="8"/>
79*c33452fbSAndroid Build Coastguard Worker                 <ValuePair Literal="min"  Numerical="-32767"/>
80*c33452fbSAndroid Build Coastguard Worker             </EnumParameter>)";
81*c33452fbSAndroid Build Coastguard Worker 
82*c33452fbSAndroid Build Coastguard Worker         // String and bit parameter arrays are not supported
83*c33452fbSAndroid Build Coastguard Worker         structure += R"(
84*c33452fbSAndroid Build Coastguard Worker             <StringParameter MaxLength="63" Name="string"/>
85*c33452fbSAndroid Build Coastguard Worker 
86*c33452fbSAndroid Build Coastguard Worker             <BitParameterBlock Size="64" Name="bit_block">
87*c33452fbSAndroid Build Coastguard Worker                 <BitParameter Pos="1"  Size="1"  Max="1"  Name="one"/>
88*c33452fbSAndroid Build Coastguard Worker                 <BitParameter Pos="2"  Size="2"  Max="2"  Name="two"/>
89*c33452fbSAndroid Build Coastguard Worker                 <BitParameter Pos="6"  Size="6"  Max="10" Name="six"/>
90*c33452fbSAndroid Build Coastguard Worker                 <BitParameter Pos="16" Size="16" Max="99" Name="sixteen"/>
91*c33452fbSAndroid Build Coastguard Worker                 <BitParameter Pos="32" Size="32" Max="4294967295" Name="thirty_two"/>
92*c33452fbSAndroid Build Coastguard Worker             </BitParameterBlock>
93*c33452fbSAndroid Build Coastguard Worker             )";
94*c33452fbSAndroid Build Coastguard Worker         return structure;
95*c33452fbSAndroid Build Coastguard Worker     }
96*c33452fbSAndroid Build Coastguard Worker 
getConfigparameterFramework::AllParamsPF97*c33452fbSAndroid Build Coastguard Worker     Config getConfig()
98*c33452fbSAndroid Build Coastguard Worker     {
99*c33452fbSAndroid Build Coastguard Worker         Config config;
100*c33452fbSAndroid Build Coastguard Worker         config.components = nodeDesc("ComponentType", "component_type", getBasicParams());
101*c33452fbSAndroid Build Coastguard Worker         config.instances =
102*c33452fbSAndroid Build Coastguard Worker             getBasicParams() + nodeDesc("ParameterBlock", "parameter_block", getBasicParams()) +
103*c33452fbSAndroid Build Coastguard Worker             nodeDesc("ParameterBlock", "parameter_block_array", getBasicParams(),
104*c33452fbSAndroid Build Coastguard Worker                      "ArrayLength='2'") +
105*c33452fbSAndroid Build Coastguard Worker             nodeDesc("Component", "component_scalar", "", "Type='component_type'") +
106*c33452fbSAndroid Build Coastguard Worker             nodeDesc("Component", "component_array", "", "Type='component_type' ArrayLength='2'");
107*c33452fbSAndroid Build Coastguard Worker         return config;
108*c33452fbSAndroid Build Coastguard Worker     }
109*c33452fbSAndroid Build Coastguard Worker 
checkStructureparameterFramework::AllParamsPF110*c33452fbSAndroid Build Coastguard Worker     void checkStructure(const string &path, const string &expected)
111*c33452fbSAndroid Build Coastguard Worker     {
112*c33452fbSAndroid Build Coastguard Worker         CHECK_NOTHROW(checkXMLEq(ElementHandle{*this, path}.getStructureAsXML(), expected));
113*c33452fbSAndroid Build Coastguard Worker     }
114*c33452fbSAndroid Build Coastguard Worker 
115*c33452fbSAndroid Build Coastguard Worker     /** Use libxml2 to pretty format xml.
116*c33452fbSAndroid Build Coastguard Worker      * Equivalent of xmllint --format
117*c33452fbSAndroid Build Coastguard Worker      */
canonicalizeXMLparameterFramework::AllParamsPF118*c33452fbSAndroid Build Coastguard Worker     static string canonicalizeXML(const string &xml)
119*c33452fbSAndroid Build Coastguard Worker     {
120*c33452fbSAndroid Build Coastguard Worker         // Parse xml
121*c33452fbSAndroid Build Coastguard Worker         // Might be better to specialize std::default_delete<xmlDoc>.
122*c33452fbSAndroid Build Coastguard Worker         std::unique_ptr<xmlDoc, void (*)(xmlDoc *)> doc{
123*c33452fbSAndroid Build Coastguard Worker             xmlReadMemory(xml.c_str(), (int)xml.length(), "structure.xml", nullptr,
124*c33452fbSAndroid Build Coastguard Worker                           XML_PARSE_NOBLANKS),
125*c33452fbSAndroid Build Coastguard Worker             xmlFreeDoc};
126*c33452fbSAndroid Build Coastguard Worker         if (doc == nullptr) {
127*c33452fbSAndroid Build Coastguard Worker             throw Exception{"Failed to parse document: " + xml};
128*c33452fbSAndroid Build Coastguard Worker         }
129*c33452fbSAndroid Build Coastguard Worker 
130*c33452fbSAndroid Build Coastguard Worker         // Dump it formated
131*c33452fbSAndroid Build Coastguard Worker         int size;
132*c33452fbSAndroid Build Coastguard Worker 
133*c33452fbSAndroid Build Coastguard Worker         // Need to use exception unsafe raw pointer as of libxml2 c api
134*c33452fbSAndroid Build Coastguard Worker         xmlChar *unsafeFormated;
135*c33452fbSAndroid Build Coastguard Worker 
136*c33452fbSAndroid Build Coastguard Worker         // TODO: Should use canonicalization (aka c14n).
137*c33452fbSAndroid Build Coastguard Worker         //       cf: http://xmlsoft.org/html/libxml-c14n.html
138*c33452fbSAndroid Build Coastguard Worker         //           https://en.wikipedia.org/wiki/Canonical_XML
139*c33452fbSAndroid Build Coastguard Worker         //       Additionally to what is listed on that page,
140*c33452fbSAndroid Build Coastguard Worker         //       attributes are also ordered deterministically.
141*c33452fbSAndroid Build Coastguard Worker         //       That would solve the workaround in the node function with pre/post attributes.
142*c33452fbSAndroid Build Coastguard Worker         //       Unfortunately c14n is not available in appveyor (Windows CI) libxml2 prebuild
143*c33452fbSAndroid Build Coastguard Worker         xmlDocDumpFormatMemoryEnc(doc.get(), &unsafeFormated, &size, "UTF-8", 1);
144*c33452fbSAndroid Build Coastguard Worker         std::unique_ptr<xmlChar, void (*)(void *)> formated{unsafeFormated, xmlFree};
145*c33452fbSAndroid Build Coastguard Worker 
146*c33452fbSAndroid Build Coastguard Worker         if (formated == nullptr) {
147*c33452fbSAndroid Build Coastguard Worker             throw Exception{"Could not dump xml: " + xml};
148*c33452fbSAndroid Build Coastguard Worker         }
149*c33452fbSAndroid Build Coastguard Worker 
150*c33452fbSAndroid Build Coastguard Worker         return string{(char *)formated.get()};
151*c33452fbSAndroid Build Coastguard Worker     }
152*c33452fbSAndroid Build Coastguard Worker 
checkEqparameterFramework::AllParamsPF153*c33452fbSAndroid Build Coastguard Worker     static void checkEq(const string &result, const string &expected)
154*c33452fbSAndroid Build Coastguard Worker     {
155*c33452fbSAndroid Build Coastguard Worker         CHECK(result == expected);
156*c33452fbSAndroid Build Coastguard Worker 
157*c33452fbSAndroid Build Coastguard Worker         // Pretty print the word differences with colors
158*c33452fbSAndroid Build Coastguard Worker         // It does not matter if it fails as the test would still fail
159*c33452fbSAndroid Build Coastguard Worker         // due to the above CHECK.
160*c33452fbSAndroid Build Coastguard Worker         if (result != expected) {
161*c33452fbSAndroid Build Coastguard Worker             utility::TmpFile resultFile(result);
162*c33452fbSAndroid Build Coastguard Worker             utility::TmpFile expectedFile(expected);
163*c33452fbSAndroid Build Coastguard Worker             string command = "git --no-pager diff --word-diff-regex='[^ <>]+'"
164*c33452fbSAndroid Build Coastguard Worker                              "                    --color --no-index --exit-code " +
165*c33452fbSAndroid Build Coastguard Worker                              resultFile.getPath() + ' ' + expectedFile.getPath();
166*c33452fbSAndroid Build Coastguard Worker 
167*c33452fbSAndroid Build Coastguard Worker             // `system` return -1 or 127 on failure, the command error code otherwise
168*c33452fbSAndroid Build Coastguard Worker             // `git diff` return 1 if the files are the different (thanks to --exit-code)
169*c33452fbSAndroid Build Coastguard Worker             auto status = system(command.c_str());
170*c33452fbSAndroid Build Coastguard Worker #ifdef WIFEXITED // Posix platform
171*c33452fbSAndroid Build Coastguard Worker             bool success = WIFEXITED(status) and WEXITSTATUS(status) == 1;
172*c33452fbSAndroid Build Coastguard Worker #else
173*c33452fbSAndroid Build Coastguard Worker             bool success = status == 1;
174*c33452fbSAndroid Build Coastguard Worker #endif
175*c33452fbSAndroid Build Coastguard Worker             if (not success) {
176*c33452fbSAndroid Build Coastguard Worker                 WARN("Warning: Failed to pretty-print the difference between "
177*c33452fbSAndroid Build Coastguard Worker                      "actual and expected results with `git diff'");
178*c33452fbSAndroid Build Coastguard Worker             }
179*c33452fbSAndroid Build Coastguard Worker         }
180*c33452fbSAndroid Build Coastguard Worker     }
181*c33452fbSAndroid Build Coastguard Worker 
checkXMLEqparameterFramework::AllParamsPF182*c33452fbSAndroid Build Coastguard Worker     static void checkXMLEq(const string &result, const string &expected)
183*c33452fbSAndroid Build Coastguard Worker     {
184*c33452fbSAndroid Build Coastguard Worker         checkEq(canonicalizeXML(result), canonicalizeXML(expected));
185*c33452fbSAndroid Build Coastguard Worker     }
186*c33452fbSAndroid Build Coastguard Worker 
nodeparameterFramework::AllParamsPF187*c33452fbSAndroid Build Coastguard Worker     static string node(string tag, string name, string content, string attributes = "",
188*c33452fbSAndroid Build Coastguard Worker                        string postAttributes = "")
189*c33452fbSAndroid Build Coastguard Worker     {
190*c33452fbSAndroid Build Coastguard Worker         return "<" + tag + " " + attributes + " Name='" + name + "' " + postAttributes + ">" +
191*c33452fbSAndroid Build Coastguard Worker                content + "</" + tag + ">";
192*c33452fbSAndroid Build Coastguard Worker     }
193*c33452fbSAndroid Build Coastguard Worker     /** Node with a description.
194*c33452fbSAndroid Build Coastguard Worker      * @param[in] maybeDescription If nullptr, description will be generated from the name
195*c33452fbSAndroid Build Coastguard Worker      *                             Otherwise, the description.
196*c33452fbSAndroid Build Coastguard Worker      */
nodeDescparameterFramework::AllParamsPF197*c33452fbSAndroid Build Coastguard Worker     static string nodeDesc(string tag, string name, string content, string attributes = "",
198*c33452fbSAndroid Build Coastguard Worker                            const char *maybeDescription = nullptr)
199*c33452fbSAndroid Build Coastguard Worker     {
200*c33452fbSAndroid Build Coastguard Worker         string description = "description_" + name;
201*c33452fbSAndroid Build Coastguard Worker         if (maybeDescription != nullptr) {
202*c33452fbSAndroid Build Coastguard Worker             description = maybeDescription;
203*c33452fbSAndroid Build Coastguard Worker         }
204*c33452fbSAndroid Build Coastguard Worker         return node(tag, name, content, attributes, "Description='" + description + "'");
205*c33452fbSAndroid Build Coastguard Worker     }
206*c33452fbSAndroid Build Coastguard Worker 
rootNodeparameterFramework::AllParamsPF207*c33452fbSAndroid Build Coastguard Worker     static string rootNode(string name, string attributes, string content)
208*c33452fbSAndroid Build Coastguard Worker     {
209*c33452fbSAndroid Build Coastguard Worker         return '<' + name + ' ' + attributes + '>' + content + "</" + name + '>';
210*c33452fbSAndroid Build Coastguard Worker     }
211*c33452fbSAndroid Build Coastguard Worker };
212*c33452fbSAndroid Build Coastguard Worker 
213*c33452fbSAndroid Build Coastguard Worker SCENARIO_METHOD(AllParamsPF, "Export boolean", "[handler][structure][xml]")
214*c33452fbSAndroid Build Coastguard Worker {
215*c33452fbSAndroid Build Coastguard Worker     string expected = rootNode("BooleanParameter", "Name='bool' Description='bool'", "");
216*c33452fbSAndroid Build Coastguard Worker     checkStructure("/test/test/bool", expected);
217*c33452fbSAndroid Build Coastguard Worker }
218*c33452fbSAndroid Build Coastguard Worker 
219*c33452fbSAndroid Build Coastguard Worker SCENARIO_METHOD(AllParamsPF, "Export component", "[handler][structure][xml]")
220*c33452fbSAndroid Build Coastguard Worker {
221*c33452fbSAndroid Build Coastguard Worker     string expected = rootNode("ParameterBlock", "Name='component_scalar' "
222*c33452fbSAndroid Build Coastguard Worker                                                  "Description='description_component_scalar'",
223*c33452fbSAndroid Build Coastguard Worker                                getBasicParams());
224*c33452fbSAndroid Build Coastguard Worker     checkStructure("/test/test/component_scalar", expected);
225*c33452fbSAndroid Build Coastguard Worker }
226*c33452fbSAndroid Build Coastguard Worker 
227*c33452fbSAndroid Build Coastguard Worker SCENARIO_METHOD(AllParamsPF, "Export component array", "[handler][structure][xml]")
228*c33452fbSAndroid Build Coastguard Worker {
229*c33452fbSAndroid Build Coastguard Worker     string expected = rootNode(
230*c33452fbSAndroid Build Coastguard Worker         "ParameterBlock", "Name='component_array' Description='description_component_array'",
231*c33452fbSAndroid Build Coastguard Worker         nodeDesc("ParameterBlock", "0", getBasicParams(), "", "description_component_array") +
232*c33452fbSAndroid Build Coastguard Worker             nodeDesc("ParameterBlock", "1", getBasicParams(), "", "description_component_array"));
233*c33452fbSAndroid Build Coastguard Worker     checkStructure("/test/test/component_array", expected);
234*c33452fbSAndroid Build Coastguard Worker }
235*c33452fbSAndroid Build Coastguard Worker 
236*c33452fbSAndroid Build Coastguard Worker SCENARIO_METHOD(AllParamsPF, "Export all parameters", "[handler][structure][xml]")
237*c33452fbSAndroid Build Coastguard Worker {
238*c33452fbSAndroid Build Coastguard Worker     string paramExpected = getBasicParams() +
239*c33452fbSAndroid Build Coastguard Worker                            nodeDesc("ParameterBlock", "parameter_block", getBasicParams()) +
240*c33452fbSAndroid Build Coastguard Worker                            nodeDesc("ParameterBlock", "parameter_block_array",
241*c33452fbSAndroid Build Coastguard Worker                                     nodeDesc("ParameterBlock", "0", getBasicParams(), "",
242*c33452fbSAndroid Build Coastguard Worker                                              // description is inherited from array
243*c33452fbSAndroid Build Coastguard Worker                                              "description_parameter_block_array") +
244*c33452fbSAndroid Build Coastguard Worker                                         nodeDesc("ParameterBlock", "1", getBasicParams(), "",
245*c33452fbSAndroid Build Coastguard Worker                                                  "description_parameter_block_array")) +
246*c33452fbSAndroid Build Coastguard Worker                            // Components should be exported as parameterBlock
247*c33452fbSAndroid Build Coastguard Worker                            nodeDesc("ParameterBlock", "component_scalar", getBasicParams()) +
248*c33452fbSAndroid Build Coastguard Worker                            nodeDesc("ParameterBlock", "component_array",
249*c33452fbSAndroid Build Coastguard Worker                                     nodeDesc("ParameterBlock", "0", getBasicParams(), "",
250*c33452fbSAndroid Build Coastguard Worker                                              // description is inherited from array
251*c33452fbSAndroid Build Coastguard Worker                                              "description_component_array") +
252*c33452fbSAndroid Build Coastguard Worker                                         nodeDesc("ParameterBlock", "1", getBasicParams(), "",
253*c33452fbSAndroid Build Coastguard Worker                                                  "description_component_array"));
254*c33452fbSAndroid Build Coastguard Worker 
255*c33452fbSAndroid Build Coastguard Worker     WHEN ("Exporting subsystem") {
256*c33452fbSAndroid Build Coastguard Worker         string expected = rootNode("Subsystem", "Name='test'", paramExpected);
257*c33452fbSAndroid Build Coastguard Worker         checkStructure("/test/test", expected);
258*c33452fbSAndroid Build Coastguard Worker     }
259*c33452fbSAndroid Build Coastguard Worker 
260*c33452fbSAndroid Build Coastguard Worker     WHEN ("Exporting systemClass") {
261*c33452fbSAndroid Build Coastguard Worker         string expected = rootNode("SystemClass", "Name='test'",
262*c33452fbSAndroid Build Coastguard Worker                                    "<Subsystem Name='test'>" + paramExpected + "</Subsystem>");
263*c33452fbSAndroid Build Coastguard Worker 
264*c33452fbSAndroid Build Coastguard Worker         // Awkwardly, the root and its first child are the same element
265*c33452fbSAndroid Build Coastguard Worker         checkStructure("/test", expected);
266*c33452fbSAndroid Build Coastguard Worker         checkStructure("/", expected);
267*c33452fbSAndroid Build Coastguard Worker     }
268*c33452fbSAndroid Build Coastguard Worker }
269*c33452fbSAndroid Build Coastguard Worker 
270*c33452fbSAndroid Build Coastguard Worker struct SettingsTestPF : public AllParamsPF
271*c33452fbSAndroid Build Coastguard Worker {
parameterBlockNodeparameterFramework::SettingsTestPF272*c33452fbSAndroid Build Coastguard Worker     static string parameterBlockNode(string name, string settings)
273*c33452fbSAndroid Build Coastguard Worker     {
274*c33452fbSAndroid Build Coastguard Worker         return node("ParameterBlock", name, settings);
275*c33452fbSAndroid Build Coastguard Worker     };
mkBasicSettingsparameterFramework::SettingsTestPF276*c33452fbSAndroid Build Coastguard Worker     static string mkBasicSettings(string settings, string name)
277*c33452fbSAndroid Build Coastguard Worker     {
278*c33452fbSAndroid Build Coastguard Worker         return rootNode("ParameterBlock", "Name='" + name + "'", settings);
279*c33452fbSAndroid Build Coastguard Worker     }
280*c33452fbSAndroid Build Coastguard Worker 
fullXMLSettingsparameterFramework::SettingsTestPF281*c33452fbSAndroid Build Coastguard Worker     static string fullXMLSettings(const string &basicSettings)
282*c33452fbSAndroid Build Coastguard Worker     {
283*c33452fbSAndroid Build Coastguard Worker         string settings = basicSettings;
284*c33452fbSAndroid Build Coastguard Worker         settings +=
285*c33452fbSAndroid Build Coastguard Worker             parameterBlockNode("parameter_block", settings) +
286*c33452fbSAndroid Build Coastguard Worker             parameterBlockNode("parameter_block_array", parameterBlockNode("0", settings) +
287*c33452fbSAndroid Build Coastguard Worker                                                             parameterBlockNode("1", settings)) +
288*c33452fbSAndroid Build Coastguard Worker             parameterBlockNode("component_scalar", settings) +
289*c33452fbSAndroid Build Coastguard Worker             parameterBlockNode("component_array", parameterBlockNode("0", settings) +
290*c33452fbSAndroid Build Coastguard Worker                                                       parameterBlockNode("1", settings));
291*c33452fbSAndroid Build Coastguard Worker 
292*c33452fbSAndroid Build Coastguard Worker         return rootNode("SystemClass", "Name='test'", node("Subsystem", "test", settings, ""));
293*c33452fbSAndroid Build Coastguard Worker     }
294*c33452fbSAndroid Build Coastguard Worker 
fullBytesSettingsparameterFramework::SettingsTestPF295*c33452fbSAndroid Build Coastguard Worker     static string fullBytesSettings(const string &basicSettings)
296*c33452fbSAndroid Build Coastguard Worker     {
297*c33452fbSAndroid Build Coastguard Worker         string fullSettings;
298*c33452fbSAndroid Build Coastguard Worker         // We have the "basic params" repeated 7 times across the test
299*c33452fbSAndroid Build Coastguard Worker         // structure
300*c33452fbSAndroid Build Coastguard Worker         for (size_t i = 0; i < 7; ++i) {
301*c33452fbSAndroid Build Coastguard Worker             fullSettings += basicSettings;
302*c33452fbSAndroid Build Coastguard Worker         }
303*c33452fbSAndroid Build Coastguard Worker         return fullSettings;
304*c33452fbSAndroid Build Coastguard Worker     }
305*c33452fbSAndroid Build Coastguard Worker 
306*c33452fbSAndroid Build Coastguard Worker     /** Print Bytes as string separated hexadecimal number. */
showBytesparameterFramework::SettingsTestPF307*c33452fbSAndroid Build Coastguard Worker     static string showBytes(const Bytes &bytes)
308*c33452fbSAndroid Build Coastguard Worker     {
309*c33452fbSAndroid Build Coastguard Worker         using namespace std;
310*c33452fbSAndroid Build Coastguard Worker         ostringstream ss;
311*c33452fbSAndroid Build Coastguard Worker         ss.exceptions(ostream::badbit | ostream::failbit);
312*c33452fbSAndroid Build Coastguard Worker         for (auto byte : bytes) {
313*c33452fbSAndroid Build Coastguard Worker             ss << hex << setw(2) << setfill('0') << int{byte} << ' ';
314*c33452fbSAndroid Build Coastguard Worker         }
315*c33452fbSAndroid Build Coastguard Worker         return ss.str();
316*c33452fbSAndroid Build Coastguard Worker     }
317*c33452fbSAndroid Build Coastguard Worker 
readBytesparameterFramework::SettingsTestPF318*c33452fbSAndroid Build Coastguard Worker     static Bytes readBytes(const string &strBytes)
319*c33452fbSAndroid Build Coastguard Worker     {
320*c33452fbSAndroid Build Coastguard Worker         using namespace std;
321*c33452fbSAndroid Build Coastguard Worker         istringstream ss{strBytes};
322*c33452fbSAndroid Build Coastguard Worker         ss.exceptions(istream::badbit | istream::failbit);
323*c33452fbSAndroid Build Coastguard Worker         Bytes bytes(strBytes.size() / 3);
324*c33452fbSAndroid Build Coastguard Worker 
325*c33452fbSAndroid Build Coastguard Worker         for (auto &byte : bytes) {
326*c33452fbSAndroid Build Coastguard Worker             uint16_t notCharByte;
327*c33452fbSAndroid Build Coastguard Worker             ss >> hex >> setw(2) >> notCharByte;
328*c33452fbSAndroid Build Coastguard Worker             byte = static_cast<char>(notCharByte);
329*c33452fbSAndroid Build Coastguard Worker         }
330*c33452fbSAndroid Build Coastguard Worker         return bytes;
331*c33452fbSAndroid Build Coastguard Worker     }
332*c33452fbSAndroid Build Coastguard Worker 
checkBytesEqparameterFramework::SettingsTestPF333*c33452fbSAndroid Build Coastguard Worker     static void checkBytesEq(const Bytes &result, const string &expect)
334*c33452fbSAndroid Build Coastguard Worker     {
335*c33452fbSAndroid Build Coastguard Worker         checkEq(showBytes(result), expect);
336*c33452fbSAndroid Build Coastguard Worker     }
checkBytesEqparameterFramework::SettingsTestPF337*c33452fbSAndroid Build Coastguard Worker     static void checkBytesEq(const Bytes &result, const Bytes &expect)
338*c33452fbSAndroid Build Coastguard Worker     {
339*c33452fbSAndroid Build Coastguard Worker         checkEq(showBytes(result), showBytes(expect));
340*c33452fbSAndroid Build Coastguard Worker     }
341*c33452fbSAndroid Build Coastguard Worker };
342*c33452fbSAndroid Build Coastguard Worker 
343*c33452fbSAndroid Build Coastguard Worker static const char *defaultBasicSettingsXML = R"(
344*c33452fbSAndroid Build Coastguard Worker       <BooleanParameter Name="bool">0</BooleanParameter>
345*c33452fbSAndroid Build Coastguard Worker       <BooleanParameter Name="bool_array">0 0</BooleanParameter>
346*c33452fbSAndroid Build Coastguard Worker       <IntegerParameter Name="integer">33</IntegerParameter>
347*c33452fbSAndroid Build Coastguard Worker       <IntegerParameter Name="integer_array">-10 -10 -10 -10</IntegerParameter>
348*c33452fbSAndroid Build Coastguard Worker       <FixedPointParameter Name="fix_point">0.0000</FixedPointParameter>
349*c33452fbSAndroid Build Coastguard Worker       <FixedPointParameter Name="fix_point_array">0.0000 0.0000 0.0000</FixedPointParameter>
350*c33452fbSAndroid Build Coastguard Worker       <EnumParameter Name="enum">min</EnumParameter>
351*c33452fbSAndroid Build Coastguard Worker       <EnumParameter Name="enum_array">eight eight eight eight</EnumParameter>
352*c33452fbSAndroid Build Coastguard Worker       <StringParameter Name="string"></StringParameter>
353*c33452fbSAndroid Build Coastguard Worker       <BitParameterBlock Name="bit_block">
354*c33452fbSAndroid Build Coastguard Worker         <BitParameter Name="one">0</BitParameter>
355*c33452fbSAndroid Build Coastguard Worker         <BitParameter Name="two">0</BitParameter>
356*c33452fbSAndroid Build Coastguard Worker         <BitParameter Name="six">0</BitParameter>
357*c33452fbSAndroid Build Coastguard Worker         <BitParameter Name="sixteen">0</BitParameter>
358*c33452fbSAndroid Build Coastguard Worker         <BitParameter Name="thirty_two">0</BitParameter>
359*c33452fbSAndroid Build Coastguard Worker       </BitParameterBlock>
360*c33452fbSAndroid Build Coastguard Worker )";
361*c33452fbSAndroid Build Coastguard Worker 
362*c33452fbSAndroid Build Coastguard Worker static const char *testBasicSettingsXML = R"(
363*c33452fbSAndroid Build Coastguard Worker       <BooleanParameter Name="bool">1</BooleanParameter>
364*c33452fbSAndroid Build Coastguard Worker       <BooleanParameter Name="bool_array">0 1</BooleanParameter>
365*c33452fbSAndroid Build Coastguard Worker       <IntegerParameter Name="integer">100</IntegerParameter>
366*c33452fbSAndroid Build Coastguard Worker       <IntegerParameter Name="integer_array">-10 0 8 10</IntegerParameter>
367*c33452fbSAndroid Build Coastguard Worker       <FixedPointParameter Name="fix_point">2.2500</FixedPointParameter>
368*c33452fbSAndroid Build Coastguard Worker       <FixedPointParameter Name="fix_point_array">7.1250 0.6875 -1.0000</FixedPointParameter>
369*c33452fbSAndroid Build Coastguard Worker       <EnumParameter Name="enum">five</EnumParameter>
370*c33452fbSAndroid Build Coastguard Worker       <EnumParameter Name="enum_array">eight min eight min</EnumParameter>
371*c33452fbSAndroid Build Coastguard Worker       <StringParameter Name="string">A string of 32 character.@@@@@@@</StringParameter>
372*c33452fbSAndroid Build Coastguard Worker       <BitParameterBlock Name="bit_block">
373*c33452fbSAndroid Build Coastguard Worker         <BitParameter Name="one">1</BitParameter>
374*c33452fbSAndroid Build Coastguard Worker         <BitParameter Name="two">2</BitParameter>
375*c33452fbSAndroid Build Coastguard Worker         <BitParameter Name="six">10</BitParameter>
376*c33452fbSAndroid Build Coastguard Worker         <BitParameter Name="sixteen">72</BitParameter>
377*c33452fbSAndroid Build Coastguard Worker         <BitParameter Name="thirty_two">4294967295</BitParameter>
378*c33452fbSAndroid Build Coastguard Worker       </BitParameterBlock>
379*c33452fbSAndroid Build Coastguard Worker )";
380*c33452fbSAndroid Build Coastguard Worker static const char *testRawHexBasicSettingsXML = R"(
381*c33452fbSAndroid Build Coastguard Worker       <BooleanParameter Name="bool">0x1</BooleanParameter>
382*c33452fbSAndroid Build Coastguard Worker       <BooleanParameter Name="bool_array">0x0 0x1</BooleanParameter>
383*c33452fbSAndroid Build Coastguard Worker       <IntegerParameter Name="integer">0x0064</IntegerParameter>
384*c33452fbSAndroid Build Coastguard Worker       <IntegerParameter Name="integer_array">0xFFFFFFF6 0x00000000 0x00000008 0x0000000A</IntegerParameter>
385*c33452fbSAndroid Build Coastguard Worker       <FixedPointParameter ValueSpace="Raw" Name="fix_point">0x24000000</FixedPointParameter>
386*c33452fbSAndroid Build Coastguard Worker       <FixedPointParameter ValueSpace="Raw" Name="fix_point_array">0x72000000 0x0B000000 0xF0000000</FixedPointParameter>
387*c33452fbSAndroid Build Coastguard Worker       <EnumParameter Name="enum">0x05</EnumParameter>
388*c33452fbSAndroid Build Coastguard Worker       <EnumParameter Name="enum_array">0x0008 0x8001 0x0008 0x8001</EnumParameter>
389*c33452fbSAndroid Build Coastguard Worker       <StringParameter Name="string">A string of 32 character.@@@@@@@</StringParameter>
390*c33452fbSAndroid Build Coastguard Worker       <BitParameterBlock Name="bit_block">
391*c33452fbSAndroid Build Coastguard Worker         <BitParameter Name="one">0x1</BitParameter>
392*c33452fbSAndroid Build Coastguard Worker         <BitParameter Name="two">0x2</BitParameter>
393*c33452fbSAndroid Build Coastguard Worker         <BitParameter Name="six">0xA</BitParameter>
394*c33452fbSAndroid Build Coastguard Worker         <BitParameter Name="sixteen">0x48</BitParameter>
395*c33452fbSAndroid Build Coastguard Worker         <BitParameter Name="thirty_two">0xFFFFFFFF</BitParameter>
396*c33452fbSAndroid Build Coastguard Worker       </BitParameterBlock>
397*c33452fbSAndroid Build Coastguard Worker )";
398*c33452fbSAndroid Build Coastguard Worker 
399*c33452fbSAndroid Build Coastguard Worker SCENARIO_METHOD(SettingsTestPF, "Export and import XML settings", "[handler][settings][xml]")
400*c33452fbSAndroid Build Coastguard Worker {
401*c33452fbSAndroid Build Coastguard Worker     WHEN ("Exporting root XML") {
__anon417f51000102(string path) 402*c33452fbSAndroid Build Coastguard Worker         auto getAsXML = [this](string path) { return ElementHandle(*this, path).getAsXML(); };
403*c33452fbSAndroid Build Coastguard Worker         CHECK(getAsXML("/") == getAsXML("/test"));
404*c33452fbSAndroid Build Coastguard Worker         checkXMLEq(getAsXML("/"), fullXMLSettings(defaultBasicSettingsXML));
405*c33452fbSAndroid Build Coastguard Worker     }
406*c33452fbSAndroid Build Coastguard Worker 
407*c33452fbSAndroid Build Coastguard Worker     ElementHandle basicParams(*this, "/test/test/parameter_block");
408*c33452fbSAndroid Build Coastguard Worker     WHEN ("Exporting basic parameter XML") {
409*c33452fbSAndroid Build Coastguard Worker         checkXMLEq(basicParams.getAsXML(),
410*c33452fbSAndroid Build Coastguard Worker                    mkBasicSettings(defaultBasicSettingsXML, "parameter_block"));
411*c33452fbSAndroid Build Coastguard Worker     }
412*c33452fbSAndroid Build Coastguard Worker     string testSettings = mkBasicSettings(testBasicSettingsXML, "parameter_block");
413*c33452fbSAndroid Build Coastguard Worker     string rawTestSettings = mkBasicSettings(testRawHexBasicSettingsXML, "parameter_block");
414*c33452fbSAndroid Build Coastguard Worker 
__anon417f51000202null415*c33452fbSAndroid Build Coastguard Worker     auto checkExport = [&] {
416*c33452fbSAndroid Build Coastguard Worker         THEN ("Exported settings should be the ones imported") {
417*c33452fbSAndroid Build Coastguard Worker             checkXMLEq(basicParams.getAsXML(), testSettings);
418*c33452fbSAndroid Build Coastguard Worker         }
419*c33452fbSAndroid Build Coastguard Worker         THEN ("Exported raw settings should be the ones imported") {
420*c33452fbSAndroid Build Coastguard Worker             setRawValueSpace(true);
421*c33452fbSAndroid Build Coastguard Worker             setHexOutputFormat(true);
422*c33452fbSAndroid Build Coastguard Worker             checkXMLEq(basicParams.getAsXML(), rawTestSettings);
423*c33452fbSAndroid Build Coastguard Worker         }
424*c33452fbSAndroid Build Coastguard Worker     };
425*c33452fbSAndroid Build Coastguard Worker     WHEN ("Importing basic parameter XML") {
426*c33452fbSAndroid Build Coastguard Worker         CHECK_NOTHROW(basicParams.setAsXML(testSettings));
427*c33452fbSAndroid Build Coastguard Worker         checkExport();
428*c33452fbSAndroid Build Coastguard Worker     }
429*c33452fbSAndroid Build Coastguard Worker     WHEN ("Importing raw basic parameter XML") {
430*c33452fbSAndroid Build Coastguard Worker         CHECK_NOTHROW(basicParams.setAsXML(rawTestSettings));
431*c33452fbSAndroid Build Coastguard Worker         checkExport();
432*c33452fbSAndroid Build Coastguard Worker     }
433*c33452fbSAndroid Build Coastguard Worker }
434*c33452fbSAndroid Build Coastguard Worker 
435*c33452fbSAndroid Build Coastguard Worker static const string defaultBasicSettingsBytes =
436*c33452fbSAndroid Build Coastguard Worker     "00 00 00 21 00 f6 ff ff ff f6 ff ff ff f6 ff ff ff f6 ff ff ff 00 00 00 00 "
437*c33452fbSAndroid Build Coastguard Worker     "00 00 00 00 00 00 00 00 00 00 00 00 80 08 00 08 00 08 00 08 00 00 00 00 00 00 "
438*c33452fbSAndroid Build Coastguard Worker     "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "
439*c33452fbSAndroid Build Coastguard Worker     "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "
440*c33452fbSAndroid Build Coastguard Worker     "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ";
441*c33452fbSAndroid Build Coastguard Worker 
442*c33452fbSAndroid Build Coastguard Worker static const string testBasicSettingsBytes =
443*c33452fbSAndroid Build Coastguard Worker     "01 00 01 64 00 f6 ff ff ff 00 00 00 00 08 00 00 00 0a 00 00 00 00 00 00 24 "
444*c33452fbSAndroid Build Coastguard Worker     "00 00 00 72 00 00 00 0b 00 00 00 f0 05 08 00 01 80 08 00 01 80 41 20 73 74 72 "
445*c33452fbSAndroid Build Coastguard Worker     "69 6e 67 20 6f 66 20 33 32 20 63 68 61 72 61 63 74 65 72 2e 40 40 40 40 40 40 "
446*c33452fbSAndroid Build Coastguard Worker     "40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 "
447*c33452fbSAndroid Build Coastguard Worker     "00 00 00 00 00 00 00 8a 02 48 00 ff ff ff ff ";
448*c33452fbSAndroid Build Coastguard Worker 
449*c33452fbSAndroid Build Coastguard Worker SCENARIO_METHOD(SettingsTestPF, "Bijection of binary show and read", "[identity][test]")
450*c33452fbSAndroid Build Coastguard Worker {
451*c33452fbSAndroid Build Coastguard Worker     CHECK(showBytes(readBytes(testBasicSettingsBytes)) == testBasicSettingsBytes);
452*c33452fbSAndroid Build Coastguard Worker }
453*c33452fbSAndroid Build Coastguard Worker 
454*c33452fbSAndroid Build Coastguard Worker SCENARIO_METHOD(SettingsTestPF, "Export and import root binary settings",
455*c33452fbSAndroid Build Coastguard Worker                 "[handler][settings][bytes]")
456*c33452fbSAndroid Build Coastguard Worker {
457*c33452fbSAndroid Build Coastguard Worker     ElementHandle root(*this, "/");
458*c33452fbSAndroid Build Coastguard Worker     ElementHandle systemClass(*this, "/");
459*c33452fbSAndroid Build Coastguard Worker 
460*c33452fbSAndroid Build Coastguard Worker     THEN ("Root and system class should export the same binary") {
461*c33452fbSAndroid Build Coastguard Worker         checkBytesEq(root.getAsBytes(), systemClass.getAsBytes());
462*c33452fbSAndroid Build Coastguard Worker     }
463*c33452fbSAndroid Build Coastguard Worker     WHEN ("Exporting root binary") {
464*c33452fbSAndroid Build Coastguard Worker         checkBytesEq(root.getAsBytes(), fullBytesSettings(defaultBasicSettingsBytes));
465*c33452fbSAndroid Build Coastguard Worker     }
466*c33452fbSAndroid Build Coastguard Worker     WHEN ("Importing root binary") {
467*c33452fbSAndroid Build Coastguard Worker         string rootTestSettings = fullBytesSettings(testBasicSettingsBytes);
468*c33452fbSAndroid Build Coastguard Worker         REQUIRE_NOTHROW(root.setAsBytes(readBytes(rootTestSettings)));
469*c33452fbSAndroid Build Coastguard Worker         THEN ("Exported settings should be the ones imported") {
470*c33452fbSAndroid Build Coastguard Worker             checkBytesEq(root.getAsBytes(), rootTestSettings);
471*c33452fbSAndroid Build Coastguard Worker         }
472*c33452fbSAndroid Build Coastguard Worker     }
473*c33452fbSAndroid Build Coastguard Worker }
474*c33452fbSAndroid Build Coastguard Worker 
475*c33452fbSAndroid Build Coastguard Worker SCENARIO_METHOD(SettingsTestPF, "Export and import basic binary settings",
476*c33452fbSAndroid Build Coastguard Worker                 "[handler][settings][bytes]")
477*c33452fbSAndroid Build Coastguard Worker {
478*c33452fbSAndroid Build Coastguard Worker     ElementHandle basicParams(*this, "/test/test/parameter_block");
479*c33452fbSAndroid Build Coastguard Worker     WHEN ("Exporting basic parameter binary") {
480*c33452fbSAndroid Build Coastguard Worker         checkBytesEq(basicParams.getAsBytes(), defaultBasicSettingsBytes);
481*c33452fbSAndroid Build Coastguard Worker     }
482*c33452fbSAndroid Build Coastguard Worker     WHEN ("Importing basic parameter binary") {
483*c33452fbSAndroid Build Coastguard Worker         REQUIRE_NOTHROW(basicParams.setAsBytes(readBytes(testBasicSettingsBytes)));
484*c33452fbSAndroid Build Coastguard Worker         THEN ("Exported settings should be the ones imported") {
485*c33452fbSAndroid Build Coastguard Worker             checkBytesEq(basicParams.getAsBytes(), testBasicSettingsBytes);
486*c33452fbSAndroid Build Coastguard Worker         }
487*c33452fbSAndroid Build Coastguard Worker     }
488*c33452fbSAndroid Build Coastguard Worker }
489*c33452fbSAndroid Build Coastguard Worker 
490*c33452fbSAndroid Build Coastguard Worker SCENARIO_METHOD(SettingsTestPF, "Export and import array binary settings",
491*c33452fbSAndroid Build Coastguard Worker                 "[handler][settings][bytes]")
492*c33452fbSAndroid Build Coastguard Worker {
493*c33452fbSAndroid Build Coastguard Worker     ElementHandle array(*this, "/test/test/parameter_block_array");
494*c33452fbSAndroid Build Coastguard Worker     ElementHandle elem0(*this, "/test/test/parameter_block_array/0");
495*c33452fbSAndroid Build Coastguard Worker     WHEN ("Importing one array element") {
496*c33452fbSAndroid Build Coastguard Worker         REQUIRE_NOTHROW(elem0.setAsBytes(readBytes(testBasicSettingsBytes)));
497*c33452fbSAndroid Build Coastguard Worker         THEN ("The other element should not have changed") {
498*c33452fbSAndroid Build Coastguard Worker             checkBytesEq(array.getAsBytes(), testBasicSettingsBytes + defaultBasicSettingsBytes);
499*c33452fbSAndroid Build Coastguard Worker         }
500*c33452fbSAndroid Build Coastguard Worker     }
501*c33452fbSAndroid Build Coastguard Worker }
502*c33452fbSAndroid Build Coastguard Worker 
503*c33452fbSAndroid Build Coastguard Worker SCENARIO_METHOD(SettingsTestPF, "Import root in one format, export in an other",
504*c33452fbSAndroid Build Coastguard Worker                 "[handler][settings][bytes][xml]")
505*c33452fbSAndroid Build Coastguard Worker {
506*c33452fbSAndroid Build Coastguard Worker     ElementHandle root(*this, "/test");
507*c33452fbSAndroid Build Coastguard Worker     string rootBytesSettings = fullBytesSettings(testBasicSettingsBytes);
508*c33452fbSAndroid Build Coastguard Worker     string rootXMLSettings = fullXMLSettings(testBasicSettingsXML);
509*c33452fbSAndroid Build Coastguard Worker 
510*c33452fbSAndroid Build Coastguard Worker     WHEN ("Importing root binary") {
511*c33452fbSAndroid Build Coastguard Worker         REQUIRE_NOTHROW(root.setAsBytes(readBytes(rootBytesSettings)));
512*c33452fbSAndroid Build Coastguard Worker         THEN ("Exported XML settings should be the ones imported") {
513*c33452fbSAndroid Build Coastguard Worker             checkXMLEq(root.getAsXML(), rootXMLSettings);
514*c33452fbSAndroid Build Coastguard Worker         }
515*c33452fbSAndroid Build Coastguard Worker     }
516*c33452fbSAndroid Build Coastguard Worker 
517*c33452fbSAndroid Build Coastguard Worker     WHEN ("Importing root XML") {
518*c33452fbSAndroid Build Coastguard Worker         REQUIRE_NOTHROW(root.setAsXML(rootXMLSettings));
519*c33452fbSAndroid Build Coastguard Worker         THEN ("Exported bytes settings should be the ones imported") {
520*c33452fbSAndroid Build Coastguard Worker             checkBytesEq(root.getAsBytes(), rootBytesSettings);
521*c33452fbSAndroid Build Coastguard Worker         }
522*c33452fbSAndroid Build Coastguard Worker     }
523*c33452fbSAndroid Build Coastguard Worker }
524*c33452fbSAndroid Build Coastguard Worker 
525*c33452fbSAndroid Build Coastguard Worker SCENARIO_METHOD(SettingsTestPF, "Import basic params in one format, export in an other",
526*c33452fbSAndroid Build Coastguard Worker                 "[handler][settings][bytes][xml]")
527*c33452fbSAndroid Build Coastguard Worker {
528*c33452fbSAndroid Build Coastguard Worker     ElementHandle basicParams(*this, "/test/test/parameter_block_array/0");
529*c33452fbSAndroid Build Coastguard Worker     string basicXMLSettings = mkBasicSettings(testBasicSettingsXML, "0");
530*c33452fbSAndroid Build Coastguard Worker 
531*c33452fbSAndroid Build Coastguard Worker     WHEN ("Importing basic parameters binary") {
532*c33452fbSAndroid Build Coastguard Worker         REQUIRE_NOTHROW(basicParams.setAsBytes(readBytes(testBasicSettingsBytes)));
533*c33452fbSAndroid Build Coastguard Worker         THEN ("Exported XML settings should be the ones imported") {
534*c33452fbSAndroid Build Coastguard Worker             checkXMLEq(basicParams.getAsXML(), basicXMLSettings);
535*c33452fbSAndroid Build Coastguard Worker         }
536*c33452fbSAndroid Build Coastguard Worker     }
537*c33452fbSAndroid Build Coastguard Worker 
538*c33452fbSAndroid Build Coastguard Worker     WHEN ("Importing basic parameters XML") {
539*c33452fbSAndroid Build Coastguard Worker         REQUIRE_NOTHROW(basicParams.setAsXML(basicXMLSettings));
540*c33452fbSAndroid Build Coastguard Worker         THEN ("Exported bytes settings should be the ones imported") {
541*c33452fbSAndroid Build Coastguard Worker             checkBytesEq(basicParams.getAsBytes(), testBasicSettingsBytes);
542*c33452fbSAndroid Build Coastguard Worker         }
543*c33452fbSAndroid Build Coastguard Worker     }
544*c33452fbSAndroid Build Coastguard Worker }
545*c33452fbSAndroid Build Coastguard Worker 
546*c33452fbSAndroid Build Coastguard Worker struct MappingPF : public ParameterFramework
547*c33452fbSAndroid Build Coastguard Worker {
MappingPFparameterFramework::MappingPF548*c33452fbSAndroid Build Coastguard Worker     MappingPF() : ParameterFramework{getConfig()} { REQUIRE_NOTHROW(start()); }
549*c33452fbSAndroid Build Coastguard Worker 
550*c33452fbSAndroid Build Coastguard Worker     struct TestVector
551*c33452fbSAndroid Build Coastguard Worker     {
552*c33452fbSAndroid Build Coastguard Worker         string path;
553*c33452fbSAndroid Build Coastguard Worker         string humanReadable;
554*c33452fbSAndroid Build Coastguard Worker         list<string> valid;
555*c33452fbSAndroid Build Coastguard Worker         list<string> invalid;
556*c33452fbSAndroid Build Coastguard Worker     };
557*c33452fbSAndroid Build Coastguard Worker 
558*c33452fbSAndroid Build Coastguard Worker     list<TestVector> testVectors = {
559*c33452fbSAndroid Build Coastguard Worker         // clang-format off
560*c33452fbSAndroid Build Coastguard Worker         {"/test/test",
561*c33452fbSAndroid Build Coastguard Worker             {"rootK:rootV"},
562*c33452fbSAndroid Build Coastguard Worker             {"root"},
563*c33452fbSAndroid Build Coastguard Worker             {"param", "type", "instance", "derived"}},
564*c33452fbSAndroid Build Coastguard Worker         {"/test/test/param",
565*c33452fbSAndroid Build Coastguard Worker             {"rootK:rootV, paramK:paramV"},
566*c33452fbSAndroid Build Coastguard Worker             {"root", "param"},
567*c33452fbSAndroid Build Coastguard Worker             {"type", "derived", "instance"}},
568*c33452fbSAndroid Build Coastguard Worker         {"/test/test/component",
569*c33452fbSAndroid Build Coastguard Worker             {"rootK:rootV, typeK:typeV, derivedK:derivedV, instanceK:instanceV"},
570*c33452fbSAndroid Build Coastguard Worker             {"root", "type", "derived", "instance"},
571*c33452fbSAndroid Build Coastguard Worker             {"param"}}
572*c33452fbSAndroid Build Coastguard Worker         // clang-format on
573*c33452fbSAndroid Build Coastguard Worker     };
574*c33452fbSAndroid Build Coastguard Worker 
getConfigparameterFramework::MappingPF575*c33452fbSAndroid Build Coastguard Worker     Config getConfig()
576*c33452fbSAndroid Build Coastguard Worker     {
577*c33452fbSAndroid Build Coastguard Worker         Config config;
578*c33452fbSAndroid Build Coastguard Worker         config.subsystemMapping = "rootK:rootV";
579*c33452fbSAndroid Build Coastguard Worker         config.components = "<ComponentType   Name='componentType' Mapping='typeK:typeV'        />"
580*c33452fbSAndroid Build Coastguard Worker                             "<ComponentType   Extends='componentType' Name='derivedComponentType' "
581*c33452fbSAndroid Build Coastguard Worker                             "Mapping='derivedK:derivedV' />";
582*c33452fbSAndroid Build Coastguard Worker         config.instances = "<BooleanParameter Name='param'         Mapping='paramK:paramV'      />"
583*c33452fbSAndroid Build Coastguard Worker                            "<Component        Name='component'     Mapping='instanceK:instanceV'  "
584*c33452fbSAndroid Build Coastguard Worker                            "           Type='derivedComponentType'                              />";
585*c33452fbSAndroid Build Coastguard Worker         return config;
586*c33452fbSAndroid Build Coastguard Worker     }
587*c33452fbSAndroid Build Coastguard Worker };
588*c33452fbSAndroid Build Coastguard Worker 
589*c33452fbSAndroid Build Coastguard Worker SCENARIO_METHOD(MappingPF, "showMapping command", "[mapping]")
590*c33452fbSAndroid Build Coastguard Worker {
591*c33452fbSAndroid Build Coastguard Worker     auto cmdHandler = std::unique_ptr<CommandHandlerInterface>(createCommandHandler());
592*c33452fbSAndroid Build Coastguard Worker 
593*c33452fbSAndroid Build Coastguard Worker     for (auto &testVector : testVectors) {
594*c33452fbSAndroid Build Coastguard Worker         string output;
595*c33452fbSAndroid Build Coastguard Worker         CHECK(cmdHandler->process("showMapping", {testVector.path}, output));
596*c33452fbSAndroid Build Coastguard Worker         CHECK(output == testVector.humanReadable);
597*c33452fbSAndroid Build Coastguard Worker     }
598*c33452fbSAndroid Build Coastguard Worker }
599*c33452fbSAndroid Build Coastguard Worker 
600*c33452fbSAndroid Build Coastguard Worker SCENARIO_METHOD(MappingPF, "Mapping handle access", "[handler][mapping]")
601*c33452fbSAndroid Build Coastguard Worker {
602*c33452fbSAndroid Build Coastguard Worker     GIVEN ("A PF with mappings") {
603*c33452fbSAndroid Build Coastguard Worker         for (auto &test : testVectors) {
604*c33452fbSAndroid Build Coastguard Worker             GIVEN ("An element handle of " + test.path) {
605*c33452fbSAndroid Build Coastguard Worker                 ElementHandle handle(*this, test.path);
606*c33452fbSAndroid Build Coastguard Worker 
607*c33452fbSAndroid Build Coastguard Worker                 for (auto &valid : test.valid) {
608*c33452fbSAndroid Build Coastguard Worker                     THEN ("The following mapping should exist: " + valid) {
609*c33452fbSAndroid Build Coastguard Worker                         CHECK(handle.getMappingData(valid + "K") == valid + "V");
610*c33452fbSAndroid Build Coastguard Worker                     }
611*c33452fbSAndroid Build Coastguard Worker                 }
612*c33452fbSAndroid Build Coastguard Worker 
613*c33452fbSAndroid Build Coastguard Worker                 for (auto &invalid : test.invalid) {
614*c33452fbSAndroid Build Coastguard Worker                     THEN ("The following mapping should not exist: " + invalid) {
615*c33452fbSAndroid Build Coastguard Worker                         CHECK_THROWS_AS(handle.getMappingData(invalid + "K"), Exception);
616*c33452fbSAndroid Build Coastguard Worker                     }
617*c33452fbSAndroid Build Coastguard Worker                 }
618*c33452fbSAndroid Build Coastguard Worker             }
619*c33452fbSAndroid Build Coastguard Worker         }
620*c33452fbSAndroid Build Coastguard Worker     }
621*c33452fbSAndroid Build Coastguard Worker }
622*c33452fbSAndroid Build Coastguard Worker 
623*c33452fbSAndroid Build Coastguard Worker SCENARIO_METHOD(SettingsTestPF, "Handle Get/Set as various kinds", "[handler][dynamic]")
624*c33452fbSAndroid Build Coastguard Worker {
625*c33452fbSAndroid Build Coastguard Worker     ElementHandle intScalar(*this, "/test/test/parameter_block/integer");
626*c33452fbSAndroid Build Coastguard Worker     WHEN ("Setting a scalar integer") {
627*c33452fbSAndroid Build Coastguard Worker         WHEN ("As an array") {
628*c33452fbSAndroid Build Coastguard Worker             THEN ("It should fail") {
629*c33452fbSAndroid Build Coastguard Worker                 CHECK_THROWS(intScalar.setAsIntegerArray({0, 0}));
630*c33452fbSAndroid Build Coastguard Worker             }
631*c33452fbSAndroid Build Coastguard Worker         }
632*c33452fbSAndroid Build Coastguard Worker         WHEN ("As a scalalar") {
633*c33452fbSAndroid Build Coastguard Worker             THEN ("It should succeed") {
634*c33452fbSAndroid Build Coastguard Worker                 uint32_t expected = 111;
635*c33452fbSAndroid Build Coastguard Worker                 CHECK_NOTHROW(intScalar.setAsInteger(expected));
636*c33452fbSAndroid Build Coastguard Worker                 AND_THEN ("Getting it back should give the same value") {
637*c33452fbSAndroid Build Coastguard Worker                     uint32_t back = 42;
638*c33452fbSAndroid Build Coastguard Worker                     CHECK_NOTHROW(intScalar.getAsInteger(back));
639*c33452fbSAndroid Build Coastguard Worker                     CHECK(back == expected);
640*c33452fbSAndroid Build Coastguard Worker                 }
641*c33452fbSAndroid Build Coastguard Worker             }
642*c33452fbSAndroid Build Coastguard Worker         }
643*c33452fbSAndroid Build Coastguard Worker     }
644*c33452fbSAndroid Build Coastguard Worker 
645*c33452fbSAndroid Build Coastguard Worker     ElementHandle intArray(*this, "/test/test/parameter_block/integer_array");
646*c33452fbSAndroid Build Coastguard Worker     WHEN ("Setting a array integer") {
647*c33452fbSAndroid Build Coastguard Worker         WHEN ("As a scalar") {
648*c33452fbSAndroid Build Coastguard Worker             THEN ("It should fail") {
649*c33452fbSAndroid Build Coastguard Worker                 CHECK_THROWS(intArray.setAsSignedInteger(0));
650*c33452fbSAndroid Build Coastguard Worker             }
651*c33452fbSAndroid Build Coastguard Worker         }
652*c33452fbSAndroid Build Coastguard Worker         WHEN ("As a integer") {
653*c33452fbSAndroid Build Coastguard Worker             THEN ("It should succeed") {
654*c33452fbSAndroid Build Coastguard Worker                 const std::vector<int32_t> expected = {-9, 8, -7, 6};
655*c33452fbSAndroid Build Coastguard Worker                 CHECK_NOTHROW(intArray.setAsSignedIntegerArray(expected));
656*c33452fbSAndroid Build Coastguard Worker                 AND_THEN ("Getting it back should give the same value") {
657*c33452fbSAndroid Build Coastguard Worker                     std::vector<int32_t> back = {-42, 42, 43, -43};
658*c33452fbSAndroid Build Coastguard Worker                     CHECK_NOTHROW(intArray.getAsSignedIntegerArray(back));
659*c33452fbSAndroid Build Coastguard Worker                     CHECK(back == expected);
660*c33452fbSAndroid Build Coastguard Worker                 }
661*c33452fbSAndroid Build Coastguard Worker             }
662*c33452fbSAndroid Build Coastguard Worker         }
663*c33452fbSAndroid Build Coastguard Worker     }
664*c33452fbSAndroid Build Coastguard Worker }
665*c33452fbSAndroid Build Coastguard Worker } // namespace parameterFramework
666