diff options
Diffstat (limited to 'host/tests')
-rw-r--r-- | host/tests/common/mock_zero_copy.cpp | 10 | ||||
-rw-r--r-- | host/tests/common/mock_zero_copy.hpp | 118 | ||||
-rw-r--r-- | host/tests/device3_test.cpp | 2 | ||||
-rw-r--r-- | host/tests/sph_recv_test.cpp | 271 | ||||
-rw-r--r-- | host/tests/sph_send_test.cpp | 93 |
5 files changed, 293 insertions, 201 deletions
diff --git a/host/tests/common/mock_zero_copy.cpp b/host/tests/common/mock_zero_copy.cpp index b1d384ec7..eee96234d 100644 --- a/host/tests/common/mock_zero_copy.cpp +++ b/host/tests/common/mock_zero_copy.cpp @@ -8,7 +8,17 @@ #include "mock_zero_copy.hpp" #include <boost/shared_ptr.hpp> +using namespace uhd::transport; + +mock_zero_copy::mock_zero_copy( + vrt::if_packet_info_t::link_type_t link_type +) : _link_type(link_type) { +} + uhd::transport::managed_recv_buffer::sptr mock_zero_copy::get_recv_buff(double) { + if (_simulate_io_error) { + throw uhd::io_error("IO error exception"); //simulate an IO error + } if (_rx_mems.empty()) { return uhd::transport::managed_recv_buffer::sptr(); // timeout } diff --git a/host/tests/common/mock_zero_copy.hpp b/host/tests/common/mock_zero_copy.hpp index 838975129..867300ac5 100644 --- a/host/tests/common/mock_zero_copy.hpp +++ b/host/tests/common/mock_zero_copy.hpp @@ -14,11 +14,13 @@ #include <uhd/types/endianness.hpp> #include <uhd/types/sid.hpp> #include <uhd/utils/byteswap.hpp> +#include <uhd/exception.hpp> #include <boost/make_shared.hpp> #include <boost/shared_ptr.hpp> #include <boost/shared_array.hpp> #include <list> #include <vector> + /*********************************************************************** * Transport mockups **********************************************************************/ @@ -65,8 +67,10 @@ class mock_mrb : public uhd::transport::managed_recv_buffer { class mock_zero_copy : public uhd::transport::zero_copy_if { public: typedef boost::shared_ptr<mock_zero_copy> sptr; - uhd::transport::managed_recv_buffer::sptr get_recv_buff(double); + mock_zero_copy(uhd::transport::vrt::if_packet_info_t::link_type_t type); + + uhd::transport::managed_recv_buffer::sptr get_recv_buff(double); uhd::transport::managed_send_buffer::sptr get_send_buff(double); size_t get_num_recv_frames(void) const { return 1; } @@ -74,6 +78,25 @@ class mock_zero_copy : public uhd::transport::zero_copy_if { size_t get_recv_frame_size(void) const { return RECV_BUFF_SIZE; } size_t get_send_frame_size(void) const { return SEND_BUFF_SIZE; } + void set_simulate_io_error(bool status) { _simulate_io_error = status; } + + template <typename T, uhd::endianness_t endianness = uhd::ENDIANNESS_BIG> + void push_back_recv_packet( + uhd::transport::vrt::if_packet_info_t& ifpi, + const std::vector<T>& otw_data + ); + + template <uhd::endianness_t endianness = uhd::ENDIANNESS_BIG> + void push_back_inline_message_packet( + uhd::transport::vrt::if_packet_info_t& ifpi, + const uint32_t message + ); + + template <uhd::endianness_t endianness = uhd::ENDIANNESS_BIG> + void pop_send_packet( + uhd::transport::vrt::if_packet_info_t &ifpi + ); + private: std::list<boost::shared_array<uint8_t>> _tx_mems; std::list<size_t> _tx_lens; @@ -83,6 +106,97 @@ class mock_zero_copy : public uhd::transport::zero_copy_if { std::vector<boost::shared_ptr<mock_msb>> _msbs; std::vector<boost::shared_ptr<mock_mrb>> _mrbs; + + uhd::transport::vrt::if_packet_info_t::link_type_t _link_type; + bool _simulate_io_error = false; }; -#endif /*INCLUDED_MOCK_XPORT_HPP*/
\ No newline at end of file +template <typename T, uhd::endianness_t endianness> +void mock_zero_copy::push_back_recv_packet( + uhd::transport::vrt::if_packet_info_t& ifpi, + const std::vector<T>& otw_data +) { + using namespace uhd::transport; + + UHD_ASSERT_THROW( + ifpi.num_payload_words32 * sizeof(uint32_t) + == otw_data.size() * sizeof(T)); + + const size_t max_hdr_len = + _link_type == vrt::if_packet_info_t::LINK_TYPE_CHDR ? + vrt::chdr::max_if_hdr_words64*sizeof(uint64_t) : + (vrt::max_if_hdr_words32 + 1/*tlr*/)*sizeof(uint32_t); + + const size_t max_pkt_len = + ifpi.num_payload_words32*sizeof(uint32_t)+max_hdr_len; + + UHD_ASSERT_THROW(max_pkt_len <= RECV_BUFF_SIZE); + + // Create recv buffer + _rx_mems.push_back(boost::shared_array<uint8_t>(new uint8_t[max_pkt_len])); + uint32_t* rx_buff_ptr = reinterpret_cast<uint32_t*>(_rx_mems.back().get()); + + // Copy header + if (endianness == uhd::ENDIANNESS_BIG) { + if (_link_type == vrt::if_packet_info_t::LINK_TYPE_CHDR) { + uhd::transport::vrt::chdr::if_hdr_pack_be(rx_buff_ptr, ifpi); + } + else { + uhd::transport::vrt::if_hdr_pack_be(rx_buff_ptr, ifpi); + } + } else { + if (_link_type == vrt::if_packet_info_t::LINK_TYPE_CHDR) { + uhd::transport::vrt::chdr::if_hdr_pack_le(rx_buff_ptr, ifpi); + } + else { + uhd::transport::vrt::if_hdr_pack_le(rx_buff_ptr, ifpi); + } + } + + // Copy data + uint32_t* data_ptr = (rx_buff_ptr + ifpi.num_header_words32); + std::copy(otw_data.begin(), otw_data.end(), reinterpret_cast<T*>(data_ptr)); + _rx_lens.push_back(ifpi.num_packet_words32*sizeof(uint32_t)); +} + +template <uhd::endianness_t endianness> +void mock_zero_copy::push_back_inline_message_packet( + uhd::transport::vrt::if_packet_info_t& ifpi, + const uint32_t message +) { + const std::vector<uint32_t> data { message | uhd::byteswap(message) }; + push_back_recv_packet<uint32_t, endianness>(ifpi, data); +} + + +template <uhd::endianness_t endianness> +void mock_zero_copy::pop_send_packet( + uhd::transport::vrt::if_packet_info_t &ifpi +) { + using namespace uhd::transport; + + ifpi.num_packet_words32 = _tx_lens.front()/sizeof(uint32_t); + + uint32_t* tx_buff_ptr = reinterpret_cast<uint32_t *>(_tx_mems.front().get()); + + if (endianness == uhd::ENDIANNESS_BIG) { + if (_link_type == vrt::if_packet_info_t::LINK_TYPE_CHDR) { + uhd::transport::vrt::chdr::if_hdr_unpack_be(tx_buff_ptr, ifpi); + } + else { + uhd::transport::vrt::if_hdr_unpack_be(tx_buff_ptr, ifpi); + } + } + else { + if (_link_type == vrt::if_packet_info_t::LINK_TYPE_CHDR) { + uhd::transport::vrt::chdr::if_hdr_unpack_le(tx_buff_ptr, ifpi); + } + else { + uhd::transport::vrt::if_hdr_unpack_le(tx_buff_ptr, ifpi); + } + } + _tx_mems.pop_front(); + _tx_lens.pop_front(); +} + +#endif /*INCLUDED_MOCK_XPORT_HPP*/ diff --git a/host/tests/device3_test.cpp b/host/tests/device3_test.cpp index 658855f15..db613d06e 100644 --- a/host/tests/device3_test.cpp +++ b/host/tests/device3_test.cpp @@ -36,7 +36,7 @@ uhd::both_xports_t make_mock_transport(const uhd::sid_t& tx_sid) { xports.recv_sid = tx_sid.reversed(); xports.send_buff_size = SEND_BUFF_SIZE; xports.recv_buff_size = RECV_BUFF_SIZE; - xports.send = boost::make_shared<mock_zero_copy>(); + xports.send = boost::make_shared<mock_zero_copy>(if_packet_info_t::LINK_TYPE_CHDR); xports.recv = xports.send; return xports; } diff --git a/host/tests/sph_recv_test.cpp b/host/tests/sph_recv_test.cpp index e21e6ab07..705fd4f83 100644 --- a/host/tests/sph_recv_test.cpp +++ b/host/tests/sph_recv_test.cpp @@ -7,12 +7,15 @@ #include <boost/test/unit_test.hpp> #include "../lib/transport/super_recv_packet_handler.hpp" +#include "../common/mock_zero_copy.hpp" #include <boost/shared_array.hpp> #include <boost/bind.hpp> #include <complex> #include <vector> #include <list> +using namespace uhd::transport; + #define BOOST_CHECK_TS_CLOSE(a, b) \ BOOST_CHECK_CLOSE((a).get_real_secs(), (b).get_real_secs(), 0.001) @@ -29,71 +32,6 @@ struct overflow_handler_type{ size_t num_overflow; }; -/*********************************************************************** - * A dummy managed receive buffer for testing - **********************************************************************/ -class dummy_mrb : public uhd::transport::managed_recv_buffer{ -public: - void release(void){ - //NOP - } - - sptr get_new(boost::shared_array<char> mem, size_t len){ - _mem = mem; - return make(this, _mem.get(), len); - } - -private: - boost::shared_array<char> _mem; -}; - -/*********************************************************************** - * A dummy transport class to fill with fake data - **********************************************************************/ -class dummy_recv_xport_class{ -public: - dummy_recv_xport_class(const std::string &end) : io_status(true) { - _end = end; - } - - void set_io_status(bool status){ - io_status = status; - } - - void push_back_packet( - uhd::transport::vrt::if_packet_info_t &ifpi, - const uint32_t optional_msg_word = 0 - ){ - const size_t max_pkt_len = (ifpi.num_payload_words32 + uhd::transport::vrt::max_if_hdr_words32 + 1/*tlr*/)*sizeof(uint32_t); - _mems.push_back(boost::shared_array<char>(new char[max_pkt_len])); - if (_end == "big"){ - uhd::transport::vrt::if_hdr_pack_be(reinterpret_cast<uint32_t *>(_mems.back().get()), ifpi); - } - if (_end == "little"){ - uhd::transport::vrt::if_hdr_pack_le(reinterpret_cast<uint32_t *>(_mems.back().get()), ifpi); - } - (reinterpret_cast<uint32_t *>(_mems.back().get()) + ifpi.num_header_words32)[0] = optional_msg_word | uhd::byteswap(optional_msg_word); - _lens.push_back(ifpi.num_packet_words32*sizeof(uint32_t)); - } - - uhd::transport::managed_recv_buffer::sptr get_recv_buff(double){ - if (!io_status) throw uhd::io_error("IO error exception"); //simulate an IO error - if (_mems.empty()) return uhd::transport::managed_recv_buffer::sptr(); //timeout - _mrbs.push_back(boost::shared_ptr<dummy_mrb>(new dummy_mrb())); - uhd::transport::managed_recv_buffer::sptr mrb = _mrbs.back()->get_new(_mems.front(), _lens.front()); - _mems.pop_front(); - _lens.pop_front(); - return mrb; - } - -private: - std::list<boost::shared_array<char> > _mems; - std::list<size_t> _lens; - std::vector<boost::shared_ptr<dummy_mrb> > _mrbs; - std::string _end; - bool io_status; -}; - //////////////////////////////////////////////////////////////////////// BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_normal){ //////////////////////////////////////////////////////////////////////// @@ -103,9 +41,10 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_normal){ id.output_format = "fc32"; id.num_outputs = 1; - dummy_recv_xport_class dummy_recv_xport("big"); - uhd::transport::vrt::if_packet_info_t ifpi; - ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA; + mock_zero_copy xport(vrt::if_packet_info_t::LINK_TYPE_VRLP); + + vrt::if_packet_info_t ifpi; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 0; ifpi.packet_count = 0; ifpi.sob = true; @@ -125,7 +64,8 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_normal){ //generate a bunch of packets for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ ifpi.num_payload_words32 = 10 + i%10; - dummy_recv_xport.push_back_packet(ifpi); + std::vector<uint32_t> data(ifpi.num_payload_words32, 0); + xport.push_back_recv_packet(ifpi, data); ifpi.packet_count++; ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE); } @@ -135,7 +75,11 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_normal){ handler.set_vrt_unpacker(&uhd::transport::vrt::if_hdr_unpack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); - handler.set_xport_chan_get_buff(0, boost::bind(&dummy_recv_xport_class::get_recv_buff, &dummy_recv_xport, _1)); + handler.set_xport_chan_get_buff( + 0, + [&xport](double timeout) { + return xport.get_recv_buff(timeout); + }); handler.set_converter(id); //check the received packets @@ -165,7 +109,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_normal){ } //simulate the transport failing - dummy_recv_xport.set_io_status(false); + xport.set_simulate_io_error(true); BOOST_REQUIRE_THROW(handler.recv(&buff.front(), buff.size(), metadata, 1.0, true), uhd::io_error); } @@ -178,9 +122,10 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_sequence_error){ id.output_format = "fc32"; id.num_outputs = 1; - dummy_recv_xport_class dummy_recv_xport("big"); - uhd::transport::vrt::if_packet_info_t ifpi; - ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA; + mock_zero_copy xport(vrt::if_packet_info_t::LINK_TYPE_VRLP); + + vrt::if_packet_info_t ifpi; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 0; ifpi.packet_count = 0; ifpi.sob = true; @@ -201,18 +146,24 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_sequence_error){ for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ ifpi.num_payload_words32 = 10 + i%10; if (i != NUM_PKTS_TO_TEST/2){ //simulate a lost packet - dummy_recv_xport.push_back_packet(ifpi); + std::vector<uint32_t> data(ifpi.num_payload_words32, 0); + xport.push_back_recv_packet(ifpi, data); } ifpi.packet_count++; ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE); } //create the super receive packet handler - uhd::transport::sph::recv_packet_handler handler(1); - handler.set_vrt_unpacker(&uhd::transport::vrt::if_hdr_unpack_be); + sph::recv_packet_handler handler(1); + handler.set_vrt_unpacker(&vrt::if_hdr_unpack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); - handler.set_xport_chan_get_buff(0, boost::bind(&dummy_recv_xport_class::get_recv_buff, &dummy_recv_xport, _1)); + handler.set_xport_chan_get_buff( + 0, + [&xport](double timeout) { + return xport.get_recv_buff(timeout); + } + ); handler.set_converter(id); //check the received packets @@ -251,7 +202,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_sequence_error){ } //simulate the transport failing - dummy_recv_xport.set_io_status(false); + xport.set_simulate_io_error(true); BOOST_REQUIRE_THROW(handler.recv(&buff.front(), buff.size(), metadata, 1.0, true), uhd::io_error); } @@ -264,9 +215,10 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_inline_message){ id.output_format = "fc32"; id.num_outputs = 1; - dummy_recv_xport_class dummy_recv_xport("big"); - uhd::transport::vrt::if_packet_info_t ifpi; - ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA; + mock_zero_copy xport(vrt::if_packet_info_t::LINK_TYPE_VRLP); + + vrt::if_packet_info_t ifpi; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 0; ifpi.packet_count = 0; ifpi.sob = true; @@ -285,26 +237,35 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_inline_message){ //generate a bunch of packets for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ - ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 10 + i%10; - dummy_recv_xport.push_back_packet(ifpi); + std::vector<uint32_t> data(ifpi.num_payload_words32, 0); + xport.push_back_recv_packet(ifpi, data); ifpi.packet_count++; ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE); //simulate overflow if (i == NUM_PKTS_TO_TEST/2){ - ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_CONTEXT; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_CONTEXT; ifpi.num_payload_words32 = 1; - dummy_recv_xport.push_back_packet(ifpi, uhd::rx_metadata_t::ERROR_CODE_OVERFLOW); + + xport.push_back_inline_message_packet( + ifpi, + uhd::rx_metadata_t::ERROR_CODE_OVERFLOW); } } //create the super receive packet handler - uhd::transport::sph::recv_packet_handler handler(1); - handler.set_vrt_unpacker(&uhd::transport::vrt::if_hdr_unpack_be); + sph::recv_packet_handler handler(1); + handler.set_vrt_unpacker(&vrt::if_hdr_unpack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); - handler.set_xport_chan_get_buff(0, boost::bind(&dummy_recv_xport_class::get_recv_buff, &dummy_recv_xport, _1)); + handler.set_xport_chan_get_buff( + 0, + [&xport](double timeout) { + return xport.get_recv_buff(timeout); + } + ); handler.set_converter(id); //create an overflow handler @@ -347,7 +308,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_one_channel_inline_message){ } //simulate the transport failing - dummy_recv_xport.set_io_status(false); + xport.set_simulate_io_error(true); BOOST_REQUIRE_THROW(handler.recv(&buff.front(), buff.size(), metadata, 1.0, true), uhd::io_error); } @@ -360,8 +321,8 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_normal){ id.output_format = "fc32"; id.num_outputs = 1; - uhd::transport::vrt::if_packet_info_t ifpi; - ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA; + vrt::if_packet_info_t ifpi; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 0; ifpi.packet_count = 0; ifpi.sob = true; @@ -380,25 +341,35 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_normal){ static const size_t NUM_SAMPS_PER_BUFF = 20; static const size_t NCHANNELS = 4; - std::vector<dummy_recv_xport_class> dummy_recv_xports(NCHANNELS, dummy_recv_xport_class("big")); + std::vector<mock_zero_copy::sptr> xports; + for (size_t i = 0; i < NCHANNELS; i++) { + xports.push_back(boost::make_shared<mock_zero_copy>(vrt::if_packet_info_t::LINK_TYPE_VRLP)); + } //generate a bunch of packets for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ ifpi.num_payload_words32 = 10 + i%10; for (size_t ch = 0; ch < NCHANNELS; ch++){ - dummy_recv_xports[ch].push_back_packet(ifpi); + std::vector<uint32_t> data(ifpi.num_payload_words32, 0); + xports[ch]->push_back_recv_packet(ifpi, data); } ifpi.packet_count++; ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE); } //create the super receive packet handler - uhd::transport::sph::recv_packet_handler handler(NCHANNELS); - handler.set_vrt_unpacker(&uhd::transport::vrt::if_hdr_unpack_be); + sph::recv_packet_handler handler(NCHANNELS); + handler.set_vrt_unpacker(&vrt::if_hdr_unpack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); for (size_t ch = 0; ch < NCHANNELS; ch++){ - handler.set_xport_chan_get_buff(ch, boost::bind(&dummy_recv_xport_class::get_recv_buff, &dummy_recv_xports[ch], _1)); + mock_zero_copy::sptr xport = xports[ch]; + handler.set_xport_chan_get_buff( + ch, + [xport](double timeout) { + return xport->get_recv_buff(timeout); + } + ); } handler.set_converter(id); @@ -434,7 +405,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_normal){ //simulate the transport failing for (size_t ch = 0; ch < NCHANNELS; ch++){ - dummy_recv_xports[ch].set_io_status(false); + xports[ch]->set_simulate_io_error(true); } BOOST_REQUIRE_THROW(handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true), uhd::io_error); @@ -449,8 +420,8 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_sequence_error){ id.output_format = "fc32"; id.num_outputs = 1; - uhd::transport::vrt::if_packet_info_t ifpi; - ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA; + vrt::if_packet_info_t ifpi; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 0; ifpi.packet_count = 0; ifpi.sob = true; @@ -469,7 +440,10 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_sequence_error){ static const size_t NUM_SAMPS_PER_BUFF = 20; static const size_t NCHANNELS = 4; - std::vector<dummy_recv_xport_class> dummy_recv_xports(NCHANNELS, dummy_recv_xport_class("big")); + std::vector<mock_zero_copy::sptr> xports; + for (size_t i = 0; i < NCHANNELS; i++) { + xports.push_back(boost::make_shared<mock_zero_copy>(vrt::if_packet_info_t::LINK_TYPE_VRLP)); + } //generate a bunch of packets for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ @@ -478,19 +452,26 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_sequence_error){ if (i == NUM_PKTS_TO_TEST/2 and ch == 2){ continue; //simulates a lost packet } - dummy_recv_xports[ch].push_back_packet(ifpi); + std::vector<uint32_t> data(ifpi.num_payload_words32, 0); + xports[ch]->push_back_recv_packet(ifpi, data); } ifpi.packet_count++; ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE); } //create the super receive packet handler - uhd::transport::sph::recv_packet_handler handler(NCHANNELS); - handler.set_vrt_unpacker(&uhd::transport::vrt::if_hdr_unpack_be); + sph::recv_packet_handler handler(NCHANNELS); + handler.set_vrt_unpacker(&vrt::if_hdr_unpack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); for (size_t ch = 0; ch < NCHANNELS; ch++){ - handler.set_xport_chan_get_buff(ch, boost::bind(&dummy_recv_xport_class::get_recv_buff, &dummy_recv_xports[ch], _1)); + mock_zero_copy::sptr xport = xports[ch]; + handler.set_xport_chan_get_buff( + ch, + [xport](double timeout) { + return xport->get_recv_buff(timeout); + } + ); } handler.set_converter(id); @@ -535,7 +516,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_sequence_error){ //simulate the transport failing for (size_t ch = 0; ch < NCHANNELS; ch++){ - dummy_recv_xports[ch].set_io_status(false); + xports[ch]->set_simulate_io_error(true); } BOOST_REQUIRE_THROW(handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true), uhd::io_error); @@ -550,8 +531,8 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_time_error){ id.output_format = "fc32"; id.num_outputs = 1; - uhd::transport::vrt::if_packet_info_t ifpi; - ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA; + vrt::if_packet_info_t ifpi; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 0; ifpi.packet_count = 0; ifpi.sob = true; @@ -570,13 +551,17 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_time_error){ static const size_t NUM_SAMPS_PER_BUFF = 20; static const size_t NCHANNELS = 4; - std::vector<dummy_recv_xport_class> dummy_recv_xports(NCHANNELS, dummy_recv_xport_class("big")); + std::vector<mock_zero_copy::sptr> xports; + for (size_t i = 0; i < NCHANNELS; i++) { + xports.push_back(boost::make_shared<mock_zero_copy>(vrt::if_packet_info_t::LINK_TYPE_VRLP)); + } //generate a bunch of packets for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ ifpi.num_payload_words32 = 10 + i%10; for (size_t ch = 0; ch < NCHANNELS; ch++){ - dummy_recv_xports[ch].push_back_packet(ifpi); + std::vector<uint32_t> data(ifpi.num_payload_words32, 0); + xports[ch]->push_back_recv_packet(ifpi, data); } ifpi.packet_count++; ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE); @@ -586,12 +571,18 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_time_error){ } //create the super receive packet handler - uhd::transport::sph::recv_packet_handler handler(NCHANNELS); - handler.set_vrt_unpacker(&uhd::transport::vrt::if_hdr_unpack_be); + sph::recv_packet_handler handler(NCHANNELS); + handler.set_vrt_unpacker(&vrt::if_hdr_unpack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); for (size_t ch = 0; ch < NCHANNELS; ch++){ - handler.set_xport_chan_get_buff(ch, boost::bind(&dummy_recv_xport_class::get_recv_buff, &dummy_recv_xports[ch], _1)); + mock_zero_copy::sptr xport = xports[ch]; + handler.set_xport_chan_get_buff( + ch, + [xport](double timeout) { + return xport->get_recv_buff(timeout); + } + ); } handler.set_converter(id); @@ -630,7 +621,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_time_error){ //simulate the transport failing for (size_t ch = 0; ch < NCHANNELS; ch++){ - dummy_recv_xports[ch].set_io_status(false); + xports[ch]->set_simulate_io_error(true); } BOOST_REQUIRE_THROW(handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true), uhd::io_error); @@ -645,8 +636,8 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_exception){ id.output_format = "fc32"; id.num_outputs = 1; - uhd::transport::vrt::if_packet_info_t ifpi; - ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA; + vrt::if_packet_info_t ifpi; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 0; ifpi.packet_count = 0; ifpi.sob = true; @@ -665,13 +656,17 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_exception){ static const size_t NUM_SAMPS_PER_BUFF = 20; static const size_t NCHANNELS = 4; - std::vector<dummy_recv_xport_class> dummy_recv_xports(NCHANNELS, dummy_recv_xport_class("big")); + std::vector<mock_zero_copy::sptr> xports; + for (size_t i = 0; i < NCHANNELS; i++) { + xports.push_back(boost::make_shared<mock_zero_copy>(vrt::if_packet_info_t::LINK_TYPE_VRLP)); + } //generate a bunch of packets for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ ifpi.num_payload_words32 = 10 + i%10; for (size_t ch = 0; ch < NCHANNELS; ch++){ - dummy_recv_xports[ch].push_back_packet(ifpi); + std::vector<uint32_t> data(ifpi.num_payload_words32, 0); + xports[ch]->push_back_recv_packet(ifpi, data); } ifpi.packet_count++; ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE); @@ -681,12 +676,18 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_exception){ } //create the super receive packet handler - uhd::transport::sph::recv_packet_handler handler(NCHANNELS); - handler.set_vrt_unpacker(&uhd::transport::vrt::if_hdr_unpack_be); + sph::recv_packet_handler handler(NCHANNELS); + handler.set_vrt_unpacker(&vrt::if_hdr_unpack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); for (size_t ch = 0; ch < NCHANNELS; ch++){ - handler.set_xport_chan_get_buff(ch, boost::bind(&dummy_recv_xport_class::get_recv_buff, &dummy_recv_xports[ch], _1)); + mock_zero_copy::sptr xport = xports[ch]; + handler.set_xport_chan_get_buff( + ch, + [xport](double timeout) { + return xport->get_recv_buff(timeout); + } + ); } handler.set_converter(id); @@ -698,7 +699,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_exception){ // simulate a failure on a channel (the last one) uhd::rx_metadata_t metadata; - dummy_recv_xports[NCHANNELS-1].set_io_status(false); + xports[NCHANNELS-1]->set_simulate_io_error(true); std::cout << "exception check" << std::endl; @@ -714,8 +715,8 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_fragment){ id.output_format = "fc32"; id.num_outputs = 1; - uhd::transport::vrt::if_packet_info_t ifpi; - ifpi.packet_type = uhd::transport::vrt::if_packet_info_t::PACKET_TYPE_DATA; + vrt::if_packet_info_t ifpi; + ifpi.packet_type = vrt::if_packet_info_t::PACKET_TYPE_DATA; ifpi.num_payload_words32 = 0; ifpi.packet_count = 0; ifpi.sob = true; @@ -734,25 +735,35 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_fragment){ static const size_t NUM_SAMPS_PER_BUFF = 10; static const size_t NCHANNELS = 4; - std::vector<dummy_recv_xport_class> dummy_recv_xports(NCHANNELS, dummy_recv_xport_class("big")); + std::vector<mock_zero_copy::sptr> xports; + for (size_t i = 0; i < NCHANNELS; i++) { + xports.push_back(boost::make_shared<mock_zero_copy>(vrt::if_packet_info_t::LINK_TYPE_VRLP)); + } //generate a bunch of packets for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ ifpi.num_payload_words32 = 10 + i%10; for (size_t ch = 0; ch < NCHANNELS; ch++){ - dummy_recv_xports[ch].push_back_packet(ifpi); + std::vector<uint32_t> data(ifpi.num_payload_words32, 0); + xports[ch]->push_back_recv_packet(ifpi, data); } ifpi.packet_count++; ifpi.tsf += ifpi.num_payload_words32*size_t(TICK_RATE/SAMP_RATE); } //create the super receive packet handler - uhd::transport::sph::recv_packet_handler handler(NCHANNELS); - handler.set_vrt_unpacker(&uhd::transport::vrt::if_hdr_unpack_be); + sph::recv_packet_handler handler(NCHANNELS); + handler.set_vrt_unpacker(&vrt::if_hdr_unpack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); for (size_t ch = 0; ch < NCHANNELS; ch++){ - handler.set_xport_chan_get_buff(ch, boost::bind(&dummy_recv_xport_class::get_recv_buff, &dummy_recv_xports[ch], _1)); + mock_zero_copy::sptr xport = xports[ch]; + handler.set_xport_chan_get_buff( + ch, + [xport](double timeout) { + return xport->get_recv_buff(timeout); + } + ); } handler.set_converter(id); @@ -800,7 +811,7 @@ BOOST_AUTO_TEST_CASE(test_sph_recv_multi_channel_fragment){ //simulate the transport failing for (size_t ch = 0; ch < NCHANNELS; ch++){ - dummy_recv_xports[ch].set_io_status(false); + xports[ch]->set_simulate_io_error(true); } BOOST_REQUIRE_THROW(handler.recv(buffs, NUM_SAMPS_PER_BUFF, metadata, 1.0, true), uhd::io_error); diff --git a/host/tests/sph_send_test.cpp b/host/tests/sph_send_test.cpp index 99f23a374..2db80c8de 100644 --- a/host/tests/sph_send_test.cpp +++ b/host/tests/sph_send_test.cpp @@ -7,71 +7,18 @@ #include <boost/test/unit_test.hpp> #include "../lib/transport/super_send_packet_handler.hpp" +#include "../common/mock_zero_copy.hpp" #include <boost/shared_array.hpp> #include <boost/bind.hpp> #include <complex> #include <vector> #include <list> +using namespace uhd::transport; + #define BOOST_CHECK_TS_CLOSE(a, b) \ BOOST_CHECK_CLOSE((a).get_real_secs(), (b).get_real_secs(), 0.001) -/*********************************************************************** - * A dummy managed send buffer for testing - **********************************************************************/ -class dummy_msb : public uhd::transport::managed_send_buffer{ -public: - void release(void){ - //NOP - } - - sptr get_new(boost::shared_array<char> mem, size_t *len){ - _mem = mem; - return make(this, mem.get(), *len); - } - -private: - boost::shared_array<char> _mem; -}; - -/*********************************************************************** - * A dummy transport class to fill with fake data - **********************************************************************/ -class dummy_send_xport_class{ -public: - dummy_send_xport_class(const std::string &end){ - _end = end; - } - - void pop_front_packet( - uhd::transport::vrt::if_packet_info_t &ifpi - ){ - ifpi.num_packet_words32 = _lens.front()/sizeof(uint32_t); - if (_end == "big"){ - uhd::transport::vrt::if_hdr_unpack_be(reinterpret_cast<uint32_t *>(_mems.front().get()), ifpi); - } - if (_end == "little"){ - uhd::transport::vrt::if_hdr_unpack_le(reinterpret_cast<uint32_t *>(_mems.front().get()), ifpi); - } - _mems.pop_front(); - _lens.pop_front(); - } - - uhd::transport::managed_send_buffer::sptr get_send_buff(double){ - _msbs.push_back(boost::shared_ptr<dummy_msb>(new dummy_msb())); - _mems.push_back(boost::shared_array<char>(new char[1000])); - _lens.push_back(1000); - uhd::transport::managed_send_buffer::sptr mrb = _msbs.back()->get_new(_mems.back(), &_lens.back()); - return mrb; - } - -private: - std::list<boost::shared_array<char> > _mems; - std::list<size_t> _lens; - std::vector<boost::shared_ptr<dummy_msb> > _msbs; - std::string _end; -}; - //////////////////////////////////////////////////////////////////////// BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_one_packet_mode){ //////////////////////////////////////////////////////////////////////// @@ -81,18 +28,23 @@ BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_one_packet_mode){ id.output_format = "sc16_item32_be"; id.num_outputs = 1; - dummy_send_xport_class dummy_send_xport("big"); + mock_zero_copy xport(vrt::if_packet_info_t::LINK_TYPE_VRLP); static const double TICK_RATE = 100e6; static const double SAMP_RATE = 10e6; static const size_t NUM_PKTS_TO_TEST = 30; //create the super send packet handler - uhd::transport::sph::send_packet_handler handler(1); - handler.set_vrt_packer(&uhd::transport::vrt::if_hdr_pack_be); + sph::send_packet_handler handler(1); + handler.set_vrt_packer(&vrt::if_hdr_pack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); - handler.set_xport_chan_get_buff(0, boost::bind(&dummy_send_xport_class::get_send_buff, &dummy_send_xport, _1)); + handler.set_xport_chan_get_buff( + 0, + [&xport](double timeout) { + return xport.get_send_buff(timeout); + } + ); handler.set_converter(id); handler.set_max_samples_per_packet(20); @@ -115,10 +67,10 @@ BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_one_packet_mode){ //check the sent packets size_t num_accum_samps = 0; - uhd::transport::vrt::if_packet_info_t ifpi; + vrt::if_packet_info_t ifpi; for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ std::cout << "data check " << i << std::endl; - dummy_send_xport.pop_front_packet(ifpi); + xport.pop_send_packet(ifpi); BOOST_CHECK_EQUAL(ifpi.num_payload_words32, 10+i%10); BOOST_CHECK(ifpi.has_tsf); BOOST_CHECK_EQUAL(ifpi.tsf, num_accum_samps*TICK_RATE/SAMP_RATE); @@ -137,18 +89,23 @@ BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_full_buffer_mode){ id.output_format = "sc16_item32_be"; id.num_outputs = 1; - dummy_send_xport_class dummy_send_xport("big"); + mock_zero_copy xport(vrt::if_packet_info_t::LINK_TYPE_VRLP); static const double TICK_RATE = 100e6; static const double SAMP_RATE = 10e6; static const size_t NUM_PKTS_TO_TEST = 30; //create the super send packet handler - uhd::transport::sph::send_packet_handler handler(1); - handler.set_vrt_packer(&uhd::transport::vrt::if_hdr_pack_be); + sph::send_packet_handler handler(1); + handler.set_vrt_packer(&vrt::if_hdr_pack_be); handler.set_tick_rate(TICK_RATE); handler.set_samp_rate(SAMP_RATE); - handler.set_xport_chan_get_buff(0, boost::bind(&dummy_send_xport_class::get_send_buff, &dummy_send_xport, _1)); + handler.set_xport_chan_get_buff( + 0, + [&xport](double timeout) { + return xport.get_send_buff(timeout); + } + ); handler.set_converter(id); handler.set_max_samples_per_packet(20); @@ -168,10 +125,10 @@ BOOST_AUTO_TEST_CASE(test_sph_send_one_channel_full_buffer_mode){ //check the sent packets size_t num_accum_samps = 0; - uhd::transport::vrt::if_packet_info_t ifpi; + vrt::if_packet_info_t ifpi; for (size_t i = 0; i < NUM_PKTS_TO_TEST; i++){ std::cout << "data check " << i << std::endl; - dummy_send_xport.pop_front_packet(ifpi); + xport.pop_send_packet(ifpi); BOOST_CHECK_EQUAL(ifpi.num_payload_words32, 20UL); BOOST_CHECK(ifpi.has_tsf); BOOST_CHECK_EQUAL(ifpi.tsf, num_accum_samps*TICK_RATE/SAMP_RATE); |