1/* 2 * Copyright (c) 2011-2014, 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 <strings.h> 32#include <iostream> 33#include <stdlib.h> 34#include <sstream> 35#include <assert.h> 36#include <errno.h> 37#include <convert.hpp> 38#include <sstream> 39#include "TestPlatform.h" 40#include "ParameterMgrPlatformConnector.h" 41#include "RemoteProcessorServer.h" 42 43using std::string; 44 45class CParameterMgrPlatformConnectorLogger : public CParameterMgrPlatformConnector::ILogger 46{ 47public: 48 CParameterMgrPlatformConnectorLogger() {} 49 50 virtual void log(bool bIsWarning, const string& strLog) 51 { 52 53 if (bIsWarning) { 54 55 std::cerr << strLog << std::endl; 56 } else { 57 58 std::cout << strLog << std::endl; 59 } 60 } 61}; 62 63CTestPlatform::CTestPlatform(const string& strClass, int iPortNumber, sem_t& exitSemaphore) : 64 _pParameterMgrPlatformConnector(new CParameterMgrPlatformConnector(strClass)), 65 _pParameterMgrPlatformConnectorLogger(new CParameterMgrPlatformConnectorLogger), 66 _exitSemaphore(exitSemaphore) 67{ 68 _pCommandHandler = new CCommandHandler(this); 69 70 // Add command parsers 71 _pCommandHandler->addCommandParser("exit", &CTestPlatform::exit, 72 0, "", "Exit TestPlatform"); 73 _pCommandHandler->addCommandParser( 74 "createExclusiveSelectionCriterionFromStateList", 75 &CTestPlatform::createExclusiveSelectionCriterionFromStateList, 76 2, "<name> <stateList>", 77 "Create inclusive selection criterion from state name list"); 78 _pCommandHandler->addCommandParser( 79 "createInclusiveSelectionCriterionFromStateList", 80 &CTestPlatform::createInclusiveSelectionCriterionFromStateList, 81 2, "<name> <stateList>", 82 "Create exclusive selection criterion from state name list"); 83 84 _pCommandHandler->addCommandParser( 85 "createExclusiveSelectionCriterion", 86 &CTestPlatform::createExclusiveSelectionCriterion, 87 2, "<name> <nbStates>", "Create inclusive selection criterion"); 88 _pCommandHandler->addCommandParser( 89 "createInclusiveSelectionCriterion", 90 &CTestPlatform::createInclusiveSelectionCriterion, 91 2, "<name> <nbStates>", "Create exclusive selection criterion"); 92 93 _pCommandHandler->addCommandParser("start", &CTestPlatform::startParameterMgr, 94 0, "", "Start ParameterMgr"); 95 96 _pCommandHandler->addCommandParser("setCriterionState", &CTestPlatform::setCriterionState, 97 2, "<name> <state>", 98 "Set the current state of a selection criterion"); 99 _pCommandHandler->addCommandParser( 100 "applyConfigurations", 101 &CTestPlatform::applyConfigurations, 102 0, "", "Apply configurations selected by current selection criteria states"); 103 104 _pCommandHandler->addCommandParser( 105 "setFailureOnMissingSubsystem", 106 &CTestPlatform::setter<& CParameterMgrPlatformConnector::setFailureOnMissingSubsystem>, 107 1, "true|false", "Set policy for missing subsystems, " 108 "either abort start or fallback on virtual subsystem."); 109 _pCommandHandler->addCommandParser( 110 "getMissingSubsystemPolicy", 111 &CTestPlatform::getter<& CParameterMgrPlatformConnector::getFailureOnMissingSubsystem>, 112 0, "", "Get policy for missing subsystems, " 113 "either abort start or fallback on virtual subsystem."); 114 115 _pCommandHandler->addCommandParser( 116 "setFailureOnFailedSettingsLoad", 117 &CTestPlatform::setter<& CParameterMgrPlatformConnector::setFailureOnFailedSettingsLoad>, 118 1, "true|false", 119 "Set policy for failed settings load, either abort start or continue without domains."); 120 _pCommandHandler->addCommandParser( 121 "getFailedSettingsLoadPolicy", 122 &CTestPlatform::getter<& CParameterMgrPlatformConnector::getFailureOnFailedSettingsLoad>, 123 0, "", 124 "Get policy for failed settings load, either abort start or continue without domains."); 125 126 _pCommandHandler->addCommandParser( 127 "setValidateSchemasOnStart", 128 &CTestPlatform::setter<& CParameterMgrPlatformConnector::setValidateSchemasOnStart>, 129 1, "true|false", 130 "Set policy for schema validation based on .xsd files (false by default)."); 131 _pCommandHandler->addCommandParser( 132 "getValidateSchemasOnStart", 133 &CTestPlatform::getter<& CParameterMgrPlatformConnector::getValidateSchemasOnStart>, 134 0, "", 135 "Get policy for schema validation based on .xsd files."); 136 137 // Create server 138 _pRemoteProcessorServer = new CRemoteProcessorServer(iPortNumber, _pCommandHandler); 139 140 _pParameterMgrPlatformConnector->setLogger(_pParameterMgrPlatformConnectorLogger); 141} 142 143CTestPlatform::~CTestPlatform() 144{ 145 delete _pRemoteProcessorServer; 146 delete _pCommandHandler; 147 delete _pParameterMgrPlatformConnectorLogger; 148 delete _pParameterMgrPlatformConnector; 149} 150 151CTestPlatform::CommandReturn CTestPlatform::exit( 152 const IRemoteCommand& remoteCommand, string& strResult) 153{ 154 (void)remoteCommand; 155 156 // Release the main blocking semaphore to quit application 157 sem_post(&_exitSemaphore); 158 159 return CTestPlatform::CCommandHandler::EDone; 160} 161 162bool CTestPlatform::load(std::string& strError) 163{ 164 // Start remote processor server 165 if (!_pRemoteProcessorServer->start(strError)) { 166 167 strError = "TestPlatform: Unable to start remote processor server: " + strError; 168 return false; 169 } 170 171 return true; 172} 173 174//////////////// Remote command parsers 175/// Selection Criterion 176CTestPlatform::CommandReturn CTestPlatform::createExclusiveSelectionCriterionFromStateList( 177 const IRemoteCommand& remoteCommand, string& strResult) 178{ 179 return createExclusiveSelectionCriterionFromStateList( 180 remoteCommand.getArgument(0), remoteCommand, strResult) ? 181 CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; 182} 183 184CTestPlatform::CommandReturn CTestPlatform::createInclusiveSelectionCriterionFromStateList( 185 const IRemoteCommand& remoteCommand, string& strResult) 186{ 187 return createInclusiveSelectionCriterionFromStateList( 188 remoteCommand.getArgument(0), remoteCommand, strResult) ? 189 CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; 190} 191 192CTestPlatform::CommandReturn CTestPlatform::createExclusiveSelectionCriterion( 193 const IRemoteCommand& remoteCommand, string& strResult) 194{ 195 return createExclusiveSelectionCriterion( 196 remoteCommand.getArgument(0), 197 strtoul(remoteCommand.getArgument(1).c_str(), NULL, 0), 198 strResult) ? 199 CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; 200} 201 202CTestPlatform::CommandReturn CTestPlatform::createInclusiveSelectionCriterion( 203 const IRemoteCommand& remoteCommand, string& strResult) 204{ 205 return createInclusiveSelectionCriterion( 206 remoteCommand.getArgument(0), 207 strtoul(remoteCommand.getArgument(1).c_str(), NULL, 0), 208 strResult) ? 209 CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; 210} 211 212CTestPlatform::CommandReturn CTestPlatform::startParameterMgr( 213 const IRemoteCommand& remoteCommand, string& strResult) 214{ 215 (void)remoteCommand; 216 217 return _pParameterMgrPlatformConnector->start(strResult) ? 218 CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; 219} 220 221template <CTestPlatform::setter_t setFunction> 222CTestPlatform::CommandReturn CTestPlatform::setter( 223 const IRemoteCommand& remoteCommand, string& strResult) 224{ 225 const string& strAbort = remoteCommand.getArgument(0); 226 227 bool bFail; 228 229 if(!convertTo(strAbort, bFail)) { 230 return CTestPlatform::CCommandHandler::EShowUsage; 231 } 232 233 return (_pParameterMgrPlatformConnector->*setFunction)(bFail, strResult) ? 234 CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; 235} 236 237template <CTestPlatform::getter_t getFunction> 238CTestPlatform::CommandReturn CTestPlatform::getter( 239 const IRemoteCommand& remoteCommand, string& strResult) 240{ 241 (void)remoteCommand; 242 243 strResult = (_pParameterMgrPlatformConnector->*getFunction)() ? "true" : "false"; 244 245 return CTestPlatform::CCommandHandler::ESucceeded; 246} 247 248CTestPlatform::CommandReturn CTestPlatform::setCriterionState( 249 const IRemoteCommand& remoteCommand, string& strResult) 250{ 251 252 bool bSuccess; 253 254 const char* pcState = remoteCommand.getArgument(1).c_str(); 255 256 char* pcStrEnd; 257 258 // Reset errno to check if it is updated during the conversion (strtol/strtoul) 259 errno = 0; 260 261 uint32_t state = strtoul(pcState, &pcStrEnd, 0); 262 263 if (!errno && (*pcStrEnd == '\0')) { 264 // Sucessfull conversion, set criterion state by numerical state 265 bSuccess = setCriterionState(remoteCommand.getArgument(0), state, strResult); 266 267 } else { 268 // Conversion failed, set criterion state by lexical state 269 bSuccess = setCriterionStateByLexicalSpace(remoteCommand, strResult); 270 } 271 272 return bSuccess ? CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler:: 273 EFailed; 274 275} 276 277CTestPlatform::CommandReturn CTestPlatform::applyConfigurations(const IRemoteCommand& remoteCommand, 278 string& strResult) 279{ 280 (void)remoteCommand; 281 (void)strResult; 282 283 _pParameterMgrPlatformConnector->applyConfigurations(); 284 285 return CTestPlatform::CCommandHandler::EDone; 286} 287 288//////////////// Remote command handlers 289 290bool CTestPlatform::createExclusiveSelectionCriterionFromStateList( 291 const string& strName, 292 const IRemoteCommand& remoteCommand, 293 string& strResult) 294{ 295 296 assert(_pParameterMgrPlatformConnector != NULL); 297 298 ISelectionCriterionTypeInterface* pCriterionType = 299 _pParameterMgrPlatformConnector->createSelectionCriterionType(false); 300 301 assert(pCriterionType != NULL); 302 303 uint32_t uiNbStates = remoteCommand.getArgumentCount() - 1; 304 uint32_t uiState; 305 306 for (uiState = 0; uiState < uiNbStates; uiState++) { 307 308 const std::string& strValue = remoteCommand.getArgument(uiState + 1); 309 310 if (!pCriterionType->addValuePair(uiState, strValue)) { 311 312 strResult = "Unable to add value: " + strValue; 313 314 return false; 315 } 316 } 317 318 _pParameterMgrPlatformConnector->createSelectionCriterion(strName, pCriterionType); 319 320 return true; 321} 322 323bool CTestPlatform::createInclusiveSelectionCriterionFromStateList( 324 const string& strName, 325 const IRemoteCommand& remoteCommand, 326 string& strResult) 327{ 328 assert(_pParameterMgrPlatformConnector != NULL); 329 330 ISelectionCriterionTypeInterface* pCriterionType = 331 _pParameterMgrPlatformConnector->createSelectionCriterionType(true); 332 333 assert(pCriterionType != NULL); 334 335 uint32_t uiNbStates = remoteCommand.getArgumentCount() - 1; 336 337 if (uiNbStates > 32) { 338 339 strResult = "Maximum number of states for inclusive criterion is 32"; 340 341 return false; 342 } 343 344 uint32_t uiState; 345 346 for (uiState = 0; uiState < uiNbStates; uiState++) { 347 348 const std::string& strValue = remoteCommand.getArgument(uiState + 1); 349 350 if (!pCriterionType->addValuePair(0x1 << uiState, strValue)) { 351 352 strResult = "Unable to add value: " + strValue; 353 354 return false; 355 } 356 } 357 358 _pParameterMgrPlatformConnector->createSelectionCriterion(strName, pCriterionType); 359 360 return true; 361} 362 363 364bool CTestPlatform::createExclusiveSelectionCriterion(const string& strName, 365 uint32_t uiNbStates, 366 string& strResult) 367{ 368 ISelectionCriterionTypeInterface* pCriterionType = 369 _pParameterMgrPlatformConnector->createSelectionCriterionType(false); 370 371 uint32_t uistate; 372 373 for (uistate = 0; uistate < uiNbStates; uistate++) { 374 375 std::ostringstream ostrValue; 376 377 ostrValue << "State_"; 378 ostrValue << uistate; 379 380 if (!pCriterionType->addValuePair(uistate, ostrValue.str())) { 381 382 strResult = "Unable to add value: " + ostrValue.str(); 383 384 return false; 385 } 386 } 387 388 _pParameterMgrPlatformConnector->createSelectionCriterion(strName, pCriterionType); 389 390 return true; 391} 392 393bool CTestPlatform::createInclusiveSelectionCriterion(const string& strName, 394 uint32_t uiNbStates, 395 string& strResult) 396{ 397 ISelectionCriterionTypeInterface* pCriterionType = 398 _pParameterMgrPlatformConnector->createSelectionCriterionType(true); 399 400 if (uiNbStates > 32) { 401 402 strResult = "Maximum number of states for inclusive criterion is 32"; 403 404 return false; 405 } 406 407 uint32_t uiState; 408 409 for (uiState = 0; uiState < uiNbStates; uiState++) { 410 411 std::ostringstream ostrValue; 412 413 ostrValue << "State_0x"; 414 ostrValue << (0x1 << uiState); 415 416 if (!pCriterionType->addValuePair(0x1 << uiState, ostrValue.str())) { 417 418 strResult = "Unable to add value: " + ostrValue.str(); 419 420 return false; 421 } 422 } 423 424 _pParameterMgrPlatformConnector->createSelectionCriterion(strName, pCriterionType); 425 426 return true; 427} 428 429bool CTestPlatform::setCriterionState(const string& strName, uint32_t uiState, string& strResult) 430{ 431 ISelectionCriterionInterface* pCriterion = 432 _pParameterMgrPlatformConnector->getSelectionCriterion(strName); 433 434 if (!pCriterion) { 435 436 strResult = "Unable to retrieve selection criterion: " + strName; 437 438 return false; 439 } 440 441 pCriterion->setCriterionState(uiState); 442 443 return true; 444} 445 446bool CTestPlatform::setCriterionStateByLexicalSpace(const IRemoteCommand& remoteCommand, 447 string& strResult) 448{ 449 450 // Get criterion name 451 std::string strCriterionName = remoteCommand.getArgument(0); 452 453 ISelectionCriterionInterface* pCriterion = 454 _pParameterMgrPlatformConnector->getSelectionCriterion(strCriterionName); 455 456 if (!pCriterion) { 457 458 strResult = "Unable to retrieve selection criterion: " + strCriterionName; 459 460 return false; 461 } 462 463 // Get criterion type 464 const ISelectionCriterionTypeInterface* pCriterionType = pCriterion->getCriterionType(); 465 466 // Get substate number, the first argument (index 0) is the criterion name 467 uint32_t uiNbSubStates = remoteCommand.getArgumentCount() - 1; 468 469 // Check that exclusive criterion has only one substate 470 if (!pCriterionType->isTypeInclusive() && uiNbSubStates != 1) { 471 472 strResult = "Exclusive criterion " + strCriterionName + " can only have one state"; 473 474 return false; 475 } 476 477 /// Translate lexical state to numerical state 478 int iNumericalState = 0; 479 uint32_t uiLexicalSubStateIndex; 480 481 // Parse lexical substates 482 std::string strLexicalState = ""; 483 484 for (uiLexicalSubStateIndex = 1; 485 uiLexicalSubStateIndex <= uiNbSubStates; 486 uiLexicalSubStateIndex++) { 487 /* 488 * getNumericalValue method from ISelectionCriterionTypeInterface strip his parameter 489 * first parameter based on | sign. In case that the user uses multiple parameters 490 * to set InclusiveCriterion value, we aggregate all desired values to be sure 491 * they will be handled correctly. 492 */ 493 if (uiLexicalSubStateIndex != 1) { 494 strLexicalState += "|"; 495 } 496 strLexicalState += remoteCommand.getArgument(uiLexicalSubStateIndex); 497 } 498 499 // Translate lexical to numerical substate 500 if (!pCriterionType->getNumericalValue(strLexicalState, iNumericalState)) { 501 502 strResult = "Unable to find lexical state \"" 503 + strLexicalState + "\" in criteria " + strCriterionName; 504 505 return false; 506 } 507 508 // Set criterion new state 509 pCriterion->setCriterionState(iNumericalState); 510 511 return true; 512} 513