diff options
Diffstat (limited to 'host/test')
-rw-r--r-- | host/test/CMakeLists.txt | 42 | ||||
-rw-r--r-- | host/test/addr_test.cpp | 80 | ||||
-rw-r--r-- | host/test/buffer_test.cpp | 115 | ||||
-rw-r--r-- | host/test/byteswap_test.cpp | 39 | ||||
-rw-r--r-- | host/test/convert_types_test.cpp | 125 | ||||
-rw-r--r-- | host/test/dict_test.cpp | 72 | ||||
-rw-r--r-- | host/test/error_test.cpp | 48 | ||||
-rw-r--r-- | host/test/gain_group_test.cpp | 122 | ||||
-rw-r--r-- | host/test/main_test.cpp | 3 | ||||
-rw-r--r-- | host/test/module_test.cpp | 26 | ||||
-rw-r--r-- | host/test/subdev_spec_test.cpp | 45 | ||||
-rw-r--r-- | host/test/tune_helper_test.cpp | 174 | ||||
-rw-r--r-- | host/test/vrt_test.cpp | 141 | ||||
-rw-r--r-- | host/test/warning_test.cpp | 29 | ||||
-rw-r--r-- | host/test/wax_test.cpp | 104 |
15 files changed, 1165 insertions, 0 deletions
diff --git a/host/test/CMakeLists.txt b/host/test/CMakeLists.txt new file mode 100644 index 000000000..c620fd641 --- /dev/null +++ b/host/test/CMakeLists.txt @@ -0,0 +1,42 @@ +# +# Copyright 2010 Ettus Research LLC +# +# This program 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. +# +# This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +# + +######################################################################## +# unit test suite +######################################################################## +ADD_EXECUTABLE(main_test + main_test.cpp + addr_test.cpp + buffer_test.cpp + byteswap_test.cpp + convert_types_test.cpp + dict_test.cpp + error_test.cpp + gain_group_test.cpp + subdev_spec_test.cpp + tune_helper_test.cpp + vrt_test.cpp + warning_test.cpp + wax_test.cpp +) +TARGET_LINK_LIBRARIES(main_test uhd) +ADD_TEST(test main_test) + +######################################################################## +# demo of a loadable module +######################################################################## +ADD_LIBRARY(module_test MODULE module_test.cpp) diff --git a/host/test/addr_test.cpp b/host/test/addr_test.cpp new file mode 100644 index 000000000..d4b45aa1a --- /dev/null +++ b/host/test/addr_test.cpp @@ -0,0 +1,80 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program 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. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <boost/test/unit_test.hpp> +#include <uhd/types/mac_addr.hpp> +#include <uhd/types/device_addr.hpp> +#include <uhd/usrp/dboard_id.hpp> +#include <boost/assign/list_of.hpp> +#include <boost/foreach.hpp> +#include <algorithm> +#include <iostream> + +BOOST_AUTO_TEST_CASE(test_mac_addr){ + std::cout << "Testing mac addr..." << std::endl; + const std::string mac_addr_str("00:01:23:45:67:89"); + uhd::mac_addr_t mac_addr = uhd::mac_addr_t::from_string(mac_addr_str); + std::cout << "Input: " << mac_addr_str << std::endl; + std::cout << "Output: " << mac_addr.to_string() << std::endl; + BOOST_CHECK_EQUAL(mac_addr_str, mac_addr.to_string()); +} + +BOOST_AUTO_TEST_CASE(test_device_addr){ + std::cout << "Testing device addr..." << std::endl; + + //load the device address with something + uhd::device_addr_t dev_addr; + dev_addr["key1"] = "val1"; + dev_addr["key2"] = "val2"; + + //convert to and from args string + std::cout << "Pretty Print: " << std::endl << dev_addr.to_pp_string(); + std::string args_str = dev_addr.to_string(); + std::cout << "Args String: " << args_str << std::endl; + uhd::device_addr_t new_dev_addr(args_str); + + //they should be the same size + BOOST_REQUIRE_EQUAL(dev_addr.size(), new_dev_addr.size()); + + //the keys should match + std::vector<std::string> old_dev_addr_keys = dev_addr.keys(); + std::vector<std::string> new_dev_addr_keys = new_dev_addr.keys(); + BOOST_CHECK_EQUAL_COLLECTIONS( + old_dev_addr_keys.begin(), old_dev_addr_keys.end(), + new_dev_addr_keys.begin(), new_dev_addr_keys.end() + ); + + //the vals should match + std::vector<std::string> old_dev_addr_vals = dev_addr.vals(); + std::vector<std::string> new_dev_addr_vals = new_dev_addr.vals(); + BOOST_CHECK_EQUAL_COLLECTIONS( + old_dev_addr_vals.begin(), old_dev_addr_vals.end(), + new_dev_addr_vals.begin(), new_dev_addr_vals.end() + ); +} + +BOOST_AUTO_TEST_CASE(test_dboard_id){ + std::cout << "Testing dboard id..." << std::endl; + + using namespace uhd::usrp; + + BOOST_CHECK(dboard_id_t() == dboard_id_t::none()); + BOOST_CHECK_EQUAL(dboard_id_t().to_uint16(), dboard_id_t::none().to_uint16()); + BOOST_CHECK_EQUAL(dboard_id_t::from_string("0x1234").to_uint16(), 0x1234); + BOOST_CHECK_EQUAL(dboard_id_t::from_string("1234").to_uint16(), 1234); + std::cout << "Pretty Print: " << std::endl << dboard_id_t::none().to_pp_string(); +} diff --git a/host/test/buffer_test.cpp b/host/test/buffer_test.cpp new file mode 100644 index 000000000..aadb3f951 --- /dev/null +++ b/host/test/buffer_test.cpp @@ -0,0 +1,115 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program 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. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <boost/test/unit_test.hpp> +#include <uhd/transport/bounded_buffer.hpp> +#include <uhd/transport/alignment_buffer.hpp> +#include <boost/assign/list_of.hpp> + +using namespace boost::assign; +using namespace uhd::transport; + +static const boost::posix_time::milliseconds timeout(10); + +BOOST_AUTO_TEST_CASE(test_bounded_buffer_with_timed_wait){ + bounded_buffer<int>::sptr bb(bounded_buffer<int>::make(3)); + + //push elements, check for timeout + BOOST_CHECK(bb->push_with_timed_wait(0, timeout)); + BOOST_CHECK(bb->push_with_timed_wait(1, timeout)); + BOOST_CHECK(bb->push_with_timed_wait(2, timeout)); + BOOST_CHECK(not bb->push_with_timed_wait(3, timeout)); + + int val; + //pop elements, check for timeout and check values + BOOST_CHECK(bb->pop_with_timed_wait(val, timeout)); + BOOST_CHECK_EQUAL(val, 0); + BOOST_CHECK(bb->pop_with_timed_wait(val, timeout)); + BOOST_CHECK_EQUAL(val, 1); + BOOST_CHECK(bb->pop_with_timed_wait(val, timeout)); + BOOST_CHECK_EQUAL(val, 2); + BOOST_CHECK(not bb->pop_with_timed_wait(val, timeout)); +} + +BOOST_AUTO_TEST_CASE(test_bounded_buffer_with_pop_on_full){ + bounded_buffer<int>::sptr bb(bounded_buffer<int>::make(3)); + + //push elements, check for timeout + BOOST_CHECK(bb->push_with_pop_on_full(0)); + BOOST_CHECK(bb->push_with_pop_on_full(1)); + BOOST_CHECK(bb->push_with_pop_on_full(2)); + BOOST_CHECK(not bb->push_with_pop_on_full(3)); + + int val; + //pop elements, check for timeout and check values + BOOST_CHECK(bb->pop_with_timed_wait(val, timeout)); + BOOST_CHECK_EQUAL(val, 1); + BOOST_CHECK(bb->pop_with_timed_wait(val, timeout)); + BOOST_CHECK_EQUAL(val, 2); + BOOST_CHECK(bb->pop_with_timed_wait(val, timeout)); + BOOST_CHECK_EQUAL(val, 3); +} + +BOOST_AUTO_TEST_CASE(test_alignment_buffer){ + alignment_buffer<int, size_t>::sptr ab(alignment_buffer<int, size_t>::make(7, 3)); + //load index 0 with all good seq numbers + BOOST_CHECK(ab->push_with_pop_on_full(0, 0, 0)); + BOOST_CHECK(ab->push_with_pop_on_full(1, 1, 0)); + BOOST_CHECK(ab->push_with_pop_on_full(2, 2, 0)); + BOOST_CHECK(ab->push_with_pop_on_full(3, 3, 0)); + BOOST_CHECK(ab->push_with_pop_on_full(4, 4, 0)); + + //load index 1 with some skipped seq numbers + BOOST_CHECK(ab->push_with_pop_on_full(10, 0, 1)); + BOOST_CHECK(ab->push_with_pop_on_full(11, 1, 1)); + BOOST_CHECK(ab->push_with_pop_on_full(14, 4, 1)); + BOOST_CHECK(ab->push_with_pop_on_full(15, 5, 1)); + BOOST_CHECK(ab->push_with_pop_on_full(16, 6, 1)); + + //load index 2 with all good seq numbers + BOOST_CHECK(ab->push_with_pop_on_full(20, 0, 2)); + BOOST_CHECK(ab->push_with_pop_on_full(21, 1, 2)); + BOOST_CHECK(ab->push_with_pop_on_full(22, 2, 2)); + BOOST_CHECK(ab->push_with_pop_on_full(23, 3, 2)); + BOOST_CHECK(ab->push_with_pop_on_full(24, 4, 2)); + + //readback aligned values + std::vector<int> aligned_elems(3); + + static const std::vector<int> expected_elems0 = list_of(0)(10)(20); + BOOST_CHECK(ab->pop_elems_with_timed_wait(aligned_elems, timeout)); + BOOST_CHECK_EQUAL_COLLECTIONS( + aligned_elems.begin(), aligned_elems.end(), + expected_elems0.begin(), expected_elems0.end() + ); + + static const std::vector<int> expected_elems1 = list_of(1)(11)(21); + BOOST_CHECK(ab->pop_elems_with_timed_wait(aligned_elems, timeout)); + BOOST_CHECK_EQUAL_COLLECTIONS( + aligned_elems.begin(), aligned_elems.end(), + expected_elems1.begin(), expected_elems1.end() + ); + + //there was a skip now find 4 + + static const std::vector<int> expected_elems4 = list_of(4)(14)(24); + BOOST_CHECK(ab->pop_elems_with_timed_wait(aligned_elems, timeout)); + BOOST_CHECK_EQUAL_COLLECTIONS( + aligned_elems.begin(), aligned_elems.end(), + expected_elems4.begin(), expected_elems4.end() + ); +} diff --git a/host/test/byteswap_test.cpp b/host/test/byteswap_test.cpp new file mode 100644 index 000000000..3d50c9bfa --- /dev/null +++ b/host/test/byteswap_test.cpp @@ -0,0 +1,39 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program 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. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <boost/test/unit_test.hpp> +#include <uhd/utils/byteswap.hpp> + +BOOST_AUTO_TEST_CASE(test_byteswap16){ + boost::uint16_t x = 0x0123; + boost::uint16_t y = 0x2301; + BOOST_CHECK_EQUAL(uhd::byteswap(x), y); +} + +BOOST_AUTO_TEST_CASE(test_byteswap32){ + boost::uint32_t x = 0x01234567; + boost::uint32_t y = 0x67452301; + BOOST_CHECK_EQUAL(uhd::byteswap(x), y); +} + +BOOST_AUTO_TEST_CASE(test_byteswap64){ + //split up 64 bit constants to avoid long-long compiler warnings + boost::uint64_t x = 0x01234567 | (boost::uint64_t(0x89abcdef) << 32); + boost::uint64_t y = 0xefcdab89 | (boost::uint64_t(0x67452301) << 32); + BOOST_CHECK_EQUAL(uhd::byteswap(x), y); +} + diff --git a/host/test/convert_types_test.cpp b/host/test/convert_types_test.cpp new file mode 100644 index 000000000..1587be57f --- /dev/null +++ b/host/test/convert_types_test.cpp @@ -0,0 +1,125 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program 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. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <uhd/transport/convert_types.hpp> +#include <boost/test/unit_test.hpp> +#include <boost/cstdint.hpp> +#include <complex> + +using namespace uhd; + +template <typename host_type, typename dev_type, size_t nsamps> +void loopback( + const io_type_t &io_type, + const otw_type_t &otw_type, + const host_type *input, + host_type *output +){ + dev_type dev[nsamps]; + + //convert to dev type + transport::convert_io_type_to_otw_type( + input, io_type, + dev, otw_type, + nsamps + ); + + //convert back to host type + transport::convert_otw_type_to_io_type( + dev, otw_type, + output, io_type, + nsamps + ); +} + +typedef std::complex<boost::uint16_t> sc16_t; + +BOOST_AUTO_TEST_CASE(test_convert_types_be_sc16){ + sc16_t in_sc16[] = { + sc16_t(0, -1234), sc16_t(4321, 1234), + sc16_t(9876, -4567), sc16_t(8912, 0) + }, out_sc16[4]; + + io_type_t io_type(io_type_t::COMPLEX_INT16); + otw_type_t otw_type; + otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN; + otw_type.width = 16; + + loopback<sc16_t, boost::uint32_t, 4>(io_type, otw_type, in_sc16, out_sc16); + BOOST_CHECK_EQUAL_COLLECTIONS(in_sc16, in_sc16+4, out_sc16, out_sc16+4); +} + +BOOST_AUTO_TEST_CASE(test_convert_types_le_sc16){ + sc16_t in_sc16[] = { + sc16_t(0, -1234), sc16_t(4321, 1234), + sc16_t(9876, -4567), sc16_t(8912, 0) + }, out_sc16[4]; + + io_type_t io_type(io_type_t::COMPLEX_INT16); + otw_type_t otw_type; + otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; + otw_type.width = 16; + + loopback<sc16_t, boost::uint32_t, 4>(io_type, otw_type, in_sc16, out_sc16); + BOOST_CHECK_EQUAL_COLLECTIONS(in_sc16, in_sc16+4, out_sc16, out_sc16+4); +} + +typedef std::complex<float> fc32_t; + +#define BOOST_CHECK_CLOSE_COMPLEX(a1, a2, p) \ + BOOST_CHECK_CLOSE(a1.real(), a2.real(), p); \ + BOOST_CHECK_CLOSE(a1.imag(), a2.imag(), p); + +static const float tolerance = float(0.1); + +BOOST_AUTO_TEST_CASE(test_convert_types_be_fc32){ + fc32_t in_fc32[] = { + fc32_t(float(0), float(-0.2)), fc32_t(float(0.03), float(-0.16)), + fc32_t(float(1.0), float(.45)), fc32_t(float(0.09), float(0)) + }, out_fc32[4]; + + io_type_t io_type(io_type_t::COMPLEX_FLOAT32); + otw_type_t otw_type; + otw_type.byteorder = otw_type_t::BO_BIG_ENDIAN; + otw_type.width = 16; + + loopback<fc32_t, boost::uint32_t, 4>(io_type, otw_type, in_fc32, out_fc32); + + BOOST_CHECK_CLOSE_COMPLEX(in_fc32[0], out_fc32[0], tolerance); + BOOST_CHECK_CLOSE_COMPLEX(in_fc32[1], out_fc32[1], tolerance); + BOOST_CHECK_CLOSE_COMPLEX(in_fc32[2], out_fc32[2], tolerance); + BOOST_CHECK_CLOSE_COMPLEX(in_fc32[3], out_fc32[3], tolerance); +} + +BOOST_AUTO_TEST_CASE(test_convert_types_le_fc32){ + fc32_t in_fc32[] = { + fc32_t(float(0), float(-0.2)), fc32_t(float(0.03), float(-0.16)), + fc32_t(float(1.0), float(.45)), fc32_t(float(0.09), float(0)) + }, out_fc32[4]; + + io_type_t io_type(io_type_t::COMPLEX_FLOAT32); + otw_type_t otw_type; + otw_type.byteorder = otw_type_t::BO_LITTLE_ENDIAN; + otw_type.width = 16; + + loopback<fc32_t, boost::uint32_t, 4>(io_type, otw_type, in_fc32, out_fc32); + + BOOST_CHECK_CLOSE_COMPLEX(in_fc32[0], out_fc32[0], tolerance); + BOOST_CHECK_CLOSE_COMPLEX(in_fc32[1], out_fc32[1], tolerance); + BOOST_CHECK_CLOSE_COMPLEX(in_fc32[2], out_fc32[2], tolerance); + BOOST_CHECK_CLOSE_COMPLEX(in_fc32[3], out_fc32[3], tolerance); +} diff --git a/host/test/dict_test.cpp b/host/test/dict_test.cpp new file mode 100644 index 000000000..0501a7878 --- /dev/null +++ b/host/test/dict_test.cpp @@ -0,0 +1,72 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program 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. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <boost/test/unit_test.hpp> +#include <uhd/types/dict.hpp> +#include <boost/assign/list_of.hpp> + +BOOST_AUTO_TEST_CASE(test_dict_init){ + uhd::dict<int, int> d; + d[-1] = 3; + d[0] = 4; + d[1] = 5; + BOOST_CHECK(d.has_key(0)); + BOOST_CHECK(not d.has_key(2)); + BOOST_CHECK(d.keys()[1] == 0); + BOOST_CHECK(d.vals()[1] == 4); + BOOST_CHECK_EQUAL(d[-1], 3); +} + +BOOST_AUTO_TEST_CASE(test_dict_assign){ + uhd::dict<int, int> d = boost::assign::map_list_of + (-1, 3) + (0, 4) + (1, 5) + ; + BOOST_CHECK(d.has_key(0)); + BOOST_CHECK(not d.has_key(2)); + BOOST_CHECK(d.keys()[1] == 0); + BOOST_CHECK(d.vals()[1] == 4); + BOOST_CHECK_EQUAL(d[-1], 3); +} + +BOOST_AUTO_TEST_CASE(test_const_dict){ + const uhd::dict<int, int> d = boost::assign::map_list_of + (-1, 3) + (0, 4) + (1, 5) + ; + BOOST_CHECK(d.has_key(0)); + BOOST_CHECK(not d.has_key(2)); + BOOST_CHECK(d.keys()[1] == 0); + BOOST_CHECK(d.vals()[1] == 4); + BOOST_CHECK_EQUAL(d[-1], 3); + BOOST_CHECK_THROW(d[2], std::exception); +} + +BOOST_AUTO_TEST_CASE(test_dict_pop){ + uhd::dict<int, int> d = boost::assign::map_list_of + (-1, 3) + (0, 4) + (1, 5) + ; + BOOST_CHECK(d.has_key(0)); + BOOST_CHECK_EQUAL(d.pop(0), 4); + BOOST_CHECK(not d.has_key(0)); + BOOST_CHECK(d.keys()[0] == -1); + BOOST_CHECK(d.keys()[1] == 1); +} diff --git a/host/test/error_test.cpp b/host/test/error_test.cpp new file mode 100644 index 000000000..c76a15ab7 --- /dev/null +++ b/host/test/error_test.cpp @@ -0,0 +1,48 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program 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. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <boost/test/unit_test.hpp> +#include <uhd/utils/assert.hpp> +#include <vector> +#include <iostream> + +BOOST_AUTO_TEST_CASE(test_assert_has){ + std::vector<int> vec; + vec.push_back(2); + vec.push_back(3); + vec.push_back(5); + + //verify the std::has utility + BOOST_CHECK(std::has(vec, 2)); + BOOST_CHECK(not std::has(vec, 1)); + + std::cout << "The output of the assert_has error:" << std::endl; + try{ + uhd::assert_has(vec, 1, "prime"); + }catch(const std::exception &e){ + std::cout << e.what() << std::endl; + } +} + +BOOST_AUTO_TEST_CASE(test_assert_throw){ + std::cout << "The output of the assert throw error:" << std::endl; + try{ + UHD_ASSERT_THROW(2 + 2 == 5); + }catch(const std::exception &e){ + std::cout << e.what() << std::endl; + } +} diff --git a/host/test/gain_group_test.cpp b/host/test/gain_group_test.cpp new file mode 100644 index 000000000..6a6af8eb2 --- /dev/null +++ b/host/test/gain_group_test.cpp @@ -0,0 +1,122 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program 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. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <boost/test/unit_test.hpp> +#include <uhd/utils/gain_group.hpp> +#include <boost/bind.hpp> +#include <boost/math/special_functions/round.hpp> +#include <iostream> + +#define rint(x) boost::math::iround(x) + +using namespace uhd; + +/*********************************************************************** + * Define gain element classes with needed functions + **********************************************************************/ +class gain_element1{ +public: + + gain_range_t get_range(void){ + return gain_range_t(0, 90, 1); + } + + float get_value(void){ + return _gain; + } + + void set_value(float gain){ + float step = get_range().step; + _gain = step*rint(gain/step); + } + +private: + float _gain; +}; + +class gain_element2{ +public: + + gain_range_t get_range(void){ + return gain_range_t(-20, 10, 0.1); + } + + float get_value(void){ + return _gain; + } + + void set_value(float gain){ + float step = get_range().step; + _gain = step*rint(gain/step); + } + +private: + float _gain; +}; + +//create static instances of gain elements to be shared by the tests +static gain_element1 g1; +static gain_element2 g2; + +static gain_group::sptr get_gain_group(size_t pri1 = 0, size_t pri2 = 0){ + //create instance of gain group + gain_fcns_t gain_fcns; + gain_group::sptr gg(gain_group::make()); + + //load gain group with function sets + gain_fcns.get_range = boost::bind(&gain_element1::get_range, &g1); + gain_fcns.get_value = boost::bind(&gain_element1::get_value, &g1); + gain_fcns.set_value = boost::bind(&gain_element1::set_value, &g1, _1); + gg->register_fcns(gain_fcns, pri1); + + gain_fcns.get_range = boost::bind(&gain_element2::get_range, &g2); + gain_fcns.get_value = boost::bind(&gain_element2::get_value, &g2); + gain_fcns.set_value = boost::bind(&gain_element2::set_value, &g2, _1); + gg->register_fcns(gain_fcns, pri2); + + return gg; +} + +/*********************************************************************** + * Test cases + **********************************************************************/ +static const double tolerance = 0.001; + +BOOST_AUTO_TEST_CASE(test_gain_group_overall){ + gain_group::sptr gg = get_gain_group(); + + //test the overall stuff + gg->set_value(80); + BOOST_CHECK_CLOSE(gg->get_value(), float(80), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().min, float(-20), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().max, float(100), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().step, float(0.1), tolerance); +} + +BOOST_AUTO_TEST_CASE(test_gain_group_priority){ + gain_group::sptr gg = get_gain_group(0, 1); + + //test the overall stuff + gg->set_value(80); + BOOST_CHECK_CLOSE(gg->get_value(), float(80), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().min, float(-20), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().max, float(100), tolerance); + BOOST_CHECK_CLOSE(gg->get_range().step, float(0.1), tolerance); + + //test the the higher priority gain got filled first (gain 2) + BOOST_CHECK_CLOSE(g2.get_value(), g2.get_range().max, tolerance); +} diff --git a/host/test/main_test.cpp b/host/test/main_test.cpp new file mode 100644 index 000000000..0b47303b7 --- /dev/null +++ b/host/test/main_test.cpp @@ -0,0 +1,3 @@ +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_MAIN +#include <boost/test/unit_test.hpp> diff --git a/host/test/module_test.cpp b/host/test/module_test.cpp new file mode 100644 index 000000000..47a0e1af9 --- /dev/null +++ b/host/test/module_test.cpp @@ -0,0 +1,26 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program 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. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <uhd/utils/static.hpp> +#include <iostream> + +UHD_STATIC_BLOCK(module_test){ + std::cout << "---------------------------------------" << std::endl; + std::cout << "-- Good news, everyone!" << std::endl; + std::cout << "-- The test module has been loaded." << std::endl; + std::cout << "---------------------------------------" << std::endl; +} diff --git a/host/test/subdev_spec_test.cpp b/host/test/subdev_spec_test.cpp new file mode 100644 index 000000000..8817d5eee --- /dev/null +++ b/host/test/subdev_spec_test.cpp @@ -0,0 +1,45 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program 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. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <boost/test/unit_test.hpp> +#include <uhd/usrp/subdev_spec.hpp> +#include <boost/foreach.hpp> +#include <iostream> + +BOOST_AUTO_TEST_CASE(test_subdevice_spec){ + std::cout << "Testing subdevice specification..." << std::endl; + + //load the subdev spec with something + uhd::usrp::subdev_spec_t sd_spec; + sd_spec.push_back(uhd::usrp::subdev_spec_pair_t("A", "AB")); + sd_spec.push_back(uhd::usrp::subdev_spec_pair_t("B", "AB")); + + //convert to and from args string + std::cout << "Pretty Print: " << std::endl << sd_spec.to_pp_string(); + std::string markup_str = sd_spec.to_string(); + std::cout << "Markup String: " << markup_str << std::endl; + uhd::usrp::subdev_spec_t new_sd_spec(markup_str); + + //they should be the same size + BOOST_REQUIRE_EQUAL(sd_spec.size(), new_sd_spec.size()); + + //the contents should match + for (size_t i = 0; i < sd_spec.size(); i++){ + BOOST_CHECK_EQUAL(sd_spec.at(i).db_name, new_sd_spec.at(i).db_name); + BOOST_CHECK_EQUAL(sd_spec.at(i).sd_name, new_sd_spec.at(i).sd_name); + } +} diff --git a/host/test/tune_helper_test.cpp b/host/test/tune_helper_test.cpp new file mode 100644 index 000000000..570f47293 --- /dev/null +++ b/host/test/tune_helper_test.cpp @@ -0,0 +1,174 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program 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. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <boost/test/unit_test.hpp> +#include <uhd/usrp/tune_helper.hpp> +#include <uhd/usrp/subdev_props.hpp> +#include <uhd/usrp/dsp_props.hpp> +#include <iostream> + +using namespace uhd; +using namespace uhd::usrp; + +/*********************************************************************** + * Dummy properties objects + **********************************************************************/ +class dummy_subdev : public wax::obj{ +public: + dummy_subdev(double resolution): + _resolution(resolution) + { + /* NOP */ + } +private: + void get(const wax::obj &key, wax::obj &val){ + switch(key.as<subdev_prop_t>()){ + + case SUBDEV_PROP_FREQ: + val = _freq; + return; + + case SUBDEV_PROP_USE_LO_OFFSET: + val = false; + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } + } + + void set(const wax::obj &key, const wax::obj &val){ + switch(key.as<subdev_prop_t>()){ + case SUBDEV_PROP_FREQ: + _freq = _resolution*int(val.as<double>()/_resolution); + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } + } + + double _freq, _resolution; +}; + +class dummy_subdev_basic : public wax::obj{ +private: + void get(const wax::obj &key, wax::obj &val){ + switch(key.as<subdev_prop_t>()){ + + case SUBDEV_PROP_FREQ: + val = double(0.0); //always zero + return; + + case SUBDEV_PROP_USE_LO_OFFSET: + val = false; + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } + } + + void set(const wax::obj &key, const wax::obj &){ + switch(key.as<subdev_prop_t>()){ + case SUBDEV_PROP_FREQ: + // do nothing + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } + } +}; + +class dummy_dsp : public wax::obj{ +public: + dummy_dsp(double codec_rate): + _codec_rate(codec_rate) + { + /* NOP */ + } +private: + void get(const wax::obj &key, wax::obj &val){ + switch(key.as<dsp_prop_t>()){ + case DSP_PROP_CODEC_RATE: + val = _codec_rate; + return; + + case DSP_PROP_FREQ_SHIFT: + val = _freq_shift; + return; + + default: UHD_THROW_PROP_GET_ERROR(); + } + } + + void set(const wax::obj &key, const wax::obj &val){ + switch(key.as<dsp_prop_t>()){ + case DSP_PROP_FREQ_SHIFT: + _freq_shift = val.as<double>(); + return; + + default: UHD_THROW_PROP_SET_ERROR(); + } + } + + double _codec_rate, _freq_shift; +}; + +/*********************************************************************** + * Test cases + **********************************************************************/ +static const double tolerance = 0.001; + +BOOST_AUTO_TEST_CASE(test_tune_helper_rx){ + dummy_subdev subdev(1e6); + dummy_dsp dsp(100e6); + + std::cout << "Testing tune helper RX automatic LO offset" << std::endl; + tune_result_t tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 2.3451e9); + std::cout << tr.to_pp_string() << std::endl; + BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.345e9, tolerance); + BOOST_CHECK_CLOSE(tr.actual_dsp_freq, -100e3, tolerance); + + double freq_derived = derive_freq_from_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link()); + BOOST_CHECK_CLOSE(freq_derived, 2.3451e9, tolerance); +} + +BOOST_AUTO_TEST_CASE(test_tune_helper_tx){ + dummy_subdev subdev(1e6); + dummy_dsp dsp(100e6); + + std::cout << "Testing tune helper TX automatic LO offset" << std::endl; + tune_result_t tr = tune_tx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 2.3451e9); + std::cout << tr.to_pp_string() << std::endl; + BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.345e9, tolerance); + BOOST_CHECK_CLOSE(tr.actual_dsp_freq, 100e3, tolerance); + + double freq_derived = derive_freq_from_tx_subdev_and_dsp(subdev.get_link(), dsp.get_link()); + BOOST_CHECK_CLOSE(freq_derived, 2.3451e9, tolerance); +} + +BOOST_AUTO_TEST_CASE(test_tune_helper_rx_nyquist){ + dummy_subdev_basic subdev; + dummy_dsp dsp(100e6); + + std::cout << "Testing tune helper RX dummy basic board" << std::endl; + tune_result_t tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 55e6); + std::cout << tr.to_pp_string() << std::endl; + BOOST_CHECK_CLOSE(tr.actual_inter_freq, 0.0, tolerance); + BOOST_CHECK_CLOSE(tr.actual_dsp_freq, 45e6, tolerance); + + double freq_derived = derive_freq_from_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link()); + BOOST_CHECK_CLOSE(freq_derived, -45e6, tolerance); +} diff --git a/host/test/vrt_test.cpp b/host/test/vrt_test.cpp new file mode 100644 index 000000000..9e131a10b --- /dev/null +++ b/host/test/vrt_test.cpp @@ -0,0 +1,141 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program 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. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <boost/test/unit_test.hpp> +#include <uhd/transport/vrt_if_packet.hpp> +#include <cstdlib> + +using namespace uhd::transport; + +static void pack_and_unpack( + vrt::if_packet_info_t &if_packet_info_in +){ + boost::uint32_t header_buff[vrt::max_if_hdr_words32]; + + //pack metadata into a vrt header + vrt::if_hdr_pack_be( + header_buff, if_packet_info_in + ); + + vrt::if_packet_info_t if_packet_info_out; + if_packet_info_out.num_packet_words32 = if_packet_info_in.num_packet_words32; + + //unpack the vrt header back into metadata + vrt::if_hdr_unpack_be( + header_buff, if_packet_info_out + ); + + //check the the unpacked metadata is the same + BOOST_CHECK_EQUAL(if_packet_info_in.packet_count, if_packet_info_out.packet_count); + BOOST_CHECK_EQUAL(if_packet_info_in.num_header_words32, if_packet_info_out.num_header_words32); + BOOST_CHECK_EQUAL(if_packet_info_in.num_payload_words32, if_packet_info_out.num_payload_words32); + BOOST_CHECK_EQUAL(if_packet_info_in.has_sid, if_packet_info_out.has_sid); + if (if_packet_info_in.has_sid and if_packet_info_out.has_sid){ + BOOST_CHECK_EQUAL(if_packet_info_in.sid, if_packet_info_out.sid); + } + BOOST_CHECK_EQUAL(if_packet_info_in.has_cid, if_packet_info_out.has_cid); + if (if_packet_info_in.has_cid and if_packet_info_out.has_cid){ + BOOST_CHECK_EQUAL(if_packet_info_in.cid, if_packet_info_out.cid); + } + BOOST_CHECK_EQUAL(if_packet_info_in.has_tsi, if_packet_info_out.has_tsi); + if (if_packet_info_in.has_tsi and if_packet_info_out.has_tsi){ + BOOST_CHECK_EQUAL(if_packet_info_in.tsi, if_packet_info_out.tsi); + } + BOOST_CHECK_EQUAL(if_packet_info_in.has_tsf, if_packet_info_out.has_tsf); + if (if_packet_info_in.has_tsf and if_packet_info_out.has_tsf){ + BOOST_CHECK_EQUAL(if_packet_info_in.tsf, if_packet_info_out.tsf); + } + BOOST_CHECK_EQUAL(if_packet_info_in.has_tlr, if_packet_info_out.has_tlr); + if (if_packet_info_in.has_tlr and if_packet_info_out.has_tlr){ + BOOST_CHECK_EQUAL(if_packet_info_in.tlr, if_packet_info_out.tlr); + } +} + +/*********************************************************************** + * Loopback test the vrt packer/unpacker with various packet info combos + * The trailer is not tested as it is not convenient to do so. + **********************************************************************/ + +BOOST_AUTO_TEST_CASE(test_with_none){ + vrt::if_packet_info_t if_packet_info; + if_packet_info.packet_count = 0; + if_packet_info.has_sid = false; + if_packet_info.has_cid = false; + if_packet_info.has_tsi = false; + if_packet_info.has_tsf = false; + if_packet_info.has_tlr = false; + if_packet_info.num_payload_words32 = 0; + pack_and_unpack(if_packet_info); +} + +BOOST_AUTO_TEST_CASE(test_with_sid){ + vrt::if_packet_info_t if_packet_info; + if_packet_info.packet_count = 1; + if_packet_info.has_sid = true; + if_packet_info.has_cid = false; + if_packet_info.has_tsi = false; + if_packet_info.has_tsf = false; + if_packet_info.has_tlr = false; + if_packet_info.sid = std::rand(); + if_packet_info.num_payload_words32 = 1111; + pack_and_unpack(if_packet_info); +} + +static const bool cid_enb = false; + +BOOST_AUTO_TEST_CASE(test_with_cid){ + vrt::if_packet_info_t if_packet_info; + if_packet_info.packet_count = 2; + if_packet_info.has_sid = false; + if_packet_info.has_cid = cid_enb; + if_packet_info.has_tsi = false; + if_packet_info.has_tsf = false; + if_packet_info.has_tlr = false; + if_packet_info.cid = std::rand(); + if_packet_info.num_payload_words32 = 2222; + pack_and_unpack(if_packet_info); +} + +BOOST_AUTO_TEST_CASE(test_with_time){ + vrt::if_packet_info_t if_packet_info; + if_packet_info.packet_count = 3; + if_packet_info.has_sid = false; + if_packet_info.has_cid = false; + if_packet_info.has_tsi = true; + if_packet_info.has_tsf = true; + if_packet_info.has_tlr = false; + if_packet_info.tsi = std::rand(); + if_packet_info.tsf = std::rand(); + if_packet_info.num_payload_words32 = 33333; + pack_and_unpack(if_packet_info); +} + +BOOST_AUTO_TEST_CASE(test_with_all){ + vrt::if_packet_info_t if_packet_info; + if_packet_info.packet_count = 4; + if_packet_info.has_sid = true; + if_packet_info.has_cid = cid_enb; + if_packet_info.has_tsi = true; + if_packet_info.has_tsf = true; + if_packet_info.has_tlr = false; + if_packet_info.sid = std::rand(); + if_packet_info.cid = std::rand(); + if_packet_info.tsi = std::rand(); + if_packet_info.tsf = std::rand(); + if_packet_info.num_payload_words32 = 44444; + pack_and_unpack(if_packet_info); +} diff --git a/host/test/warning_test.cpp b/host/test/warning_test.cpp new file mode 100644 index 000000000..6202c4270 --- /dev/null +++ b/host/test/warning_test.cpp @@ -0,0 +1,29 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program 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. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <boost/test/unit_test.hpp> +#include <uhd/utils/warning.hpp> +#include <iostream> + +BOOST_AUTO_TEST_CASE(test_print_warning){ + std::cerr << "---begin print test ---" << std::endl; + uhd::print_warning( + "This is a test print for a warning message.\n" + "And this is the second line of the test print.\n" + ); + std::cerr << "---end print test ---" << std::endl; +} diff --git a/host/test/wax_test.cpp b/host/test/wax_test.cpp new file mode 100644 index 000000000..731f470ed --- /dev/null +++ b/host/test/wax_test.cpp @@ -0,0 +1,104 @@ +// +// Copyright 2010 Ettus Research LLC +// +// This program 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. +// +// This program 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 this program. If not, see <http://www.gnu.org/licenses/>. +// + +#include <boost/test/unit_test.hpp> +#include <boost/shared_ptr.hpp> +#include <uhd/wax.hpp> +#include <iostream> + +enum opt_a_t{OPTION_A_0, OPTION_A_1}; +enum opt_b_t{OPTION_B_0, OPTION_B_1}; + +BOOST_AUTO_TEST_CASE(test_enums){ + wax::obj opta = OPTION_A_0; + BOOST_CHECK_THROW(opta.as<opt_b_t>(), wax::bad_cast); + BOOST_CHECK_EQUAL(opta.as<opt_a_t>(), OPTION_A_0); +} + +/*********************************************************************** + * demo class for wax framework + **********************************************************************/ +class wax_demo : public wax::obj{ +public: + typedef boost::shared_ptr<wax_demo> sptr; + + wax_demo(size_t sub_demos, size_t len){ + d_nums = std::vector<float>(len); + if (sub_demos != 0){ + for (size_t i = 0; i < len; i++){ + d_subs.push_back(sptr(new wax_demo(sub_demos-1, len))); + } + } + } + ~wax_demo(void){ + /* NOP */ + } +private: + std::vector<float> d_nums; + std::vector<sptr> d_subs; + + void get(const wax::obj &key, wax::obj &value){ + if (d_subs.size() == 0){ + value = d_nums[key.as<size_t>()]; + }else{ + value = d_subs[key.as<size_t>()]->get_link(); + } + } + void set(const wax::obj &key, const wax::obj &value){ + if (d_subs.size() == 0){ + d_nums[key.as<size_t>()] = value.as<float>(); + }else{ + throw std::runtime_error("cant set to a wax demo with sub demos"); + } + } +}; + +BOOST_AUTO_TEST_CASE(test_chaining){ + wax_demo wd(2, 1); + std::cout << "chain 1" << std::endl; + wd[size_t(0)]; + std::cout << "chain 2" << std::endl; + wd[size_t(0)][size_t(0)]; + std::cout << "chain 3" << std::endl; + wd[size_t(0)][size_t(0)][size_t(0)]; +} + +BOOST_AUTO_TEST_CASE(test_set_get){ + wax_demo wd(2, 10); + std::cout << "set and get all" << std::endl; + for (size_t i = 0; i < 10; i++){ + for (size_t j = 0; j < 10; j++){ + for (size_t k = 0; k < 10; k++){ + float val = float(i * j * k + i + j + k); + //std::cout << i << " " << j << " " << k << std::endl; + wd[i][j][k] = val; + BOOST_CHECK_EQUAL(val, wd[i][j][k].as<float>()); + } + } + } +} + +BOOST_AUTO_TEST_CASE(test_proxy){ + wax_demo wd(2, 1); + std::cout << "store proxy" << std::endl; + wax::obj p = wd[size_t(0)][size_t(0)]; + p[size_t(0)] = float(5); + + std::cout << "assign proxy" << std::endl; + wax::obj a = p[size_t(0)]; + BOOST_CHECK_EQUAL(a.as<float>(), float(5)); +} |