diff --git a/tests/ecos/CMakeLists.txt b/tests/ecos/CMakeLists.txt index 005c5af..0e4a647 100644 --- a/tests/ecos/CMakeLists.txt +++ b/tests/ecos/CMakeLists.txt @@ -4,10 +4,11 @@ add_test_executable(test_variable_identifier) add_test_executable(test_connection) add_test_executable(test_property) add_test_executable(test_runner) +add_test_executable(test_ssp_parser) add_test_executable(test_unzipper) target_link_libraries(test_unzipper PRIVATE libzip::zip) if (MSVC AND ECOS_BUILD_CLIB) add_test_executable(test_clib) target_link_libraries(test_clib PUBLIC libecosc) -endif() \ No newline at end of file +endif() diff --git a/tests/ecos/test_ssp_parser.cpp b/tests/ecos/test_ssp_parser.cpp new file mode 100644 index 0000000..6b3872d --- /dev/null +++ b/tests/ecos/test_ssp_parser.cpp @@ -0,0 +1,116 @@ +#include +#include + +#include "ecos/ssp/ssp.hpp" + +using namespace ecos; + +namespace +{ + +void checkSystemStructure(const ssp::SystemStructureDescription& ssd) +{ + CHECK(ssd.name == "QuarterTruck"); + + const auto system = ssd.system; + CHECK(system.name == "QuarterTruckSystem"); + + CHECK(system.connections.size() == 4); + + const auto components = system.elements.components; + CHECK(components.size() == 3); + + REQUIRE(components.count("chassis")); + REQUIRE(components.count("wheel")); + REQUIRE(components.count("ground")); + + const ssp::Component& chassis = components.at("chassis"); + CHECK(chassis.source == "resources/chassis.fmu"); + REQUIRE(chassis.connectors.size() == 2); + CHECK(chassis.connectors.at("p.e").name == "p.e"); + CHECK(chassis.connectors.at("p.e").kind == "output"); + CHECK(!chassis.connectors.at("p.e").type.unit.has_value()); + CHECK(chassis.connectors.at("p.e").type.typeName() == "Real"); + CHECK(chassis.connectors.at("p.f").name == "p.f"); + CHECK(chassis.connectors.at("p.f").kind == "input"); + CHECK(!chassis.connectors.at("p.f").type.unit.has_value()); + CHECK(chassis.connectors.at("p.f").type.typeName() == "Real"); + + const ssp::Component& wheel = components.at("wheel"); + CHECK(wheel.source == "resources/wheel.fmu"); + REQUIRE(wheel.connectors.size() == 4); + CHECK(wheel.connectors.at("p.f").name == "p.f"); + CHECK(wheel.connectors.at("p1.e").name == "p1.e"); + CHECK(wheel.connectors.at("p.e").name == "p.e"); + CHECK(wheel.connectors.at("p1.f").name == "p1.f"); + + CHECK(wheel.connectors.at("p.e").type == wheel.connectors.at("p1.f").type); + + const auto& wheelParameters = wheel.parameterSets; + REQUIRE(wheelParameters.at("initialValues").parameters.size() == 3); + + const ssp::Component& ground = components.at("ground"); + CHECK(ground.source == "resources/ground.fmu"); + CHECK(ground.connectors.size() == 2); + + const auto& groundParameters = ground.parameterSets; + REQUIRE(groundParameters.empty()); + + REQUIRE(system.elements.parameterSets.size() == 1); + REQUIRE(system.elements.parameterSets.count("initialValues")); + const auto& initialValues = system.elements.parameterSets.at("initialValues"); + REQUIRE(initialValues.size() == 2); + REQUIRE(initialValues.count(chassis)); + REQUIRE(initialValues.at(chassis).size() == 3); + REQUIRE(initialValues.count(wheel)); + REQUIRE(initialValues.at(wheel).size() == 3); +} + +} // namespace + +TEST_CASE("test_ssp_parser_archive") +{ + std::filesystem::path temporal; + + { + std::shared_ptr tmp; + + { + const auto quarterTruckArchive = std::string(DATA_FOLDER) + "/ssp/quarter_truck/quarter-truck.ssp"; + ssp::SystemStructureDescription desc(quarterTruckArchive); + checkSystemStructure(desc); + tmp = desc.get_temp_dir(); + temporal = tmp->path(); + + const auto& groundComponent = desc.system.elements.components.at("ground"); + const auto groundFmu = desc.file(groundComponent.source); + REQUIRE(std::filesystem::exists(groundFmu)); + REQUIRE(groundFmu.extension().string() == ".fmu"); + } + + REQUIRE(std::filesystem::exists(temporal)); + } + + REQUIRE(!std::filesystem::exists(temporal)); +} + +TEST_CASE("test_ssp_parser_folder") +{ + const auto quarterTruckFolder = std::string(DATA_FOLDER) + "/ssp/quarter_truck"; + ssp::SystemStructureDescription desc(quarterTruckFolder); + checkSystemStructure(desc); + + const auto& ex = desc.defaultExperiment; + REQUIRE(ex); + CHECK_THAT(*ex->start, Catch::Matchers::WithinRel(10.)); + + const auto& annotations = ex->annotations; + REQUIRE(annotations.size() == 1); + REQUIRE(annotations.front().type == "com.opensimulationplatform"); + const auto& annotationNode = annotations.front().node; + const auto algorithmNode = annotationNode.child("osp:Algorithm"); + REQUIRE(algorithmNode); + const auto fixedStepNode = algorithmNode.child("osp:FixedStepAlgorithm"); + REQUIRE(fixedStepNode); + CHECK_THAT(fixedStepNode.attribute("baseStepSize").as_double(), Catch::Matchers::WithinRel(1e-4)); +}