1 //
2 // Copyright 2019 Ettus Research, a National Instruments Brand
3 //
4 // SPDX-License-Identifier: GPL-3.0-or-later
5 //
6
7 #include "common/mock_link.hpp"
8 #include <boost/test/unit_test.hpp>
9
10 using namespace uhd::transport;
11
BOOST_AUTO_TEST_CASE(test_send_get_release)12 BOOST_AUTO_TEST_CASE(test_send_get_release)
13 {
14 // Just call get_send_buff, release_send_buff, and pop_send_packet
15 // from a link containing a single frame_buff.
16 const size_t num_frames = 1;
17 const int32_t timeout_ms = 1;
18
19 const mock_send_link::link_params params = {1000, num_frames};
20
21 auto xport = std::make_shared<mock_send_link>(params);
22
23 // Check sizes
24 BOOST_CHECK_EQUAL(xport->get_num_send_frames(), params.num_frames);
25 BOOST_CHECK_EQUAL(xport->get_send_frame_size(), params.frame_size);
26
27 // Call get and release a few times and check packet contents
28 for (size_t i = 0; i < 5; i++) {
29 auto buff = xport->get_send_buff(timeout_ms);
30 BOOST_CHECK(buff);
31
32 auto* ptr = static_cast<uint8_t*>(buff->data());
33 ptr[0] = i;
34
35 buff->set_packet_size(sizeof(uint8_t));
36 xport->release_send_buff(std::move(buff));
37 BOOST_CHECK(!buff);
38
39 auto packet = xport->pop_send_packet();
40 BOOST_CHECK_EQUAL(packet.first[0], i);
41 BOOST_CHECK_EQUAL(packet.second, sizeof(uint8_t));
42 }
43 }
44
BOOST_AUTO_TEST_CASE(test_send_timeout)45 BOOST_AUTO_TEST_CASE(test_send_timeout)
46 {
47 // Test that the link returns timeouts correctly and continues to
48 // operate properly after a timeout condition.
49 const size_t num_frames = 10;
50 const int32_t timeout_ms = 1;
51
52 const mock_send_link::link_params params = {1000, num_frames};
53
54 auto xport = std::make_shared<mock_send_link>(params);
55
56 // Repeat the following a few times to check buffers are not lost
57 for (size_t i = 0; i < 3; i++) {
58 // Cause a timeout by simulating an I/O delay in the underlying
59 // link implementation.
60 std::vector<frame_buff::uptr> buffs;
61
62 for (size_t j = 0; j < num_frames / 2; j++) {
63 buffs.push_back(xport->get_send_buff(timeout_ms));
64 BOOST_CHECK(buffs.back());
65 }
66
67 // Simulate a timeout
68 xport->set_simulate_io_timeout(true);
69 BOOST_CHECK(!xport->get_send_buff(timeout_ms));
70 xport->set_simulate_io_timeout(false);
71
72 for (size_t j = 0; j < num_frames / 2; j++) {
73 buffs.push_back(xport->get_send_buff(timeout_ms));
74 BOOST_CHECK(buffs.back());
75 }
76
77 for (auto& buff : buffs) {
78 buff->set_packet_size(params.frame_size);
79 xport->release_send_buff(std::move(buff));
80 BOOST_CHECK(!buff);
81 }
82 }
83 }
84
BOOST_AUTO_TEST_CASE(test_recv_get_release)85 BOOST_AUTO_TEST_CASE(test_recv_get_release)
86 {
87 // Just call push_recv_packet, get_recv_buff, and release_recv_buff
88 // from a link containing a single frame_buff.
89 const size_t num_frames = 1;
90 const int32_t timeout_ms = 1;
91
92 const mock_recv_link::link_params params = {1000, num_frames};
93
94 auto xport = std::make_shared<mock_recv_link>(params);
95
96 // Check sizes
97 BOOST_CHECK_EQUAL(xport->get_num_recv_frames(), params.num_frames);
98 BOOST_CHECK_EQUAL(xport->get_recv_frame_size(), params.frame_size);
99
100 // Call get and release a few times and check packet contents
101 for (size_t i = 0; i < 5; i++) {
102 size_t packet_size = sizeof(uint8_t);
103 auto packet_data = boost::shared_array<uint8_t>(new uint8_t[packet_size]);
104 packet_data[0] = i;
105 xport->push_back_recv_packet(packet_data, packet_size);
106
107 auto buff = xport->get_recv_buff(timeout_ms);
108 BOOST_CHECK(buff);
109 BOOST_CHECK(buff->data());
110
111 auto* ptr = static_cast<uint8_t*>(buff->data());
112 ptr[0] = i;
113
114 xport->release_recv_buff(std::move(buff));
115 BOOST_CHECK(!buff);
116 }
117 }
118
BOOST_AUTO_TEST_CASE(test_recv_timeout)119 BOOST_AUTO_TEST_CASE(test_recv_timeout)
120 {
121 // Test that the link returns timeouts correctly and continues to
122 // operate properly after a timeout condition.
123 const size_t num_frames = 10;
124 const int32_t timeout_ms = 1;
125
126 const mock_recv_link::link_params params = {1000, num_frames};
127
128 auto xport = std::make_shared<mock_recv_link>(params);
129
130 // Repeat the following a few times to check buffers are not lost
131 for (size_t i = 0; i < 3; i++) {
132 // Cause a timeout by simulating an I/O delay in the underlying
133 // link implementation.
134 std::vector<frame_buff::uptr> buffs;
135
136 for (size_t i = 0; i < num_frames / 2; i++) {
137 size_t packet_size = sizeof(uint8_t);
138 auto packet_data = boost::shared_array<uint8_t>(new uint8_t[packet_size]);
139 xport->push_back_recv_packet(packet_data, packet_size);
140
141 buffs.push_back(xport->get_recv_buff(timeout_ms));
142 BOOST_CHECK(buffs.back());
143 }
144
145 // Simulate a timeout by getting a buffer without queueing a data array
146 BOOST_CHECK(!xport->get_recv_buff(timeout_ms));
147
148 for (size_t i = 0; i < num_frames / 2; i++) {
149 size_t packet_size = sizeof(uint8_t);
150 auto packet_data = boost::shared_array<uint8_t>(new uint8_t[packet_size]);
151 xport->push_back_recv_packet(packet_data, packet_size);
152
153 buffs.push_back(xport->get_recv_buff(timeout_ms));
154 BOOST_CHECK(buffs.back());
155 }
156
157 for (auto& buff : buffs) {
158 xport->release_recv_buff(std::move(buff));
159 BOOST_CHECK(!buff);
160 }
161 }
162 }
163