diff --git a/power_grid_model_io_native_c/power_grid_model_io_native/include/power_grid_model_io_native/common/enum.hpp b/power_grid_model_io_native_c/power_grid_model_io_native/include/power_grid_model_io_native/common/enum.hpp new file mode 100644 index 0000000..9ce2a84 --- /dev/null +++ b/power_grid_model_io_native_c/power_grid_model_io_native/include/power_grid_model_io_native/common/enum.hpp @@ -0,0 +1,16 @@ +// SPDX-FileCopyrightText: Contributors to the Power Grid Model project +// +// SPDX-License-Identifier: MPL-2.0 + +#pragma once + +#include "common.hpp" + +namespace power_grid_model_io_native { + +enum class ExperimentalFeatures : IntS { + experimental_features_disabled = 0, + experimental_features_enabled = 1, +}; + +} // namespace power_grid_model_io_native diff --git a/power_grid_model_io_native_c/power_grid_model_io_native/include/power_grid_model_io_native/vnf_converter/vnf_pgm_converter.hpp b/power_grid_model_io_native_c/power_grid_model_io_native/include/power_grid_model_io_native/vnf_converter/vnf_pgm_converter.hpp index ddb2272..ce51ec2 100644 --- a/power_grid_model_io_native_c/power_grid_model_io_native/include/power_grid_model_io_native/vnf_converter/vnf_pgm_converter.hpp +++ b/power_grid_model_io_native_c/power_grid_model_io_native/include/power_grid_model_io_native/vnf_converter/vnf_pgm_converter.hpp @@ -6,6 +6,9 @@ #ifndef POWER_GRID_MODEL_IO_NATIVE_C_VNF_PGM_CONVERTER_HPP #define POWER_GRID_MODEL_IO_NATIVE_C_VNF_PGM_CONVERTER_HPP +#include +#include + #include #include #include @@ -15,11 +18,13 @@ #include +namespace power_grid_model_io_native { + inline power_grid_model::ConstDataset create_const_dataset_from_container(power_grid_model::Container const& /*container*/, power_grid_model::meta_data::MetaData const& meta_data) { // for now leave it empty - std::string_view const dataset_name = "empty_dataset"; + std::string_view const dataset_name = "input"; power_grid_model::ConstDataset const_dataset{false, 1, dataset_name, meta_data}; return const_dataset; } @@ -32,23 +37,25 @@ inline std::string serialize_data(power_grid_model::ConstDataset const& const_da class PgmVnfConverter { public: - PgmVnfConverter(char* buffer = nullptr, power_grid_model::WritableDataset* data = nullptr); + using enum ExperimentalFeatures; + PgmVnfConverter(std::string_view buffer, + ExperimentalFeatures experimental_feature_flag = experimental_features_disabled); // Public member functions void parse_vnf_file(); void convert_input(); std::string const& get_serialized_data() const; - void set_file_buffer(char* file_buffer); - void set_deserialized_data(power_grid_model::WritableDataset* deserialized_data); - char* get_file_buffer(); - power_grid_model::WritableDataset* get_deserialized_data(); + void set_file_buffer(std::string_view file_buffer); + void set_deserialized_dataset(power_grid_model::WritableDataset* deserialized_data); + std::string_view get_file_buffer() const; + power_grid_model::WritableDataset* get_deserialized_dataset(); private: // Private attributes - char* f_file_buffer; - power_grid_model::WritableDataset* - deserialized_data; // this type because it is generated by a deserializer type structure + std::string_view f_file_buffer; + power_grid_model::WritableDataset* deserialized_data{ + nullptr}; // this type because it is generated by a deserializer type structure std::string serialized_data; // Private member functions @@ -62,17 +69,21 @@ class PgmVnfConverter { void convert_links_input(); }; -inline PgmVnfConverter::PgmVnfConverter(char* buffer, power_grid_model::WritableDataset* data) - : f_file_buffer(buffer), deserialized_data(data) { - using namespace std::string_literals; - using power_grid_model::ExperimentalFeature; - throw ExperimentalFeature{"PGM_VNF_converter", ExperimentalFeature::TypeValuePair{.name = "PGM_VNF_conversion", - .value = std::to_string(1)}}; +inline PgmVnfConverter::PgmVnfConverter(std::string_view buffer, ExperimentalFeatures experimental_feature_flag) + : f_file_buffer(buffer) { + if (experimental_feature_flag == experimental_features_disabled) { + using power_grid_model::ExperimentalFeature; + throw ExperimentalFeature{ + "PGM_VNF_converter", + ExperimentalFeature::TypeValuePair{.name = "PGM_VNF_conversion", + .value = "PgmVnfConverter is still in an experimental phase, if you'd " + "like to use it, enable experimental features."}}; + } } inline void PgmVnfConverter::parse_vnf_file() { // the function should use a deserializer type structure - // will be implemented later + // will be implemented later. } inline void PgmVnfConverter::convert_input() { @@ -87,11 +98,11 @@ inline void PgmVnfConverter::convert_input() { power_grid_model::Container container; - for (const auto& node : nodes) { + for (auto const& node : nodes) { container.emplace(node.id(), node); } - constexpr const auto& meta_data = power_grid_model::meta_data::meta_data_gen::meta_data; + constexpr auto const& meta_data = power_grid_model::meta_data::meta_data_gen::meta_data; power_grid_model::ConstDataset const const_dataset = create_const_dataset_from_container(container, meta_data); std::string const serialized_pgm_data = serialize_data(const_dataset); @@ -104,15 +115,17 @@ inline void PgmVnfConverter::convert_input() { this->serialized_data = serialized_pgm_data; } -inline void PgmVnfConverter::set_file_buffer(char* file_buffer) { this->f_file_buffer = file_buffer; } +inline void PgmVnfConverter::set_file_buffer(std::string_view file_buffer) { this->f_file_buffer = file_buffer; } -inline void PgmVnfConverter::set_deserialized_data(power_grid_model::WritableDataset* data) { +inline void PgmVnfConverter::set_deserialized_dataset(power_grid_model::WritableDataset* data) { this->deserialized_data = data; } -inline char* PgmVnfConverter::get_file_buffer() { return this->f_file_buffer; } +inline std::string_view PgmVnfConverter::get_file_buffer() const { return this->f_file_buffer; } -inline power_grid_model::WritableDataset* PgmVnfConverter::get_deserialized_data() { return this->deserialized_data; } +inline power_grid_model::WritableDataset* PgmVnfConverter::get_deserialized_dataset() { + return this->deserialized_data; +} inline std::string const& PgmVnfConverter::get_serialized_data() const { return this->serialized_data; } @@ -121,7 +134,7 @@ inline std::vector PgmVnfConverter::convert_node_input() std::vector nodes; nodes.reserve(node_inputs.size()); - for (const auto& node_input : node_inputs) { + for (auto const& node_input : node_inputs) { nodes.emplace_back(node_input); } @@ -163,4 +176,6 @@ inline std::string const& convert_input_wrapper(PgmVnfConverter* obj) { return obj->get_serialized_data(); } +} // namespace power_grid_model_io_native + #endif // POWER_GRID_MODEL_IO_NATIVE_C_VNF_PGM_CONVERTER_HPP diff --git a/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/vnf_pgm_converter.h b/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/vnf_pgm_converter.h index 9dbfb9c..b11e85e 100644 --- a/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/vnf_pgm_converter.h +++ b/power_grid_model_io_native_c/power_grid_model_io_native_c/include/power_grid_model_io_native_c/vnf_pgm_converter.h @@ -19,7 +19,8 @@ extern "C" { * @return The pointer to a PGM_IO_VnfConverter instance. The instance must be freed by * PGM_IO_destroy_vnf_converter. */ -PGM_IO_API PGM_IO_VnfConverter* PGM_IO_create_vnf_converter(PGM_IO_Handle* handle, char* file_buffer); +PGM_IO_API PGM_IO_VnfConverter* PGM_IO_create_vnf_converter(PGM_IO_Handle* handle, char const* file_buffer, + PGM_IO_ExperimentalFeatures experimental_features); /** * @brief Retrieve the transformed input data from .vnf format to PGM format diff --git a/power_grid_model_io_native_c/power_grid_model_io_native_c/src/vnf_pgm_converter.cpp b/power_grid_model_io_native_c/power_grid_model_io_native_c/src/vnf_pgm_converter.cpp index 9b78b96..b8065ed 100644 --- a/power_grid_model_io_native_c/power_grid_model_io_native_c/src/vnf_pgm_converter.cpp +++ b/power_grid_model_io_native_c/power_grid_model_io_native_c/src/vnf_pgm_converter.cpp @@ -4,6 +4,7 @@ #define PGM_IO_DLL_EXPORTS +#include #include #include "handle.hpp" @@ -11,22 +12,41 @@ #include #include +#include -using power_grid_model::ConstDataset; +namespace pgm_io = power_grid_model_io_native; -struct PGM_IO_VnfConverter : public PgmVnfConverter { +struct PGM_IO_VnfConverter : public pgm_io::PgmVnfConverter { using PgmVnfConverter::PgmVnfConverter; }; -// TODO(Laurynas-Jagutis) add call_with_catch for these functions. -PGM_IO_VnfConverter* PGM_IO_create_vnf_converter(const PGM_IO_Handle* /*handle*/, char* file_buffer) { - auto* converter = new PGM_IO_VnfConverter(file_buffer); - parse_vnf_file_wrapper(converter); - return converter; +PGM_IO_VnfConverter* PGM_IO_create_vnf_converter(PGM_IO_Handle* handle, char const* file_buffer, + PGM_IO_ExperimentalFeatures experimental_features) { + return call_with_catch( + handle, + [file_buffer, experimental_features] { + using enum pgm_io::ExperimentalFeatures; + auto experimental_feature = experimental_features_disabled; + switch (experimental_features) { + case PGM_IO_experimental_features_disabled: + experimental_feature = experimental_features_disabled; + break; + case PGM_IO_experimental_features_enabled: + experimental_feature = experimental_features_enabled; + break; + default: + throw power_grid_model::MissingCaseForEnumError{"PGM_IO_create_vnf_converter", experimental_features}; + } + auto* converter = new PGM_IO_VnfConverter(file_buffer, experimental_feature); + parse_vnf_file_wrapper(converter); + return converter; + }, + PGM_IO_regular_error); } -char const* PGM_IO_get_vnf_input_data(const PGM_IO_Handle* /*handle*/, PGM_IO_VnfConverter* converter_ptr) { - return convert_input_wrapper(converter_ptr).c_str(); +char const* PGM_IO_get_vnf_input_data(PGM_IO_Handle* handle, PGM_IO_VnfConverter* converter_ptr) { + return call_with_catch( + handle, [converter_ptr] { return convert_input_wrapper(converter_ptr).c_str(); }, PGM_IO_regular_error); } void PGM_IO_destroy_vnf_converter(PGM_IO_VnfConverter* converter_ptr) { delete converter_ptr; } diff --git a/tests/c_api_tests/CMakeLists.txt b/tests/c_api_tests/CMakeLists.txt index beb5468..80e418f 100644 --- a/tests/c_api_tests/CMakeLists.txt +++ b/tests/c_api_tests/CMakeLists.txt @@ -5,12 +5,15 @@ set(PROJECT_SOURCES "test_c_api.cpp" "test_entry_point.cpp" + "test_c_api_vnf_converter.cpp" ) add_executable(power_grid_model_io_native_c_api_tests ${PROJECT_SOURCES}) target_link_libraries(power_grid_model_io_native_c_api_tests PRIVATE + power_grid_model + power_grid_model_io_native power_grid_model_io_native_c doctest::doctest ) diff --git a/tests/c_api_tests/test_c_api_vnf_converter.cpp b/tests/c_api_tests/test_c_api_vnf_converter.cpp new file mode 100644 index 0000000..00ac5a4 --- /dev/null +++ b/tests/c_api_tests/test_c_api_vnf_converter.cpp @@ -0,0 +1,56 @@ +// SPDX-FileCopyrightText: Contributors to the Power Grid Model project +// +// SPDX-License-Identifier: MPL-2.0 + +# + +#include +#include +#include + +#include + +#include +#include + +namespace power_grid_model_io_native { + +using enum PGM_IO_ExperimentalFeatures; + +TEST_CASE("Test PGM_IO_create_vnf_converter") { + PGM_IO_ExperimentalFeatures experimental_feature_flag = PGM_IO_experimental_features_disabled; + + SUBCASE("Test PGM_IO_create_vnf_converter without experimental feature flag") { + PGM_IO_Handle* handle = PGM_IO_create_handle(); + auto converter = PGM_IO_create_vnf_converter(handle, "", experimental_feature_flag); + CHECK(PGM_IO_error_code(handle) == PGM_IO_regular_error); + PGM_IO_destroy_vnf_converter(converter); + PGM_IO_destroy_handle(handle); + } + + SUBCASE("Test PGM_IO_create_vnf_converter with experimental feature flag") { + PGM_IO_Handle* handle = PGM_IO_create_handle(); + experimental_feature_flag = PGM_IO_experimental_features_enabled; + auto converter = PGM_IO_create_vnf_converter(handle, "", experimental_feature_flag); + CHECK(converter != nullptr); + PGM_IO_destroy_vnf_converter(converter); + PGM_IO_destroy_handle(handle); + } +} + +TEST_CASE("Test PGM_IO_get_vnf_input_data") { + PGM_IO_Handle* handle = PGM_IO_create_handle(); + PGM_IO_ExperimentalFeatures experimental_feature_flag = PGM_IO_experimental_features_enabled; + + auto converter = PGM_IO_create_vnf_converter(handle, "", experimental_feature_flag); + CHECK(converter != nullptr); + + auto json_result = PGM_IO_get_vnf_input_data(handle, converter); + std::string_view json_string = R"({"version":"1.0","type":"input","is_batch":false,"attributes":{},"data":{}})"; + CHECK(json_string == json_result); + + PGM_IO_destroy_vnf_converter(converter); + PGM_IO_destroy_handle(handle); +} + +} // namespace power_grid_model_io_native diff --git a/tests/cpp_unit_tests/test_pgm_vnf_converter.cpp b/tests/cpp_unit_tests/test_pgm_vnf_converter.cpp index 21f12ce..245bf50 100644 --- a/tests/cpp_unit_tests/test_pgm_vnf_converter.cpp +++ b/tests/cpp_unit_tests/test_pgm_vnf_converter.cpp @@ -2,12 +2,92 @@ // // SPDX-License-Identifier: MPL-2.0 +#include #include +#include +#include +#include + +#include #include namespace power_grid_model_io_native { -TEST_CASE("Test converter constructor") { CHECK_THROWS_AS(PgmVnfConverter(), power_grid_model::ExperimentalFeature); }; +using enum ExperimentalFeatures; + +std::string_view json_string = R"({"version":"1.0","type":"input","is_batch":false,"attributes":{},"data":{}})"; + +TEST_CASE("Test converter constructor") { + SUBCASE("Without experimental features") { + CHECK_THROWS_AS(PgmVnfConverter("", experimental_features_disabled), power_grid_model::ExperimentalFeature); + } + + SUBCASE("With experimental features") { CHECK_NOTHROW(PgmVnfConverter("", experimental_features_enabled)); } +} + +TEST_CASE("Test parse_vnf_file is callable") { + auto converter = PgmVnfConverter("", experimental_features_enabled); + CHECK_NOTHROW(converter.parse_vnf_file()); +} + +TEST_CASE("Test convert_input") { + auto converter = PgmVnfConverter("", experimental_features_enabled); + SUBCASE("Test convert_input is callable") { CHECK_NOTHROW(converter.convert_input()); } + SUBCASE("Test convert_input") { + converter.convert_input(); + auto json_result = converter.get_serialized_data(); + CHECK(json_string == json_result); + } +} + +TEST_CASE("Test create_const_dataset_from_container is callable") { + power_grid_model::Container container; + constexpr const auto& meta_data = power_grid_model::meta_data::meta_data_gen::meta_data; + CHECK_NOTHROW(create_const_dataset_from_container(container, meta_data)); +} + +TEST_CASE("Test serialize_data") { + power_grid_model::Container container; + constexpr const auto& meta_data = power_grid_model::meta_data::meta_data_gen::meta_data; + power_grid_model::ConstDataset const const_dataset = create_const_dataset_from_container(container, meta_data); + CHECK_NOTHROW(serialize_data(const_dataset)); + auto result = serialize_data(const_dataset); + CHECK(result == json_string); +} + +TEST_CASE("Test setter/getter of file_buffer") { + auto converter = PgmVnfConverter("", experimental_features_enabled); + std::string_view value = "123"; + converter.set_file_buffer(value); + auto file_buff = converter.get_file_buffer(); + CHECK(file_buff == value); +} + +TEST_CASE("Test setter/getter of deserialized_data") { + constexpr auto const& meta_data = power_grid_model::meta_data::meta_data_gen::meta_data; + + std::string_view const dataset_name = "input"; + power_grid_model::WritableDataset writable_dataset{false, 1, dataset_name, meta_data}; + + auto converter = PgmVnfConverter("", experimental_features_enabled); + converter.set_deserialized_dataset(&writable_dataset); + auto writable_dataset_after_getter = converter.get_deserialized_dataset(); + CHECK(&writable_dataset == writable_dataset_after_getter); +} + +TEST_CASE("Test parse_vnf_file_wrapper") { + auto converter = PgmVnfConverter("", experimental_features_enabled); + PgmVnfConverter* converterPtr = &converter; + CHECK_NOTHROW(parse_vnf_file_wrapper(converterPtr)); +} + +TEST_CASE("Test convert_input_wrapper") { + auto converter = PgmVnfConverter("", experimental_features_enabled); + PgmVnfConverter* converterPtr = &converter; + CHECK_NOTHROW(convert_input_wrapper(converterPtr)); + auto result = convert_input_wrapper(converterPtr); + CHECK(json_string == result); +} } // namespace power_grid_model_io_native