Skip to content

Commit

Permalink
Merge pull request #15 from PowerGridModel/feature/c-tests
Browse files Browse the repository at this point in the history
C api and unit tests for vnf converter
  • Loading branch information
mgovers authored Oct 30, 2024
2 parents 1274760 + 1db9a92 commit e2ad0ca
Show file tree
Hide file tree
Showing 7 changed files with 225 additions and 34 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-FileCopyrightText: Contributors to the Power Grid Model project <[email protected]>
//
// 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
Original file line number Diff line number Diff line change
Expand Up @@ -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 <power_grid_model_io_native/common/common.hpp>
#include <power_grid_model_io_native/common/enum.hpp>

#include <power_grid_model/auxiliary/dataset.hpp>
#include <power_grid_model/auxiliary/meta_data_gen.hpp>
#include <power_grid_model/auxiliary/serialization/serializer.hpp>
Expand All @@ -15,11 +18,13 @@

#include <iostream>

namespace power_grid_model_io_native {

inline power_grid_model::ConstDataset
create_const_dataset_from_container(power_grid_model::Container<power_grid_model::Node> 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;
}
Expand All @@ -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
Expand All @@ -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() {
Expand All @@ -87,11 +98,11 @@ inline void PgmVnfConverter::convert_input() {

power_grid_model::Container<power_grid_model::Node> container;

for (const auto& node : nodes) {
for (auto const& node : nodes) {
container.emplace<power_grid_model::Node>(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);
Expand All @@ -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; }

Expand All @@ -121,7 +134,7 @@ inline std::vector<power_grid_model::Node> PgmVnfConverter::convert_node_input()
std::vector<power_grid_model::Node> 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);
}

Expand Down Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,29 +4,49 @@

#define PGM_IO_DLL_EXPORTS

#include <power_grid_model_io_native/common/enum.hpp>
#include <power_grid_model_io_native/vnf_converter/vnf_pgm_converter.hpp>

#include "handle.hpp"
#include <power_grid_model_io_native_c/basics.h>
#include <power_grid_model_io_native_c/vnf_pgm_converter.h>

#include <power_grid_model/auxiliary/dataset.hpp>
#include <power_grid_model/common/exception.hpp>

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; }
3 changes: 3 additions & 0 deletions tests/c_api_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
Expand Down
56 changes: 56 additions & 0 deletions tests/c_api_tests/test_c_api_vnf_converter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// SPDX-FileCopyrightText: Contributors to the Power Grid Model project <[email protected]>
//
// SPDX-License-Identifier: MPL-2.0

#

#include <power_grid_model_io_native_c/basics.h>
#include <power_grid_model_io_native_c/handle.h>
#include <power_grid_model_io_native_c/vnf_pgm_converter.h>

#include <power_grid_model/common/exception.hpp>

#include <cstring>
#include <doctest/doctest.h>

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
82 changes: 81 additions & 1 deletion tests/cpp_unit_tests/test_pgm_vnf_converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,92 @@
//
// SPDX-License-Identifier: MPL-2.0

#include <power_grid_model_io_native/common/enum.hpp>
#include <power_grid_model_io_native/vnf_converter/vnf_pgm_converter.hpp>

#include <power_grid_model/auxiliary/dataset.hpp>
#include <power_grid_model/auxiliary/meta_data.hpp>
#include <power_grid_model/auxiliary/meta_gen/gen_getters.hpp>

#include <cstring>
#include <doctest/doctest.h>

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<power_grid_model::Node> 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<power_grid_model::Node> 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

0 comments on commit e2ad0ca

Please sign in to comment.