Home | History | Annotate | Download | only in test-platform
      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 
     43 using std::string;
     44 
     45 class CParameterMgrPlatformConnectorLogger : public CParameterMgrPlatformConnector::ILogger
     46 {
     47 public:
     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 
     63 CTestPlatform::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 
    143 CTestPlatform::~CTestPlatform()
    144 {
    145     delete _pRemoteProcessorServer;
    146     delete _pCommandHandler;
    147     delete _pParameterMgrPlatformConnectorLogger;
    148     delete _pParameterMgrPlatformConnector;
    149 }
    150 
    151 CTestPlatform::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 
    162 bool 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
    176 CTestPlatform::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 
    184 CTestPlatform::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 
    192 CTestPlatform::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 
    202 CTestPlatform::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 
    212 CTestPlatform::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 
    221 template <CTestPlatform::setter_t setFunction>
    222 CTestPlatform::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 
    237 template <CTestPlatform::getter_t getFunction>
    238 CTestPlatform::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 
    248 CTestPlatform::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 
    277 CTestPlatform::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 
    290 bool 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 
    323 bool 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 
    364 bool 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 
    393 bool 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 
    429 bool 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 
    446 bool 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