diff options
Diffstat (limited to 'host/test')
| -rw-r--r-- | host/test/CMakeLists.txt | 56 | ||||
| -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 | 242 | ||||
| -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/module_test.cpp | 26 | ||||
| -rw-r--r-- | host/test/subdev_spec_test.cpp | 45 | ||||
| -rw-r--r-- | host/test/time_spec_test.cpp | 61 | ||||
| -rw-r--r-- | host/test/tune_helper_test.cpp | 253 | ||||
| -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, 1433 insertions, 0 deletions
diff --git a/host/test/CMakeLists.txt b/host/test/CMakeLists.txt new file mode 100644 index 000000000..2cc987f0c --- /dev/null +++ b/host/test/CMakeLists.txt @@ -0,0 +1,56 @@ +# +# 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 +######################################################################## +SET(test_sources +    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 +    time_spec_test.cpp +    tune_helper_test.cpp +    vrt_test.cpp +    warning_test.cpp +    wax_test.cpp +) + +#turn each test cpp file into an executable with an int main() function +ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK -DBOOST_TEST_MAIN) + +#for each source: build an executable, register it as a test, and install +FOREACH(test_source ${test_sources}) +    GET_FILENAME_COMPONENT(test_name ${test_source} NAME_WE) +    ADD_EXECUTABLE(${test_name} ${test_source}) +    TARGET_LINK_LIBRARIES(${test_name} uhd) +    ADD_TEST(${test_name} ${test_name}) +    INSTALL(TARGETS ${test_name} RUNTIME DESTINATION ${PKG_DATA_DIR}/tests) +ENDFOREACH(test_source) + +######################################################################## +# demo of a loadable module +######################################################################## +ADD_LIBRARY(module_test MODULE module_test.cpp) + +INSTALL(TARGETS +   RUNTIME DESTINATION ${PKG_DATA_DIR}/tests +) 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..8445412e7 --- /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 double timeout = 0.01/*secs*/; + +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..2148302b6 --- /dev/null +++ b/host/test/convert_types_test.cpp @@ -0,0 +1,242 @@ +// +// 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/foreach.hpp> +#include <boost/cstdint.hpp> +#include <boost/asio/buffer.hpp> +#include <complex> +#include <vector> +#include <cstdlib> + +using namespace uhd; + +//typedefs for complex types +typedef std::complex<boost::int16_t> sc16_t; +typedef std::complex<float> fc32_t; + +//extract pointer to POD since using &vector.front() throws in MSVC +template <typename T> void * pod2ptr(T &pod){ +    return boost::asio::buffer_cast<void *>(boost::asio::buffer(pod)); +} +template <typename T> const void * pod2ptr(const T &pod){ +    return boost::asio::buffer_cast<const void *>(boost::asio::buffer(pod)); +} + +/*********************************************************************** + * Loopback runner: + *    convert input buffer into intermediate buffer + *    convert intermediate buffer into output buffer + **********************************************************************/ +template <typename Range> static void loopback( +    size_t nsamps, +    const io_type_t &io_type, +    const otw_type_t &otw_type, +    const Range &input, +    Range &output +){ +    //item32 is largest device type +    std::vector<boost::uint32_t> dev(nsamps); + +    //convert to dev type +    transport::convert_io_type_to_otw_type( +        pod2ptr(input), io_type, +        pod2ptr(dev), otw_type, +        nsamps +    ); + +    //convert back to host type +    transport::convert_otw_type_to_io_type( +        pod2ptr(dev), otw_type, +        pod2ptr(output), io_type, +        nsamps +    ); +} + +/*********************************************************************** + * Test short conversion + **********************************************************************/ +static void test_convert_types_sc16( +    size_t nsamps, +    const io_type_t &io_type, +    const otw_type_t &otw_type +){ +    //fill the input samples +    std::vector<sc16_t> input(nsamps), output(nsamps); +    BOOST_FOREACH(sc16_t &in, input) in = sc16_t( +        std::rand()-(RAND_MAX/2), +        std::rand()-(RAND_MAX/2) +    ); + +    //run the loopback and test +    loopback(nsamps, io_type, otw_type, input, output); +    BOOST_CHECK_EQUAL_COLLECTIONS(input.begin(), input.end(), output.begin(), output.end()); +} + +BOOST_AUTO_TEST_CASE(test_convert_types_be_sc16){ +    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; + +    //try various lengths to test edge cases +    for (size_t nsamps = 0; nsamps < 16; nsamps++){ +        test_convert_types_sc16(nsamps, io_type, otw_type); +    } +} + +BOOST_AUTO_TEST_CASE(test_convert_types_le_sc16){ +    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; + +    //try various lengths to test edge cases +    for (size_t nsamps = 0; nsamps < 16; nsamps++){ +        test_convert_types_sc16(nsamps, io_type, otw_type); +    } +} + +/*********************************************************************** + * Test float conversion + **********************************************************************/ +static void test_convert_types_fc32( +    size_t nsamps, +    const io_type_t &io_type, +    const otw_type_t &otw_type +){ +    //fill the input samples +    std::vector<fc32_t> input(nsamps), output(nsamps); +    BOOST_FOREACH(fc32_t &in, input) in = fc32_t( +        (std::rand()/float(RAND_MAX/2)) - 1, +        (std::rand()/float(RAND_MAX/2)) - 1 +    ); + +    //run the loopback and test +    loopback(nsamps, io_type, otw_type, input, output); +    for (size_t i = 0; i < nsamps; i++){ +        BOOST_CHECK_CLOSE_FRACTION(input[i].real(), output[i].real(), float(0.01)); +        BOOST_CHECK_CLOSE_FRACTION(input[i].imag(), output[i].imag(), float(0.01)); +    } +} + +BOOST_AUTO_TEST_CASE(test_convert_types_be_fc32){ +    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; + +    //try various lengths to test edge cases +    for (size_t nsamps = 0; nsamps < 16; nsamps++){ +        test_convert_types_fc32(nsamps, io_type, otw_type); +    } +} + +BOOST_AUTO_TEST_CASE(test_convert_types_le_fc32){ +    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; + +    //try various lengths to test edge cases +    for (size_t nsamps = 0; nsamps < 16; nsamps++){ +        test_convert_types_fc32(nsamps, io_type, otw_type); +    } +} + +/*********************************************************************** + * Test float to short conversion loopback + **********************************************************************/ +BOOST_AUTO_TEST_CASE(test_convert_types_fc32_to_sc16){ +    io_type_t io_type_in(io_type_t::COMPLEX_FLOAT32); +    io_type_t io_type_out(io_type_t::COMPLEX_INT16); + +    otw_type_t otw_type; +    otw_type.byteorder = otw_type_t::BO_NATIVE; +    otw_type.width = 16; + +    const size_t nsamps = 13; +    std::vector<fc32_t> input(nsamps); +    BOOST_FOREACH(fc32_t &in, input) in = fc32_t( +        (std::rand()/float(RAND_MAX/2)) - 1, +        (std::rand()/float(RAND_MAX/2)) - 1 +    ); + +    //convert float to dev +    std::vector<boost::uint32_t> tmp(nsamps); +    transport::convert_io_type_to_otw_type( +        pod2ptr(input), io_type_in, +        pod2ptr(tmp), otw_type, +        nsamps +    ); + +    //convert dev to short +    std::vector<sc16_t> output(nsamps); +    transport::convert_otw_type_to_io_type( +        pod2ptr(tmp), otw_type, +        pod2ptr(output), io_type_out, +        nsamps +    ); + +    //test that the inputs and outputs match +    for (size_t i = 0; i < nsamps; i++){ +        BOOST_CHECK_CLOSE_FRACTION(input[i].real(), output[i].real()/float(32767), float(0.01)); +        BOOST_CHECK_CLOSE_FRACTION(input[i].imag(), output[i].imag()/float(32767), float(0.01)); +    } +} + +/*********************************************************************** + * Test short to float conversion loopback + **********************************************************************/ +BOOST_AUTO_TEST_CASE(test_convert_types_sc16_to_fc32){ +    io_type_t io_type_in(io_type_t::COMPLEX_INT16); +    io_type_t io_type_out(io_type_t::COMPLEX_FLOAT32); + +    otw_type_t otw_type; +    otw_type.byteorder = otw_type_t::BO_NATIVE; +    otw_type.width = 16; + +    const size_t nsamps = 13; +    std::vector<sc16_t> input(nsamps); +    BOOST_FOREACH(sc16_t &in, input) in = sc16_t( +        std::rand()-(RAND_MAX/2), +        std::rand()-(RAND_MAX/2) +    ); + +    //convert short to dev +    std::vector<boost::uint32_t> tmp(nsamps); +    transport::convert_io_type_to_otw_type( +        pod2ptr(input), io_type_in, +        pod2ptr(tmp), otw_type, +        nsamps +    ); + +    //convert dev to float +    std::vector<fc32_t> output(nsamps); +    transport::convert_otw_type_to_io_type( +        pod2ptr(tmp), otw_type, +        pod2ptr(output), io_type_out, +        nsamps +    ); + +    //test that the inputs and outputs match +    for (size_t i = 0; i < nsamps; i++){ +        BOOST_CHECK_CLOSE_FRACTION(input[i].real()/float(32767), output[i].real(), float(0.01)); +        BOOST_CHECK_CLOSE_FRACTION(input[i].imag()/float(32767), output[i].imag(), float(0.01)); +    } +} 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..555ccaed3 --- /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, float(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("g1", 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("g2", gain_fcns, pri2); + +    return gg; +} + +/*********************************************************************** + * Test cases + **********************************************************************/ +static const float tolerance = float(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/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/time_spec_test.cpp b/host/test/time_spec_test.cpp new file mode 100644 index 000000000..5ad782160 --- /dev/null +++ b/host/test/time_spec_test.cpp @@ -0,0 +1,61 @@ +// +// 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/time_spec.hpp> +#include <boost/foreach.hpp> +#include <iostream> + +BOOST_AUTO_TEST_CASE(test_time_spec_compare){ +    std::cout << "Testing time specification compare..." << std::endl; + +    BOOST_CHECK(uhd::time_spec_t(2.0) == uhd::time_spec_t(2.0)); +    BOOST_CHECK(uhd::time_spec_t(2.0) > uhd::time_spec_t(1.0)); +    BOOST_CHECK(uhd::time_spec_t(1.0) < uhd::time_spec_t(2.0)); + +    BOOST_CHECK(uhd::time_spec_t(1.1) == uhd::time_spec_t(1.1)); +    BOOST_CHECK(uhd::time_spec_t(1.1) > uhd::time_spec_t(1.0)); +    BOOST_CHECK(uhd::time_spec_t(1.0) < uhd::time_spec_t(1.1)); + +    BOOST_CHECK(uhd::time_spec_t(0.1) == uhd::time_spec_t(0.1)); +    BOOST_CHECK(uhd::time_spec_t(0.2) > uhd::time_spec_t(0.1)); +    BOOST_CHECK(uhd::time_spec_t(0.1) < uhd::time_spec_t(0.2)); +} + +#define CHECK_TS_EQUAL(lhs, rhs) \ +    BOOST_CHECK_CLOSE((lhs).get_real_secs(), (rhs).get_real_secs(), 0.001) + +BOOST_AUTO_TEST_CASE(test_time_spec_arithmetic){ +    std::cout << "Testing time specification arithmetic..." << std::endl; + +    CHECK_TS_EQUAL(uhd::time_spec_t(2.3) + uhd::time_spec_t(1.0), uhd::time_spec_t(3.3)); +    CHECK_TS_EQUAL(uhd::time_spec_t(2.3) - uhd::time_spec_t(1.0), uhd::time_spec_t(1.3)); +    CHECK_TS_EQUAL(uhd::time_spec_t(1.0) + uhd::time_spec_t(2.3), uhd::time_spec_t(3.3)); +    CHECK_TS_EQUAL(uhd::time_spec_t(1.0) - uhd::time_spec_t(2.3), uhd::time_spec_t(-1.3)); +} + +BOOST_AUTO_TEST_CASE(test_time_spec_parts){ +    std::cout << "Testing time specification parts..." << std::endl; + +    BOOST_CHECK_EQUAL(uhd::time_spec_t(1.1).get_full_secs(), 1); +    BOOST_CHECK_CLOSE(uhd::time_spec_t(1.1).get_frac_secs(), 0.1, 0.001); +    BOOST_CHECK_EQUAL(uhd::time_spec_t(1.1).get_tick_count(100), 10); + +    BOOST_CHECK_EQUAL(uhd::time_spec_t(-1.1).get_full_secs(), -1); +    BOOST_CHECK_CLOSE(uhd::time_spec_t(-1.1).get_frac_secs(), -0.1, 0.001); +    BOOST_CHECK_EQUAL(uhd::time_spec_t(-1.1).get_tick_count(100), -10); +} diff --git a/host/test/tune_helper_test.cpp b/host/test/tune_helper_test.cpp new file mode 100644 index 000000000..e0500ae3f --- /dev/null +++ b/host/test/tune_helper_test.cpp @@ -0,0 +1,253 @@ +// +// 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_subdev_bw : public wax::obj{ +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 = true; +            return; + +        case SUBDEV_PROP_BANDWIDTH: +            val = _bandwidth; +            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 = val.as<double>(); +            return; + +        case SUBDEV_PROP_BANDWIDTH: +            _bandwidth = val.as<double>(); +            return; + +        default: UHD_THROW_PROP_SET_ERROR(); +        } +    } + +    double _freq, _bandwidth; +}; + +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){ +        named_prop_t key = named_prop_t::extract(key_); +        switch(key.as<dsp_prop_t>()){ +        case DSP_PROP_CODEC_RATE: +            val = _codec_rate; +            return; + +        case DSP_PROP_HOST_RATE: +            val = _host_rate; +            return; + +        case DSP_PROP_FREQ_SHIFT: +            val = _freq_shift; +            return; + +        case DSP_PROP_FREQ_SHIFT_NAMES: +            val = prop_names_t(1, ""); +            return; + +        default: UHD_THROW_PROP_GET_ERROR(); +        } +    } + +    void set(const wax::obj &key_, const wax::obj &val){ +        named_prop_t key = named_prop_t::extract(key_); +        switch(key.as<dsp_prop_t>()){ +        case DSP_PROP_FREQ_SHIFT: +            _freq_shift = val.as<double>(); +            return; + +        case DSP_PROP_HOST_RATE: +            _host_rate = val.as<double>(); +            return; + +        default: UHD_THROW_PROP_SET_ERROR(); +        } +    } + +    double _codec_rate, _freq_shift, _host_rate; +}; + +/*********************************************************************** + * 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 IF offset" << std::endl; +    tune_result_t tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 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(), 0); +    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 IF offset" << std::endl; +    tune_result_t tr = tune_tx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 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(), 0); +    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(), 0, 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(), 0); +    BOOST_CHECK_CLOSE(freq_derived, -45e6, tolerance); +} + +BOOST_AUTO_TEST_CASE(test_tune_helper_rx_lo_off){ +    dummy_subdev_bw subdev; +    dummy_dsp dsp(100e6); +    tune_result_t tr; + +    std::cout << "Testing tune helper RX automatic LO offset B >> fs" << std::endl; +    subdev[SUBDEV_PROP_BANDWIDTH] = double(40e6); +    dsp[DSP_PROP_HOST_RATE] = double(4e6); +    tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 2.45e9); +    std::cout << tr.to_pp_string() << std::endl; +    BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.45e9+4e6/2, tolerance); + +    std::cout << "Testing tune helper RX automatic LO offset B > fs" << std::endl; +    subdev[SUBDEV_PROP_BANDWIDTH] = double(40e6); +    dsp[DSP_PROP_HOST_RATE] = double(25e6); +    tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 2.45e9); +    std::cout << tr.to_pp_string() << std::endl; +    BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.45e9+(40e6-25e6)/2, tolerance); + +    std::cout << "Testing tune helper RX automatic LO offset B < fs" << std::endl; +    subdev[SUBDEV_PROP_BANDWIDTH] = double(20e6); +    dsp[DSP_PROP_HOST_RATE] = double(25e6); +    tr = tune_rx_subdev_and_dsp(subdev.get_link(), dsp.get_link(), 0, 2.45e9); +    std::cout << tr.to_pp_string() << std::endl; +    BOOST_CHECK_CLOSE(tr.actual_inter_freq, 2.45e9, 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..db19955de --- /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_warning_post){ +    std::cerr << "---begin print test ---" << std::endl; +    uhd::warning::post( +        "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)); +}  | 
