Merge remote-tracking branch 'upstream/development' into mueller/master
This commit is contained in:
commit
0d6d44f72f
@ -19,6 +19,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/544
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/544
|
||||||
- doSendRead Hook
|
- doSendRead Hook
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/545
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/545
|
||||||
|
- Dockumentation for DHB
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/551
|
||||||
|
|
||||||
### HAL additions
|
### HAL additions
|
||||||
|
|
||||||
@ -43,6 +45,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|||||||
could lead to compile errors that `#include "fsfw/FSFW.h"` was not found.
|
could lead to compile errors that `#include "fsfw/FSFW.h"` was not found.
|
||||||
- Fix for build regression in Catch2 v3.0.0-preview4
|
- Fix for build regression in Catch2 v3.0.0-preview4
|
||||||
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/548
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/548
|
||||||
|
- Fix in unittest which failed on CI
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/552
|
||||||
|
- Fix in helper script
|
||||||
|
PR: https://egit.irs.uni-stuttgart.de/fsfw/fsfw/pulls/553
|
||||||
|
|
||||||
## API Changes
|
## API Changes
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
|
|
||||||
set(FSFW_VERSION 3)
|
set(FSFW_VERSION 4)
|
||||||
set(FSFW_SUBVERSION 0)
|
set(FSFW_SUBVERSION 0)
|
||||||
set(FSFW_REVISION 1)
|
set(FSFW_REVISION 0)
|
||||||
|
|
||||||
# Add the cmake folder so the FindSphinx module is found
|
# Add the cmake folder so the FindSphinx module is found
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
|
||||||
|
36
README.md
36
README.md
@ -107,6 +107,42 @@ cmake --build . -- fsfw-tests_coverage -j
|
|||||||
|
|
||||||
The `coverage.py` script located in the `script` folder can also be used to do this conveniently.
|
The `coverage.py` script located in the `script` folder can also be used to do this conveniently.
|
||||||
|
|
||||||
|
## Building the documentations
|
||||||
|
|
||||||
|
The FSFW documentation is built using the tools Sphinx, doxygen and breathe based on the
|
||||||
|
instructions provided in [this blogpost](https://devblogs.microsoft.com/cppblog/clear-functional-c-documentation-with-sphinx-breathe-doxygen-cmake/). If you
|
||||||
|
want to do this locally, set up the prerequisites first. This requires a ``python3``
|
||||||
|
installation as well. Example here is for Ubuntu.
|
||||||
|
|
||||||
|
```sh
|
||||||
|
sudo apt-get install doxygen graphviz
|
||||||
|
```
|
||||||
|
|
||||||
|
And the following Python packages
|
||||||
|
|
||||||
|
```sh
|
||||||
|
python3 -m pip install sphinx breathe
|
||||||
|
```
|
||||||
|
|
||||||
|
You can set up a documentation build system using the following commands
|
||||||
|
|
||||||
|
```sh
|
||||||
|
mkdir build-docs && cd build-docs
|
||||||
|
cmake -DFSFW_BUILD_DOCS=ON -DFSFW_OSAL=host ..
|
||||||
|
```
|
||||||
|
|
||||||
|
Then you can generate the documentation using
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cmake --build . -j
|
||||||
|
```
|
||||||
|
|
||||||
|
You can find the generated documentation inside the `docs/sphinx` folder inside the build
|
||||||
|
folder. Simply open the `index.html` in the webbrowser of your choice.
|
||||||
|
|
||||||
|
The `helper.py` script located in the script` folder can also be used to create, build
|
||||||
|
and open the documentation conveniently. Try `helper.py -h for more information.
|
||||||
|
|
||||||
## Formatting the sources
|
## Formatting the sources
|
||||||
|
|
||||||
The formatting is done by the `clang-format` tool. The configuration is contained within the
|
The formatting is done by the `clang-format` tool. The configuration is contained within the
|
||||||
|
@ -14,7 +14,8 @@ requirements, which are fulfilled by implementing certain interfaces:
|
|||||||
communication bus, for example SpaceWire, UART or SPI: :cpp:class:`DeviceCommunicationIF`
|
communication bus, for example SpaceWire, UART or SPI: :cpp:class:`DeviceCommunicationIF`
|
||||||
- The handler has housekeeping data which has to be exposed to the operator and/or other software
|
- The handler has housekeeping data which has to be exposed to the operator and/or other software
|
||||||
components: :cpp:class:`HasLocalDataPoolIF`
|
components: :cpp:class:`HasLocalDataPoolIF`
|
||||||
- The handler has configurable parameters
|
- The handler has configurable parameters: :cpp:class:`ReceivesParameterMessagesIF` which
|
||||||
|
also implements :cpp:class:`HasParametersIF`
|
||||||
- The handler has health states, for example to indicate a broken device:
|
- The handler has health states, for example to indicate a broken device:
|
||||||
:cpp:class:`HasHealthIF`
|
:cpp:class:`HasHealthIF`
|
||||||
- The handler has modes. For example there are the core modes `MODE_ON`, `MODE_OFF`
|
- The handler has modes. For example there are the core modes `MODE_ON`, `MODE_OFF`
|
||||||
|
@ -90,8 +90,21 @@ Building the documentation
|
|||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
The FSFW documentation is built using the tools Sphinx, doxygen and breathe based on the
|
The FSFW documentation is built using the tools Sphinx, doxygen and breathe based on the
|
||||||
instructions provided in `this blogpost <https://devblogs.microsoft.com/cppblog/clear-functional-c-documentation-with-sphinx-breathe-doxygen-cmake/>`_. You can set up a
|
instructions provided in `this blogpost <https://devblogs.microsoft.com/cppblog/clear-functional-c-documentation-with-sphinx-breathe-doxygen-cmake/>`_. If you
|
||||||
documentation build system using the following commands
|
want to do this locally, set up the prerequisites first. This requires a ``python3``
|
||||||
|
installation as well. Example here is for Ubuntu.
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
sudo apt-get install doxygen graphviz
|
||||||
|
|
||||||
|
And the following Python packages
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
python3 -m pip install sphinx breathe
|
||||||
|
|
||||||
|
You can set up a documentation build system using the following commands
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
@ -110,6 +123,14 @@ folder. Simply open the ``index.html`` in the webbrowser of your choice.
|
|||||||
The ``helper.py`` script located in the ``script`` folder can also be used to create, build
|
The ``helper.py`` script located in the ``script`` folder can also be used to create, build
|
||||||
and open the documentation conveniently. Try ``helper.py -h`` for more information.
|
and open the documentation conveniently. Try ``helper.py -h`` for more information.
|
||||||
|
|
||||||
|
Formatting the source
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
The formatting is done by the ``clang-format`` tool. The configuration is contained within the
|
||||||
|
``.clang-format`` file in the repository root. As long as ``clang-format`` is installed, you
|
||||||
|
can run the ``apply-clang-format.sh`` helper script to format all source files consistently.
|
||||||
|
|
||||||
|
|
||||||
.. _`Hosted FSFW example`: https://egit.irs.uni-stuttgart.de/fsfw/fsfw-example-hosted
|
.. _`Hosted FSFW example`: https://egit.irs.uni-stuttgart.de/fsfw/fsfw-example-hosted
|
||||||
.. _`Catch2 library`: https://github.com/catchorg/Catch2
|
.. _`Catch2 library`: https://github.com/catchorg/Catch2
|
||||||
.. _`Code coverage`: https://github.com/bilke/cmake-modules/tree/master
|
.. _`Code coverage`: https://github.com/bilke/cmake-modules/tree/master
|
||||||
|
@ -22,7 +22,7 @@ ReturnValue_t UioMapper::getMappedAdress(uint32_t** address, Permissions permiss
|
|||||||
int fd = open(uioFile.c_str(), O_RDWR);
|
int fd = open(uioFile.c_str(), O_RDWR);
|
||||||
if (fd < 1) {
|
if (fd < 1) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "PtmeAxiConfig::initialize: Invalid UIO device file" << std::endl;
|
sif::error << "PtmeAxiConfig::initialize: Invalid UIO device file" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
@ -36,8 +36,8 @@ ReturnValue_t UioMapper::getMappedAdress(uint32_t** address, Permissions permiss
|
|||||||
|
|
||||||
if (*address == MAP_FAILED) {
|
if (*address == MAP_FAILED) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "UioMapper::getMappedAdress: Failed to map physical address of uio device "
|
sif::error << "UioMapper::getMappedAdress: Failed to map physical address of uio device "
|
||||||
<< uioFile.c_str() << " and map" << static_cast<int>(mapNum) << std::endl;
|
<< uioFile.c_str() << " and map" << static_cast<int>(mapNum) << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
@ -52,7 +52,7 @@ ReturnValue_t UioMapper::getMapSize(size_t* size) {
|
|||||||
fp = fopen(namestream.str().c_str(), "r");
|
fp = fopen(namestream.str().c_str(), "r");
|
||||||
if (fp == nullptr) {
|
if (fp == nullptr) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "UioMapper::getMapSize: Failed to open file " << namestream.str() << std::endl;
|
sif::error << "UioMapper::getMapSize: Failed to open file " << namestream.str() << std::endl;
|
||||||
#endif
|
#endif
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
@ -60,11 +60,12 @@ ReturnValue_t UioMapper::getMapSize(size_t* size) {
|
|||||||
int items = fscanf(fp, "%s", hexstring);
|
int items = fscanf(fp, "%s", hexstring);
|
||||||
if (items != 1) {
|
if (items != 1) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "UioMapper::getMapSize: Failed with error code " << errno
|
sif::error << "UioMapper::getMapSize: Failed with error code " << errno
|
||||||
<< " to read size "
|
<< " to read size "
|
||||||
"string from file "
|
"string from file "
|
||||||
<< namestream.str() << std::endl;
|
<< namestream.str() << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
fclose(fp);
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
uint32_t sizeTmp = 0;
|
uint32_t sizeTmp = 0;
|
||||||
@ -74,9 +75,10 @@ ReturnValue_t UioMapper::getMapSize(size_t* size) {
|
|||||||
}
|
}
|
||||||
if (items != 1) {
|
if (items != 1) {
|
||||||
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
#if FSFW_CPP_OSTREAM_ENABLED == 1
|
||||||
sif::warning << "UioMapper::getMapSize: Failed with error code " << errno << "to convert "
|
sif::error << "UioMapper::getMapSize: Failed with error code " << errno << "to convert "
|
||||||
<< "size of map" << mapNum << " to integer" << std::endl;
|
<< "size of map" << mapNum << " to integer" << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
fclose(fp);
|
||||||
return HasReturnvaluesIF::RETURN_FAILED;
|
return HasReturnvaluesIF::RETURN_FAILED;
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
@ -143,7 +143,10 @@ def handle_tests_type(args, build_dir_list: list):
|
|||||||
if which("valgrind") is None:
|
if which("valgrind") is None:
|
||||||
print("Please install valgrind first")
|
print("Please install valgrind first")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
os.chdir(UNITTEST_FOLDER_NAME)
|
if os.path.split(os.getcwd())[1] != UNITTEST_FOLDER_NAME:
|
||||||
|
# If we are in a different directory we try to switch into it but
|
||||||
|
# this might fail
|
||||||
|
os.chdir(UNITTEST_FOLDER_NAME)
|
||||||
os.system("valgrind --leak-check=full ./fsfw-tests")
|
os.system("valgrind --leak-check=full ./fsfw-tests")
|
||||||
os.chdir("..")
|
os.chdir("..")
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ uint16_t CRC::crc16ccitt(uint8_t const input[], uint32_t length, uint16_t starti
|
|||||||
// {
|
// {
|
||||||
// if (xor_out[i] == true)
|
// if (xor_out[i] == true)
|
||||||
// crc_value = crc_value + pow(2,(15 -i)); // reverse CrC result before
|
// crc_value = crc_value + pow(2,(15 -i)); // reverse CrC result before
|
||||||
// Final XOR
|
//Final XOR
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// crc_value = 0;// for debug mode
|
// crc_value = 0;// for debug mode
|
||||||
|
@ -65,10 +65,9 @@ class PeriodicPosixTask : public PosixThread, public PeriodicTaskIF {
|
|||||||
/**
|
/**
|
||||||
* @brief The function containing the actual functionality of the task.
|
* @brief The function containing the actual functionality of the task.
|
||||||
* @details The method sets and starts
|
* @details The method sets and starts
|
||||||
* the task's period, then enters a loop that is repeated indefinitely. Within
|
* the task's period, then enters a loop that is repeated indefinitely. Within the
|
||||||
* the loop, all performOperation methods of the added objects are called. Afterwards the task
|
* loop, all performOperation methods of the added objects are called. Afterwards the task will be
|
||||||
* will be blocked until the next period. On missing the deadline, the deadlineMissedFunction is
|
* blocked until the next period. On missing the deadline, the deadlineMissedFunction is executed.
|
||||||
* executed.
|
|
||||||
*/
|
*/
|
||||||
virtual void taskFunctionality(void);
|
virtual void taskFunctionality(void);
|
||||||
/**
|
/**
|
||||||
|
@ -13,8 +13,8 @@ class ExecutableObjectIF;
|
|||||||
* @brief This class represents a specialized task for periodic activities of multiple objects.
|
* @brief This class represents a specialized task for periodic activities of multiple objects.
|
||||||
*
|
*
|
||||||
* @details MultiObjectTask is an extension to ObjectTask in the way that it is able to execute
|
* @details MultiObjectTask is an extension to ObjectTask in the way that it is able to execute
|
||||||
* multiple objects that implement the ExecutableObjectIF interface. The
|
* multiple objects that implement the ExecutableObjectIF interface. The objects
|
||||||
* objects must be added prior to starting the task.
|
* must be added prior to starting the task.
|
||||||
* @author baetz
|
* @author baetz
|
||||||
* @ingroup task_handling
|
* @ingroup task_handling
|
||||||
*/
|
*/
|
||||||
|
@ -169,8 +169,8 @@ class RMAP : public HasReturnvaluesIF {
|
|||||||
* @param buffer the data to write
|
* @param buffer the data to write
|
||||||
* @param length length of data
|
* @param length length of data
|
||||||
* @return
|
* @return
|
||||||
* - @c COMMAND_NULLPOINTER datalen was != 0 but data was ==
|
* - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL in
|
||||||
* NULL in write command
|
* write command
|
||||||
* - return codes of RMAPChannelIF::sendCommand()
|
* - return codes of RMAPChannelIF::sendCommand()
|
||||||
*/
|
*/
|
||||||
static ReturnValue_t sendWriteCommand(RMAPCookie *cookie, const uint8_t *buffer, size_t length);
|
static ReturnValue_t sendWriteCommand(RMAPCookie *cookie, const uint8_t *buffer, size_t length);
|
||||||
@ -205,8 +205,8 @@ class RMAP : public HasReturnvaluesIF {
|
|||||||
* @param cookie to cookie to read from
|
* @param cookie to cookie to read from
|
||||||
* @param expLength the expected maximum length of the reply
|
* @param expLength the expected maximum length of the reply
|
||||||
* @return
|
* @return
|
||||||
* - @c COMMAND_NULLPOINTER datalen was != 0 but data was ==
|
* - @c COMMAND_NULLPOINTER datalen was != 0 but data was == NULL in
|
||||||
* NULL in write command, or nullpointer in read command
|
* write command, or nullpointer in read command
|
||||||
* - return codes of RMAPChannelIF::sendCommand()
|
* - return codes of RMAPChannelIF::sendCommand()
|
||||||
*/
|
*/
|
||||||
static ReturnValue_t sendReadCommand(RMAPCookie *cookie, uint32_t expLength);
|
static ReturnValue_t sendReadCommand(RMAPCookie *cookie, uint32_t expLength);
|
||||||
|
@ -75,10 +75,10 @@ class RMAPChannelIF {
|
|||||||
* - @c RETURN_OK
|
* - @c RETURN_OK
|
||||||
* - @c COMMAND_NO_DESCRIPTORS_AVAILABLE no descriptors available for sending
|
* - @c COMMAND_NO_DESCRIPTORS_AVAILABLE no descriptors available for sending
|
||||||
* command; command was not sent
|
* command; command was not sent
|
||||||
* - @c COMMAND_BUFFER_FULL no receiver buffer available for
|
* - @c COMMAND_BUFFER_FULL no receiver buffer available for expected len;
|
||||||
* expected len; command was not sent
|
* command was not sent
|
||||||
* - @c COMMAND_TOO_BIG the data that was to be sent was too long for
|
* - @c COMMAND_TOO_BIG the data that was to be sent was too long for the hw
|
||||||
* the hw to handle (write command) or the expected len was bigger than maximal expected len (read
|
* to handle (write command) or the expected len was bigger than maximal expected len (read
|
||||||
* command) command was not sent
|
* command) command was not sent
|
||||||
* - @c COMMAND_CHANNEL_DEACTIVATED the channel has no port set
|
* - @c COMMAND_CHANNEL_DEACTIVATED the channel has no port set
|
||||||
* - @c NOT_SUPPORTED if you dont feel like
|
* - @c NOT_SUPPORTED if you dont feel like
|
||||||
@ -97,8 +97,8 @@ class RMAPChannelIF {
|
|||||||
* - @c REPLY_NO_REPLY no reply was received
|
* - @c REPLY_NO_REPLY no reply was received
|
||||||
* - @c REPLY_NOT_SENT command was not sent, implies no reply
|
* - @c REPLY_NOT_SENT command was not sent, implies no reply
|
||||||
* - @c REPLY_NOT_YET_SENT command is still waiting to be sent
|
* - @c REPLY_NOT_YET_SENT command is still waiting to be sent
|
||||||
* - @c WRITE_REPLY_INTERFACE_BUSY Interface is busy (transmission
|
* - @c WRITE_REPLY_INTERFACE_BUSY Interface is busy (transmission buffer still
|
||||||
* buffer still being processed)
|
* being processed)
|
||||||
* - @c WRITE_REPLY_TRANSMISSION_ERROR Interface encountered errors during last
|
* - @c WRITE_REPLY_TRANSMISSION_ERROR Interface encountered errors during last
|
||||||
* operation, data could not be processed. (transmission error)
|
* operation, data could not be processed. (transmission error)
|
||||||
* - @c WRITE_REPLY_INVALID_DATA Invalid data (amount / value)
|
* - @c WRITE_REPLY_INVALID_DATA Invalid data (amount / value)
|
||||||
|
@ -45,7 +45,7 @@ TEST_CASE("Command Executor", "[cmd-exec]") {
|
|||||||
result = cmdExecutor.check(bytesHaveBeenRead);
|
result = cmdExecutor.check(bytesHaveBeenRead);
|
||||||
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
||||||
usleep(500);
|
usleep(500);
|
||||||
REQUIRE(limitIdx < 5);
|
REQUIRE(limitIdx < 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
limitIdx = 0;
|
limitIdx = 0;
|
||||||
@ -71,8 +71,9 @@ TEST_CASE("Command Executor", "[cmd-exec]") {
|
|||||||
limitIdx++;
|
limitIdx++;
|
||||||
result = cmdExecutor.check(bytesHaveBeenRead);
|
result = cmdExecutor.check(bytesHaveBeenRead);
|
||||||
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
||||||
|
// This ensures that the tests do not block indefinitely
|
||||||
usleep(500);
|
usleep(500);
|
||||||
REQUIRE(limitIdx < 20);
|
REQUIRE(limitIdx < 500);
|
||||||
}
|
}
|
||||||
limitIdx = 0;
|
limitIdx = 0;
|
||||||
CHECK(bytesHaveBeenRead == true);
|
CHECK(bytesHaveBeenRead == true);
|
||||||
@ -89,7 +90,7 @@ TEST_CASE("Command Executor", "[cmd-exec]") {
|
|||||||
std::string allTheReply(reinterpret_cast<char*>(largerReadBuffer));
|
std::string allTheReply(reinterpret_cast<char*>(largerReadBuffer));
|
||||||
// I am just going to assume that this string is the same across ping implementations
|
// I am just going to assume that this string is the same across ping implementations
|
||||||
// of different Linux systems
|
// of different Linux systems
|
||||||
REQUIRE(allTheReply.find("localhost ping statistics") != std::string::npos);
|
REQUIRE(allTheReply.find("PING localhost") != std::string::npos);
|
||||||
|
|
||||||
// Now check failing command
|
// Now check failing command
|
||||||
result = cmdExecutor.load("false", false, false);
|
result = cmdExecutor.load("false", false, false);
|
||||||
@ -101,8 +102,9 @@ TEST_CASE("Command Executor", "[cmd-exec]") {
|
|||||||
limitIdx++;
|
limitIdx++;
|
||||||
result = cmdExecutor.check(bytesHaveBeenRead);
|
result = cmdExecutor.check(bytesHaveBeenRead);
|
||||||
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
REQUIRE(result != CommandExecutor::COMMAND_ERROR);
|
||||||
|
// This ensures that the tests do not block indefinitely
|
||||||
usleep(500);
|
usleep(500);
|
||||||
REQUIRE(limitIdx < 20);
|
REQUIRE(limitIdx < 500);
|
||||||
}
|
}
|
||||||
REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED);
|
REQUIRE(result == HasReturnvaluesIF::RETURN_FAILED);
|
||||||
REQUIRE(cmdExecutor.getLastError() == 1);
|
REQUIRE(cmdExecutor.getLastError() == 1);
|
||||||
|
Loading…
Reference in New Issue
Block a user