| /* |
| * Copyright (c) 2011-2014, Intel Corporation |
| * All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without modification, |
| * are permitted provided that the following conditions are met: |
| * |
| * 1. Redistributions of source code must retain the above copyright notice, this |
| * list of conditions and the following disclaimer. |
| * |
| * 2. Redistributions in binary form must reproduce the above copyright notice, |
| * this list of conditions and the following disclaimer in the documentation and/or |
| * other materials provided with the distribution. |
| * |
| * 3. Neither the name of the copyright holder nor the names of its contributors |
| * may be used to endorse or promote products derived from this software without |
| * specific prior written permission. |
| * |
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR |
| * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
| * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include <strings.h> |
| #include <iostream> |
| #include <stdlib.h> |
| #include <sstream> |
| #include <assert.h> |
| #include <errno.h> |
| #include <convert.hpp> |
| #include <sstream> |
| #include "TestPlatform.h" |
| #include "ParameterMgrPlatformConnector.h" |
| #include "RemoteProcessorServer.h" |
| |
| using std::string; |
| |
| class CParameterMgrPlatformConnectorLogger : public CParameterMgrPlatformConnector::ILogger |
| { |
| public: |
| CParameterMgrPlatformConnectorLogger() {} |
| |
| virtual void log(bool bIsWarning, const string& strLog) |
| { |
| |
| if (bIsWarning) { |
| |
| std::cerr << strLog << std::endl; |
| } else { |
| |
| std::cout << strLog << std::endl; |
| } |
| } |
| }; |
| |
| CTestPlatform::CTestPlatform(const string& strClass, int iPortNumber, sem_t& exitSemaphore) : |
| _pParameterMgrPlatformConnector(new CParameterMgrPlatformConnector(strClass)), |
| _pParameterMgrPlatformConnectorLogger(new CParameterMgrPlatformConnectorLogger), |
| _exitSemaphore(exitSemaphore) |
| { |
| _pCommandHandler = new CCommandHandler(this); |
| |
| // Add command parsers |
| _pCommandHandler->addCommandParser("exit", &CTestPlatform::exit, |
| 0, "", "Exit TestPlatform"); |
| _pCommandHandler->addCommandParser( |
| "createExclusiveSelectionCriterionFromStateList", |
| &CTestPlatform::createExclusiveSelectionCriterionFromStateList, |
| 2, "<name> <stateList>", |
| "Create inclusive selection criterion from state name list"); |
| _pCommandHandler->addCommandParser( |
| "createInclusiveSelectionCriterionFromStateList", |
| &CTestPlatform::createInclusiveSelectionCriterionFromStateList, |
| 2, "<name> <stateList>", |
| "Create exclusive selection criterion from state name list"); |
| |
| _pCommandHandler->addCommandParser( |
| "createExclusiveSelectionCriterion", |
| &CTestPlatform::createExclusiveSelectionCriterion, |
| 2, "<name> <nbStates>", "Create inclusive selection criterion"); |
| _pCommandHandler->addCommandParser( |
| "createInclusiveSelectionCriterion", |
| &CTestPlatform::createInclusiveSelectionCriterion, |
| 2, "<name> <nbStates>", "Create exclusive selection criterion"); |
| |
| _pCommandHandler->addCommandParser("start", &CTestPlatform::startParameterMgr, |
| 0, "", "Start ParameterMgr"); |
| |
| _pCommandHandler->addCommandParser("setCriterionState", &CTestPlatform::setCriterionState, |
| 2, "<name> <state>", |
| "Set the current state of a selection criterion"); |
| _pCommandHandler->addCommandParser( |
| "applyConfigurations", |
| &CTestPlatform::applyConfigurations, |
| 0, "", "Apply configurations selected by current selection criteria states"); |
| |
| _pCommandHandler->addCommandParser( |
| "setFailureOnMissingSubsystem", |
| &CTestPlatform::setter<& CParameterMgrPlatformConnector::setFailureOnMissingSubsystem>, |
| 1, "true|false", "Set policy for missing subsystems, " |
| "either abort start or fallback on virtual subsystem."); |
| _pCommandHandler->addCommandParser( |
| "getMissingSubsystemPolicy", |
| &CTestPlatform::getter<& CParameterMgrPlatformConnector::getFailureOnMissingSubsystem>, |
| 0, "", "Get policy for missing subsystems, " |
| "either abort start or fallback on virtual subsystem."); |
| |
| _pCommandHandler->addCommandParser( |
| "setFailureOnFailedSettingsLoad", |
| &CTestPlatform::setter<& CParameterMgrPlatformConnector::setFailureOnFailedSettingsLoad>, |
| 1, "true|false", |
| "Set policy for failed settings load, either abort start or continue without domains."); |
| _pCommandHandler->addCommandParser( |
| "getFailedSettingsLoadPolicy", |
| &CTestPlatform::getter<& CParameterMgrPlatformConnector::getFailureOnFailedSettingsLoad>, |
| 0, "", |
| "Get policy for failed settings load, either abort start or continue without domains."); |
| |
| _pCommandHandler->addCommandParser( |
| "setValidateSchemasOnStart", |
| &CTestPlatform::setter<& CParameterMgrPlatformConnector::setValidateSchemasOnStart>, |
| 1, "true|false", |
| "Set policy for schema validation based on .xsd files (false by default)."); |
| _pCommandHandler->addCommandParser( |
| "getValidateSchemasOnStart", |
| &CTestPlatform::getter<& CParameterMgrPlatformConnector::getValidateSchemasOnStart>, |
| 0, "", |
| "Get policy for schema validation based on .xsd files."); |
| |
| // Create server |
| _pRemoteProcessorServer = new CRemoteProcessorServer(iPortNumber, _pCommandHandler); |
| |
| _pParameterMgrPlatformConnector->setLogger(_pParameterMgrPlatformConnectorLogger); |
| } |
| |
| CTestPlatform::~CTestPlatform() |
| { |
| delete _pRemoteProcessorServer; |
| delete _pCommandHandler; |
| delete _pParameterMgrPlatformConnectorLogger; |
| delete _pParameterMgrPlatformConnector; |
| } |
| |
| CTestPlatform::CommandReturn CTestPlatform::exit( |
| const IRemoteCommand& remoteCommand, string& strResult) |
| { |
| (void)remoteCommand; |
| |
| // Release the main blocking semaphore to quit application |
| sem_post(&_exitSemaphore); |
| |
| return CTestPlatform::CCommandHandler::EDone; |
| } |
| |
| bool CTestPlatform::load(std::string& strError) |
| { |
| // Start remote processor server |
| if (!_pRemoteProcessorServer->start(strError)) { |
| |
| strError = "TestPlatform: Unable to start remote processor server: " + strError; |
| return false; |
| } |
| |
| return true; |
| } |
| |
| //////////////// Remote command parsers |
| /// Selection Criterion |
| CTestPlatform::CommandReturn CTestPlatform::createExclusiveSelectionCriterionFromStateList( |
| const IRemoteCommand& remoteCommand, string& strResult) |
| { |
| return createExclusiveSelectionCriterionFromStateList( |
| remoteCommand.getArgument(0), remoteCommand, strResult) ? |
| CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; |
| } |
| |
| CTestPlatform::CommandReturn CTestPlatform::createInclusiveSelectionCriterionFromStateList( |
| const IRemoteCommand& remoteCommand, string& strResult) |
| { |
| return createInclusiveSelectionCriterionFromStateList( |
| remoteCommand.getArgument(0), remoteCommand, strResult) ? |
| CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; |
| } |
| |
| CTestPlatform::CommandReturn CTestPlatform::createExclusiveSelectionCriterion( |
| const IRemoteCommand& remoteCommand, string& strResult) |
| { |
| return createExclusiveSelectionCriterion( |
| remoteCommand.getArgument(0), |
| strtoul(remoteCommand.getArgument(1).c_str(), NULL, 0), |
| strResult) ? |
| CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; |
| } |
| |
| CTestPlatform::CommandReturn CTestPlatform::createInclusiveSelectionCriterion( |
| const IRemoteCommand& remoteCommand, string& strResult) |
| { |
| return createInclusiveSelectionCriterion( |
| remoteCommand.getArgument(0), |
| strtoul(remoteCommand.getArgument(1).c_str(), NULL, 0), |
| strResult) ? |
| CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; |
| } |
| |
| CTestPlatform::CommandReturn CTestPlatform::startParameterMgr( |
| const IRemoteCommand& remoteCommand, string& strResult) |
| { |
| (void)remoteCommand; |
| |
| return _pParameterMgrPlatformConnector->start(strResult) ? |
| CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; |
| } |
| |
| template <CTestPlatform::setter_t setFunction> |
| CTestPlatform::CommandReturn CTestPlatform::setter( |
| const IRemoteCommand& remoteCommand, string& strResult) |
| { |
| const string& strAbort = remoteCommand.getArgument(0); |
| |
| bool bFail; |
| |
| if(!convertTo(strAbort, bFail)) { |
| return CTestPlatform::CCommandHandler::EShowUsage; |
| } |
| |
| return (_pParameterMgrPlatformConnector->*setFunction)(bFail, strResult) ? |
| CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler::EFailed; |
| } |
| |
| template <CTestPlatform::getter_t getFunction> |
| CTestPlatform::CommandReturn CTestPlatform::getter( |
| const IRemoteCommand& remoteCommand, string& strResult) |
| { |
| (void)remoteCommand; |
| |
| strResult = (_pParameterMgrPlatformConnector->*getFunction)() ? "true" : "false"; |
| |
| return CTestPlatform::CCommandHandler::ESucceeded; |
| } |
| |
| CTestPlatform::CommandReturn CTestPlatform::setCriterionState( |
| const IRemoteCommand& remoteCommand, string& strResult) |
| { |
| |
| bool bSuccess; |
| |
| const char* pcState = remoteCommand.getArgument(1).c_str(); |
| |
| char* pcStrEnd; |
| |
| // Reset errno to check if it is updated during the conversion (strtol/strtoul) |
| errno = 0; |
| |
| uint32_t state = strtoul(pcState, &pcStrEnd, 0); |
| |
| if (!errno && (*pcStrEnd == '\0')) { |
| // Sucessfull conversion, set criterion state by numerical state |
| bSuccess = setCriterionState(remoteCommand.getArgument(0), state, strResult); |
| |
| } else { |
| // Conversion failed, set criterion state by lexical state |
| bSuccess = setCriterionStateByLexicalSpace(remoteCommand, strResult); |
| } |
| |
| return bSuccess ? CTestPlatform::CCommandHandler::EDone : CTestPlatform::CCommandHandler:: |
| EFailed; |
| |
| } |
| |
| CTestPlatform::CommandReturn CTestPlatform::applyConfigurations(const IRemoteCommand& remoteCommand, |
| string& strResult) |
| { |
| (void)remoteCommand; |
| (void)strResult; |
| |
| _pParameterMgrPlatformConnector->applyConfigurations(); |
| |
| return CTestPlatform::CCommandHandler::EDone; |
| } |
| |
| //////////////// Remote command handlers |
| |
| bool CTestPlatform::createExclusiveSelectionCriterionFromStateList( |
| const string& strName, |
| const IRemoteCommand& remoteCommand, |
| string& strResult) |
| { |
| |
| assert(_pParameterMgrPlatformConnector != NULL); |
| |
| ISelectionCriterionTypeInterface* pCriterionType = |
| _pParameterMgrPlatformConnector->createSelectionCriterionType(false); |
| |
| assert(pCriterionType != NULL); |
| |
| uint32_t uiNbStates = remoteCommand.getArgumentCount() - 1; |
| uint32_t uiState; |
| |
| for (uiState = 0; uiState < uiNbStates; uiState++) { |
| |
| const std::string& strValue = remoteCommand.getArgument(uiState + 1); |
| |
| if (!pCriterionType->addValuePair(uiState, strValue)) { |
| |
| strResult = "Unable to add value: " + strValue; |
| |
| return false; |
| } |
| } |
| |
| _pParameterMgrPlatformConnector->createSelectionCriterion(strName, pCriterionType); |
| |
| return true; |
| } |
| |
| bool CTestPlatform::createInclusiveSelectionCriterionFromStateList( |
| const string& strName, |
| const IRemoteCommand& remoteCommand, |
| string& strResult) |
| { |
| assert(_pParameterMgrPlatformConnector != NULL); |
| |
| ISelectionCriterionTypeInterface* pCriterionType = |
| _pParameterMgrPlatformConnector->createSelectionCriterionType(true); |
| |
| assert(pCriterionType != NULL); |
| |
| uint32_t uiNbStates = remoteCommand.getArgumentCount() - 1; |
| |
| if (uiNbStates > 32) { |
| |
| strResult = "Maximum number of states for inclusive criterion is 32"; |
| |
| return false; |
| } |
| |
| uint32_t uiState; |
| |
| for (uiState = 0; uiState < uiNbStates; uiState++) { |
| |
| const std::string& strValue = remoteCommand.getArgument(uiState + 1); |
| |
| if (!pCriterionType->addValuePair(0x1 << uiState, strValue)) { |
| |
| strResult = "Unable to add value: " + strValue; |
| |
| return false; |
| } |
| } |
| |
| _pParameterMgrPlatformConnector->createSelectionCriterion(strName, pCriterionType); |
| |
| return true; |
| } |
| |
| |
| bool CTestPlatform::createExclusiveSelectionCriterion(const string& strName, |
| uint32_t uiNbStates, |
| string& strResult) |
| { |
| ISelectionCriterionTypeInterface* pCriterionType = |
| _pParameterMgrPlatformConnector->createSelectionCriterionType(false); |
| |
| uint32_t uistate; |
| |
| for (uistate = 0; uistate < uiNbStates; uistate++) { |
| |
| std::ostringstream ostrValue; |
| |
| ostrValue << "State_"; |
| ostrValue << uistate; |
| |
| if (!pCriterionType->addValuePair(uistate, ostrValue.str())) { |
| |
| strResult = "Unable to add value: " + ostrValue.str(); |
| |
| return false; |
| } |
| } |
| |
| _pParameterMgrPlatformConnector->createSelectionCriterion(strName, pCriterionType); |
| |
| return true; |
| } |
| |
| bool CTestPlatform::createInclusiveSelectionCriterion(const string& strName, |
| uint32_t uiNbStates, |
| string& strResult) |
| { |
| ISelectionCriterionTypeInterface* pCriterionType = |
| _pParameterMgrPlatformConnector->createSelectionCriterionType(true); |
| |
| if (uiNbStates > 32) { |
| |
| strResult = "Maximum number of states for inclusive criterion is 32"; |
| |
| return false; |
| } |
| |
| uint32_t uiState; |
| |
| for (uiState = 0; uiState < uiNbStates; uiState++) { |
| |
| std::ostringstream ostrValue; |
| |
| ostrValue << "State_0x"; |
| ostrValue << (0x1 << uiState); |
| |
| if (!pCriterionType->addValuePair(0x1 << uiState, ostrValue.str())) { |
| |
| strResult = "Unable to add value: " + ostrValue.str(); |
| |
| return false; |
| } |
| } |
| |
| _pParameterMgrPlatformConnector->createSelectionCriterion(strName, pCriterionType); |
| |
| return true; |
| } |
| |
| bool CTestPlatform::setCriterionState(const string& strName, uint32_t uiState, string& strResult) |
| { |
| ISelectionCriterionInterface* pCriterion = |
| _pParameterMgrPlatformConnector->getSelectionCriterion(strName); |
| |
| if (!pCriterion) { |
| |
| strResult = "Unable to retrieve selection criterion: " + strName; |
| |
| return false; |
| } |
| |
| pCriterion->setCriterionState(uiState); |
| |
| return true; |
| } |
| |
| bool CTestPlatform::setCriterionStateByLexicalSpace(const IRemoteCommand& remoteCommand, |
| string& strResult) |
| { |
| |
| // Get criterion name |
| std::string strCriterionName = remoteCommand.getArgument(0); |
| |
| ISelectionCriterionInterface* pCriterion = |
| _pParameterMgrPlatformConnector->getSelectionCriterion(strCriterionName); |
| |
| if (!pCriterion) { |
| |
| strResult = "Unable to retrieve selection criterion: " + strCriterionName; |
| |
| return false; |
| } |
| |
| // Get criterion type |
| const ISelectionCriterionTypeInterface* pCriterionType = pCriterion->getCriterionType(); |
| |
| // Get substate number, the first argument (index 0) is the criterion name |
| uint32_t uiNbSubStates = remoteCommand.getArgumentCount() - 1; |
| |
| // Check that exclusive criterion has only one substate |
| if (!pCriterionType->isTypeInclusive() && uiNbSubStates != 1) { |
| |
| strResult = "Exclusive criterion " + strCriterionName + " can only have one state"; |
| |
| return false; |
| } |
| |
| /// Translate lexical state to numerical state |
| int iNumericalState = 0; |
| uint32_t uiLexicalSubStateIndex; |
| |
| // Parse lexical substates |
| std::string strLexicalState = ""; |
| |
| for (uiLexicalSubStateIndex = 1; |
| uiLexicalSubStateIndex <= uiNbSubStates; |
| uiLexicalSubStateIndex++) { |
| /* |
| * getNumericalValue method from ISelectionCriterionTypeInterface strip his parameter |
| * first parameter based on | sign. In case that the user uses multiple parameters |
| * to set InclusiveCriterion value, we aggregate all desired values to be sure |
| * they will be handled correctly. |
| */ |
| if (uiLexicalSubStateIndex != 1) { |
| strLexicalState += "|"; |
| } |
| strLexicalState += remoteCommand.getArgument(uiLexicalSubStateIndex); |
| } |
| |
| // Translate lexical to numerical substate |
| if (!pCriterionType->getNumericalValue(strLexicalState, iNumericalState)) { |
| |
| strResult = "Unable to find lexical state \"" |
| + strLexicalState + "\" in criteria " + strCriterionName; |
| |
| return false; |
| } |
| |
| // Set criterion new state |
| pCriterion->setCriterionState(iNumericalState); |
| |
| return true; |
| } |