1 /*
2  * Copyright (c) 2011-2015, Intel Corporation
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this
9  * list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation and/or
13  * other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors
16  * may be used to endorse or promote products derived from this software without
17  * specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
23  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
26  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <stdlib.h>
32 #include <sstream>
33 #include <assert.h>
34 #include <errno.h>
35 #include <convert.hpp>
36 #include <sstream>
37 #include "TestPlatform.h"
38 
39 using std::string;
40 
CTestPlatform(const string & strClass,uint16_t iPortNumber)41 CTestPlatform::CTestPlatform(const string &strClass, uint16_t iPortNumber)
42     : mParameterMgrPlatformConnector(strClass), mLogger(), mRemoteProcessorServer(iPortNumber)
43 {
44     mParameterMgrPlatformConnector.setLogger(&mLogger);
45 }
46 
~CTestPlatform()47 CTestPlatform::~CTestPlatform()
48 {
49 }
50 
exit(const IRemoteCommand &,string &)51 CTestPlatform::CommandReturn CTestPlatform::exit(const IRemoteCommand & /*command*/,
52                                                  string & /*strResult*/)
53 {
54     mRemoteProcessorServer.stop();
55 
56     return CTestPlatform::CCommandHandler::EDone;
57 }
58 
run(std::string & strError)59 bool CTestPlatform::run(std::string &strError)
60 {
61     // Start remote processor server
62     if (!mRemoteProcessorServer.start(strError)) {
63 
64         strError = "TestPlatform: Unable to start remote processor server: " + strError;
65         return false;
66     }
67 
68     CCommandHandler commandHandler(this);
69 
70     // Add command parsers
71     commandHandler.addCommandParser("exit", &CTestPlatform::exit, 0, "", "Exit TestPlatform");
72     commandHandler.addCommandParser("createExclusiveSelectionCriterionFromStateList",
73                                     &CTestPlatform::createExclusiveSelectionCriterionFromStateList,
74                                     2, "<name> <stateList>",
75                                     "Create inclusive selection criterion from state name list");
76     commandHandler.addCommandParser("createInclusiveSelectionCriterionFromStateList",
77                                     &CTestPlatform::createInclusiveSelectionCriterionFromStateList,
78                                     2, "<name> <stateList>",
79                                     "Create exclusive selection criterion from state name list");
80 
81     commandHandler.addCommandParser("createExclusiveSelectionCriterion",
82                                     &CTestPlatform::createExclusiveSelectionCriterion, 2,
83                                     "<name> <nbStates>", "Create inclusive selection criterion");
84     commandHandler.addCommandParser("createInclusiveSelectionCriterion",
85                                     &CTestPlatform::createInclusiveSelectionCriterion, 2,
86                                     "<name> <nbStates>", "Create exclusive selection criterion");
87 
88     commandHandler.addCommandParser("start", &CTestPlatform::startParameterMgr, 0, "",
89                                     "Start ParameterMgr");
90 
91     commandHandler.addCommandParser("setCriterionState", &CTestPlatform::setCriterionState, 2,
92                                     "<name> <state>",
93                                     "Set the current state of a selection criterion");
94     commandHandler.addCommandParser(
95         "applyConfigurations", &CTestPlatform::applyConfigurations, 0, "",
96         "Apply configurations selected by current selection criteria states");
97 
98     commandHandler.addCommandParser(
99         "setFailureOnMissingSubsystem",
100         &CTestPlatform::setter<&CParameterMgrPlatformConnector::setFailureOnMissingSubsystem>, 1,
101         "true|false", "Set policy for missing subsystems, "
102                       "either abort start or fallback on virtual subsystem.");
103     commandHandler.addCommandParser(
104         "getMissingSubsystemPolicy",
105         &CTestPlatform::getter<&CParameterMgrPlatformConnector::getFailureOnMissingSubsystem>, 0,
106         "", "Get policy for missing subsystems, "
107             "either abort start or fallback on virtual subsystem.");
108 
109     commandHandler.addCommandParser(
110         "setFailureOnFailedSettingsLoad",
111         &CTestPlatform::setter<&CParameterMgrPlatformConnector::setFailureOnFailedSettingsLoad>, 1,
112         "true|false",
113         "Set policy for failed settings load, either abort start or continue without domains.");
114     commandHandler.addCommandParser(
115         "getFailedSettingsLoadPolicy",
116         &CTestPlatform::getter<&CParameterMgrPlatformConnector::getFailureOnFailedSettingsLoad>, 0,
117         "", "Get policy for failed settings load, either abort start or continue without domains.");
118 
119     commandHandler.addCommandParser(
120         "setValidateSchemasOnStart",
121         &CTestPlatform::setter<&CParameterMgrPlatformConnector::setValidateSchemasOnStart>, 1,
122         "true|false", "Set policy for schema validation based on .xsd files (false by default).");
123     commandHandler.addCommandParser(
124         "getValidateSchemasOnStart",
125         &CTestPlatform::getter<&CParameterMgrPlatformConnector::getValidateSchemasOnStart>, 0, "",
126         "Get policy for schema validation based on .xsd files.");
127 
128     commandHandler.addCommandParser("getSchemaUri", &CTestPlatform::getSchemaUri, 0, "",
129                                     "Get the directory where schemas can be found.");
130     commandHandler.addCommandParser("setSchemaUri", &CTestPlatform::setSchemaUri, 1, "<directory>",
131                                     "Set the directory where schemas can be found.");
132 
133     return mRemoteProcessorServer.process(commandHandler);
134 }
135 
136 //////////////// Remote command parsers
137 /// Selection Criterion
createExclusiveSelectionCriterionFromStateList(const IRemoteCommand & remoteCommand,string & strResult)138 CTestPlatform::CommandReturn CTestPlatform::createExclusiveSelectionCriterionFromStateList(
139     const IRemoteCommand &remoteCommand, string &strResult)
140 {
141     return createExclusiveSelectionCriterionFromStateList(remoteCommand.getArgument(0),
142                                                           remoteCommand, strResult)
143                ? CTestPlatform::CCommandHandler::EDone
144                : CTestPlatform::CCommandHandler::EFailed;
145 }
146 
createInclusiveSelectionCriterionFromStateList(const IRemoteCommand & remoteCommand,string & strResult)147 CTestPlatform::CommandReturn CTestPlatform::createInclusiveSelectionCriterionFromStateList(
148     const IRemoteCommand &remoteCommand, string &strResult)
149 {
150     return createInclusiveSelectionCriterionFromStateList(remoteCommand.getArgument(0),
151                                                           remoteCommand, strResult)
152                ? CTestPlatform::CCommandHandler::EDone
153                : CTestPlatform::CCommandHandler::EFailed;
154 }
155 
createExclusiveSelectionCriterion(const IRemoteCommand & remoteCommand,string & strResult)156 CTestPlatform::CommandReturn CTestPlatform::createExclusiveSelectionCriterion(
157     const IRemoteCommand &remoteCommand, string &strResult)
158 {
159     return createExclusiveSelectionCriterion(remoteCommand.getArgument(0),
160                                              strtoul(remoteCommand.getArgument(1).c_str(), NULL, 0),
161                                              strResult)
162                ? CTestPlatform::CCommandHandler::EDone
163                : CTestPlatform::CCommandHandler::EFailed;
164 }
165 
createInclusiveSelectionCriterion(const IRemoteCommand & remoteCommand,string & strResult)166 CTestPlatform::CommandReturn CTestPlatform::createInclusiveSelectionCriterion(
167     const IRemoteCommand &remoteCommand, string &strResult)
168 {
169     return createInclusiveSelectionCriterion(remoteCommand.getArgument(0),
170                                              strtoul(remoteCommand.getArgument(1).c_str(), NULL, 0),
171                                              strResult)
172                ? CTestPlatform::CCommandHandler::EDone
173                : CTestPlatform::CCommandHandler::EFailed;
174 }
175 
startParameterMgr(const IRemoteCommand &,string & strResult)176 CTestPlatform::CommandReturn CTestPlatform::startParameterMgr(
177     const IRemoteCommand & /*remoteCommand*/, string &strResult)
178 {
179     return mParameterMgrPlatformConnector.start(strResult)
180                ? CTestPlatform::CCommandHandler::EDone
181                : CTestPlatform::CCommandHandler::EFailed;
182 }
183 
184 template <CTestPlatform::setter_t setFunction>
setter(const IRemoteCommand & remoteCommand,string & strResult)185 CTestPlatform::CommandReturn CTestPlatform::setter(const IRemoteCommand &remoteCommand,
186                                                    string &strResult)
187 {
188     const string &strAbort = remoteCommand.getArgument(0);
189 
190     bool bFail;
191 
192     if (!convertTo(strAbort, bFail)) {
193         return CTestPlatform::CCommandHandler::EShowUsage;
194     }
195 
196     return (mParameterMgrPlatformConnector.*setFunction)(bFail, strResult)
197                ? CTestPlatform::CCommandHandler::EDone
198                : CTestPlatform::CCommandHandler::EFailed;
199 }
200 
201 template <CTestPlatform::getter_t getFunction>
getter(const IRemoteCommand &,string & strResult)202 CTestPlatform::CommandReturn CTestPlatform::getter(const IRemoteCommand & /*command*/,
203                                                    string &strResult)
204 {
205     strResult = (mParameterMgrPlatformConnector.*getFunction)() ? "true" : "false";
206 
207     return CTestPlatform::CCommandHandler::ESucceeded;
208 }
209 
getSchemaUri(const IRemoteCommand &,string & result)210 CTestPlatform::CommandReturn CTestPlatform::getSchemaUri(const IRemoteCommand & /*remotecommand*/,
211                                                          string &result)
212 {
213     result = mParameterMgrPlatformConnector.getSchemaUri();
214     return CTestPlatform::CCommandHandler::EDone;
215 }
216 
setSchemaUri(const IRemoteCommand & remotecommand,string &)217 CTestPlatform::CommandReturn CTestPlatform::setSchemaUri(const IRemoteCommand &remotecommand,
218                                                          string & /*result*/)
219 {
220     mParameterMgrPlatformConnector.setSchemaUri(remotecommand.getArgument(0));
221     return CTestPlatform::CCommandHandler::EDone;
222 }
223 
setCriterionState(const IRemoteCommand & remoteCommand,string & strResult)224 CTestPlatform::CommandReturn CTestPlatform::setCriterionState(const IRemoteCommand &remoteCommand,
225                                                               string &strResult)
226 {
227 
228     bool bSuccess;
229 
230     uint32_t state;
231 
232     if (convertTo(remoteCommand.getArgument(1), state)) {
233         // Sucessfull conversion, set criterion state by numerical state
234         bSuccess = setCriterionState(remoteCommand.getArgument(0), state, strResult);
235 
236     } else {
237         // Conversion failed, set criterion state by lexical state
238         bSuccess = setCriterionStateByLexicalSpace(remoteCommand, strResult);
239     }
240 
241     return bSuccess ? CTestPlatform::CCommandHandler::EDone
242                     : CTestPlatform::CCommandHandler::EFailed;
243 }
244 
applyConfigurations(const IRemoteCommand &,string &)245 CTestPlatform::CommandReturn CTestPlatform::applyConfigurations(const IRemoteCommand & /*command*/,
246                                                                 string & /*strResult*/)
247 {
248     mParameterMgrPlatformConnector.applyConfigurations();
249 
250     return CTestPlatform::CCommandHandler::EDone;
251 }
252 
253 //////////////// Remote command handlers
254 
createExclusiveSelectionCriterionFromStateList(const string & strName,const IRemoteCommand & remoteCommand,string & strResult)255 bool CTestPlatform::createExclusiveSelectionCriterionFromStateList(
256     const string &strName, const IRemoteCommand &remoteCommand, string &strResult)
257 {
258     ISelectionCriterionTypeInterface *pCriterionType =
259         mParameterMgrPlatformConnector.createSelectionCriterionType(false);
260 
261     assert(pCriterionType != NULL);
262 
263     size_t nbStates = remoteCommand.getArgumentCount() - 1;
264 
265     for (size_t state = 0; state < nbStates; state++) {
266 
267         const std::string &strValue = remoteCommand.getArgument(state + 1);
268 
269         // FIXME state type vs addValuePair params
270         if (!pCriterionType->addValuePair(int(state), strValue, strResult)) {
271 
272             strResult = "Unable to add value: " + strValue + ": " + strResult;
273 
274             return false;
275         }
276     }
277 
278     mParameterMgrPlatformConnector.createSelectionCriterion(strName, pCriterionType);
279 
280     return true;
281 }
282 
createInclusiveSelectionCriterionFromStateList(const string & strName,const IRemoteCommand & remoteCommand,string & strResult)283 bool CTestPlatform::createInclusiveSelectionCriterionFromStateList(
284     const string &strName, const IRemoteCommand &remoteCommand, string &strResult)
285 {
286     ISelectionCriterionTypeInterface *pCriterionType =
287         mParameterMgrPlatformConnector.createSelectionCriterionType(true);
288 
289     assert(pCriterionType != NULL);
290 
291     size_t nbStates = remoteCommand.getArgumentCount() - 1;
292 
293     for (size_t state = 0; state < nbStates; state++) {
294 
295         const std::string &strValue = remoteCommand.getArgument(state + 1);
296 
297         if (!pCriterionType->addValuePair(0x1 << state, strValue, strResult)) {
298 
299             strResult = "Unable to add value: " + strValue + ": " + strResult;
300 
301             return false;
302         }
303     }
304 
305     mParameterMgrPlatformConnector.createSelectionCriterion(strName, pCriterionType);
306 
307     return true;
308 }
309 
createExclusiveSelectionCriterion(const string & strName,size_t nbStates,string & strResult)310 bool CTestPlatform::createExclusiveSelectionCriterion(const string &strName, size_t nbStates,
311                                                       string &strResult)
312 {
313     ISelectionCriterionTypeInterface *pCriterionType =
314         mParameterMgrPlatformConnector.createSelectionCriterionType(false);
315 
316     for (size_t state = 0; state < nbStates; state++) {
317 
318         std::ostringstream ostrValue;
319 
320         ostrValue << "State_";
321         ostrValue << state;
322 
323         // FIXME state type vs addValuePair params
324         if (!pCriterionType->addValuePair(int(state), ostrValue.str(), strResult)) {
325 
326             strResult = "Unable to add value: " + ostrValue.str() + ": " + strResult;
327 
328             return false;
329         }
330     }
331 
332     mParameterMgrPlatformConnector.createSelectionCriterion(strName, pCriterionType);
333 
334     return true;
335 }
336 
createInclusiveSelectionCriterion(const string & strName,size_t nbStates,string & strResult)337 bool CTestPlatform::createInclusiveSelectionCriterion(const string &strName, size_t nbStates,
338                                                       string &strResult)
339 {
340     ISelectionCriterionTypeInterface *pCriterionType =
341         mParameterMgrPlatformConnector.createSelectionCriterionType(true);
342 
343     for (size_t state = 0; state < nbStates; state++) {
344 
345         std::ostringstream ostrValue;
346 
347         ostrValue << "State_0x";
348         ostrValue << (0x1 << state);
349 
350         if (!pCriterionType->addValuePair(0x1 << state, ostrValue.str(), strResult)) {
351 
352             strResult = "Unable to add value: " + ostrValue.str() + ": " + strResult;
353 
354             return false;
355         }
356     }
357 
358     mParameterMgrPlatformConnector.createSelectionCriterion(strName, pCriterionType);
359 
360     return true;
361 }
362 
setCriterionState(const string & strName,uint32_t uiState,string & strResult)363 bool CTestPlatform::setCriterionState(const string &strName, uint32_t uiState, string &strResult)
364 {
365     ISelectionCriterionInterface *pCriterion =
366         mParameterMgrPlatformConnector.getSelectionCriterion(strName);
367 
368     if (!pCriterion) {
369 
370         strResult = "Unable to retrieve selection criterion: " + strName;
371 
372         return false;
373     }
374 
375     pCriterion->setCriterionState(uiState);
376 
377     return true;
378 }
379 
setCriterionStateByLexicalSpace(const IRemoteCommand & remoteCommand,string & strResult)380 bool CTestPlatform::setCriterionStateByLexicalSpace(const IRemoteCommand &remoteCommand,
381                                                     string &strResult)
382 {
383 
384     // Get criterion name
385     std::string strCriterionName = remoteCommand.getArgument(0);
386 
387     ISelectionCriterionInterface *pCriterion =
388         mParameterMgrPlatformConnector.getSelectionCriterion(strCriterionName);
389 
390     if (!pCriterion) {
391 
392         strResult = "Unable to retrieve selection criterion: " + strCriterionName;
393 
394         return false;
395     }
396 
397     // Get criterion type
398     const ISelectionCriterionTypeInterface *pCriterionType = pCriterion->getCriterionType();
399 
400     // Get substate number, the first argument (index 0) is the criterion name
401     size_t nbSubStates = remoteCommand.getArgumentCount() - 1;
402 
403     // Check that exclusive criterion has only one substate
404     if (!pCriterionType->isTypeInclusive() && nbSubStates != 1) {
405 
406         strResult = "Exclusive criterion " + strCriterionName + " can only have one state";
407 
408         return false;
409     }
410 
411     /// Translate lexical state to numerical state
412     int iNumericalState = 0;
413     size_t lexicalSubStateIndex;
414 
415     // Parse lexical substates
416     std::string strLexicalState = "";
417 
418     for (lexicalSubStateIndex = 1; lexicalSubStateIndex <= nbSubStates; lexicalSubStateIndex++) {
419         /*
420          * getNumericalValue method from ISelectionCriterionTypeInterface strip his parameter
421          * first parameter based on | sign. In case that the user uses multiple parameters
422          * to set InclusiveCriterion value, we aggregate all desired values to be sure
423          * they will be handled correctly.
424          */
425         if (lexicalSubStateIndex != 1) {
426             strLexicalState += "|";
427         }
428         strLexicalState += remoteCommand.getArgument(lexicalSubStateIndex);
429     }
430 
431     // Translate lexical to numerical substate
432     if (!pCriterionType->getNumericalValue(strLexicalState, iNumericalState)) {
433 
434         strResult = "Unable to find lexical state \"" + strLexicalState + "\" in criteria " +
435                     strCriterionName;
436 
437         return false;
438     }
439 
440     // Set criterion new state
441     pCriterion->setCriterionState(iNumericalState);
442 
443     return true;
444 }
445