aboutsummaryrefslogtreecommitdiffstats
path: root/host/tests/link_test.cpp
blob: dd147686e860bae24f9e8dcdc3b70a86fd793dc9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//
// Copyright 2019 Ettus Research, a National Instruments Brand
//
// SPDX-License-Identifier: GPL-3.0-or-later
//

#include "common/mock_link.hpp"
#include <boost/test/unit_test.hpp>

using namespace uhd::transport;

BOOST_AUTO_TEST_CASE(test_send_get_release)
{
    // Just call get_send_buff, release_send_buff, and pop_send_packet
    // from a link containing a single frame_buff.
    const size_t num_frames  = 1;
    const int32_t timeout_ms = 1;

    const mock_send_link::link_params params = {1000, num_frames};

    auto xport = std::make_shared<mock_send_link>(params);

    // Check sizes
    BOOST_CHECK_EQUAL(xport->get_num_send_frames(), params.num_frames);
    BOOST_CHECK_EQUAL(xport->get_send_frame_size(), params.frame_size);

    // Call get and release a few times and check packet contents
    for (size_t i = 0; i < 5; i++) {
        auto buff = xport->get_send_buff(timeout_ms);
        BOOST_CHECK(buff);

        auto* ptr = static_cast<uint8_t*>(buff->data());
        ptr[0]    = i;

        buff->set_packet_size(sizeof(uint8_t));
        xport->release_send_buff(std::move(buff));
        BOOST_CHECK(!buff);

        auto packet = xport->pop_send_packet();
        BOOST_CHECK_EQUAL(packet.first[0], i);
        BOOST_CHECK_EQUAL(packet.second, sizeof(uint8_t));
    }
}

BOOST_AUTO_TEST_CASE(test_send_timeout)
{
    // Test that the link returns timeouts correctly and continues to
    // operate properly after a timeout condition.
    const size_t num_frames  = 10;
    const int32_t timeout_ms = 1;

    const mock_send_link::link_params params = {1000, num_frames};

    auto xport = std::make_shared<mock_send_link>(params);

    // Repeat the following a few times to check buffers are not lost
    for (size_t i = 0; i < 3; i++) {
        // Cause a timeout by simulating an I/O delay in the underlying
        // link implementation.
        std::vector<frame_buff::uptr> buffs;

        for (size_t j = 0; j < num_frames / 2; j++) {
            buffs.push_back(xport->get_send_buff(timeout_ms));
            BOOST_CHECK(buffs.back());
        }

        // Simulate a timeout
        xport->set_simulate_io_timeout(true);
        BOOST_CHECK(!xport->get_send_buff(timeout_ms));
        xport->set_simulate_io_timeout(false);

        for (size_t j = 0; j < num_frames / 2; j++) {
            buffs.push_back(xport->get_send_buff(timeout_ms));
            BOOST_CHECK(buffs.back());
        }

        for (auto& buff : buffs) {
            buff->set_packet_size(params.frame_size);
            xport->release_send_buff(std::move(buff));
            BOOST_CHECK(!buff);
        }
    }
}

BOOST_AUTO_TEST_CASE(test_recv_get_release)
{
    // Just call push_recv_packet, get_recv_buff, and release_recv_buff
    // from a link containing a single frame_buff.
    const size_t num_frames  = 1;
    const int32_t timeout_ms = 1;

    const mock_recv_link::link_params params = {1000, num_frames};

    auto xport = std::make_shared<mock_recv_link>(params);

    // Check sizes
    BOOST_CHECK_EQUAL(xport->get_num_recv_frames(), params.num_frames);
    BOOST_CHECK_EQUAL(xport->get_recv_frame_size(), params.frame_size);

    // Call get and release a few times and check packet contents
    for (size_t i = 0; i < 5; i++) {
        size_t packet_size = sizeof(uint8_t);
        auto packet_data   = boost::shared_array<uint8_t>(new uint8_t[packet_size]);
        packet_data[0]     = static_cast<uint8_t>(i);
        xport->push_back_recv_packet(packet_data, packet_size);

        auto buff = xport->get_recv_buff(timeout_ms);
        BOOST_CHECK(buff);
        BOOST_CHECK(buff->data());

        auto* ptr = static_cast<uint8_t*>(buff->data());
        BOOST_CHECK_EQUAL(ptr[0], static_cast<uint8_t>(i));

        xport->release_recv_buff(std::move(buff));
        BOOST_CHECK(!buff);
    }
}

BOOST_AUTO_TEST_CASE(test_recv_timeout)
{
    // Test that the link returns timeouts correctly and continues to
    // operate properly after a timeout condition.
    const size_t num_frames  = 10;
    const int32_t timeout_ms = 1;

    const mock_recv_link::link_params params = {1000, num_frames};

    auto xport = std::make_shared<mock_recv_link>(params);

    // Repeat the following a few times to check buffers are not lost
    for (size_t i = 0; i < 3; i++) {
        // Cause a timeout by simulating an I/O delay in the underlying
        // link implementation.
        std::vector<frame_buff::uptr> buffs;

        for (size_t i = 0; i < num_frames / 2; i++) {
            size_t packet_size = sizeof(uint8_t);
            auto packet_data   = boost::shared_array<uint8_t>(new uint8_t[packet_size]);
            xport->push_back_recv_packet(packet_data, packet_size);

            buffs.push_back(xport->get_recv_buff(timeout_ms));
            BOOST_CHECK(buffs.back());
        }

        // Simulate a timeout by getting a buffer without queueing a data array
        BOOST_CHECK(!xport->get_recv_buff(timeout_ms));

        for (size_t i = 0; i < num_frames / 2; i++) {
            size_t packet_size = sizeof(uint8_t);
            auto packet_data   = boost::shared_array<uint8_t>(new uint8_t[packet_size]);
            xport->push_back_recv_packet(packet_data, packet_size);

            buffs.push_back(xport->get_recv_buff(timeout_ms));
            BOOST_CHECK(buffs.back());
        }

        for (auto& buff : buffs) {
            xport->release_recv_buff(std::move(buff));
            BOOST_CHECK(!buff);
        }
    }
}