diff --git a/tests/executables_src/testOptimiseUnmappedVariables.cc b/tests/executables_src/testOptimiseUnmappedVariables.cc new file mode 100644 index 0000000000000000000000000000000000000000..d7f50e8609b06b1aeeb397767e1f4e202a1a66d5 --- /dev/null +++ b/tests/executables_src/testOptimiseUnmappedVariables.cc @@ -0,0 +1,177 @@ +/* + * testApplication.cc + * + * Created on: Nov 15, 2017 + * Author: Martin Hierholzer + */ + +#include <chrono> +#include <future> + +#define BOOST_TEST_MODULE testApplication + +#include <boost/filesystem.hpp> +#include <boost/mpl/list.hpp> +#include <boost/thread.hpp> + +#include <libxml++/libxml++.h> + +#include "Application.h" +#include "ControlSystemModule.h" +#include "Multiplier.h" +#include "Pipe.h" +#include "TestFacility.h" + +#define BOOST_NO_EXCEPTIONS +#include <boost/test/included/unit_test.hpp> +#undef BOOST_NO_EXCEPTIONS + +using namespace boost::unit_test_framework; +namespace ctk = ChimeraTK; + +/*********************************************************************************************************************/ +/* Application without name */ + +struct TestApp : public ctk::Application { + TestApp(const std::string& name) : ctk::Application(name) {} + ~TestApp() { shutdown(); } + + void defineConnections() { + csmod["Multiplier"]("input") >> multiplierD.input; + multiplierD.output >> csmod["Multiplier"]("tap"); + multiplierD.output >> pipe.input; + pipe.output >> csmod["mySubModule"]("output"); + pipe.output >> csmod["mySubModule"]("output_copy"); + } + + ctk::ConstMultiplier<double> multiplierD{this, "multiplierD", "Some module", 42}; + ctk::ScalarPipe<double> pipe{this, "pipe", "unit", "Some pipe module"}; + ctk::ControlSystemModule csmod; +}; + +/*********************************************************************************************************************/ + +BOOST_AUTO_TEST_CASE(testOptimiseUnmappedVariables) { + std::cout << "***************************************************************" << std::endl; + std::cout << "==> testOptimiseUnmappedVariables" << std::endl; + + // test without even calling the function + { + TestApp app("testApp"); + ctk::TestFacility test; + auto input = test.getScalar<double>("/Multiplier/input"); + auto tap = test.getScalar<double>("/Multiplier/tap"); + auto output = test.getScalar<double>("/mySubModule/output"); + auto output_copy = test.getScalar<double>("/mySubModule/output_copy"); + test.runApplication(); + input = 10; + input.write(); + test.stepApplication(); + BOOST_CHECK(tap.readNonBlocking()); + BOOST_CHECK_CLOSE(double(tap), 420., 0.001); + BOOST_CHECK(!tap.readNonBlocking()); + BOOST_CHECK(output.readNonBlocking()); + BOOST_CHECK_CLOSE(double(output), 420., 0.001); + BOOST_CHECK(!output.readNonBlocking()); + BOOST_CHECK(output_copy.readNonBlocking()); + BOOST_CHECK_CLOSE(double(output_copy), 420., 0.001); + BOOST_CHECK(!output_copy.readNonBlocking()); + } + + // test passing empty set + { + TestApp app("testApp"); + ctk::TestFacility test; + auto input = test.getScalar<double>("/Multiplier/input"); + auto tap = test.getScalar<double>("/Multiplier/tap"); + auto output = test.getScalar<double>("/mySubModule/output"); + auto output_copy = test.getScalar<double>("/mySubModule/output_copy"); + app.optimiseUnmappedVariables({}); + test.runApplication(); + input = 10; + input.write(); + test.stepApplication(); + BOOST_CHECK(tap.readNonBlocking()); + BOOST_CHECK_CLOSE(double(tap), 420., 0.001); + BOOST_CHECK(!tap.readNonBlocking()); + BOOST_CHECK(output.readNonBlocking()); + BOOST_CHECK_CLOSE(double(output), 420., 0.001); + BOOST_CHECK(!output.readNonBlocking()); + BOOST_CHECK(output_copy.readNonBlocking()); + BOOST_CHECK_CLOSE(double(output_copy), 420., 0.001); + BOOST_CHECK(!output_copy.readNonBlocking()); + } + + // test passing single variable + { + TestApp app("testApp"); + ctk::TestFacility test; + auto input = test.getScalar<double>("/Multiplier/input"); + auto tap = test.getScalar<double>("/Multiplier/tap"); + auto output = test.getScalar<double>("/mySubModule/output"); + auto output_copy = test.getScalar<double>("/mySubModule/output_copy"); + app.optimiseUnmappedVariables({"/Multiplier/tap"}); + test.runApplication(); + input = 10; + input.write(); + test.stepApplication(); + BOOST_CHECK(!tap.readNonBlocking()); + BOOST_CHECK(output.readNonBlocking()); + BOOST_CHECK_CLOSE(double(output), 420., 0.001); + BOOST_CHECK(!output.readNonBlocking()); + BOOST_CHECK(output_copy.readNonBlocking()); + BOOST_CHECK_CLOSE(double(output_copy), 420., 0.001); + BOOST_CHECK(!output_copy.readNonBlocking()); + } + + // test passing two variables + { + TestApp app("testApp"); + ctk::TestFacility test; + auto input = test.getScalar<double>("/Multiplier/input"); + auto tap = test.getScalar<double>("/Multiplier/tap"); + auto output = test.getScalar<double>("/mySubModule/output"); + auto output_copy = test.getScalar<double>("/mySubModule/output_copy"); + app.optimiseUnmappedVariables({"/Multiplier/tap", "/mySubModule/output"}); + test.runApplication(); + input = 10; + input.write(); + test.stepApplication(); + BOOST_CHECK(!tap.readNonBlocking()); + BOOST_CHECK(!output.readNonBlocking()); + BOOST_CHECK(output_copy.readNonBlocking()); + BOOST_CHECK_CLOSE(double(output_copy), 420., 0.001); + BOOST_CHECK(!output_copy.readNonBlocking()); + } + + // test passing two variables, now with the other copy of the output + { + TestApp app("testApp"); + ctk::TestFacility test; + auto input = test.getScalar<double>("/Multiplier/input"); + auto tap = test.getScalar<double>("/Multiplier/tap"); + auto output = test.getScalar<double>("/mySubModule/output"); + auto output_copy = test.getScalar<double>("/mySubModule/output_copy"); + app.optimiseUnmappedVariables({"/Multiplier/tap", "/mySubModule/output_copy"}); + test.runApplication(); + input = 10; + input.write(); + test.stepApplication(); + BOOST_CHECK(!tap.readNonBlocking()); + BOOST_CHECK(output.readNonBlocking()); + BOOST_CHECK_CLOSE(double(output), 420., 0.001); + BOOST_CHECK(!output.readNonBlocking()); + BOOST_CHECK(!output_copy.readNonBlocking()); + } + + // test passing unknown variables + { + TestApp app("testApp"); + ctk::TestFacility test; + auto input = test.getScalar<double>("/Multiplier/input"); + auto tap = test.getScalar<double>("/Multiplier/tap"); + auto output = test.getScalar<double>("/mySubModule/output"); + BOOST_CHECK_THROW(app.optimiseUnmappedVariables({"/Multiplier/tap", "/this/is/not/known"}), std::out_of_range); + } + +}