![]() |
ChimeraTK-DeviceAccess 03.25.00
|
Class to test any backend for correct behaviour. More...
#include <UnifiedBackendTest.h>
Collaboration diagram for ChimeraTK::UnifiedBackendTest< VECTOR_OF_REGISTERS_T >: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. | |
| void | runTests (const std::string &cdd_, const std::string &cdd2_="") |
| Execute all tests. | |
| UnifiedBackendTest< VECTOR_OF_REGISTERS_T > & | testOnlyTransferElement () |
| Call if not a real backend is tested but just a special TransferElement implementation. | |
Protected Member Functions | |
| void | test_B_3_1_2_1 () |
| Test synchronous read. | |
| void | test_NOSPEC_partial_read () |
| Partial accessor read. | |
| void | test_NOSPEC_write () |
| Test write. | |
| void | test_NOSPEC_partial_write () |
| Test partial write. | |
| void | test_B_3_2_1_2 () |
| Test write() does not destroy application buffer. | |
| void | test_B_3_2_2 () |
| Test destructive write. | |
| void | test_B_4_2_4 () |
| Test transfer implementations do not change the application buffer. | |
| void | test_B_4_2_5 () |
| Test that xxxTransferYyy() can be skipped between preXxx() and postXxx() | |
| void | test_B_6_4 () |
| Test application buffer unchanged after exception. | |
| void | test_B_7_2 () |
| Test data loss in write. | |
| void | test_B_8_2 () |
| Test async read fills _readQueue. | |
| void | test_B_8_2_1 () |
| Test _readQueue overrun. | |
| void | test_B_8_3 () |
| Test new runtime errors are put to _readQueue in async reads. | |
| void | test_B_8_4 () |
| Test async read consistency heartbeat. | |
| void | test_B_8_5 () |
| Test no async transfers until activateAsyncRead(). | |
| void | test_B_8_5_1 () |
| Test activateAsynchronousRead. | |
| void | test_B_8_5_2 () |
| Test initial value. | |
| void | test_B_8_5_3 () |
| Accessors created after activateAsyncRead() are immediately active. | |
| void | test_B_8_5_4_3 () |
| Calling activateAsyncRead() when already active has no effect. | |
| void | test_B_8_6_6 () |
| Test interrupt() | |
| void | test_B_9_1 () |
| Test reporting exceptions to exception backend. | |
| void | test_B_9_2_2 () |
| Test repeated setException() has no effect (in particular, no additional exceptions in async transfers) | |
| void | test_B_9_3_1 () |
| Test setException() disables asynchronous read transfers. | |
| void | test_B_9_3_2 () |
| Test exactly one runtime_error in the _readQueue per async read accessor. | |
| void | test_B_9_4_1 () |
| Test doReadTransferSynchronously throws runtime_error after setException() until recovery. | |
| void | test_B_9_5 () |
| Test write operations throw after setException() | |
| void | test_NOSPEC_newVersionAfterOpen () |
| Test versions after calling open() are newer than any version before. | |
| void | test_B_11_2_1 () |
| Test version number bigger for newer values. | |
| void | test_B_11_2_2 () |
| Test consistent data gets same VersionNumber. | |
| void | test_B_11_6 () |
| Test the value after construction for the version number in the application buffer. | |
| void | test_B_12_1_3_1 () |
| If an element that is already in the list of internal elements is passed to TransferElement::replaceTransferElement(), it does not change the internal elements. | |
| void | test_B_12_1_5_1 () |
| mayReplaceOther() of itself returns "false" | |
| void | test_C_5_2_1_2 () |
| Test logic_error for non-existing register. | |
| void | test_C_5_2_2_2 () |
| Test logic_error for exceeding register size. | |
| void | test_C_5_2_3_2 () |
| Test logic_error for wrong access mode flags. | |
| void | test_C_5_2_5_2 () |
| Test logic_error on operation while backend closed. | |
| void | test_C_5_2_6_2 () |
| Test logic_error on read operation on write-only register. | |
| void | test_C_5_2_7_2 () |
| Test logic_error on write operation on read-only register. | |
| void | test_C_5_3 () |
| Test read-only/write-only information changes after runtime_error. | |
| void | test_C_5_3_2 () |
| Test read-only/write-only information cached per accessor. | |
| void | test_C_5_3_3 () |
| Test read-only/write-only information always returned from cache if available. | |
| void | test_NOSPEC_valueAfterConstruction () |
| Test the content of the application data buffer after construction. | |
| void | test_NOSPEC_backendNotClosedAfterException () |
| Test that the backend does not close itself after seeing an exception. | |
| void | test_NOSPEC_rawTransfer () |
| Test that the backend does not close itself after seeing an exception. | |
| void | test_NOSPEC_catalogueRaw () |
| Test that the catalogue information for the raw accessor is correct. | |
| void | test_NOSPEC_catalogueReadWrite () |
| Test that the catalogue and accessor information for read and write are correct. | |
| void | recoverDevice (ChimeraTK::Device &d) |
| Utility functions for recurring tasks. | |
| template<typename REG_T > | |
| bool | isRead (REG_T x={}) |
| Utility functions for register traits. | |
| 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 | |
| std::string | cdd |
| CDD for backend to test. | |
| std::string | cdd2 |
| bool | _testOnlyTransferElement {false} |
| Flag whether to disable tests for the backend itself. | |
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 275 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 368 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 560 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 469 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 474 of file UnifiedBackendTest.h.
|
inlineprotected |
Utility functions for register traits.
Definition at line 453 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 478 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 464 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 459 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 482 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 654 of file UnifiedBackendTest.h.
|
protected |
Utility functions for recurring tasks.
Definition at line 1034 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 886 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 541 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 579 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 598 of file UnifiedBackendTest.h.
|
protected |
Test version number bigger for newer values.
Definition at line 2934 of file UnifiedBackendTest.h.
|
protected |
Test consistent data gets same VersionNumber.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!! TODO FIXME This test is not complete yet !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Definition at line 3094 of file UnifiedBackendTest.h.
|
protected |
Test the value after construction for the version number in the application buffer.
Definition at line 3152 of file UnifiedBackendTest.h.
|
protected |
If an element that is already in the list of internal elements is passed to TransferElement::replaceTransferElement(), it does not change the internal elements.
Definition at line 3176 of file UnifiedBackendTest.h.
|
protected |
mayReplaceOther() of itself returns "false"
Definition at line 3203 of file UnifiedBackendTest.h.
|
protected |
|
protected |
Test write() does not destroy application buffer.
(Exception case is covered by B.6.4)
Definition at line 1279 of file UnifiedBackendTest.h.
|
protected |
|
protected |
Test transfer implementations do not change the application buffer.
Definition at line 1395 of file UnifiedBackendTest.h.
|
protected |
Test that xxxTransferYyy() can be skipped between preXxx() and postXxx()
Definition at line 1474 of file UnifiedBackendTest.h.
|
protected |
Test application buffer unchanged after exception.
Definition at line 1554 of file UnifiedBackendTest.h.
|
protected |
|
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 1846 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 1945 of file UnifiedBackendTest.h.
|
protected |
Test new runtime errors are put to _readQueue in async reads.
Definition at line 2002 of file UnifiedBackendTest.h.
|
protected |
|
protected |
Test no async transfers until activateAsyncRead().
FIXME: This test is broken (see redmine ticket #11311)
Definition at line 2129 of file UnifiedBackendTest.h.
|
protected |
|
protected |
|
protected |
Accessors created after activateAsyncRead() are immediately active.
Definition at line 2326 of file UnifiedBackendTest.h.
|
protected |
Calling activateAsyncRead() when already active has no effect.
Definition at line 2357 of file UnifiedBackendTest.h.
|
protected |
Test interrupt()
Definition at line 2396 of file UnifiedBackendTest.h.
|
protected |
Test reporting exceptions to exception backend.
Definition at line 2451 of file UnifiedBackendTest.h.
|
protected |
Test repeated setException() has no effect (in particular, no additional exceptions in async transfers)
Definition at line 2706 of file UnifiedBackendTest.h.
|
protected |
Test setException() disables asynchronous read transfers.
Definition at line 2760 of file UnifiedBackendTest.h.
|
protected |
Test exactly one runtime_error in the _readQueue per async read accessor.
Definition at line 2811 of file UnifiedBackendTest.h.
|
protected |
Test doReadTransferSynchronously throws runtime_error after setException() until recovery.
Definition at line 2860 of file UnifiedBackendTest.h.
|
protected |
Test write operations throw after setException()
Definition at line 2898 of file UnifiedBackendTest.h.
|
protected |
Test logic_error for non-existing register.
Definition at line 3224 of file UnifiedBackendTest.h.
|
protected |
Test logic_error for exceeding register size.
Definition at line 3254 of file UnifiedBackendTest.h.
|
protected |
Test logic_error for wrong access mode flags.
Definition at line 3319 of file UnifiedBackendTest.h.
|
protected |
Test logic_error on operation while backend closed.
Definition at line 3347 of file UnifiedBackendTest.h.
|
protected |
Test logic_error on read operation on write-only register.
Definition at line 3391 of file UnifiedBackendTest.h.
|
protected |
Test logic_error on write operation on read-only register.
Definition at line 3423 of file UnifiedBackendTest.h.
|
protected |
Test read-only/write-only information changes after runtime_error.
Definition at line 3445 of file UnifiedBackendTest.h.
|
protected |
Test read-only/write-only information cached per accessor.
Definition at line 3486 of file UnifiedBackendTest.h.
|
protected |
Test read-only/write-only information always returned from cache if available.
Definition at line 3527 of file UnifiedBackendTest.h.
|
protected |
Test that the backend does not close itself after seeing an exception.
Definition at line 3593 of file UnifiedBackendTest.h.
|
protected |
Test that the catalogue information for the raw accessor is correct.
Definition at line 3946 of file UnifiedBackendTest.h.
|
protected |
Test that the catalogue and accessor information for read and write are correct.
Definition at line 3986 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 3010 of file UnifiedBackendTest.h.
|
protected |
|
protected |
|
protected |
Test that the backend does not close itself after seeing an exception.
Definition at line 3851 of file UnifiedBackendTest.h.
|
protected |
Test the content of the application data buffer after construction.
Definition at line 3569 of file UnifiedBackendTest.h.
|
protected |
|
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 395 of file UnifiedBackendTest.h.
|
inlineprotected |
Definition at line 621 of file UnifiedBackendTest.h.
|
protected |
Flag whether to disable tests for the backend itself.
Definition at line 493 of file UnifiedBackendTest.h.
|
protected |
CDD for backend to test.
Definition at line 490 of file UnifiedBackendTest.h.
|
protected |
Definition at line 490 of file UnifiedBackendTest.h.
|
protected |
boost::mpl::vector with all register descriptors
Definition at line 487 of file UnifiedBackendTest.h.