Newer
Older
/*
* testModules.cc - Test ApplicationModule, ModuleGroup and VariableGroup
*
* Created on: Sep 27, 2017
* Author: Martin Hierholzer
*/
#include <future>
#include <chrono>
#define BOOST_TEST_MODULE testModules
#include <boost/test/included/unit_test.hpp>
#include <boost/test/test_case_template.hpp>
Martin Christoph Hierholzer
committed
using namespace boost::unit_test_framework;
#include <boost/mpl/list.hpp>
#include "ApplicationCore.h"
namespace ctk = ChimeraTK;
/*********************************************************************************************************************/
/* Variable group used in the modules */
struct SomeGroup : ctk::VariableGroup {
using ctk::VariableGroup::VariableGroup;
ctk::ScalarPushInput<std::string> inGroup{this, "inGroup", "", "This is a string", {"C", "A"}};
ctk::ArrayPushInput<int64_t> alsoInGroup{this, "alsoInGroup", "justANumber", 16, "A 64 bit number array", {"A", "D"}};
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
};
/*********************************************************************************************************************/
/* A plain application module for testing */
struct TestModule : public ctk::ApplicationModule {
using ctk::ApplicationModule::ApplicationModule;
ctk::ScalarPushInput<int> someInput{this, "nameOfSomeInput", "cm", "This is just some input for testing", {"A", "B"}};
ctk::ScalarOutput<double> someOutput{this, "someOutput", "V", "Description", {"A", "C"}};
SomeGroup someGroup{this, "someGroup", "Description of my test group"};
struct AnotherGroup : ctk::VariableGroup {
using ctk::VariableGroup::VariableGroup;
ctk::ScalarPushInput<uint8_t> foo{this, "foo", "counts", "Some counter", {"D"}};
} anotherGroup{this, "anotherName", "Description of my other group"};
void mainLoop() {
while(true) {
someInput.read();
int val = someInput;
someOutput = val;
someOutput.write();
}
}
};
/*********************************************************************************************************************/
/* Simple application with just one module */
struct OneModuleApp : public ctk::Application {
OneModuleApp() : Application("myApp") {}
~OneModuleApp() { shutdown(); }
using Application::makeConnections; // we call makeConnections() manually in the tests to catch exceptions etc.
void defineConnections() {} // the setup is done in the tests
TestModule testModule{this, "testModule", "Module to test"};
};
/*********************************************************************************************************************/
/* Application with a vector of modules */
struct VectorOfModulesApp : public ctk::Application {
VectorOfModulesApp(size_t nInstances)
: Application("myApp"),
_nInstances(nInstances)
{}
~VectorOfModulesApp() { shutdown(); }
using Application::makeConnections; // we call makeConnections() manually in the tests to catch exceptions etc.
void defineConnections() {
for(size_t i = 0; i < _nInstances; ++i) {
std::string name = "testModule_" + std::to_string(i) + "_instance";
vectorOfTestModule.emplace_back(this, name, "Description");
}
}
size_t _nInstances;
std::vector<TestModule> vectorOfTestModule;
};
/*********************************************************************************************************************/
/* An application module with a vector of a variable group*/
struct VectorModule : public ctk::ApplicationModule {
VectorModule(ctk::EntityOwner *owner, const std::string &name, const std::string &description, size_t nInstances,
bool eliminateHierarchy=false, const std::unordered_set<std::string> &tags={})
: ctk::ApplicationModule(owner, name, description, eliminateHierarchy, tags)
{
for(size_t i=0; i < nInstances; ++i) {
std::string name = "testGroup_" + std::to_string(i);
vectorOfSomeGroup.emplace_back(this, name, "Description 2");
}
}
Martin Christoph Hierholzer
committed
VectorModule() {}
ctk::ScalarPushInput<int> someInput{this, "nameOfSomeInput", "cm", "This is just some input for testing", {"A", "B"}};
Martin Christoph Hierholzer
committed
ctk::ArrayOutput<double> someOutput{this, "someOutput", "V", 1, "Description", {"A", "C"}};
std::vector<SomeGroup> vectorOfSomeGroup;
struct AnotherGroup : ctk::VariableGroup {
using ctk::VariableGroup::VariableGroup;
ctk::ScalarPushInput<uint8_t> foo{this, "foo", "counts", "Some counter", {"D"}};
} anotherGroup{this, "anotherName", "Description of my other group"};
void mainLoop() {
while(true) {
someInput.read();
int val = someInput;
Martin Christoph Hierholzer
committed
someOutput[0] = val;
someOutput.write();
}
}
};
/*********************************************************************************************************************/
/* An module group with a vector of a application moduoles */
struct VectorModuleGroup : public ctk::ModuleGroup {
VectorModuleGroup(EntityOwner *owner, const std::string &name, const std::string &description, size_t nInstances,
bool eliminateHierarchy=false, const std::unordered_set<std::string> &tags={})
: ctk::ModuleGroup(owner, name, description, eliminateHierarchy, tags)
{
for(size_t i=0; i < nInstances; ++i) {
std::string name = "test_" + std::to_string(i);
vectorOfVectorModule.emplace_back(this, name, "Description 3", nInstances);
}
}
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
VectorModuleGroup() {}
Martin Christoph Hierholzer
committed
std::vector<VectorModule> vectorOfVectorModule;
Martin Christoph Hierholzer
committed
};
/*********************************************************************************************************************/
/* Application with a vector of module groups containing a vector of modules containing a vector of variable groups */
struct VectorOfEverythingApp : public ctk::Application {
VectorOfEverythingApp(size_t nInstances)
: Application("myApp"),
_nInstances(nInstances)
{}
~VectorOfEverythingApp() { shutdown(); }
using Application::makeConnections; // we call makeConnections() manually in the tests to catch exceptions etc.
void defineConnections() {
for(size_t i = 0; i < _nInstances; ++i) {
std::string name = "testModule_" + std::to_string(i) + "_instance";
vectorOfVectorModuleGroup.emplace_back(this, name, "Description", _nInstances);
}
}
size_t _nInstances;
std::vector<VectorModuleGroup> vectorOfVectorModuleGroup;
};
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
/* Application with various modules that get initialised only during defineConnections(). */
struct AssignModuleLaterApp : public ctk::Application {
AssignModuleLaterApp()
: Application("myApp")
{}
~AssignModuleLaterApp() { shutdown(); }
using Application::makeConnections; // we call makeConnections() manually in the tests to catch exceptions etc.
void defineConnections() {
Martin Christoph Hierholzer
committed
modGroupInstanceToAssignLater = VectorModuleGroup(this, "modGroupInstanceToAssignLater",
"This instance of VectorModuleGroup was assigned using the operator=()", 42);
modInstanceToAssignLater = VectorModule(this, "modInstanceToAssignLater",
"This instance of VectorModule was assigned using the operator=()", 13);
Martin Christoph Hierholzer
committed
}
Martin Christoph Hierholzer
committed
VectorModuleGroup modGroupInstanceToAssignLater;
VectorModule modInstanceToAssignLater;
Martin Christoph Hierholzer
committed
};
/*********************************************************************************************************************/
/* test module and variable ownerships */
BOOST_AUTO_TEST_CASE( test_ownership ) {
std::cout << "*********************************************************************************************************************" << std::endl;
std::cout << "==> test_ownership" << std::endl;
Martin Christoph Hierholzer
committed
OneModuleApp app;
Martin Christoph Hierholzer
committed
BOOST_CHECK( app.testModule.getOwner() == &app );
BOOST_CHECK( app.testModule.someGroup.getOwner() == &(app.testModule) );
BOOST_CHECK( app.testModule.anotherGroup.getOwner() == &(app.testModule) );
Martin Christoph Hierholzer
committed
BOOST_CHECK( app.testModule.someInput.getOwner() == &(app.testModule) );
BOOST_CHECK( app.testModule.someOutput.getOwner() == &(app.testModule) );
Martin Christoph Hierholzer
committed
BOOST_CHECK( app.testModule.someGroup.inGroup.getOwner() == &(app.testModule.someGroup) );
BOOST_CHECK( app.testModule.someGroup.alsoInGroup.getOwner() == &(app.testModule.someGroup) );
Martin Christoph Hierholzer
committed
BOOST_CHECK( app.testModule.anotherGroup.foo.getOwner() == &(app.testModule.anotherGroup) );
}
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
/* test that modules cannot be owned by the wrong types */
BOOST_AUTO_TEST_CASE( test_badHierarchies ) {
std::cout << "*********************************************************************************************************************" << std::endl;
std::cout << "==> test_badHierarchies" << std::endl;
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// ******************************************
// *** Tests for ApplicationModule
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// check app ApplicationModules cannot be owned by other app modules
{
OneModuleApp app;
try {
TestModule willFail(&(app.testModule), "willFail", "");
BOOST_FAIL("Exception expected");
}
catch(ctk::ApplicationExceptionWithID<ctk::ApplicationExceptionID::illegalParameter>&) {
}
}
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// check app ApplicationModules cannot be owned by variable groups
{
OneModuleApp app;
try {
TestModule willFail(&(app.testModule.someGroup), "willFail", "");
BOOST_FAIL("Exception expected");
}
catch(ctk::ApplicationExceptionWithID<ctk::ApplicationExceptionID::illegalParameter>&) {
}
}
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// check app ApplicationModules cannot be owned by nothing
{
OneModuleApp app;
try {
TestModule willFail(nullptr, "willFail", "");
BOOST_FAIL("Exception expected");
}
catch(ctk::ApplicationExceptionWithID<ctk::ApplicationExceptionID::illegalParameter>&) {
}
}
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// ******************************************
// *** Tests for VariableGroup
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// check app VariableGroup cannot be owned by Applications
{
OneModuleApp app;
try {
SomeGroup willFail(&(app), "willFail", "");
BOOST_FAIL("Exception expected");
}
catch(ctk::ApplicationExceptionWithID<ctk::ApplicationExceptionID::illegalParameter>&) {
}
}
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// check app VariableGroup cannot be owned by ModuleGroups
{
VectorOfEverythingApp app(1);
app.defineConnections();
try {
SomeGroup willFail(&(app.vectorOfVectorModuleGroup[0]), "willFail", "");
BOOST_FAIL("Exception expected");
}
catch(ctk::ApplicationExceptionWithID<ctk::ApplicationExceptionID::illegalParameter>&) {
}
}
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// check app VariableGroup cannot be owned by nothing
{
OneModuleApp app;
try {
SomeGroup willFail(nullptr, "willFail", "");
BOOST_FAIL("Exception expected");
}
catch(ctk::ApplicationExceptionWithID<ctk::ApplicationExceptionID::illegalParameter>&) {
}
}
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// ******************************************
// *** Tests for ModuleGroup
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// check app ModuleGroups cannot be owned by ApplicationModules
{
OneModuleApp app;
try {
VectorModuleGroup willFail(&(app.testModule), "willFail", "", 1);
BOOST_FAIL("Exception expected");
}
catch(ctk::ApplicationExceptionWithID<ctk::ApplicationExceptionID::illegalParameter>&) {
}
}
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// check app ModuleGroups cannot be owned by VariableGroups
{
OneModuleApp app;
try {
VectorModuleGroup willFail(&(app.testModule.someGroup), "willFail", "", 1);
BOOST_FAIL("Exception expected");
}
catch(ctk::ApplicationExceptionWithID<ctk::ApplicationExceptionID::illegalParameter>&) {
}
}
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// check app ModuleGroups cannot be owned by nothing
{
OneModuleApp app;
try {
VectorModuleGroup willFail(nullptr, "willFail", "", 1);
BOOST_FAIL("Exception expected");
}
catch(ctk::ApplicationExceptionWithID<ctk::ApplicationExceptionID::illegalParameter>&) {
}
}
}
/*********************************************************************************************************************/
/* test that modules can be owned by the right types */
BOOST_AUTO_TEST_CASE( test_allowedHierarchies ) {
std::cout << "*********************************************************************************************************************" << std::endl;
std::cout << "==> test_allowedHierarchies" << std::endl;
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// ******************************************
// *** Tests for ApplicationModule
// check ApplicationModules can be owned by Applications
{
OneModuleApp app;
TestModule shouldNotFail(&(app), "shouldNotFail", "");
}
// check ApplicationModules can be owned by ModuleGroups
{
VectorOfEverythingApp app(1);
app.defineConnections();
TestModule shouldNotFail(&(app.vectorOfVectorModuleGroup[0]), "shouldNotFail", "");
}
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// ******************************************
// *** Tests for VariableGroup
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// check VariableGroup can be owned by ApplicationModules
{
OneModuleApp app;
SomeGroup shouldNotFail(&(app.testModule), "shouldNotFail", "");
}
// check VariableGroup can be owned by VariableGroup
{
OneModuleApp app;
SomeGroup shouldNotFail(&(app.testModule.someGroup), "shouldNotFail", "");
}
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// ******************************************
// *** Tests for ModuleGroup
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// check ModuleGroup can be owned by Applications
{
OneModuleApp app;
VectorModuleGroup shouldNotFail(&(app), "shouldNotFail", "", 1);
}
// check ModuleGroup can be owned by ModuleGroups
{
VectorOfEverythingApp app(1);
app.defineConnections();
VectorModuleGroup shouldNotFail(&(app.vectorOfVectorModuleGroup[0]), "shouldNotFail", "", 1);
}
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
}
/*********************************************************************************************************************/
/* test getSubmoduleList() and getSubmoduleListRecursive() */
BOOST_AUTO_TEST_CASE( test_getSubmoduleList ) {
std::cout << "*********************************************************************************************************************" << std::endl;
std::cout << "==> test_getSubmoduleList" << std::endl;
OneModuleApp app;
{
std::list<ctk::Module*> list = app.getSubmoduleList();
BOOST_CHECK( list.size() == 1 );
BOOST_CHECK( list.front() == &(app.testModule) );
}
Martin Christoph Hierholzer
committed
{
std::list<ctk::Module*> list = app.testModule.getSubmoduleList();
BOOST_CHECK( list.size() == 2 );
size_t foundSomeGroup = 0;
size_t foundAnotherGroup = 0;
for(auto mod : list) {
if(mod == &(app.testModule.someGroup)) foundSomeGroup++;
if(mod == &(app.testModule.anotherGroup)) foundAnotherGroup++;
}
BOOST_CHECK( foundSomeGroup == 1 );
BOOST_CHECK( foundAnotherGroup == 1 );
}
Martin Christoph Hierholzer
committed
{
std::list<ctk::Module*> list = app.getSubmoduleListRecursive();
BOOST_CHECK( list.size() == 3 );
size_t foundTestModule = 0;
size_t foundSomeGroup = 0;
size_t foundAnotherGroup = 0;
for(auto mod : list) {
if(mod == &(app.testModule)) foundTestModule++;
if(mod == &(app.testModule.someGroup)) foundSomeGroup++;
if(mod == &(app.testModule.anotherGroup)) foundAnotherGroup++;
}
BOOST_CHECK( foundTestModule == 1 );
BOOST_CHECK( foundSomeGroup == 1 );
BOOST_CHECK( foundAnotherGroup == 1 );
}
Martin Christoph Hierholzer
committed
{
std::list<ctk::Module*> list = app.testModule.getSubmoduleListRecursive(); // identical to getSubmoduleList(), since no deeper hierarchies
BOOST_CHECK( list.size() == 2 );
size_t foundSomeGroup = 0;
size_t foundAnotherGroup = 0;
for(auto mod : list) {
if(mod == &(app.testModule.someGroup)) foundSomeGroup++;
if(mod == &(app.testModule.anotherGroup)) foundAnotherGroup++;
}
BOOST_CHECK( foundSomeGroup == 1 );
BOOST_CHECK( foundAnotherGroup == 1 );
}
}
/*********************************************************************************************************************/
/* test getAccessorList() and getAccessorListRecursive() */
BOOST_AUTO_TEST_CASE( test_getAccessorList ) {
std::cout << "*********************************************************************************************************************" << std::endl;
std::cout << "==> test_getAccessorList" << std::endl;
OneModuleApp app;
{
std::list<ctk::VariableNetworkNode> &list = app.testModule.getAccessorList();
BOOST_CHECK( list.size() == 2 );
size_t foundSomeInput = 0;
size_t foundSomeOutput = 0;
for(auto var : list) {
if(var == app.testModule.someInput) foundSomeInput++;
if(var == app.testModule.someOutput) foundSomeOutput++;
}
BOOST_CHECK( foundSomeInput == 1 );
BOOST_CHECK( foundSomeOutput == 1 );
}
Martin Christoph Hierholzer
committed
{
const SomeGroup &someGroup(app.testModule.someGroup);
const std::list<ctk::VariableNetworkNode> &list = someGroup.getAccessorList();
BOOST_CHECK( list.size() == 2 );
size_t foundInGroup = 0;
size_t foundAlsoInGroup = 0;
for(auto var : list) {
if(var == app.testModule.someGroup.inGroup) foundInGroup++;
if(var == app.testModule.someGroup.alsoInGroup) foundAlsoInGroup++;
}
BOOST_CHECK( foundInGroup == 1 );
BOOST_CHECK( foundAlsoInGroup == 1 );
}
Martin Christoph Hierholzer
committed
{
std::list<ctk::VariableNetworkNode> list = app.getAccessorListRecursive();
BOOST_CHECK( list.size() == 5 );
size_t foundSomeInput = 0;
size_t foundSomeOutput = 0;
size_t foundInGroup = 0;
size_t foundAlsoInGroup = 0;
size_t foundFoo = 0;
for(auto var : list) {
if(var == app.testModule.someInput) foundSomeInput++;
if(var == app.testModule.someOutput) foundSomeOutput++;
if(var == app.testModule.someGroup.inGroup) foundInGroup++;
if(var == app.testModule.someGroup.alsoInGroup) foundAlsoInGroup++;
if(var == app.testModule.anotherGroup.foo) foundFoo++;
}
BOOST_CHECK( foundSomeInput == 1 );
BOOST_CHECK( foundSomeOutput == 1 );
BOOST_CHECK( foundInGroup == 1 );
BOOST_CHECK( foundAlsoInGroup == 1 );
BOOST_CHECK( foundFoo == 1 );
}
Martin Christoph Hierholzer
committed
{
std::list<ctk::VariableNetworkNode> list = app.testModule.getAccessorListRecursive();
BOOST_CHECK( list.size() == 5 );
size_t foundSomeInput = 0;
size_t foundSomeOutput = 0;
size_t foundInGroup = 0;
size_t foundAlsoInGroup = 0;
size_t foundFoo = 0;
for(auto var : list) {
if(var == app.testModule.someInput) foundSomeInput++;
if(var == app.testModule.someOutput) foundSomeOutput++;
if(var == app.testModule.someGroup.inGroup) foundInGroup++;
if(var == app.testModule.someGroup.alsoInGroup) foundAlsoInGroup++;
if(var == app.testModule.anotherGroup.foo) foundFoo++;
}
BOOST_CHECK( foundSomeInput == 1 );
BOOST_CHECK( foundSomeOutput == 1 );
BOOST_CHECK( foundInGroup == 1 );
BOOST_CHECK( foundAlsoInGroup == 1 );
BOOST_CHECK( foundFoo == 1 );
}
Martin Christoph Hierholzer
committed
{
std::list<ctk::VariableNetworkNode> list = app.testModule.anotherGroup.getAccessorListRecursive();
BOOST_CHECK( list.size() == 1 );
size_t foundFoo = 0;
for(auto var : list) {
if(var == app.testModule.anotherGroup.foo) foundFoo++;
}
BOOST_CHECK( foundFoo == 1 );
}
Martin Christoph Hierholzer
committed
/*********************************************************************************************************************/
/* test function call operator of the ApplicationModule */
BOOST_AUTO_TEST_CASE( testApplicationModuleFnCallOp ) {
std::cout << "*********************************************************************************************************************" << std::endl;
std::cout << "==> testApplicationModuleFnCallOp" << std::endl;
OneModuleApp app;
BOOST_CHECK( app.testModule("nameOfSomeInput") == static_cast<ctk::VariableNetworkNode>(app.testModule.someInput) );
BOOST_CHECK( app.testModule("nameOfSomeInput") != static_cast<ctk::VariableNetworkNode>(app.testModule.someOutput) );
BOOST_CHECK( app.testModule("someOutput") == static_cast<ctk::VariableNetworkNode>(app.testModule.someOutput) );
Martin Christoph Hierholzer
committed
BOOST_CHECK( app.testModule("nameOfSomeInput").getType() == ctk::NodeType::Application );
BOOST_CHECK( app.testModule("nameOfSomeInput").getMode() == ctk::UpdateMode::push );
BOOST_CHECK( app.testModule("nameOfSomeInput").getDirection() == ctk::VariableDirection::consuming );
BOOST_CHECK( app.testModule("nameOfSomeInput").getValueType() == typeid(int) );
BOOST_CHECK( app.testModule("nameOfSomeInput").getName() == "nameOfSomeInput" );
BOOST_CHECK( app.testModule("nameOfSomeInput").getQualifiedName() == "/myApp/testModule/nameOfSomeInput" );
BOOST_CHECK( app.testModule("nameOfSomeInput").getUnit() == "cm" );
BOOST_CHECK( app.testModule("nameOfSomeInput").getDescription() == "This is just some input for testing" );
BOOST_CHECK( app.testModule("nameOfSomeInput").getTags() == std::unordered_set<std::string>({"A", "B"}) );
Martin Christoph Hierholzer
committed
Martin Christoph Hierholzer
committed
// check exception if variable not found
try {
app.testModule("notExisting");
BOOST_FAIL("Exception expected");
}
catch(std::logic_error&){
}
}
/*********************************************************************************************************************/
/* test function call operator of the ApplicationModule */
BOOST_AUTO_TEST_CASE( testApplicationModuleSubscriptOp ) {
std::cout << "*********************************************************************************************************************" << std::endl;
std::cout << "==> testApplicationModuleSubscriptOp" << std::endl;
OneModuleApp app;
Martin Christoph Hierholzer
committed
BOOST_CHECK( app.testModule["someGroup"].getName() == "someGroup" );
BOOST_CHECK( app.testModule["anotherName"].getName() == "anotherName" );
BOOST_CHECK( app.testModule["someGroup"]("inGroup") == app.testModule.someGroup.inGroup );
BOOST_CHECK( app.testModule["someGroup"]("alsoInGroup") == app.testModule.someGroup.alsoInGroup );
BOOST_CHECK( app.testModule["anotherName"]("foo") == app.testModule.anotherGroup.foo );
Martin Christoph Hierholzer
committed
// check exception if group not found
try {
app.testModule["notExisting"];
BOOST_FAIL("Exception expected");
}
catch(std::logic_error&){
}
}
/*********************************************************************************************************************/
/* test finding variables by tag */
BOOST_AUTO_TEST_CASE( testFindTags ) {
std::cout << "*********************************************************************************************************************" << std::endl;
std::cout << "==> testFindTags" << std::endl;
OneModuleApp app;
Martin Christoph Hierholzer
committed
// search for tag "A"
{
ctk::VirtualModule tagA = app.testModule.findTag("A");
Martin Christoph Hierholzer
committed
// check direct variables
{
std::list<ctk::VariableNetworkNode> &list = tagA.getAccessorList();
BOOST_CHECK( list.size() == 2 );
size_t foundSomeInput = 0;
size_t foundSomeOutput = 0;
for(auto var : list) {
if(var == app.testModule.someInput) foundSomeInput++;
if(var == app.testModule.someOutput) foundSomeOutput++;
}
BOOST_CHECK( foundSomeInput == 1 );
BOOST_CHECK( foundSomeOutput == 1 );
}
Martin Christoph Hierholzer
committed
// check number of submodules
{
std::list<ctk::Module*> list = tagA.getSubmoduleList();
BOOST_CHECK( list.size() == 1 );
}
Martin Christoph Hierholzer
committed
// check content of submodule
{
std::list<ctk::VariableNetworkNode> list = tagA["someGroup"].getAccessorList();
BOOST_CHECK( list.size() == 2 );
size_t foundInGroup = 0;
size_t foundAlsoInGroup = 0;
for(auto var : list) {
if(var == app.testModule.someGroup.inGroup) foundInGroup++;
if(var == app.testModule.someGroup.alsoInGroup) foundAlsoInGroup++;
}
BOOST_CHECK( foundInGroup == 1 );
BOOST_CHECK( foundAlsoInGroup == 1 );
}
Martin Christoph Hierholzer
committed
}
// search for tag "D"
{
ctk::VirtualModule tagD = app.testModule.findTag("D");
Martin Christoph Hierholzer
committed
// check direct variables
{
std::list<ctk::VariableNetworkNode> &list = tagD.getAccessorList();
BOOST_CHECK( list.size() == 0 );
}
Martin Christoph Hierholzer
committed
// check number of submodules
{
std::list<ctk::Module*> list = tagD.getSubmoduleList();
BOOST_CHECK( list.size() == 2 );
}
Martin Christoph Hierholzer
committed
// check content of submodule "someGroup"
{
std::list<ctk::VariableNetworkNode> list = tagD["someGroup"].getAccessorList();
BOOST_CHECK( list.size() == 1 );
size_t foundAlsoInGroup = 0;
for(auto var : list) {
if(var == app.testModule.someGroup.alsoInGroup) foundAlsoInGroup++;
}
BOOST_CHECK( foundAlsoInGroup == 1 );
}
Martin Christoph Hierholzer
committed
// check content of submodule "anotherName"
{
std::list<ctk::VariableNetworkNode> list = tagD["anotherName"].getAccessorList();
BOOST_CHECK( list.size() == 1 );
size_t foundFoo = 0;
for(auto var : list) {
if(var == app.testModule.anotherGroup.foo) foundFoo++;
}
BOOST_CHECK( foundFoo == 1 );
}
Martin Christoph Hierholzer
committed
}
// search for tag "D", exclude tag "A"
{
ctk::VirtualModule tagDnotA = app.testModule.findTag("D").excludeTag("A");
Martin Christoph Hierholzer
committed
// check direct variables
{
std::list<ctk::VariableNetworkNode> &list = tagDnotA.getAccessorList();
BOOST_CHECK( list.size() == 0 );
}
Martin Christoph Hierholzer
committed
// check number of submodules
{
std::list<ctk::Module*> list = tagDnotA.getSubmoduleList();
BOOST_CHECK( list.size() == 1 );
}
Martin Christoph Hierholzer
committed
// check content of submodule "anotherName"
{
std::list<ctk::VariableNetworkNode> list = tagDnotA["anotherName"].getAccessorList();
BOOST_CHECK( list.size() == 1 );
size_t foundFoo = 0;
for(auto var : list) {
if(var == app.testModule.anotherGroup.foo) foundFoo++;
}
BOOST_CHECK( foundFoo == 1 );
}
Martin Christoph Hierholzer
committed
}
/*********************************************************************************************************************/
/* test flatten() */
BOOST_AUTO_TEST_CASE( testFlatten ) {
std::cout << "*********************************************************************************************************************" << std::endl;
std::cout << "==> testFlatten" << std::endl;
OneModuleApp app;
Martin Christoph Hierholzer
committed
ctk::VirtualModule flattened = app.testModule.flatten();
// check number of submodules
{
std::list<ctk::Module*> list = flattened.getSubmoduleList();
BOOST_CHECK( list.size() == 0 );
}
Martin Christoph Hierholzer
committed
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
// check direct variables
{
std::list<ctk::VariableNetworkNode> &list = flattened.getAccessorList();
BOOST_CHECK( list.size() == 5 );
size_t foundSomeInput = 0;
size_t foundSomeOutput = 0;
size_t foundInGroup = 0;
size_t foundAlsoInGroup = 0;
size_t foundFoo = 0;
for(auto var : list) {
if(var == app.testModule.someInput) foundSomeInput++;
if(var == app.testModule.someOutput) foundSomeOutput++;
if(var == app.testModule.someGroup.inGroup) foundInGroup++;
if(var == app.testModule.someGroup.alsoInGroup) foundAlsoInGroup++;
if(var == app.testModule.anotherGroup.foo) foundFoo++;
}
BOOST_CHECK( foundSomeInput == 1 );
BOOST_CHECK( foundSomeOutput == 1 );
BOOST_CHECK( foundInGroup == 1 );
BOOST_CHECK( foundAlsoInGroup == 1 );
BOOST_CHECK( foundFoo == 1 );
}
}
/*********************************************************************************************************************/
/* test addTag() */
BOOST_AUTO_TEST_CASE( testAddTag ) {
std::cout << "*********************************************************************************************************************" << std::endl;
std::cout << "==> testAddTag" << std::endl;
OneModuleApp app;
app.testModule.addTag("newTag");
Martin Christoph Hierholzer
committed
ctk::VirtualModule withNewTag = app.findTag("newTag");
// check submodule hierarchy
{
BOOST_CHECK( withNewTag.getSubmoduleList().size() == 1 );
BOOST_CHECK( withNewTag.getAccessorList().size() == 0 );
BOOST_CHECK( withNewTag["testModule"].getSubmoduleList().size() == 2 );
BOOST_CHECK( withNewTag["testModule"].getAccessorList().size() == 2 );
BOOST_CHECK( withNewTag["testModule"]["someGroup"].getSubmoduleList().size() == 0 );
BOOST_CHECK( withNewTag["testModule"]["someGroup"].getAccessorList().size() == 2 );
BOOST_CHECK( withNewTag["testModule"]["anotherName"].getSubmoduleList().size() == 0 );
BOOST_CHECK( withNewTag["testModule"]["anotherName"].getAccessorList().size() == 1 );
}
Martin Christoph Hierholzer
committed
// check all variables
{
std::list<ctk::VariableNetworkNode> list = withNewTag.getAccessorListRecursive();
BOOST_CHECK( list.size() == 5 );
size_t foundSomeInput = 0;
size_t foundSomeOutput = 0;
size_t foundInGroup = 0;
size_t foundAlsoInGroup = 0;
size_t foundFoo = 0;
for(auto var : list) {
if(var == app.testModule.someInput) foundSomeInput++;
if(var == app.testModule.someOutput) foundSomeOutput++;
if(var == app.testModule.someGroup.inGroup) foundInGroup++;
if(var == app.testModule.someGroup.alsoInGroup) foundAlsoInGroup++;
if(var == app.testModule.anotherGroup.foo) foundFoo++;
}
BOOST_CHECK( foundSomeInput == 1 );
BOOST_CHECK( foundSomeOutput == 1 );
BOOST_CHECK( foundInGroup == 1 );
BOOST_CHECK( foundAlsoInGroup == 1 );
BOOST_CHECK( foundFoo == 1 );
}
}
/*********************************************************************************************************************/
/* test correct behaviour when using a std::vector of ApplicationModules */
BOOST_AUTO_TEST_CASE( testVectorOfApplicationModule ) {
std::cout << "*********************************************************************************************************************" << std::endl;
std::cout << "==> testVectorOfApplicationModule" << std::endl;
// create app with a vector containing 10 modules
size_t nInstances = 10;
VectorOfModulesApp app(nInstances);
// the app creates the 10 module instances in defineConnections, check if this is done proplery (a quite redundant test...)
BOOST_CHECK(app.vectorOfTestModule.size() == 0);
app.defineConnections();
BOOST_CHECK(app.vectorOfTestModule.size() == nInstances);
// some direct checks on the created instances
for(size_t i=0; i<nInstances; ++i) {
std::string name = "testModule_" + std::to_string(i) + "_instance";
BOOST_CHECK( app.vectorOfTestModule[i].getName() == name );
auto node = static_cast<ctk::VariableNetworkNode>(app.vectorOfTestModule[i].someInput);
BOOST_CHECK( node.getQualifiedName() == "/myApp/"+name+"/nameOfSomeInput" );
// check accessor list
std::list<ctk::VariableNetworkNode> accList = app.vectorOfTestModule[i].getAccessorList();
BOOST_CHECK( accList.size() == 2 );
size_t foundSomeInput = 0;
size_t foundSomeOutput = 0;
for(auto &acc : accList) {
if(acc == app.vectorOfTestModule[i].someInput) foundSomeInput++;
if(acc == app.vectorOfTestModule[i].someOutput) foundSomeOutput++;
}
BOOST_CHECK( foundSomeInput == 1 );
BOOST_CHECK( foundSomeOutput == 1 );
// check submodule list
std::list<ctk::Module*> modList = app.vectorOfTestModule[i].getSubmoduleList();
BOOST_CHECK( modList.size() == 2 );
size_t foundSomeGroup = 0;
size_t foundAnotherGroup = 0;
for(auto mod : modList) {
if(mod == &(app.vectorOfTestModule[i].someGroup)) foundSomeGroup++;
if(mod == &(app.vectorOfTestModule[i].anotherGroup)) foundAnotherGroup++;
}
BOOST_CHECK( foundSomeGroup == 1 );
BOOST_CHECK( foundAnotherGroup == 1 );
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
}
// check if instances appear properly in getSubmoduleList()
{
std::list<ctk::Module*> list = app.getSubmoduleList();
BOOST_CHECK( list.size() == nInstances );
std::map<size_t, size_t> instancesFound;
for(size_t i = 0; i < nInstances; ++i) instancesFound[i] = 0;
for(auto mod : list) {
for(size_t i = 0; i < nInstances; ++i) {
if(mod == &(app.vectorOfTestModule[i])) instancesFound[i]++;
}
}
for(size_t i = 0; i < nInstances; ++i) {
BOOST_CHECK( instancesFound[i] == 1 );
}
}
// check if instances appear properly in getSubmoduleListRecursive() as well
{
std::list<ctk::Module*> list = app.getSubmoduleListRecursive();
BOOST_CHECK( list.size() == 3*nInstances );
std::map<size_t, size_t> instancesFound, instancesSomeGroupFound, instancesAnotherGroupFound;
for(size_t i = 0; i < nInstances; ++i) {
instancesFound[i] = 0;
instancesSomeGroupFound[i] = 0;
instancesAnotherGroupFound[i] = 0;
}
for(auto mod : list) {
for(size_t i = 0; i < nInstances; ++i) {
if(mod == &(app.vectorOfTestModule[i])) instancesFound[i]++;
if(mod == &(app.vectorOfTestModule[i].someGroup)) instancesSomeGroupFound[i]++;
if(mod == &(app.vectorOfTestModule[i].anotherGroup)) instancesAnotherGroupFound[i]++;
}
}
for(size_t i = 0; i < nInstances; ++i) {
BOOST_CHECK( instancesFound[i] == 1 );
BOOST_CHECK( instancesSomeGroupFound[i] == 1 );
BOOST_CHECK( instancesAnotherGroupFound[i] == 1 );
}
}
// check ownerships
for(size_t i = 0; i < nInstances; ++i) {
BOOST_CHECK( app.vectorOfTestModule[i].getOwner() == &app );
BOOST_CHECK( app.vectorOfTestModule[i].someInput.getOwner() == &(app.vectorOfTestModule[i]) );
BOOST_CHECK( app.vectorOfTestModule[i].someOutput.getOwner() == &(app.vectorOfTestModule[i]) );
BOOST_CHECK( app.vectorOfTestModule[i].someGroup.getOwner() == &(app.vectorOfTestModule[i]) );
BOOST_CHECK( app.vectorOfTestModule[i].someGroup.inGroup.getOwner() == &(app.vectorOfTestModule[i].someGroup) );
BOOST_CHECK( app.vectorOfTestModule[i].someGroup.alsoInGroup.getOwner() == &(app.vectorOfTestModule[i].someGroup) );
BOOST_CHECK( app.vectorOfTestModule[i].anotherGroup.getOwner() == &(app.vectorOfTestModule[i]) );
BOOST_CHECK( app.vectorOfTestModule[i].anotherGroup.foo.getOwner() == &(app.vectorOfTestModule[i].anotherGroup) );
}
}
/*********************************************************************************************************************/
/* test correct behaviour when using a std::vector of ModuleGroup, ApplicationModule and VariableGroup at the same time */
BOOST_AUTO_TEST_CASE( testVectorsOfAllModules ) {
std::cout << "*********************************************************************************************************************" << std::endl;
std::cout << "==> testVectorsOfAllModules" << std::endl;
// create app with a vector containing 10 modules
size_t nInstances = 10;
VectorOfEverythingApp app(nInstances);
Martin Christoph Hierholzer
committed
//-------------------------------------------------------------------------------------------------------------------
// the app creates the 10 module instances in defineConnections, check if this is done proplery (a quite redundant
// test...)
BOOST_CHECK(app.vectorOfVectorModuleGroup.size() == 0);
app.defineConnections();
BOOST_CHECK(app.vectorOfVectorModuleGroup.size() == nInstances);
for(size_t i=0; i < nInstances; ++i) {
BOOST_CHECK(app.vectorOfVectorModuleGroup[i].vectorOfVectorModule.size() == nInstances);
for(size_t k=0; k < nInstances; ++k) {
BOOST_CHECK(app.vectorOfVectorModuleGroup[i].vectorOfVectorModule[k].vectorOfSomeGroup.size() == nInstances);
}
}
Martin Christoph Hierholzer
committed
//-------------------------------------------------------------------------------------------------------------------
// check presence in lists (getSubmoduleList() and getAccessorList())
{ // checks on first hierarchy level (application has the list of module groups)
std::list<ctk::Module*> list = app.getSubmoduleList();
BOOST_CHECK( list.size() == nInstances );
std::map<size_t, size_t> found;
for(size_t i=0; i < nInstances; ++i) found[i] = 0;
for(auto mod : list) {
for(size_t i=0; i < nInstances; ++i) {
if(mod == &(app.vectorOfVectorModuleGroup[i])) found[i]++;
}
}
for(size_t i=0; i < nInstances; ++i) BOOST_CHECK( found[i] == 1 );
Martin Christoph Hierholzer
committed
}
{ // checks on second hierarchy level (each module group has the list of modules)
for(size_t i=0; i < nInstances; ++i) {
std::list<ctk::Module*> list = app.vectorOfVectorModuleGroup[i].getSubmoduleList();
BOOST_CHECK( list.size() == nInstances );
std::map<size_t, size_t> found;
for(size_t k=0; k < nInstances; ++k) found[k] = 0;
for(auto mod : list) {
for(size_t k=0; k < nInstances; ++k) {
if(mod == &(app.vectorOfVectorModuleGroup[i].vectorOfVectorModule[k])) found[k]++;
}
}
for(size_t k=0; k < nInstances; ++k) BOOST_CHECK( found[k] == 1 );
}
}
{ // checks on third hierarchy level (each module has accessors and variable groups)
for(size_t i=0; i < nInstances; ++i) {
for(size_t k=0; k < nInstances; ++k) {
Martin Christoph Hierholzer
committed
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// search for accessors
std::list<ctk::VariableNetworkNode> accList = app.vectorOfVectorModuleGroup[i].vectorOfVectorModule[k].getAccessorList();
BOOST_CHECK_EQUAL( accList.size(), 2 );
size_t someInputFound = 0;
size_t someOutputFound = 0;
for(auto acc : accList) {
if(acc == app.vectorOfVectorModuleGroup[i].vectorOfVectorModule[k].someInput) someInputFound++;
if(acc == app.vectorOfVectorModuleGroup[i].vectorOfVectorModule[k].someOutput) someOutputFound++;
}
BOOST_CHECK_EQUAL( someInputFound, 1 );
BOOST_CHECK_EQUAL( someOutputFound, 1 );
// search for variable groups
std::list<ctk::Module*> modList = app.vectorOfVectorModuleGroup[i].vectorOfVectorModule[k].getSubmoduleList();
BOOST_CHECK_EQUAL( modList.size(), nInstances + 1 );
std::map<size_t, size_t> someGroupFound;
for(size_t m=0; m < nInstances; ++m) someGroupFound[m] = 0;
size_t anotherGroupFound = 0;
for(auto mod : modList) {
for(size_t m=0; m < nInstances; ++m) {
if(mod == &(app.vectorOfVectorModuleGroup[i].vectorOfVectorModule[k].vectorOfSomeGroup[m])) someGroupFound[m]++;
}
if(mod == &(app.vectorOfVectorModuleGroup[i].vectorOfVectorModule[k].anotherGroup)) anotherGroupFound++;
}
for(size_t m=0; m < nInstances; ++m) {
BOOST_CHECK_EQUAL( someGroupFound[m], 1 );
}