Skip to content
Snippets Groups Projects
Commit 468fe158 authored by vargheseg's avatar vargheseg
Browse files

Refactoring: testExceptionHandling.cc

- Introduced PollModule::triggerRead
- status/message process variable are now instantiated in the fixture
- use name scheme for tests:
    runtimeErrorReporting
     - runtimeErrorReporting_faultReporting
parent 71c84337
No related branches found
No related tags found
No related merge requests found
......@@ -23,10 +23,10 @@
using namespace boost::unit_test_framework;
namespace ctk = ChimeraTK;
// TODO: extend/rename test application as required/ make new test applications as the exception
// handling cases are covered.
/**************************/
struct Module : ctk::ApplicationModule {
/*
* This module polls device register on demand.
*/
struct PollModule : ctk::ApplicationModule {
using ctk::ApplicationModule::ApplicationModule;
ctk::ScalarPollInput<int> fromDevice{this, "REG1", "", "", {"DEVICE"}};
......@@ -34,12 +34,28 @@ struct Module : ctk::ApplicationModule {
void mainLoop() override {
while(true) {
readAll();
if(block == true) {
boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
continue;
}
fromDevice.read();
toCs = static_cast<int>(fromDevice);
writeAll();
block = true;
}
}
/*
* trigger a poll type read on the device register: REG1
*/
void triggerRead() {
block = false;
while(block == false) {
boost::this_thread::sleep_for(boost::chrono::milliseconds(100));
}
}
std::atomic<bool> block{true};
};
struct DummyApplication : ctk::Application {
......@@ -48,10 +64,10 @@ struct DummyApplication : ctk::Application {
// +----------+ +------+
constexpr static char const* ExceptionDummyCDD1 = "(ExceptionDummy:1?map=test.map)";
DummyApplication() : Application("testFault") {}
DummyApplication() : Application("DummyApplication") {}
~DummyApplication() { shutdown(); }
Module m{this, "", ""};
PollModule pollModule{this, "", ""};
ctk::ControlSystemModule cs;
ctk::DeviceModule device{this, ExceptionDummyCDD1};
......@@ -69,44 +85,47 @@ struct Fixture_noTestFacility {
deviceBackend->open();
testFacitiy.runApplication();
status.replace(
testFacitiy.getScalar<int>(ctk::RegisterPath("/Devices") / DummyApplication::ExceptionDummyCDD1 / "status"));
message.replace(testFacitiy.getScalar<std::string>(
ctk::RegisterPath("/Devices") / DummyApplication::ExceptionDummyCDD1 / "message"));
//
// As a test precondition, the DeviceModule must have completed its startup procedure. The code
// block below is a workaround to ensure this.
//
// Code below depends on behavior of process variable 'status', where 'status' is initialized
// with 0 as default after which its written with:
// - 1 (before DeviceModule begins opening the device),
// - 0 (once DeviceModule successfully opens the device/device startup is complete).
// This sequence is similar for the associated 'message' variable; replace 0/1 values above
// with an empty/non-empty string.
// As a test precondition, the DeviceModule must have completed its startup procedure. The
// device module writes status to 0 and message to "" once the initialization is complete and
// the device is functional.
//
// Thus checking for two writes on these variables is a resonable indication that device startup
// is done. (provided the assumption explained above holds).
// This behavior is used as a workaround to ensure we exit only after startup is complete
/************************************************************************************************/
auto status =
testFacitiy.getScalar<int>(ctk::RegisterPath("/Devices") / DummyApplication::ExceptionDummyCDD1 / "status");
auto message = testFacitiy.getScalar<std::string>(
ctk::RegisterPath("/Devices") / DummyApplication::ExceptionDummyCDD1 / "message");
CHECK_TIMEOUT(status.readNonBlocking() == true, 100000);
CHECK_TIMEOUT(status.readNonBlocking() == true, 100000);
CHECK_TIMEOUT(message.readNonBlocking() == true, 100000);
CHECK_TIMEOUT(message.readNonBlocking() == true, 100000);
CHECK_TIMEOUT(
[&]() {
status.readLatest();
return static_cast<int>(status);
}() == 0,
100000);
CHECK_TIMEOUT(
[&]() {
message.readLatest();
return static_cast<std::string>(message);
}() == "",
100000);
/************************************************************************************************/
}
~Fixture_noTestFacility() { deviceBackend->throwExceptionRead = false; }
boost::shared_ptr<ctk::ExceptionDummy> deviceBackend;
DummyApplication app;
DummyApplication application;
ctk::TestFacility testFacitiy{false};
ctk::ScalarRegisterAccessor<int> status;
ctk::ScalarRegisterAccessor<std::string> message;
};
/* **********************************/
/*
* This test suite checks behavior on a device related runtime error.
*/
BOOST_AUTO_TEST_SUITE(checkRuntimeErrorHandling)
BOOST_AUTO_TEST_SUITE(runtimeErrorHandling)
/*
* Verify the framework creates fault indicator process variables for a device.
......@@ -120,16 +139,18 @@ BOOST_AUTO_TEST_SUITE(checkRuntimeErrorHandling)
*
* \anchor testExceptionHandling_b_2_1 \ref exceptionHandling_b_2_1 "B.2.1"
*/
BOOST_FIXTURE_TEST_CASE(testFaultReporting, Fixture_noTestFacility) {
auto status =
testFacitiy.getScalar<int>(ctk::RegisterPath("/Devices") / DummyApplication::ExceptionDummyCDD1 / "status");
auto message = testFacitiy.getScalar<std::string>(
ctk::RegisterPath("/Devices") / DummyApplication::ExceptionDummyCDD1 / "message");
BOOST_FIXTURE_TEST_CASE(runtimeErrorHandling_testFaultReporting, Fixture_noTestFacility) {
std::cout << "runtimeErrorHandling_testFaultReporting" << std::endl;
// These are instantiated in the fixture:
// status -> /Devices/(ExceptionDummy:1?map=test.map)/status
// message -> /Devices/(ExceptionDummy:1?map=test.map)/message
BOOST_CHECK_EQUAL(status, 0);
BOOST_CHECK_EQUAL(static_cast<std::string>(message), "");
deviceBackend->throwExceptionRead = true;
application.pollModule.triggerRead(); // causes device exception
CHECK_TIMEOUT(status.readNonBlocking() == true, 10000);
CHECK_TIMEOUT(message.readNonBlocking() == true, 10000);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment