Skip to content
Snippets Groups Projects
Commit 7b4d3f6e authored by Martin Christoph Hierholzer's avatar Martin Christoph Hierholzer
Browse files

- added a TestFacility helper class to simplify writing tests

- updated the tests for the testable mode and test the TestFacility class there as well
parent 9dc1ae42
No related branches found
No related tags found
No related merge requests found
/*
* TestFacility.h
*
* Created on: Feb 17, 2017
* Author: Martin Hierholzer
*/
#ifndef CHIMERATK_TEST_FACILITY
#define CHIMERATK_TEST_FACILITY
#include <ChimeraTK/ControlSystemAdapter/ControlSystemPVManager.h>
#include <mtca4u/ScalarRegisterAccessor.h>
#include <mtca4u/OneDRegisterAccessor.h>
#include "Application.h"
#include "TestDecoratorRegisterAccessor.h"
namespace ChimeraTK {
/** Helper class to facilitate tests of applications based on ApplicationCore */
class TestFacility {
public:
/** The constructor will internally obtain the instance of the application, so the instance of the TestFacility
* must not be created before the application (i.e. usually not before the main() routine). The application will
* automatically be put into the testable mode and initialised. */
TestFacility() {
auto pvManagers = createPVManager();
pvManager = pvManagers.first;
Application::getInstance().setPVManager(pvManagers.second);
Application::getInstance().enableTestableMode();
Application::getInstance().initialise();
}
/** Start the application. This simply calls Application::run(). Since the application is in testable mode, it
* will be ??? TODO define precisely what happens on start up */
void runApplication() const {
Application::getInstance().run();
}
/** Perform a "step" of the application. This runs the application until all input provided to it has been
* processed and all application modules wait for new data in blocking read calls. This function returns only
* after the application has reached that stated and was paused again. After returning from this function,
* the result can be checked and new data can be provided to the application. The new data will not be
* processed until the next call to step(). */
void stepApplication() const {
Application::getInstance().stepApplication();
}
/** Obtain a scalar process variable from the application, which is published to the control system. */
template<typename T>
mtca4u::ScalarRegisterAccessor<T> getScalar(const mtca4u::RegisterPath &name) const {
auto pv = boost::make_shared<TestDecoratorRegisterAccessor<T>>(pvManager->getProcessArray<T>(name));
return mtca4u::ScalarRegisterAccessor<T>(pv);
}
/** Obtain an array-type process variable from the application, which is published to the control system. */
template<typename T>
mtca4u::OneDRegisterAccessor<T> getArray(const mtca4u::RegisterPath &name) const {
auto pv = boost::make_shared<TestDecoratorRegisterAccessor<T>>(pvManager->getProcessArray<T>(name));
return mtca4u::OneDRegisterAccessor<T>(pv);
}
protected:
boost::shared_ptr<ControlSystemPVManager> pvManager;
};
} /* namespace ChimeraTK */
#endif /* CHIMERATK_TEST_FACILITY */
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "ControlSystemModule.h" #include "ControlSystemModule.h"
#include "TestDecoratorRegisterAccessor.h" #include "TestDecoratorRegisterAccessor.h"
#include "VariableGroup.h" #include "VariableGroup.h"
#include "TestFacility.h"
using namespace boost::unit_test_framework; using namespace boost::unit_test_framework;
namespace ctk = ChimeraTK; namespace ctk = ChimeraTK;
...@@ -44,30 +45,6 @@ typedef boost::mpl::list<int8_t,uint8_t, ...@@ -44,30 +45,6 @@ typedef boost::mpl::list<int8_t,uint8_t,
int32_t,uint32_t, int32_t,uint32_t,
float,double> test_types; float,double> test_types;
/*********************************************************************************************************************/
/* the NoLoopTestModule is a dummy test module with an empty mainLoop */
template<typename T>
struct NoLoopTestModule : public ctk::ApplicationModule {
NoLoopTestModule(ctk::EntityOwner *owner, const std::string &name) : ctk::ApplicationModule(owner,name) {}
ctk::ScalarPushInput<T> someInput{this, "someInput", "cm", "This is just some input for testing"};
ctk::ScalarPushInput<uint32_t> someUIntInput{this, "someUIntInput", "", "Unsigned integer"};
ctk::ScalarOutput<T> someOutput{this, "someOutput", "cm", "Description"};
struct Outputs : public ctk::VariableGroup {
using ctk::VariableGroup::VariableGroup;
ctk::ScalarOutput<T> v1{this, "v1", "cm", "Output 1 for testing"};
ctk::ScalarOutput<T> v2{this, "v2", "cm", "Output 2 for testing"};
ctk::ScalarOutput<T> v3{this, "v3", "cm", "Output 3 for testing"};
ctk::ScalarOutput<T> v4{this, "v4", "cm", "Output 4 for testing"};
};
Outputs outputs{this, "outputs"};
void mainLoop() {
}
};
/*********************************************************************************************************************/ /*********************************************************************************************************************/
/* the BlockingReadTestModule blockingly reads its input in the main loop and writes the result to its output */ /* the BlockingReadTestModule blockingly reads its input in the main loop and writes the result to its output */
...@@ -172,7 +149,7 @@ struct TestApplication : public ctk::Application { ...@@ -172,7 +149,7 @@ struct TestApplication : public ctk::Application {
using Application::makeConnections; // we call makeConnections() manually in the tests to catch exceptions etc. using Application::makeConnections; // we call makeConnections() manually in the tests to catch exceptions etc.
void defineConnections() {} // the setup is done in the tests void defineConnections() {} // the setup is done in the tests
NoLoopTestModule<T> noLoopTestModule{this,"noLoopTestModule"}; ctk::ControlSystemModule cs{""};
BlockingReadTestModule<T> blockingReadTestModule{this,"blockingReadTestModule"}; BlockingReadTestModule<T> blockingReadTestModule{this,"blockingReadTestModule"};
AsyncReadTestModule<T> asyncReadTestModule{this,"asyncReadTestModule"}; AsyncReadTestModule<T> asyncReadTestModule{this,"asyncReadTestModule"};
ReadAnyTestModule<T> readAnyTestModule{this,"readAnyTestModule"}; ReadAnyTestModule<T> readAnyTestModule{this,"readAnyTestModule"};
...@@ -187,87 +164,26 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( testNoDecorator, T, test_types ) { ...@@ -187,87 +164,26 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( testNoDecorator, T, test_types ) {
TestApplication<T> app; TestApplication<T> app;
app.noLoopTestModule.someOutput >> app.noLoopTestModule.someInput; auto pvManagers = ctk::createPVManager();
app.blockingReadTestModule.someOutput >> app.blockingReadTestModule.someInput; // just to avoid runtime warning app.setPVManager(pvManagers.second);
app.asyncReadTestModule.someOutput >> app.asyncReadTestModule.someInput; // just to avoid runtime warning
app.noLoopTestModule.outputs >= app.readAnyTestModule.inputs; // just to avoid runtime warning app.blockingReadTestModule >= app.cs["blocking"];
app.readAnyTestModule.value >> ctk::VariableNetworkNode::makeConstant<T>(false, 0, 1); // just to avoid runtime warning app.asyncReadTestModule >= app.cs["async"];
app.readAnyTestModule.index >> app.noLoopTestModule.someUIntInput; // just to avoid runtime warning app.readAnyTestModule >= app.cs["readAny"];
app.initialise(); app.initialise();
app.run(); app.run();
// check if we got the decorator for the input // check if we got the decorator for the input
auto hlinput = app.noLoopTestModule.someInput.getHighLevelImplElement(); auto hlinput = app.blockingReadTestModule.someInput.getHighLevelImplElement();
BOOST_CHECK( boost::dynamic_pointer_cast<ctk::TestDecoratorRegisterAccessor<T>>(hlinput) == nullptr ); BOOST_CHECK( boost::dynamic_pointer_cast<ctk::TestDecoratorRegisterAccessor<T>>(hlinput) == nullptr );
// check that we did not get the decorator for the output // check that we did not get the decorator for the output
auto hloutput = app.noLoopTestModule.someOutput.getHighLevelImplElement(); auto hloutput = app.blockingReadTestModule.someOutput.getHighLevelImplElement();
BOOST_CHECK( boost::dynamic_pointer_cast<ctk::TestDecoratorRegisterAccessor<T>>(hloutput) == nullptr ); BOOST_CHECK( boost::dynamic_pointer_cast<ctk::TestDecoratorRegisterAccessor<T>>(hloutput) == nullptr );
} }
/*********************************************************************************************************************/
/* simply test the TestDecoratorRegisterAccessor if it is used and if it properly works as a decorator */
BOOST_AUTO_TEST_CASE_TEMPLATE( testDecorator, T, test_types ) {
std::cout << "*********************************************************************************************************************" << std::endl;
std::cout << "==> testDecorator<" << typeid(T).name() << ">" << std::endl;
TestApplication<T> app;
app.noLoopTestModule.someOutput >> app.noLoopTestModule.someInput;
app.blockingReadTestModule.someOutput >> app.blockingReadTestModule.someInput; // just to avoid runtime warning
app.asyncReadTestModule.someOutput >> app.asyncReadTestModule.someInput; // just to avoid runtime warning
app.noLoopTestModule.outputs >= app.readAnyTestModule.inputs; // just to avoid runtime warning
app.readAnyTestModule.value >> ctk::VariableNetworkNode::makeConstant<T>(false, 0, 1); // just to avoid runtime warning
app.readAnyTestModule.index >> app.noLoopTestModule.someUIntInput; // just to avoid runtime warning
app.enableTestableMode();
app.initialise();
app.run();
app.resumeApplication(); // don't take control in this test
// check if we got the decorator for the input
auto hlinput = app.noLoopTestModule.someInput.getHighLevelImplElement();
BOOST_CHECK( boost::dynamic_pointer_cast<ctk::TestDecoratorRegisterAccessor<T>>(hlinput) != nullptr );
// check that we did not get the decorator for the output
auto hloutput = app.noLoopTestModule.someOutput.getHighLevelImplElement();
BOOST_CHECK( boost::dynamic_pointer_cast<ctk::TestDecoratorRegisterAccessor<T>>(hloutput) == nullptr );
// check meta-data
BOOST_CHECK(app.noLoopTestModule.someInput.isReadOnly());
BOOST_CHECK(app.noLoopTestModule.someInput.isReadable());
BOOST_CHECK(!app.noLoopTestModule.someInput.isWriteable());
// test non blocking read
app.noLoopTestModule.someInput = 41;
for(int i=0; i<5; ++i) {
app.noLoopTestModule.someOutput = 42+i;
bool ret = app.noLoopTestModule.someInput.readNonBlocking();
BOOST_CHECK(ret == false);
int val = app.noLoopTestModule.someInput;
BOOST_CHECK(val == 42+i-1);
app.noLoopTestModule.someOutput.write();
ret = app.noLoopTestModule.someInput.readNonBlocking();
BOOST_CHECK(ret == true);
val = app.noLoopTestModule.someInput;
BOOST_CHECK(val == 42+i);
}
bool ret = app.noLoopTestModule.someInput.readNonBlocking();
BOOST_CHECK(ret == false);
// test blocking read
for(int i=0; i<5; ++i) {
auto future = std::async(std::launch::async, [&app] { app.noLoopTestModule.someInput.read(); });
app.noLoopTestModule.someOutput = 120+i;
BOOST_CHECK(future.wait_for(std::chrono::milliseconds(10)) == std::future_status::timeout);
app.noLoopTestModule.someOutput.write();
BOOST_CHECK(future.wait_for(std::chrono::milliseconds(100)) == std::future_status::ready);
int val = app.noLoopTestModule.someInput;
BOOST_CHECK(val == 120+i);
}
}
/*********************************************************************************************************************/ /*********************************************************************************************************************/
/* test blocking read in test mode */ /* test blocking read in test mode */
...@@ -277,25 +193,25 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( testBlockingRead, T, test_types ) { ...@@ -277,25 +193,25 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( testBlockingRead, T, test_types ) {
TestApplication<T> app; TestApplication<T> app;
app.noLoopTestModule.someOutput >> app.blockingReadTestModule.someInput; app.cs("input") >> app.blockingReadTestModule.someInput;
app.blockingReadTestModule.someOutput >> app.noLoopTestModule.someInput; app.blockingReadTestModule.someOutput >> app.cs("output");
app.asyncReadTestModule.someOutput >> app.asyncReadTestModule.someInput; // just to avoid runtime warning app.asyncReadTestModule >= app.cs["async"]; // avoid runtime warning
app.noLoopTestModule.outputs >= app.readAnyTestModule.inputs; // just to avoid runtime warning app.readAnyTestModule >= app.cs["readAny"]; // avoid runtime warning
app.readAnyTestModule.value >> ctk::VariableNetworkNode::makeConstant<T>(false, 0, 1); // just to avoid runtime warning
app.readAnyTestModule.index >> app.noLoopTestModule.someUIntInput; // just to avoid runtime warning ctk::TestFacility test;
app.enableTestableMode(); auto pvInput = test.getScalar<T>("input");
app.initialise(); auto pvOutput = test.getScalar<T>("output");
app.run(); test.runApplication();
// test blocking read when taking control in the test thread // test blocking read when taking control in the test thread (note: the blocking read is executed in the app module!)
for(int i=0; i<5; ++i) { for(int i=0; i<5; ++i) {
app.noLoopTestModule.someOutput = 120+i; pvInput = 120+i;
app.noLoopTestModule.someOutput.write(); pvInput.write();
usleep(10000); usleep(10000);
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == false); BOOST_CHECK(pvOutput.readNonBlocking() == false);
app.stepApplication(); test.stepApplication();
CHECK_TIMEOUT(app.noLoopTestModule.someInput.readNonBlocking() == true, 200); CHECK_TIMEOUT(pvOutput.readNonBlocking() == true, 200);
int val = app.noLoopTestModule.someInput; int val = pvOutput;
BOOST_CHECK(val == 120+i); BOOST_CHECK(val == 120+i);
} }
...@@ -310,25 +226,31 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( testAsyncRead, T, test_types ) { ...@@ -310,25 +226,31 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( testAsyncRead, T, test_types ) {
TestApplication<T> app; TestApplication<T> app;
app.noLoopTestModule.someOutput >> app.asyncReadTestModule.someInput; app.cs("input") >> app.asyncReadTestModule.someInput;
app.asyncReadTestModule.someOutput >> app.noLoopTestModule.someInput; app.asyncReadTestModule.someOutput >> app.cs("output");
app.blockingReadTestModule.someOutput >> app.blockingReadTestModule.someInput; // just to avoid runtime warning app.blockingReadTestModule >= app.cs["blocking"]; // avoid runtime warning
app.noLoopTestModule.outputs >= app.readAnyTestModule.inputs; // just to avoid runtime warning app.readAnyTestModule >= app.cs["readAny"]; // avoid runtime warning
app.readAnyTestModule.value >> ctk::VariableNetworkNode::makeConstant<T>(false, 0, 1); // just to avoid runtime warning
app.readAnyTestModule.index >> app.noLoopTestModule.someUIntInput; // just to avoid runtime warning ctk::TestFacility test;
app.enableTestableMode();
app.initialise(); auto pvInput = test.getScalar<T>("input");
app.run(); auto pvOutput = test.getScalar<T>("output");
test.runApplication();
// test blocking read when taking control in the test thread // test blocking read when taking control in the test thread
for(int i=0; i<5; ++i) { for(int i=0; i<5; ++i) {
app.noLoopTestModule.someOutput = 120+i; pvInput = 120+i;
app.noLoopTestModule.someOutput.write(); pvInput.write();
usleep(10000); usleep(10000);
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == false); BOOST_CHECK(pvOutput.readNonBlocking() == false);
app.stepApplication(); test.stepApplication();
CHECK_TIMEOUT(app.noLoopTestModule.someInput.readNonBlocking() == true, 200); bool ret = pvOutput.readNonBlocking();
int val = app.noLoopTestModule.someInput; BOOST_CHECK(ret == true);
if(!ret) {
CHECK_TIMEOUT(pvOutput.readNonBlocking() == true, 10000);
}
int val = pvOutput;
BOOST_CHECK(val == 120+i); BOOST_CHECK(val == 120+i);
} }
...@@ -343,122 +265,135 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( testReadAny, T, test_types ) { ...@@ -343,122 +265,135 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( testReadAny, T, test_types ) {
TestApplication<T> app; TestApplication<T> app;
app.noLoopTestModule.someOutput >> app.asyncReadTestModule.someInput; // just to avoid runtime warning app.readAnyTestModule.inputs >= app.cs["input"];
app.asyncReadTestModule.someOutput >> ctk::VariableNetworkNode::makeConstant<T>(false, 0, 1); // just to avoid runtime warning app.readAnyTestModule.value >> app.cs("value");
app.blockingReadTestModule.someOutput >> app.blockingReadTestModule.someInput; // just to avoid runtime warning app.readAnyTestModule.index >> app.cs("index");
app.noLoopTestModule.outputs >= app.readAnyTestModule.inputs; app.blockingReadTestModule >= app.cs["blocking"]; // avoid runtime warning
app.readAnyTestModule.value >> app.noLoopTestModule.someInput; app.asyncReadTestModule >= app.cs["async"]; // avoid runtime warning
app.readAnyTestModule.index >> app.noLoopTestModule.someUIntInput;
app.enableTestableMode(); ctk::TestFacility test;
app.initialise(); auto value = test.getScalar<T>("value");
app.run(); auto index = test.getScalar<uint32_t>("index");
auto v1 = test.getScalar<T>("input/v1");
auto v2 = test.getScalar<T>("input/v2");
auto v3 = test.getScalar<T>("input/v3");
auto v4 = test.getScalar<T>("input/v4");
test.runApplication();
// check that we don't receive anything yet // check that we don't receive anything yet
usleep(10000); usleep(10000);
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == false); BOOST_CHECK(value.readNonBlocking() == false);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == false); BOOST_CHECK(index.readNonBlocking() == false);
// send something to v4 // send something to v4
app.noLoopTestModule.outputs.v4 = 66; v4 = 66;
app.noLoopTestModule.outputs.v4.write(); v4.write();
// check that we still don't receive anything yet // check that we still don't receive anything yet
usleep(10000); usleep(10000);
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == false); BOOST_CHECK(value.readNonBlocking() == false);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == false); BOOST_CHECK(index.readNonBlocking() == false);
// run the application and check that we got the expected result // run the application and check that we got the expected result
app.stepApplication(); test.stepApplication();
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == true); BOOST_CHECK(value.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == true); BOOST_CHECK(index.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someInput == 66); BOOST_CHECK(value == 66);
BOOST_CHECK(app.noLoopTestModule.someUIntInput == 4); BOOST_CHECK(index == 4);
// send something to v1 // send something to v1
app.noLoopTestModule.outputs.v1 = 33; v1 = 33;
app.noLoopTestModule.outputs.v1.write(); v1.write();
// check that we still don't receive anything yet // check that we still don't receive anything yet
usleep(10000); usleep(10000);
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == false); BOOST_CHECK(value.readNonBlocking() == false);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == false); BOOST_CHECK(index.readNonBlocking() == false);
// run the application and check that we got the expected result // run the application and check that we got the expected result
app.stepApplication(); test.stepApplication();
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == true); BOOST_CHECK(value.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == true); BOOST_CHECK(index.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someInput == 33); BOOST_CHECK(value == 33);
BOOST_CHECK(app.noLoopTestModule.someUIntInput == 1); BOOST_CHECK(index == 1);
// send something to v1 again // send something to v1 again
app.noLoopTestModule.outputs.v1 = 34; v1 = 34;
app.noLoopTestModule.outputs.v1.write(); v1.write();
// check that we still don't receive anything yet // check that we still don't receive anything yet
usleep(10000); usleep(10000);
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == false); BOOST_CHECK(value.readNonBlocking() == false);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == false); BOOST_CHECK(index.readNonBlocking() == false);
// run the application and check that we got the expected result // run the application and check that we got the expected result
app.stepApplication(); test.stepApplication();
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == true); BOOST_CHECK(value.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someInput == 34); BOOST_CHECK(index.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someUIntInput == 1); BOOST_CHECK(value == 34);
BOOST_CHECK(index == 1);
// send something to v3 // send something to v3
app.noLoopTestModule.outputs.v3 = 40; v3 = 40;
app.noLoopTestModule.outputs.v3.write(); v3.write();
// check that we still don't receive anything yet // check that we still don't receive anything yet
usleep(10000); usleep(10000);
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == false); BOOST_CHECK(value.readNonBlocking() == false);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == false); BOOST_CHECK(index.readNonBlocking() == false);
// run the application and check that we got the expected result // run the application and check that we got the expected result
app.stepApplication(); test.stepApplication();
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == true); BOOST_CHECK(value.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == true); BOOST_CHECK(index.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someInput == 40); BOOST_CHECK(value == 40);
BOOST_CHECK(app.noLoopTestModule.someUIntInput == 3); BOOST_CHECK(index == 3);
// send something to v2 // send something to v2
app.noLoopTestModule.outputs.v2 = 50; v2 = 50;
app.noLoopTestModule.outputs.v2.write(); v2.write();
// check that we still don't receive anything yet // check that we still don't receive anything yet
usleep(10000); usleep(10000);
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == false); BOOST_CHECK(value.readNonBlocking() == false);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == false); BOOST_CHECK(index.readNonBlocking() == false);
// run the application and check that we got the expected result // run the application and check that we got the expected result
app.stepApplication(); test.stepApplication();
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == true); BOOST_CHECK(value.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == true); BOOST_CHECK(index.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someInput == 50); BOOST_CHECK(value == 50);
BOOST_CHECK(app.noLoopTestModule.someUIntInput == 2); BOOST_CHECK(index == 2);
// check that stepApplication() throws an exception if no input data is available
try {
test.stepApplication();
BOOST_ERROR("IllegalParameter exception expected.");
}
catch(ctk::ApplicationExceptionWithID<ctk::ApplicationExceptionID::illegalParameter>) {
}
// check that we still don't receive anything anymore
usleep(10000);
BOOST_CHECK(value.readNonBlocking() == false);
BOOST_CHECK(index.readNonBlocking() == false);
// send something to v1 a 3rd time // send something to v1 a 3rd time
app.noLoopTestModule.outputs.v1 = 35; v1 = 35;
app.noLoopTestModule.outputs.v1.write(); v1.write();
// check that we still don't receive anything yet // check that we still don't receive anything yet
usleep(10000); usleep(10000);
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == false); BOOST_CHECK(value.readNonBlocking() == false);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == false); BOOST_CHECK(index.readNonBlocking() == false);
// run the application and check that we got the expected result // run the application and check that we got the expected result
app.stepApplication(); test.stepApplication();
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == true); BOOST_CHECK(value.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == true); BOOST_CHECK(index.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someInput == 35); BOOST_CHECK(value == 35);
BOOST_CHECK(app.noLoopTestModule.someUIntInput == 1); BOOST_CHECK(index == 1);
// check that we still don't receive anything anymore, even if we try running the application again
app.stepApplication();
usleep(10000);
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == false);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == false);
} }
...@@ -472,74 +407,85 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( testChainedModules, T, test_types ) { ...@@ -472,74 +407,85 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( testChainedModules, T, test_types ) {
TestApplication<T> app; TestApplication<T> app;
// put everything we got into one chain // put everything we got into one chain
app.noLoopTestModule.outputs >= app.readAnyTestModule.inputs; app.readAnyTestModule.inputs >= app.cs["input"];
app.readAnyTestModule.value >> app.blockingReadTestModule.someInput; app.readAnyTestModule.value >> app.blockingReadTestModule.someInput;
app.blockingReadTestModule.someOutput >> app.asyncReadTestModule.someInput; app.blockingReadTestModule.someOutput >> app.asyncReadTestModule.someInput;
app.asyncReadTestModule.someOutput >> app.noLoopTestModule.someInput; app.asyncReadTestModule.someOutput >> app.cs("value");
app.readAnyTestModule.index >> app.noLoopTestModule.someUIntInput; app.readAnyTestModule.index >> app.cs("index");
app.noLoopTestModule.someOutput >> ctk::VariableNetworkNode::makeConstant<T>(false, 0, 1); // just to avoid runtime warning
ctk::TestFacility test;
app.enableTestableMode(); auto value = test.getScalar<T>("value");
app.initialise(); auto index = test.getScalar<uint32_t>("index");
app.run(); auto v1 = test.getScalar<T>("input/v1");
auto v2 = test.getScalar<T>("input/v2");
auto v3 = test.getScalar<T>("input/v3");
auto v4 = test.getScalar<T>("input/v4");
test.runApplication();
// check that we don't receive anything yet // check that we don't receive anything yet
usleep(10000); usleep(10000);
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == false); BOOST_CHECK(value.readNonBlocking() == false);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == false); BOOST_CHECK(index.readNonBlocking() == false);
// send something to v2 // send something to v2
app.noLoopTestModule.outputs.v2 = 11; v2 = 11;
app.noLoopTestModule.outputs.v2.write(); v2.write();
// check that we still don't receive anything yet // check that we still don't receive anything yet
usleep(10000); usleep(10000);
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == false); BOOST_CHECK(value.readNonBlocking() == false);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == false); BOOST_CHECK(index.readNonBlocking() == false);
// run the application and check that we got the expected result // run the application and check that we got the expected result
app.stepApplication(); app.stepApplication();
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == true); BOOST_CHECK(value.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == true); BOOST_CHECK(index.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someInput == 11); BOOST_CHECK(value == 11);
BOOST_CHECK(app.noLoopTestModule.someUIntInput == 2); BOOST_CHECK(index == 2);
// send something to v3 // send something to v3
app.noLoopTestModule.outputs.v3 = 12; v3 = 12;
app.noLoopTestModule.outputs.v3.write(); v3.write();
// check that we still don't receive anything yet // check that we still don't receive anything yet
usleep(10000); usleep(10000);
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == false); BOOST_CHECK(value.readNonBlocking() == false);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == false); BOOST_CHECK(index.readNonBlocking() == false);
// run the application and check that we got the expected result // run the application and check that we got the expected result
app.stepApplication(); app.stepApplication();
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == true); BOOST_CHECK(value.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == true); BOOST_CHECK(index.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someInput == 12); BOOST_CHECK(value == 12);
BOOST_CHECK(app.noLoopTestModule.someUIntInput == 3); BOOST_CHECK(index == 3);
// send something to v3 again // send something to v3 again
app.noLoopTestModule.outputs.v3 = 13; v3 = 13;
app.noLoopTestModule.outputs.v3.write(); v3.write();
// check that we still don't receive anything yet // check that we still don't receive anything yet
usleep(10000); usleep(10000);
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == false); BOOST_CHECK(value.readNonBlocking() == false);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == false); BOOST_CHECK(index.readNonBlocking() == false);
// run the application and check that we got the expected result // run the application and check that we got the expected result
app.stepApplication(); app.stepApplication();
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == true); BOOST_CHECK(value.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == true); BOOST_CHECK(index.readNonBlocking() == true);
BOOST_CHECK(app.noLoopTestModule.someInput == 13); BOOST_CHECK(value == 13);
BOOST_CHECK(app.noLoopTestModule.someUIntInput == 3); BOOST_CHECK(index == 3);
// check that stepApplication() throws an exception if no input data is available
try {
test.stepApplication();
BOOST_ERROR("IllegalParameter exception expected.");
}
catch(ctk::ApplicationExceptionWithID<ctk::ApplicationExceptionID::illegalParameter>) {
}
// check that we still don't receive anything anymore, even if we try running the application again // check that we still don't receive anything anymore
app.stepApplication();
usleep(10000); usleep(10000);
BOOST_CHECK(app.noLoopTestModule.someInput.readNonBlocking() == false); BOOST_CHECK(value.readNonBlocking() == false);
BOOST_CHECK(app.noLoopTestModule.someUIntInput.readNonBlocking() == false); BOOST_CHECK(index.readNonBlocking() == false);
} }
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