mirror of
https://github.com/eclipse-openvehicle-api/openvehicle-api.git
synced 2026-07-02 05:35:11 +00:00
198
tests/unit_tests/sdv_control/includes.h
Normal file
198
tests/unit_tests/sdv_control/includes.h
Normal file
@@ -0,0 +1,198 @@
|
||||
#ifndef INCLUDES_H
|
||||
#define INCLUDES_H
|
||||
|
||||
#include "../../include/gtest_custom.h"
|
||||
#include <support/sdv_core.h>
|
||||
#include <support/app_control.h>
|
||||
#include <support/pssup.h>
|
||||
#include "../../../global/exec_dir_helper.h"
|
||||
#include "../../../sdv_executables/sdv_control/startup_shutdown.h"
|
||||
|
||||
/**
|
||||
* @brief App control helper with automated server shutdown
|
||||
*/
|
||||
class CAppControlHelper : public sdv::app::CAppControl
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Constructor
|
||||
* @param[in] bAutoStartServer When set, the constructor will start the server and the destructor will shutdown the server.
|
||||
* @param[in] uiInstanceID The instance ID to use or 0 for the default instance.
|
||||
*/
|
||||
CAppControlHelper(bool bAutoStartServer = false, uint32_t uiInstanceID = 0u) : m_bAutoStartServer(bAutoStartServer),
|
||||
m_uiInstanceID(uiInstanceID)
|
||||
{
|
||||
// Initialize system
|
||||
std::string ssStartup = R"code(
|
||||
[LogHandler]
|
||||
ViewFilter = "Fatal"
|
||||
|
||||
[Application]
|
||||
Mode = "Maintenance"
|
||||
)code";
|
||||
if (uiInstanceID) ssStartup += "Instance = " + std::to_string(uiInstanceID) + "\n";
|
||||
Startup(ssStartup);
|
||||
|
||||
// Automatically start the server
|
||||
if (bAutoStartServer)
|
||||
{
|
||||
// Startup the server
|
||||
int iRet = StartupSDVServer(CreateContext("STARTUP"));
|
||||
m_bServerStarted = iRet == 0 ? true : false;
|
||||
EXPECT_EQ(iRet, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Destructor
|
||||
*/
|
||||
~CAppControlHelper()
|
||||
{
|
||||
// Automatically shut down the server
|
||||
if (m_bServerStarted)
|
||||
{
|
||||
// Shutdown the server
|
||||
ShutdownSDVServer(CreateContext("SHUTDOWN"));
|
||||
}
|
||||
|
||||
// Wait shortly to allow the shutdown to take place.
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
|
||||
// Terminate (in case the shutdown got stuck).
|
||||
TerminateServerProcess();
|
||||
|
||||
// Shutdown
|
||||
Shutdown();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Terminate a process with the ID.
|
||||
*/
|
||||
void TerminateServerProcess(sdv::process::TProcessID tServerProcessID = GetServerProcessID())
|
||||
{
|
||||
// Get the process control service and terminate the process
|
||||
sdv::process::IProcessControl* pProcessControl = sdv::core::GetObject<sdv::process::IProcessControl>("ProcessControlService");
|
||||
if (tServerProcessID && pProcessControl) pProcessControl->Terminate(tServerProcessID);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns whether the server was started automatically.
|
||||
* @return The server start status.
|
||||
*/
|
||||
bool ServerAutoStarted() const
|
||||
{
|
||||
return m_bServerStarted;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Create a context structure
|
||||
* @param[in] rssCommands One or more commands separated by a space.
|
||||
* @return The context structure.
|
||||
*/
|
||||
SContext CreateContext(const std::string& rssCommands) const
|
||||
{
|
||||
SContext sContext;
|
||||
sContext.bSilent = true;
|
||||
sContext.bServerSilent = true;
|
||||
sContext.pathInstallDir = "../tests/bin/" + std::to_string(m_uiInstanceID ? m_uiInstanceID : 1000u);
|
||||
if (m_uiInstanceID)
|
||||
sContext.uiInstanceID = m_uiInstanceID;
|
||||
size_t nPos = 0;
|
||||
while (true)
|
||||
{
|
||||
size_t nSeparator = rssCommands.find_first_of(" \f\n\r\t\v", nPos);
|
||||
sContext.seqCmdLine.push_back(rssCommands.substr(nPos, nSeparator - nPos));
|
||||
if (nSeparator == std::string::npos) break;
|
||||
nPos = nSeparator + 1;
|
||||
}
|
||||
return sContext;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_bAutoStartServer = false; ///< When set, the constructor will start the server and the destructor will
|
||||
///< shutdown the server.
|
||||
bool m_bServerStarted = false; ///< When set, the server was started successfully by this class.
|
||||
uint32_t m_uiInstanceID = 0; ///< The instance ID to use for the connection.
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Interpret a table returned by the list command.
|
||||
* @param[in] rssTable Reference to the string holding the table.
|
||||
* @return Vector with rows containing a vector each with cells.
|
||||
*/
|
||||
inline std::vector<std::vector<std::string>> InterpretTable(const std::string& rssTable)
|
||||
{
|
||||
// Read a cell; call until string is empty. Newline detected is set when the last cell on the line or in the table has been
|
||||
// read.
|
||||
size_t nPos = 0;
|
||||
auto fnReadCell = [&nPos, rssTable](bool& rbStartNewLine) -> std::string
|
||||
{
|
||||
// Skip whitespace except newline
|
||||
nPos = rssTable.find_first_not_of(" \f\r\t\v", nPos);
|
||||
|
||||
// Check for a newline
|
||||
if (nPos != std::string::npos && rssTable[nPos] == '\n')
|
||||
{
|
||||
rbStartNewLine = true;
|
||||
nPos++;
|
||||
|
||||
// Skip a header bar
|
||||
if (rbStartNewLine && nPos != rssTable.size() && rssTable[nPos] == '-')
|
||||
{
|
||||
nPos = rssTable.find_first_of("\n", nPos);
|
||||
if (nPos != std::string::npos) nPos++;
|
||||
}
|
||||
}
|
||||
|
||||
// Skip whitespace
|
||||
nPos = rssTable.find_first_not_of(" \f\n\r\t\v", nPos);
|
||||
if (nPos > rssTable.size()) return {};
|
||||
|
||||
// Find text
|
||||
std::string ssCell;
|
||||
size_t nStart = nPos;
|
||||
size_t nStop = 0;
|
||||
while (true)
|
||||
{
|
||||
// Find the next whitespace
|
||||
nPos = rssTable.find_first_of(" \f\n\r\t\v", nPos);
|
||||
nStop = nPos;
|
||||
if (nPos == std::string::npos)
|
||||
break;
|
||||
|
||||
// If there at the most one space to the next word, this is considered to belong to the text
|
||||
if (rssTable[nPos] != ' ') break;
|
||||
nPos++;
|
||||
if (nPos == rssTable.size()) break;
|
||||
if (std::isspace(rssTable[nPos])) break;
|
||||
}
|
||||
|
||||
// Return the cel text
|
||||
return rssTable.substr(nStart, nStop - nStart);
|
||||
};
|
||||
|
||||
// Run through the table and add rows with cells.
|
||||
bool bStartNewRow = true;
|
||||
std::vector<std::vector<std::string>> vecTable;
|
||||
std::string ssCell;
|
||||
while (!(ssCell = fnReadCell(bStartNewRow)).empty())
|
||||
{
|
||||
// Start a new row?
|
||||
if (bStartNewRow)
|
||||
vecTable.resize(vecTable.size() + 1);
|
||||
bStartNewRow = false;
|
||||
|
||||
// Get a reference to the last row
|
||||
if (vecTable.empty()) break; // Should not happen!
|
||||
std::vector<std::string>& rvecRow = vecTable.back();
|
||||
|
||||
// Insert the cell
|
||||
rvecRow.push_back(std::move(ssCell));
|
||||
}
|
||||
|
||||
// Return the table
|
||||
return vecTable;
|
||||
}
|
||||
|
||||
|
||||
#endif // !defined INCLUDES_H
|
||||
Reference in New Issue
Block a user