From 51cd1d0c29921e6a443760b477aec4db401beef2 Mon Sep 17 00:00:00 2001 From: Carles Fernandez Date: Mon, 10 Jul 2017 23:59:18 +0200 Subject: [PATCH] Add unit tests for Data Type Adapter blocks --- src/tests/test_main.cc | 1 + .../adapter/adapter_test.cc | 407 ++++++++++++++++++ 2 files changed, 408 insertions(+) create mode 100644 src/tests/unit-tests/signal-processing-blocks/adapter/adapter_test.cc diff --git a/src/tests/test_main.cc b/src/tests/test_main.cc index b78051a69..49e9138b6 100644 --- a/src/tests/test_main.cc +++ b/src/tests/test_main.cc @@ -82,6 +82,7 @@ DECLARE_string(log_dir); #include "unit-tests/signal-processing-blocks/sources/gnss_sdr_valve_test.cc" #include "unit-tests/signal-processing-blocks/adapter/pass_through_test.cc" +#include "unit-tests/signal-processing-blocks/adapter/adapter_test.cc" #include "unit-tests/signal-processing-blocks/filter/fir_filter_test.cc" diff --git a/src/tests/unit-tests/signal-processing-blocks/adapter/adapter_test.cc b/src/tests/unit-tests/signal-processing-blocks/adapter/adapter_test.cc new file mode 100644 index 000000000..b2d917fbc --- /dev/null +++ b/src/tests/unit-tests/signal-processing-blocks/adapter/adapter_test.cc @@ -0,0 +1,407 @@ +/*! + * \file adapter_test.cc + * \brief This file implements tests for the DataTypeAdapter block + * \author Carles Fernandez-Prades, 2017. cfernandez(at)cttc.es + * + * + * ------------------------------------------------------------------------- + * + * Copyright (C) 2010-2017 (see AUTHORS file for a list of contributors) + * + * GNSS-SDR is a software defined Global Navigation + * Satellite Systems receiver + * + * This file is part of GNSS-SDR. + * + * GNSS-SDR is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GNSS-SDR is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with GNSS-SDR. If not, see . + * + * ------------------------------------------------------------------------- + */ + +#include +#include +#include +#include +#include +#include +#include +#include "byte_to_short.h" +#include "ibyte_to_cbyte.h" +#include "ibyte_to_complex.h" +#include "ibyte_to_cshort.h" +#include "ishort_to_complex.h" +#include "ishort_to_cshort.h" +#include "in_memory_configuration.h" + + +class DataTypeAdapter: public ::testing::Test +{ +public: + DataTypeAdapter(); + ~DataTypeAdapter(); + int run_byte_to_short_block(); + int run_ibyte_to_cbyte_block(); + int run_ibyte_to_complex_block(); + int run_ibyte_to_cshort_block(); + int run_ishort_to_complex_block(); + int run_ishort_to_cshort_block(); + std::string file_name_input; + std::string file_name_output; + std::vector input_data_bytes; + std::vector input_data_shorts; +}; + + +DataTypeAdapter::DataTypeAdapter() +{ + file_name_input = "adapter_test_input.dat"; + file_name_output = "adapter_test_output.dat"; + int8_t input_bytes[] = {2, 23, -1, 127, -127, 0}; + short input_shorts[] = {2, 23, -1, 127, -127, 0, 255, 255}; + + const std::vector input_data_bytes_(input_bytes, input_bytes + sizeof(input_bytes) / sizeof(int8_t)); + input_data_bytes = input_data_bytes_; + + const std::vector input_data_shorts_(input_shorts, input_shorts + sizeof(input_shorts) / sizeof(short)); + input_data_shorts = input_data_shorts_; +} + + +DataTypeAdapter::~DataTypeAdapter() +{} + + +int DataTypeAdapter::run_ishort_to_cshort_block() +{ + std::shared_ptr config = std::make_shared(); + config->set_property("Test.implementation", "Ishort_To_Cshort"); + std::shared_ptr ishort_to_cshort = std::make_shared(config.get(), "Test", 1, 1); + std::string expected_implementation = "Ishort_To_Cshort"; + EXPECT_EQ(expected_implementation, ishort_to_cshort->implementation()); + + std::ofstream ofs(file_name_input.c_str(), std::ofstream::binary); + for(std::vector::const_iterator i = input_data_shorts.begin(); i != input_data_shorts.end(); ++i) + { + short aux = *i; + ofs.write(reinterpret_cast(&aux), sizeof(short)); + } + ofs.close(); + + auto top_block = gr::make_top_block("Ishort_To_Cshort test"); + auto file_source = gr::blocks::file_source::make(sizeof(short), file_name_input.c_str()); + auto sink = gr::blocks::file_sink::make(sizeof(lv_16sc_t), file_name_output.c_str(), false); + + EXPECT_NO_THROW( { + top_block->connect(file_source, 0, ishort_to_cshort->get_left_block(), 0); + top_block->connect(ishort_to_cshort->get_right_block(), 0, sink, 0); + top_block->run(); + }); + return 0; +} + + +int DataTypeAdapter::run_ishort_to_complex_block() +{ + std::shared_ptr config = std::make_shared(); + config->set_property("Test.implementation", "Ishort_To_Complex"); + std::shared_ptr ishort_to_complex = std::make_shared(config.get(), "Test", 1, 1); + std::string expected_implementation = "Ishort_To_Complex"; + EXPECT_EQ(expected_implementation, ishort_to_complex->implementation()); + + std::ofstream ofs(file_name_input.c_str(), std::ofstream::binary); + for(std::vector::const_iterator i = input_data_shorts.begin(); i != input_data_shorts.end(); ++i) + { + short aux = *i; + ofs.write(reinterpret_cast(&aux), sizeof(short)); + } + ofs.close(); + + auto top_block = gr::make_top_block("Ishort_To_Complex test"); + auto file_source = gr::blocks::file_source::make(sizeof(short), file_name_input.c_str()); + auto sink = gr::blocks::file_sink::make(sizeof(gr_complex), file_name_output.c_str(), false); + + EXPECT_NO_THROW( { + top_block->connect(file_source, 0, ishort_to_complex->get_left_block(), 0); + top_block->connect(ishort_to_complex->get_right_block(), 0, sink, 0); + top_block->run(); + }); + return 0; +} + + +int DataTypeAdapter::run_ibyte_to_cshort_block() +{ + std::shared_ptr config = std::make_shared(); + config->set_property("Test.implementation", "Ibyte_To_Cshort"); + std::shared_ptr ibyte_to_cshort = std::make_shared(config.get(), "Test", 1, 1); + std::string expected_implementation = "Ibyte_To_Cshort"; + EXPECT_EQ(expected_implementation, ibyte_to_cshort->implementation()); + + std::ofstream ofs(file_name_input.c_str()); + for(std::vector::const_iterator i = input_data_bytes.begin(); i != input_data_bytes.end(); ++i) + { + ofs << *i; + } + ofs.close(); + + auto top_block = gr::make_top_block("Ibyte_To_Cshort test"); + auto file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name_input.c_str()); + auto sink = gr::blocks::file_sink::make(sizeof(lv_16sc_t), file_name_output.c_str(), false); + + EXPECT_NO_THROW( { + top_block->connect(file_source, 0, ibyte_to_cshort->get_left_block(), 0); + top_block->connect(ibyte_to_cshort->get_right_block(), 0, sink, 0); + top_block->run(); + }); + return 0; +} + + +int DataTypeAdapter::run_ibyte_to_complex_block() +{ + std::shared_ptr config = std::make_shared(); + config->set_property("Test.implementation", "Ibyte_To_Complex"); + std::shared_ptr ibyte_to_complex = std::make_shared(config.get(), "Test", 1, 1); + std::string expected_implementation = "Ibyte_To_Complex"; + EXPECT_EQ(expected_implementation, ibyte_to_complex->implementation()); + + std::ofstream ofs(file_name_input.c_str() ); + for(std::vector::const_iterator i = input_data_bytes.begin(); i != input_data_bytes.end(); ++i) + { + ofs << *i; + } + ofs.close(); + + auto top_block = gr::make_top_block("Ibyte_To_Complex test"); + auto file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name_input.c_str()); + auto sink = gr::blocks::file_sink::make(sizeof(gr_complex), file_name_output.c_str(), false); + + EXPECT_NO_THROW( { + top_block->connect(file_source, 0, ibyte_to_complex->get_left_block(), 0); + top_block->connect(ibyte_to_complex->get_right_block(), 0, sink, 0); + top_block->run(); + }); + return 0; +} + + +int DataTypeAdapter::run_ibyte_to_cbyte_block() +{ + std::shared_ptr config = std::make_shared(); + config->set_property("Test.implementation", "Ibyte_To_Cbyte"); + std::shared_ptr ibyte_to_cbyte = std::make_shared(config.get(), "Test", 1, 1); + std::string expected_implementation = "Ibyte_To_Cbyte"; + EXPECT_EQ(expected_implementation, ibyte_to_cbyte->implementation()); + + std::ofstream ofs(file_name_input.c_str()); + for(std::vector::const_iterator i = input_data_bytes.begin(); i != input_data_bytes.end(); ++i) + { + ofs << *i; + } + ofs.close(); + + auto top_block = gr::make_top_block("Ibyte_To_Cbyte test"); + auto file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name_input.c_str()); + auto sink = gr::blocks::file_sink::make(sizeof(short), file_name_output.c_str(), false); + + EXPECT_NO_THROW( { + top_block->connect(file_source, 0, ibyte_to_cbyte->get_left_block(), 0); + top_block->connect(ibyte_to_cbyte->get_right_block(), 0, sink, 0); + top_block->run(); + }); + return 0; +} + + +int DataTypeAdapter::run_byte_to_short_block() +{ + std::shared_ptr config = std::make_shared(); + config->set_property("Test.implementation", "Byte_To_Short"); + std::shared_ptr byte_to_short = std::make_shared(config.get(), "Test", 1, 1); + std::string expected_implementation = "Byte_To_Short"; + EXPECT_EQ(expected_implementation, byte_to_short->implementation()); + + std::ofstream ofs(file_name_input.c_str()); + for(std::vector::const_iterator i = input_data_bytes.begin(); i != input_data_bytes.end(); ++i) + { + ofs << *i; + } + ofs.close(); + + auto top_block = gr::make_top_block("Byte_To_Short test"); + auto file_source = gr::blocks::file_source::make(sizeof(int8_t), file_name_input.c_str()); + auto sink = gr::blocks::file_sink::make(sizeof(int16_t), file_name_output.c_str(), false); + + EXPECT_NO_THROW( { + top_block->connect(file_source, 0, byte_to_short->get_left_block(), 0); + top_block->connect(byte_to_short->get_right_block(), 0, sink, 0); + top_block->run(); + }); + return 0; +} + + +TEST_F(DataTypeAdapter, ByteToShortValidationOfResults) +{ + run_byte_to_short_block(); + std::ifstream ifs(file_name_output.data(), std::ifstream::binary | std::ifstream::in ); + + int16_t iSample; + int i = 0; + try + { + while(ifs.read(reinterpret_cast(&iSample), sizeof(int16_t))) + { + EXPECT_EQ(input_data_bytes.at(i), static_cast(iSample / 256)); // Scale down! + i++; + } + } + catch(std::system_error& e) + { + std::cerr << e.code().message() << std::endl; + } + ifs.close(); + remove(file_name_input.c_str()); + remove(file_name_output.c_str()); +} + + +TEST_F(DataTypeAdapter, IbyteToCbyteValidationOfResults) +{ + run_ibyte_to_cbyte_block(); + std::ifstream ifs(file_name_output.data(), std::ifstream::binary | std::ifstream::in ); + lv_8sc_t iSample; + int i = 0; + try + { + while(ifs.read(reinterpret_cast(&iSample), sizeof(lv_8sc_t))) + { + EXPECT_EQ(input_data_bytes.at(i), iSample.real()); + i++; + EXPECT_EQ(input_data_bytes.at(i), iSample.imag()); + i++; + } + } + catch(std::system_error& e) + { + std::cerr << e.code().message() << std::endl; + } + ifs.close(); + remove(file_name_input.c_str()); + remove(file_name_output.c_str()); +} + + +TEST_F(DataTypeAdapter, IbyteToComplexValidationOfResults) +{ + run_ibyte_to_cbyte_block(); + std::ifstream ifs(file_name_output.data(), std::ifstream::binary | std::ifstream::in ); + gr_complex iSample; + int i = 0; + try + { + while(ifs.read(reinterpret_cast(&iSample), sizeof(gr_complex))) + { + EXPECT_EQ(input_data_bytes.at(i), static_cast(iSample.real())); + i++; + EXPECT_EQ(input_data_bytes.at(i), static_cast(iSample.imag())); + i++; + } + } + catch(std::system_error& e) + { + std::cerr << e.code().message() << std::endl; + } + ifs.close(); + remove(file_name_input.c_str()); + remove(file_name_output.c_str()); +} + + +TEST_F(DataTypeAdapter, IbyteToCshortValidationOfResults) +{ + run_ibyte_to_cshort_block(); + std::ifstream ifs(file_name_output.data(), std::ifstream::binary | std::ifstream::in ); + lv_16sc_t iSample; + int i = 0; + try + { + while(ifs.read(reinterpret_cast(&iSample), sizeof(lv_16sc_t))) + { + EXPECT_EQ(input_data_bytes.at(i), static_cast(iSample.real())); + i++; + EXPECT_EQ(input_data_bytes.at(i), static_cast(iSample.imag())); + i++; + } + } + catch(std::system_error& e) + { + std::cerr << e.code().message() << std::endl; + } + ifs.close(); + remove(file_name_input.c_str()); + remove(file_name_output.c_str()); +} + + +TEST_F(DataTypeAdapter, IshortToComplexValidationOfResults) +{ + run_ishort_to_complex_block(); + std::ifstream ifs(file_name_output.data(), std::ifstream::binary | std::ifstream::in ); + gr_complex iSample; + int i = 0; + try + { + while(ifs.read(reinterpret_cast(&iSample), sizeof(gr_complex))) + { + EXPECT_EQ(input_data_shorts.at(i), static_cast(iSample.real())); + i++; + EXPECT_EQ(input_data_shorts.at(i), static_cast(iSample.imag())); + i++; + } + } + catch(std::system_error& e) + { + std::cerr << e.code().message() << std::endl; + } + ifs.close(); + remove(file_name_input.c_str()); + remove(file_name_output.c_str()); +} + + +TEST_F(DataTypeAdapter, IshortToCshortValidationOfResults) +{ + run_ishort_to_cshort_block(); + std::ifstream ifs(file_name_output.data(), std::ifstream::binary | std::ifstream::in ); + lv_16sc_t iSample; + int i = 0; + try + { + while(ifs.read(reinterpret_cast(&iSample), sizeof(lv_16sc_t))) + { + EXPECT_EQ(input_data_shorts.at(i), static_cast(iSample.real())); + i++; + EXPECT_EQ(input_data_shorts.at(i), static_cast(iSample.imag())); + i++; + } + } + catch(std::system_error& e) + { + std::cerr << e.code().message() << std::endl; + } + ifs.close(); + remove(file_name_input.c_str()); + remove(file_name_output.c_str()); +}