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

remove obsolete tests

parent 8c915713
No related branches found
No related tags found
No related merge requests found
// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
// SPDX-License-Identifier: LGPL-3.0-or-later
#define BOOST_TEST_MODULE testDirectDeviceToCS
#include "Application.h"
#include "ApplicationModule.h"
#include "ScalarAccessor.h"
#include "VariableGroup.h"
#include <boost/test/included/unit_test.hpp>
using namespace boost::unit_test_framework;
namespace ctk = ChimeraTK;
BOOST_AUTO_TEST_CASE(ALL_TESTS_DISABLED) {}
#if 0
struct TestApplication : public ctk::Application {
TestApplication() : Application("testSuite") {}
~TestApplication() { shutdown(); }
void defineConnections() override {}
ctk::ControlSystemModule cs1;
ctk::ControlSystemModule cs2;
struct IO : ctk::ApplicationModule {
using ctk::ApplicationModule::ApplicationModule;
struct : ctk::VariableGroup {
using ctk::VariableGroup::VariableGroup;
ctk::ScalarPushInput<int> input{this, "input", "", ""};
ctk::ScalarOutput<int> output{this, "output", "", ""};
} data{this, "data", ""};
void mainLoop() {
while(true) {
data.output = 1 * data.input;
writeAllDestructively();
readAll();
}
}
};
IO module1{this, "M1", ""};
IO module2{this, "M2", ""};
};
BOOST_AUTO_TEST_CASE(testNetworkMerging1) { // Test merging works if if going in different directions
std::cout << "testNetworkMerging1" << std::endl;
TestApplication app;
auto pvManagers = ctk::createPVManager();
app.setPVManager(pvManagers.second);
// Connect a push input to CS1 and a poll output to CS2 for the same variable.
app.module1.data.input >> app.cs1("Foo");
app.module2.data.output >> app.cs2("Foo");
app.initialise();
app.run();
}
BOOST_AUTO_TEST_CASE(testNetworkMerging2) { // Test merging works if if going in different directions
std::cout << "testNetworkMerging2" << std::endl;
TestApplication app;
auto pvManagers = ctk::createPVManager();
app.setPVManager(pvManagers.second);
// Connect a push input to CS1 and a poll output to CS2 for the same variable, reverse order.
app.cs1("Foo") >> app.module1.data.input;
app.cs2("Foo") >> app.module2.data.input;
app.initialise();
app.run();
}
BOOST_AUTO_TEST_CASE(testNetworkMerging3) { // Test merging works if if going in different directions
std::cout << "testNetworkMerging3" << std::endl;
TestApplication app;
auto pvManagers = ctk::createPVManager();
app.setPVManager(pvManagers.second);
// Connect a push input to CS1 and a poll output to CS2 for the same variable, reverse order.
app.cs1("Foo") >> app.module1.data.input;
app.module2.data.output >> app.cs2("Foo");
app.initialise();
app.run();
}
BOOST_AUTO_TEST_CASE(testNetworkMerging4) { // Test merging works if if going in different directions
std::cout << "testNetworkMerging4" << std::endl;
TestApplication app;
auto pvManagers = ctk::createPVManager();
app.setPVManager(pvManagers.second);
// Connect a push input to CS1 and a poll output to CS2 for the same variable, reverse order.
app.module1.data.output >> app.cs1("Foo");
BOOST_CHECK_THROW(app.module2.data.output >> app.cs2("Foo"), ChimeraTK::logic_error);
}
#endif
// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
// SPDX-License-Identifier: LGPL-3.0-or-later
#include <chrono>
#include <future>
#define BOOST_TEST_MODULE testConnectTo
#include "Application.h"
#include "ApplicationModule.h"
#include "ModuleGroup.h"
#include "ScalarAccessor.h"
#include "TestFacility.h"
#include "VariableGroup.h"
#include <boost/mpl/list.hpp>
#include <boost/test/included/unit_test.hpp>
#include <boost/thread.hpp>
using namespace boost::unit_test_framework;
namespace ctk = ChimeraTK;
BOOST_AUTO_TEST_CASE(all_test_disabled) {}
#if 0
/*********************************************************************************************************************/
/* Build first hierarchy */
struct FirstHierarchy : ctk::ModuleGroup {
using ctk::ModuleGroup::ModuleGroup;
struct TestModule : ctk::ApplicationModule {
using ctk::ApplicationModule::ApplicationModule;
struct VarGroup : ctk::VariableGroup {
using ctk::VariableGroup::VariableGroup;
ctk::ScalarPushInput<int> varA{this, "varA", "MV/m", "Desc"};
ctk::ScalarPushInput<int> varB{this, "varB", "MV/m", "Desc"};
ctk::ScalarOutput<int> varC{this, "varC", "MV/m", "Desc"};
} varGroup{this, "VarGroup", "A group"};
ctk::ScalarPushInput<int> varA{this, "varA", "MV/m", "Desc"};
ctk::ScalarOutput<int> varX{this, "varX", "MV/m", "Desc"};
void prepare() override { writeAll(); /*send initial values*/ }
void mainLoop() override {}
} testModule{this, "TestModule", ""};
struct SecondModule : ctk::ApplicationModule {
SecondModule(ModuleGroup* owner, const std::string& name, const std::string& description)
: ctk::ApplicationModule(owner, name, description) {
for(size_t i = 0; i < 22; ++i) myVec.emplace_back(this, "Var" + std::to_string(i), "Unit", "Foo");
}
SecondModule() { throw; } // work around for gcc bug: constructor must be present but is unused
std::vector<ctk::ScalarPushInput<int>> myVec;
void prepare() override { writeAll(); /*send initial values*/ }
void mainLoop() override {}
} secondModule{this, "SecondModule", ""};
};
/*********************************************************************************************************************/
/* Build second hierarchy */
struct SecondHierarchy : ctk::ModuleGroup {
using ctk::ModuleGroup::ModuleGroup;
struct TestModule : ctk::ApplicationModule {
using ctk::ApplicationModule::ApplicationModule;
struct VarGroup : ctk::VariableGroup {
using ctk::VariableGroup::VariableGroup;
ctk::ScalarOutput<int> varA{this, "varA", "MV/m", "Desc"};
ctk::ScalarPushInput<int> varC{this, "varC", "MV/m", "Desc"};
ctk::ScalarPushInput<int> varD{this, "varD", "MV/m", "Desc"};
} varGroup{this, "VarGroup", "A group"};
ctk::ScalarPushInput<int> extraVar{this, "extraVar", "MV/m", "Desc"};
ctk::ScalarOutput<int> varA{this, "varA", "MV/m", "Desc"};
struct EliminatedGroup : ctk::VariableGroup {
using ctk::VariableGroup::VariableGroup;
ctk::ScalarPushInput<int> varX{this, "varX", "MV/m", "Desc"};
struct VarGroup : ctk::VariableGroup {
using ctk::VariableGroup::VariableGroup;
ctk::ScalarOutput<int> varB{this, "varB", "MV/m", "Desc"};
} varGroup{this, "VarGroup", "This group shall be merged with testModule.varGroup in connectTo()"};
} eliminatedGroup{this, ".", "A group whose hierarchy gets eliminated"};
void prepare() override { writeAll(); /*send initial values*/ }
void mainLoop() override {}
} testModule{this, "TestModule", ""};
struct SecondModule : ctk::ApplicationModule {
SecondModule(ModuleGroup* owner, const std::string& name, const std::string& description)
: ctk::ApplicationModule(owner, name, description) {
for(size_t i = 0; i < 22; ++i) myVec.emplace_back(this, "Var" + std::to_string(i), "Unit", "Foo");
}
SecondModule() { throw; } // work around for gcc bug: constructor must be present but is unused
struct ExtraGroup : ctk::VariableGroup {
using ctk::VariableGroup::VariableGroup;
ctk::ScalarOutput<int> varA{this, "varA", "MV/m", "Desc"};
} extraGroup{this, "ExtraGroup", "A group"};
std::vector<ctk::ScalarOutput<int>> myVec;
void prepare() override { writeAll(); /*send initial values*/ }
void mainLoop() override {}
} secondModule{this, "SecondModule", ""};
};
/*********************************************************************************************************************/
/* dummy application */
struct TestApplication : public ctk::Application {
TestApplication() : Application("testSuite") {}
~TestApplication() { shutdown(); }
void defineConnections() {} // the setup is done in the tests
FirstHierarchy first{this, "first", "The test module"};
SecondHierarchy second{this, "second", "The test module"};
};
/*********************************************************************************************************************/
/* test connectTo() */
BOOST_AUTO_TEST_CASE(testConnectTo) {
std::cout << "***************************************************************"
"******************************************************"
<< std::endl;
std::cout << "==> testConnectTo" << std::endl;
TestApplication app;
app.first.connectTo(app.second);
ctk::TestFacility test(app);
test.runApplication();
app.second.testModule.varGroup.varA = 1;
app.second.testModule.eliminatedGroup.varGroup.varB = 2;
app.first.testModule.varGroup.varC = 3;
app.second.testModule.varA = 4;
app.first.testModule.varX = 5;
for(int i = 0; i < 22; ++i) {
app.second.secondModule.myVec[i] = 6 + i;
}
app.first.testModule.writeAll();
app.first.secondModule.writeAll();
app.second.testModule.writeAll();
app.second.secondModule.writeAll();
app.first.testModule.readAllLatest();
app.first.secondModule.readAllLatest();
app.second.testModule.readAllLatest();
app.second.secondModule.readAllLatest();
BOOST_CHECK_EQUAL((int)app.first.testModule.varGroup.varA, 1);
BOOST_CHECK_EQUAL((int)app.first.testModule.varGroup.varB, 2);
BOOST_CHECK_EQUAL((int)app.second.testModule.varGroup.varC, 3);
BOOST_CHECK_EQUAL((int)app.first.testModule.varA, 4);
BOOST_CHECK_EQUAL((int)app.second.testModule.eliminatedGroup.varX, 5);
for(int i = 0; i < 22; ++i) {
BOOST_CHECK_EQUAL((int)app.first.secondModule.myVec[i], 6 + i);
}
}
/*********************************************************************************************************************/
/* check if makeing the same connection twice does not fail */
BOOST_AUTO_TEST_CASE(testConnectTwice) {
std::cout << "***************************************************************"
"******************************************************"
<< std::endl;
std::cout << "==> testConnectTwice" << std::endl;
TestApplication app;
app.second.testModule.varA >> app.first.testModule.varA;
app.first.connectTo(app.second);
ctk::TestFacility test(app);
test.runApplication();
app.second.testModule.varGroup.varA = 1;
app.second.testModule.eliminatedGroup.varGroup.varB = 2;
app.first.testModule.varGroup.varC = 3;
app.second.testModule.varA = 4;
app.first.testModule.varX = 5;
for(int i = 0; i < 22; ++i) {
app.second.secondModule.myVec[i] = 6 + i;
}
app.first.testModule.writeAll();
app.first.secondModule.writeAll();
app.second.testModule.writeAll();
app.second.secondModule.writeAll();
app.first.testModule.readAllLatest();
app.first.secondModule.readAllLatest();
app.second.testModule.readAllLatest();
app.second.secondModule.readAllLatest();
BOOST_CHECK_EQUAL((int)app.first.testModule.varGroup.varA, 1);
BOOST_CHECK_EQUAL((int)app.first.testModule.varGroup.varB, 2);
BOOST_CHECK_EQUAL((int)app.second.testModule.varGroup.varC, 3);
BOOST_CHECK_EQUAL((int)app.first.testModule.varA, 4);
BOOST_CHECK_EQUAL((int)app.second.testModule.eliminatedGroup.varX, 5);
for(int i = 0; i < 22; ++i) {
BOOST_CHECK_EQUAL((int)app.first.secondModule.myVec[i], 6 + i);
}
}
#endif
// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
// SPDX-License-Identifier: LGPL-3.0-or-later
#define BOOST_TEST_MODULE testDirectDeviceToCS
#include "Application.h"
#include "check_timeout.h"
#include "DeviceModule.h"
#include "PeriodicTrigger.h"
#include "TestFacility.h"
#include <ChimeraTK/Device.h>
#include <boost/mpl/list.hpp>
#define BOOST_NO_EXCEPTIONS
#include <boost/test/included/unit_test.hpp>
#undef BOOST_NO_EXCEPTIONS
using namespace boost::unit_test_framework;
namespace ctk = ChimeraTK;
// list of user types the accessors are tested with
typedef boost::mpl::list<int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, float, double> test_types;
/*********************************************************************************************************************/
/* Helper function to synchronize with device initialization
*
* This is required because we open the device manually in the test cases.
*/
static bool deviceIsInitialised(std::string alias, boost::shared_ptr<ctk::ControlSystemPVManager> csPVManager) {
auto dummyDeviceStatus = csPVManager->getProcessArray<int>("/Devices/" + alias + "/status");
dummyDeviceStatus->read();
return dummyDeviceStatus->accessData(0) == 0;
}
/*********************************************************************************************************************/
/* dummy application */
template<typename T>
struct TestApplication : public ctk::Application {
TestApplication() : Application("testSuite") {
ChimeraTK::BackendFactory::getInstance().setDMapFilePath("test.dmap");
}
~TestApplication() { shutdown(); }
ctk::DeviceModule dev{this, "Dummy0"};
};
/*********************************************************************************************************************/
/* dummy application for connectTo() test */
struct TestApplicationConnectTo : ctk::Application {
TestApplicationConnectTo() : Application("testSuite") {}
~TestApplicationConnectTo();
ctk::PeriodicTrigger trigger{this, "trigger", ""};
ctk::DeviceModule dev{this, "(dummy?map=test3.map)"};
};
TestApplicationConnectTo::~TestApplicationConnectTo() {
shutdown();
}
/*********************************************************************************************************************/
template<typename T, typename LAMBDA>
void testDirectRegister(ctk::TestFacility& test, ChimeraTK::ScalarRegisterAccessor<T> sender,
ChimeraTK::ScalarRegisterAccessor<T> receiver, LAMBDA trigger, bool testMinMax = true) {
std::cout << "testDirectRegister<" << typeid(T).name() << ">: " << sender.getName() << " -> " << receiver.getName()
<< std::endl;
sender = 42;
sender.write();
trigger();
test.stepApplication();
receiver.read();
BOOST_CHECK_EQUAL(receiver, 42);
if(std::numeric_limits<T>::is_signed) {
sender = -120;
sender.write();
trigger();
test.stepApplication();
receiver.read();
BOOST_CHECK_EQUAL(receiver, -120);
}
if(testMinMax) {
sender = std::numeric_limits<T>::max();
sender.write();
trigger();
test.stepApplication();
receiver.read();
BOOST_CHECK_EQUAL(receiver, std::numeric_limits<T>::max());
sender = std::numeric_limits<T>::min();
sender.write();
trigger();
test.stepApplication();
receiver.read();
BOOST_CHECK_EQUAL(receiver, std::numeric_limits<T>::min());
sender = std::numeric_limits<T>::epsilon();
sender.write();
trigger();
test.stepApplication();
receiver.read();
BOOST_CHECK_EQUAL(receiver, std::numeric_limits<T>::epsilon());
}
}
/*********************************************************************************************************************/
/* test direct control system to device connections */
BOOST_AUTO_TEST_CASE_TEMPLATE(testDirectCStoDev, T, test_types) {
std::cout << "testDirectCStoDev" << std::endl;
TestApplication<T> app;
auto pvManagers = ctk::createPVManager();
app.setPVManager(pvManagers.second);
// app.cs("myFeeder", typeid(T), 1) >> app.dev("/MyModule/actuator");
app.initialise();
app.run();
ChimeraTK::Device dev;
dev.open("Dummy0");
// Synchronize to DeviceModule init/recovery procedure being finshed
CHECK_TIMEOUT(deviceIsInitialised("Dummy0", pvManagers.first), 10000);
auto myFeeder = pvManagers.first->getProcessArray<T>("/myFeeder");
BOOST_CHECK(myFeeder->getName() == "/myFeeder");
myFeeder->accessData(0) = 18;
myFeeder->write();
CHECK_TIMEOUT(dev.read<T>("/MyModule/actuator") == 18, 10000);
myFeeder->accessData(0) = 20;
myFeeder->write();
CHECK_TIMEOUT(dev.read<T>("/MyModule/actuator") == 20, 10000);
}
/*********************************************************************************************************************/
/* test direct control system to device connections with fan out */
BOOST_AUTO_TEST_CASE_TEMPLATE(testDirectCStoDevFanOut, T, test_types) {
std::cout << "testDirectCStoDevFanOut" << std::endl;
TestApplication<T> app;
auto pvManagers = ctk::createPVManager();
app.setPVManager(pvManagers.second);
// app.cs("myFeeder", typeid(T), 1) >> app.dev("/MyModule/actuator") >> app.dev("/Deeper/hierarchies/also");
app.initialise();
app.run();
ChimeraTK::Device dev;
dev.open("Dummy0");
// Synchronize to DeviceModule init/recovery procedure being finshed
CHECK_TIMEOUT(deviceIsInitialised("Dummy0", pvManagers.first), 10000);
auto myFeeder = pvManagers.first->getProcessArray<T>("/myFeeder");
BOOST_CHECK(myFeeder->getName() == "/myFeeder");
myFeeder->accessData(0) = 18;
myFeeder->write();
CHECK_TIMEOUT(dev.read<T>("/MyModule/actuator") == 18, 10000);
CHECK_TIMEOUT(dev.read<T>("/MyModule/readBack") == 18, 10000);
myFeeder->accessData(0) = 20;
myFeeder->write();
CHECK_TIMEOUT(dev.read<T>("/MyModule/actuator") == 20, 10000);
CHECK_TIMEOUT(dev.read<T>("/MyModule/readBack") == 20, 10000);
}
/*********************************************************************************************************************/
/* test connectTo */
BOOST_AUTO_TEST_CASE(testConnectTo) {
std::cout << "testConnectTo" << std::endl;
ctk::Device dev;
dev.open("(dummy?map=test3.map)");
TestApplicationConnectTo app;
// app.dev.connectTo(app.cs, app.trigger.tick);
ctk::TestFacility test{app};
auto devActuator = dev.getScalarRegisterAccessor<int32_t>("/MyModule/actuator");
// The direction of 'readback' is "device to application". For this to work it had to be read only.
// In order to write to it in the test, we use the "DUMMY_WRITEABLE" variable.
auto devReadback = dev.getScalarRegisterAccessor<int32_t>("/MyModule/readBack.DUMMY_WRITEABLE");
auto devint32 = dev.getScalarRegisterAccessor<int32_t>("/Integers/signed32");
auto devuint32 = dev.getScalarRegisterAccessor<uint32_t>("/Integers/unsigned32");
auto devint16 = dev.getScalarRegisterAccessor<int16_t>("/Integers/signed16");
auto devuint16 = dev.getScalarRegisterAccessor<uint16_t>("/Integers/unsigned16");
auto devint8 = dev.getScalarRegisterAccessor<int8_t>("/Integers/signed8");
auto devuint8 = dev.getScalarRegisterAccessor<uint8_t>("/Integers/unsigned8");
auto devfloat = dev.getScalarRegisterAccessor<float>("/FixedPoint/value");
auto devDeep1 = dev.getScalarRegisterAccessor<int32_t>("/Deep/Hierarchies/Need/Tests/As/well");
auto devDeep2 = dev.getScalarRegisterAccessor<int32_t>("/Deep/Hierarchies/Need/Another/test");
auto csActuator = test.getScalar<int32_t>("/MyModule/actuator");
auto csReadback = test.getScalar<int32_t>("/MyModule/readBack");
auto csint32 = test.getScalar<int32_t>("/Integers/signed32");
auto csuint32 = test.getScalar<uint32_t>("/Integers/unsigned32");
auto csint16 = test.getScalar<int16_t>("/Integers/signed16");
auto csuint16 = test.getScalar<uint16_t>("/Integers/unsigned16");
auto csint8 = test.getScalar<int8_t>("/Integers/signed8");
auto csuint8 = test.getScalar<uint8_t>("/Integers/unsigned8");
auto csfloat = test.getScalar<float>("/FixedPoint/value");
auto csDeep1 = test.getScalar<int32_t>("/Deep/Hierarchies/Need/Tests/As/well");
auto csDeep2 = test.getScalar<int32_t>("/Deep/Hierarchies/Need/Another/test");
test.runApplication();
testDirectRegister(test, csActuator, devActuator, [] {});
testDirectRegister(test, devReadback, csReadback, [&] { app.trigger.sendTrigger(); });
testDirectRegister(test, csint32, devint32, [] {});
testDirectRegister(test, csuint32, devuint32, [] {});
testDirectRegister(test, csint16, devint16, [] {});
testDirectRegister(test, csuint16, devuint16, [] {});
testDirectRegister(test, csint8, devint8, [] {});
testDirectRegister(test, csuint8, devuint8, [] {});
testDirectRegister(
test, csfloat, devfloat, [] {}, false);
testDirectRegister(test, csDeep1, devDeep1, [] {});
testDirectRegister(test, csDeep2, devDeep2, [] {});
}
/*********************************************************************************************************************/
/* test connectTo */
BOOST_AUTO_TEST_CASE(testConnectToSubHierarchies) {
std::cout << "testConnectToSubHierarchies" << std::endl;
ctk::Device dev;
dev.open("(dummy?map=test3.map)");
TestApplicationConnectTo app;
// app.dev["Deep"]["Hierarchies"].connectTo(app.cs, app.trigger.tick);
// app.dev["Integers"].connectTo(app.cs["Ints"], app.trigger.tick);
ctk::TestFacility test{app};
auto devint32 = dev.getScalarRegisterAccessor<int32_t>("/Integers/signed32");
auto devuint32 = dev.getScalarRegisterAccessor<uint32_t>("/Integers/unsigned32");
auto devint16 = dev.getScalarRegisterAccessor<int16_t>("/Integers/signed16");
auto devuint16 = dev.getScalarRegisterAccessor<uint16_t>("/Integers/unsigned16");
auto devint8 = dev.getScalarRegisterAccessor<int8_t>("/Integers/signed8");
auto devuint8 = dev.getScalarRegisterAccessor<uint8_t>("/Integers/unsigned8");
auto devDeep1 = dev.getScalarRegisterAccessor<int32_t>("/Deep/Hierarchies/Need/Tests/As/well");
auto devDeep2 = dev.getScalarRegisterAccessor<int32_t>("/Deep/Hierarchies/Need/Another/test");
auto csint32 = test.getScalar<int32_t>("/Ints/signed32");
auto csuint32 = test.getScalar<uint32_t>("/Ints/unsigned32");
auto csint16 = test.getScalar<int16_t>("/Ints/signed16");
auto csuint16 = test.getScalar<uint16_t>("/Ints/unsigned16");
auto csint8 = test.getScalar<int8_t>("/Ints/signed8");
auto csuint8 = test.getScalar<uint8_t>("/Ints/unsigned8");
auto csDeep1 = test.getScalar<int32_t>("/Need/Tests/As/well");
auto csDeep2 = test.getScalar<int32_t>("/Need/Another/test");
test.runApplication();
testDirectRegister(test, csint32, devint32, [] {});
testDirectRegister(test, csuint32, devuint32, [] {});
testDirectRegister(test, csint16, devint16, [] {});
testDirectRegister(test, csuint16, devuint16, [] {});
testDirectRegister(test, csint8, devint8, [] {});
testDirectRegister(test, csuint8, devuint8, [] {});
testDirectRegister(test, csDeep1, devDeep1, [] {});
testDirectRegister(test, csDeep2, devDeep2, [] {});
}
// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
// SPDX-License-Identifier: LGPL-3.0-or-later
#define BOOST_TEST_MODULE testHideThis
#include <boost/test/included/unit_test.hpp>
using namespace boost::unit_test_framework;
#include "Application.h"
#include "ApplicationModule.h"
#include "ScalarAccessor.h"
#include "TestFacility.h"
#include "VariableGroup.h"
using namespace ChimeraTK;
struct TestApp : public Application {
TestApp() : Application("test") {}
~TestApp() override { shutdown(); }
// hides itself, and then produces A and B as sub-grops. Works.
struct A : public ApplicationModule {
using ApplicationModule::ApplicationModule;
struct : public VariableGroup {
using VariableGroup::VariableGroup;
ScalarPushInput<int> in{this, "input", "", ""};
} self{this, "A", ""};
// the output of A is the input of B
struct : public VariableGroup {
using VariableGroup::VariableGroup;
ScalarOutput<int> in{this, "input", "", ""};
} b{this, "B", ""};
void mainLoop() override {
while(true) {
b.in = 2 * int(self.in);
b.in.write();
self.in.read();
}
}
} a{this, ".", ""};
// This part was broken: Tried to hide itself like A, but failed. Result was B/B/input and B/output
// Now is fixed
struct B : public ApplicationModule {
using ApplicationModule::ApplicationModule;
struct : public VariableGroup {
using VariableGroup::VariableGroup;
ScalarPushInput<int> in{this, "input", "", ""};
} self{this, "B", ""};
// the output of B is one level up (global output)
ScalarOutput<int> out{this, "output", "", ""};
void mainLoop() override {
while(true) {
out = 3 * int(self.in);
out.write();
self.in.read();
}
}
} b{this, ".", ""}; // name it "HiddenB" here and it works
};
BOOST_AUTO_TEST_CASE(testBIsHidden) {
TestApp t;
ChimeraTK::TestFacility testFacility(t);
testFacility.runApplication();
t.dumpConnections();
testFacility.writeScalar<int>("/A/input", 5);
testFacility.stepApplication();
BOOST_CHECK_EQUAL(testFacility.readScalar<int>("B/input"), 10); // A multiplies with 2
// this checks two things:
// 1. B/output has been moved to root
// 2. B/B/input has been moved to B/input and connected through the CS with the output of A
BOOST_CHECK_EQUAL(testFacility.readScalar<int>("output"), 30); // B multiplies with 3
}
...@@ -20,6 +20,19 @@ ...@@ -20,6 +20,19 @@
using namespace boost::unit_test_framework; using namespace boost::unit_test_framework;
namespace ctk = ChimeraTK; namespace ctk = ChimeraTK;
/*********************************************************************************************************************/
/*********************************************************************************************************************/
/**
* This test checks use of relative paths in modules at the example of a VariableGroup.
*
* TODO:
* - Rename this test source file
* - Add checks for relative paths in ModuleGroups and ApplicationModules
* - Add checks for relative paths in accessors
*/
/*********************************************************************************************************************/
/*********************************************************************************************************************/ /*********************************************************************************************************************/
struct TestGroup : public ctk::VariableGroup { struct TestGroup : public ctk::VariableGroup {
......
...@@ -53,10 +53,6 @@ BOOST_AUTO_TEST_CASE(testTwoScalarPollPushAccessors) { ...@@ -53,10 +53,6 @@ BOOST_AUTO_TEST_CASE(testTwoScalarPollPushAccessors) {
BOOST_CHECK_THROW(ChimeraTK::TestFacility tf(app, false), ctk::logic_error); BOOST_CHECK_THROW(ChimeraTK::TestFacility tf(app, false), ctk::logic_error);
} }
/*********************************************************************************************************************/
/* test case for no feeder - There cannot be no feeder any more, ApplicationCore will generate a CS feeder then */
/*********************************************************************************************************************/ /*********************************************************************************************************************/
/* test case for two feeders */ /* test case for two feeders */
......
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