ChimeraTK-DeviceAccess
03.18.00
|
Class to test any backend for correct behaviour. More...
#include <UnifiedBackendTest.h>
Classes | |
class | EnableDisableActionList |
"Strong typedef" for list of pairs of functors for enabling and disabling a test condition. More... | |
struct | ExceptionReportingBackend |
Special DeviceBackend used for testing the exception reporting to the backend. More... | |
struct | forceAsyncReadInconsistency_proxy_helper |
struct | forceAsyncReadInconsistency_proxy_helper< T, false > |
class | has_nValuesToTest |
struct | nValuesToTest_proxy_helper |
struct | nValuesToTest_proxy_helper< T, false > |
struct | setForceDataLossWrite_proxy_helper |
struct | setForceDataLossWrite_proxy_helper< T, false > |
struct | switchReadOnly_proxy_helper |
struct | switchReadOnly_proxy_helper< T, false > |
struct | switchWriteOnly_proxy_helper |
struct | switchWriteOnly_proxy_helper< T, false > |
struct | writeQueueLength_proxy_helper |
struct | writeQueueLength_proxy_helper< T, false > |
Public Member Functions | |
template<typename REG_T > | |
UnifiedBackendTest< typename boost::mpl::push_back< VECTOR_OF_REGISTERS_T, REG_T >::type > | addRegister () |
Add a register to be used by the test. More... | |
void | runTests (const std::string &cdd_, const std::string &cdd2_="") |
Execute all tests. More... | |
UnifiedBackendTest< VECTOR_OF_REGISTERS_T > & | testOnlyTransferElement () |
Call if not a real backend is tested but just a special TransferElement implementation. More... | |
Protected Member Functions | |
void | test_B_3_1_2_1 () |
Test synchronous read. More... | |
void | test_NOSPEC_write () |
Test write. More... | |
void | test_B_3_2_1_2 () |
Test write() does not destroy application buffer. More... | |
void | test_B_3_2_2 () |
Test destructive write. More... | |
void | test_B_4_2_4 () |
Test transfer implementations do not change the application buffer. More... | |
void | test_B_6_4 () |
Test application buffer unchanged after exception. More... | |
void | test_B_7_2 () |
Test data loss in write. More... | |
void | test_B_8_2 () |
Test async read fills _readQueue. More... | |
void | test_B_8_2_1 () |
Test _readQueue overrun. More... | |
void | test_B_8_3 () |
Test new runtime errors are put to _readQueue in async reads. More... | |
void | test_B_8_4 () |
Test async read consistency heartbeat. More... | |
void | test_B_8_5 () |
Test no async transfers until activateAsyncRead(). More... | |
void | test_B_8_5_1 () |
Test activateAsynchronousRead. More... | |
void | test_B_8_5_2 () |
Test initial value. More... | |
void | test_B_8_5_3 () |
Accessors created after activateAsyncRead() are immediately active. More... | |
void | test_B_8_6_6 () |
Test interrupt() More... | |
void | test_B_9_1 () |
Test reporting exceptions to exception backend. More... | |
void | test_B_9_2_2 () |
Test repeated setException() has no effect (in particular, no additional exceptions in async transfers) More... | |
void | test_B_9_3_1 () |
Test setException() disables asynchronous read transfers. More... | |
void | test_B_9_3_2 () |
Test exactly one runtime_error in the _readQueue per async read accessor. More... | |
void | test_B_9_4_1 () |
Test doReadTransferSynchronously throws runtime_error after setException() until recovery. More... | |
void | test_B_9_5 () |
Test write operations throw after setException() More... | |
void | test_NOSPEC_newVersionAfterOpen () |
Test versions after calling open() are newer than any version before. More... | |
void | test_B_11_2_1 () |
Test version number bigger for newer values. More... | |
void | test_B_11_2_2 () |
Test consistent data gets same VersionNumber. More... | |
void | test_B_11_6 () |
Test the value after construction for the version number in the application buffer. More... | |
void | test_C_5_2_1_2 () |
Test logic_error for non-existing register. More... | |
void | test_C_5_2_2_2 () |
Test logic_error for exceeding register size. More... | |
void | test_C_5_2_3_2 () |
Test logic_error for wrong access mode flags. More... | |
void | test_C_5_2_5_2 () |
Test logic_error on operation while backend closed. More... | |
void | test_C_5_2_6_2 () |
Test logic_error on read operation on write-only register. More... | |
void | test_C_5_2_7_2 () |
Test logic_error on write operation on read-only register. More... | |
void | test_C_5_3 () |
Test read-only/write-only information changes after runtime_error. More... | |
void | test_C_5_3_2 () |
Test read-only/write-only information cached per accessor. More... | |
void | test_C_5_3_3 () |
Test read-only/write-only information always returned from cache if available. More... | |
void | test_NOSPEC_valueAfterConstruction () |
Test the content of the application data buffer after construction. More... | |
void | test_NOSPEC_backendNotClosedAfterException () |
Test that the backend does not close itself after seeing an exception. More... | |
void | test_NOSPEC_rawTransfer () |
Test that the backend does not close itself after seeing an exception. More... | |
void | test_NOSPEC_catalogueRaw () |
Test that the catalogue information for the raw accessor is correct. More... | |
void | test_NOSPEC_catalogueReadWrite () |
Test that the catalogue and accessor information for read and write are correct. More... | |
void | recoverDevice (ChimeraTK::Device &d) |
Utility functions for recurring tasks. More... | |
template<typename REG_T > | |
bool | isRead (REG_T x={}) |
Utility functions for register traits. More... | |
template<typename REG_T > | |
bool | isWrite (REG_T x={}) |
template<typename REG_T > | |
bool | isSyncRead (REG_T x={}) |
template<typename REG_T > | |
bool | isAsyncRead (REG_T x={}) |
template<typename REG_T > | |
bool | isRaw (REG_T x={}) |
template<typename REG_T > | |
bool | isReadOnly (REG_T x={}) |
template<typename REG_T > | |
bool | isWriteOnly (REG_T x={}) |
template<typename T > | |
void | setForceDataLossWrite (T t, bool enable) |
template<typename T > | |
void | forceAsyncReadInconsistency (T t) |
template<typename T > | |
void | switchReadOnly (T t, bool enable) |
template<typename T > | |
void | switchWriteOnly (T t, bool enable) |
template<typename T > | |
size_t | writeQueueLength (T t) |
template<typename T > | |
size_t | nValuesToTest (T t) |
Protected Attributes | |
VECTOR_OF_REGISTERS_T | registers |
boost::mpl::vector with all register descriptors More... | |
std::string | cdd |
CDD for backend to test. More... | |
std::string | cdd2 |
bool | _testOnlyTransferElement {false} |
Flag whether to disable tests for the backend itself. More... | |
Class to test any backend for correct behaviour.
Instantiate this class and call all (!) preparatory functions to provide the tests with the backend-specific test actions etc. Finally call runTests() to execute all tests. Internally the BOOST unit test framework is used, so this shall be called inside a normal unit test.
Failing to call all preparatory functions will result in an error. This allows a safe test schema evolution - if more backend specific actions for enabling and disabling test conditions are needed for the tests and the backend test has not yet been updated, tests will fail.
Actions are usually specified as list of pairs of functors. The pair's first element is always the action to enable the the test condition, the second is the action to disable it. By providing multiple entries in the lists it is possible to test several code paths the backend has to end up in the intended test condition. For example in case of forceRuntimeErrorOnRead(): runtime_errors in a read can be caused by a timeout in the communication channel, or by a bad reply of the device. Two list entries would be provided in this case, one to make read operations run into timeouts, and one to make the (dummy) device reply with garbage. If only one singe code path exists to get to the test condition, it is perfectly fine to have only a single entry in the list.
In the same way as for the actions, names of registers etc. are provided as lists, so all test can be repeated for different registers, if required for full coverage.
Instantiate with default template argument, then call addRegister() to add any number of registers, i.e.:
auto ubt = UnifiedBackendTest<>.addRegister<RegisterA>().addRegister<RegisterB>().addRegister<RegisterC>() ubt.runTest("myCDD");
See addRegister() for more details.
Note: This is work in progress. Tests are by far not yet complete. Interface changes of the test class are also likely.
Definition at line 259 of file UnifiedBackendTest.h.
|
inline |
Add a register to be used by the test.
This function takes a register descriptor in form of a struct type as template argument and returns a new UnifiedBackendTest object.
The register descriptor must be of the following form:
struct MyRegisterDescriptor { std::string path() {return "/path/of/register";} bool isWriteable() {return true;} bool isReadable() {return true;} ChimeraTK::AccessModeFlags supportedFlags() {return {ChimeraTK::AccessMode::wait_for_new_data};} size_t nChannels() {return 1;} size_t nElementsPerChannel() {return 5;} size_t nRuntimeErrorCases() {return 1;} // see setForceRuntimeError()
/// Number of values to test in read and write tests. Put in how many calls to generateValue() are necessary /// to cover all corner cases to be tested. Should be at least 2 even if no corner cases are to be tested. /// Optional, defaults to 2. size_t nValuesToTest() {return 2;}
typedef int32_t minimumUserType; typedef minimumUserType rawUserType; // only used if AccessMode::raw is supprted, can be omitted otherwise
/// Generate value which can be represented by the register. Make sure it's different from the /// previous one and that it's not all zero to ensure that the test is sensitive. /// Template argument 'Type 'can be UserType or RawType if raw is supported. If the 'raw' flag is /// false, data is converted to the UserType (e.g. using ChimeraTK::numericToUserType), otherwise /// unconverted (raw) data is returned. /// In case the accessor does not support AccessMode::raw, the 'raw' argument can be omitted. template<typename Type> std::vector<std::vector<Type>> generateValue(bool raw = false);
/// Obtain the current value of the register. The value can be raw or converted to /// UserType (see generateValue()). In case the accessor does not support AccessMode::raw, the 'raw' argument can be omitted. template<typename Type> std::vector<std::vector<Type>> getRemoteValue(bool raw = false);
/// Set remote value to a value generated in the same way as in generateValue(). void setRemoteValue();
/// Force runtime errors when reading or writing (at least) this register. Whether other registers are also /// affected by this is not important for the test (i.e. blocking the entire communication is ok). /// It is guaranteed that this function is always called in pairs with first enable = true and then /// enable = false, without calling setForceRuntimeError() for any other register in between. /// The second case argument will be set to a number between 0 and nRuntimeErrorCases()-1. Each case will be /// enabled and disabled separately. It is guaranteed that never two cases are enabled at the same time. If /// nRuntimeErrorCases() == 0, this function will never be called. void setForceRuntimeError(bool enable, size_t case);
/// Describe which test capabilities are provided by the register descriptor. Enable capabilities for which /// the corresponding functions are provided by this register descriptor. Disable capabilities which are /// intentionally not provided to avoid a warning. static constexpr auto capabilities = TestCapabilities<>().enableForceDataLossWrite();
/// Used by setForceDataLossWrite(). Can be omitted if Capability forceDataLossWrite = disabled. size_t writeQueueLength() {return std::numeric_limits<size_t>::max();}
/// Force data loss during write operations. It is expected that data loss occurs exactly writeQueueLength /// write operations after calling this function with enable=true. /// Can be omitted if Capability forceDataLossWrite = disabled. /// It is guaranteed that this function is always called in pairs with first enable = true and then /// enable = false. void setForceDataLossWrite(bool enable);
/// Do whatever necessary that data last received via a push-type subscription is inconsistent with the actual /// value (as read by a synchronous read). This can e.g. be achieved by changing the value without publishing /// the update to the subscribers. /// Can be omitted if Capability asyncReadInconsistency = disabled. This should be done only if such /// inconsistencies are already prevented by the protocol. void forceAsyncReadInconsistency();
/// Do whatever necessary that the register changes into a read-only register. /// Can be omitted if TestCapability switchReadOnly = disabled. /// It is guaranteed that this function is always called in pairs with first enable = true and then /// enable = false. void switchReadOnly(bool enable);
/// Do whatever necessary that the register changes into a write-only register. /// Can be omitted if TestCapability switchWriteOnly = disabled. /// It is guaranteed that this function is always called in pairs with first enable = true and then /// enable = false. void switchWriteOnly(bool enable); };
Note: Instances of the register descriptors are created and discarded arbitrarily. If it is necessary to store any data (e.g. seeds for generating values), use static member variables.
Properties of the register are implemented as functions instead of data members to make it easier to override values when using a common base class for multiple descriptors to avoid code duplication (without triggering a shadowing warning).
Definition at line 352 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 538 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 447 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 452 of file UnifiedBackendTest.h.
|
inlineprotected |
Utility functions for register traits.
Definition at line 431 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 456 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 442 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 437 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 460 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 632 of file UnifiedBackendTest.h.
|
protected |
Utility functions for recurring tasks.
Definition at line 989 of file UnifiedBackendTest.h.
void ChimeraTK::UnifiedBackendTest< VECTOR_OF_REGISTERS_T >::runTests | ( | const std::string & | cdd_, |
const std::string & | cdd2_ = "" |
||
) |
Execute all tests.
Call this function within a BOOST_AUTO_TEST_CASE after calling all preparatory functions below. The tests are executed for the backend identified by the given CDD.
A second CDD should be specified, if it is possible to reach the same registers through a different backend.
Definition at line 864 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 519 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 557 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 576 of file UnifiedBackendTest.h.
|
protected |
Test version number bigger for newer values.
Definition at line 2643 of file UnifiedBackendTest.h.
|
protected |
Test consistent data gets same VersionNumber.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!! TODO FIXME This test is not complete yet !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Definition at line 2803 of file UnifiedBackendTest.h.
|
protected |
Test the value after construction for the version number in the application buffer.
Definition at line 2861 of file UnifiedBackendTest.h.
|
protected |
Test synchronous read.
Definition at line 1013 of file UnifiedBackendTest.h.
|
protected |
Test write() does not destroy application buffer.
(Exception case is covered by B.6.4)
Definition at line 1115 of file UnifiedBackendTest.h.
|
protected |
Test destructive write.
Definition at line 1155 of file UnifiedBackendTest.h.
|
protected |
Test transfer implementations do not change the application buffer.
Definition at line 1223 of file UnifiedBackendTest.h.
|
protected |
Test application buffer unchanged after exception.
Definition at line 1302 of file UnifiedBackendTest.h.
|
protected |
Test data loss in write.
Definition at line 1504 of file UnifiedBackendTest.h.
|
protected |
Test async read fills _readQueue.
Note: we do not care about read() vs. readNonBlocking() in this test, since that part of the implementation is in the base class and hence tested in testTransferElement.
Definition at line 1594 of file UnifiedBackendTest.h.
|
protected |
Test _readQueue overrun.
FIXME: This test is not really complete. It tests whether the latest value survives. It does not test though which other values are surviving. For this the test needs to know the length of the implementation specific data transport queue, which is currently not known to it (the length of the _readQueue continuation is always 1).
Definition at line 1693 of file UnifiedBackendTest.h.
|
protected |
Test new runtime errors are put to _readQueue in async reads.
Definition at line 1750 of file UnifiedBackendTest.h.
|
protected |
Test async read consistency heartbeat.
Definition at line 1811 of file UnifiedBackendTest.h.
|
protected |
Test no async transfers until activateAsyncRead().
FIXME: This test is broken (see redmine ticket #11311)
Definition at line 1877 of file UnifiedBackendTest.h.
|
protected |
Test activateAsynchronousRead.
REMOVE
REMOVE
Definition at line 1945 of file UnifiedBackendTest.h.
|
protected |
Test initial value.
Definition at line 2010 of file UnifiedBackendTest.h.
|
protected |
Accessors created after activateAsyncRead() are immediately active.
Definition at line 2074 of file UnifiedBackendTest.h.
|
protected |
Test interrupt()
Definition at line 2105 of file UnifiedBackendTest.h.
|
protected |
Test reporting exceptions to exception backend.
Definition at line 2160 of file UnifiedBackendTest.h.
|
protected |
Test repeated setException() has no effect (in particular, no additional exceptions in async transfers)
Definition at line 2415 of file UnifiedBackendTest.h.
|
protected |
Test setException() disables asynchronous read transfers.
Definition at line 2469 of file UnifiedBackendTest.h.
|
protected |
Test exactly one runtime_error in the _readQueue per async read accessor.
Definition at line 2520 of file UnifiedBackendTest.h.
|
protected |
Test doReadTransferSynchronously throws runtime_error after setException() until recovery.
Definition at line 2569 of file UnifiedBackendTest.h.
|
protected |
Test write operations throw after setException()
Definition at line 2607 of file UnifiedBackendTest.h.
|
protected |
Test logic_error for non-existing register.
Definition at line 2883 of file UnifiedBackendTest.h.
|
protected |
Test logic_error for exceeding register size.
Definition at line 2913 of file UnifiedBackendTest.h.
|
protected |
Test logic_error for wrong access mode flags.
Definition at line 2978 of file UnifiedBackendTest.h.
|
protected |
Test logic_error on operation while backend closed.
Definition at line 3006 of file UnifiedBackendTest.h.
|
protected |
Test logic_error on read operation on write-only register.
Definition at line 3050 of file UnifiedBackendTest.h.
|
protected |
Test logic_error on write operation on read-only register.
Definition at line 3082 of file UnifiedBackendTest.h.
|
protected |
Test read-only/write-only information changes after runtime_error.
Definition at line 3104 of file UnifiedBackendTest.h.
|
protected |
Test read-only/write-only information cached per accessor.
Definition at line 3145 of file UnifiedBackendTest.h.
|
protected |
Test read-only/write-only information always returned from cache if available.
Definition at line 3186 of file UnifiedBackendTest.h.
|
protected |
Test that the backend does not close itself after seeing an exception.
Definition at line 3252 of file UnifiedBackendTest.h.
|
protected |
Test that the catalogue information for the raw accessor is correct.
Definition at line 3605 of file UnifiedBackendTest.h.
|
protected |
Test that the catalogue and accessor information for read and write are correct.
Definition at line 3645 of file UnifiedBackendTest.h.
|
protected |
Test versions after calling open() are newer than any version before.
FIXME: missing in spec
This test is checking that initial values have version numbers larger than VersionNumbers created by the application before calling open().
Definition at line 2719 of file UnifiedBackendTest.h.
|
protected |
Test that the backend does not close itself after seeing an exception.
Definition at line 3510 of file UnifiedBackendTest.h.
|
protected |
Test the content of the application data buffer after construction.
Definition at line 3228 of file UnifiedBackendTest.h.
|
protected |
Test write.
Definition at line 1075 of file UnifiedBackendTest.h.
|
inline |
Call if not a real backend is tested but just a special TransferElement implementation.
This will disable those tests which do not make sense in that context. Use this for testing the ControlSystemAdapter's ProcessArray, or the NDRegisterAccessorDecorator base class.
Definition at line 379 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 599 of file UnifiedBackendTest.h.
|
protected |
Flag whether to disable tests for the backend itself.
Definition at line 471 of file UnifiedBackendTest.h.
|
protected |
CDD for backend to test.
Definition at line 468 of file UnifiedBackendTest.h.
|
protected |
Definition at line 468 of file UnifiedBackendTest.h.
|
protected |
boost::mpl::vector with all register descriptors
Definition at line 465 of file UnifiedBackendTest.h.