1 //
2 // Copyright (C) 2019-2020 Codership Oy <info@codership.com>
3 //
4 
5 #include "check_gcomm.hpp"
6 #include "fair_send_queue.hpp"
7 
8 #include <check.h>
9 
make_datagram(char header)10 static gcomm::Datagram make_datagram(char header)
11 {
12     static const char data[1] = { 0 };
13     gcomm::Datagram ret(gu::SharedBuffer(new gu::Buffer(data, data + 1)));
14     ret.set_header_offset(ret.header_offset() - 1);
15     ret.header()[ret.header_offset()] = header;
16     return ret;
17 }
18 
get_header(const gcomm::Datagram & dg)19 static gu::byte_t get_header(const gcomm::Datagram& dg)
20 {
21     return dg.header()[dg.header_offset()];
22 }
23 
24 // Test the make_datagram() helper above.
START_TEST(test_datagram)25 START_TEST(test_datagram)
26 {
27     gcomm::Datagram dg(make_datagram(1));
28     ck_assert(dg.len() == 2);
29     ck_assert(get_header(dg) == 1);
30 }
31 END_TEST
32 
START_TEST(test_push_back)33 START_TEST(test_push_back)
34 {
35     gcomm::FairSendQueue fsq;
36     gcomm::Datagram dg(make_datagram(1));
37     fsq.push_back(0, dg);
38     ck_assert(fsq.front().len() == 2);
39     ck_assert(get_header(fsq.front()) == 1);
40 }
41 END_TEST
42 
START_TEST(test_push_back_same_segments)43 START_TEST(test_push_back_same_segments)
44 {
45     gcomm::FairSendQueue fsq;
46     gcomm::Datagram dg(make_datagram(1));
47     fsq.push_back(0, dg);
48     ck_assert(get_header(fsq.front()) == 1);
49     ck_assert(get_header(fsq.back()) == 1);
50     fsq.push_back(0, make_datagram(2));
51     ck_assert(get_header(fsq.front()) == 1);
52     ck_assert(get_header(fsq.back()) == 2);
53 }
54 END_TEST
55 
START_TEST(test_push_back_different_segments)56 START_TEST(test_push_back_different_segments)
57 {
58     gcomm::FairSendQueue fsq;
59     gcomm::Datagram dg(make_datagram(1));
60     fsq.push_back(0, dg);
61     ck_assert(get_header(fsq.front()) == 1);
62     ck_assert(get_header(fsq.back()) == 1);
63     fsq.push_back(1, make_datagram(2));
64     ck_assert(get_header(fsq.front()) == 1);
65     ck_assert(get_header(fsq.back()) == 2);
66 }
67 END_TEST
68 
START_TEST(test_empty)69 START_TEST(test_empty)
70 {
71     gcomm::FairSendQueue fsq;
72     ck_assert(fsq.empty());
73     fsq.push_back(0, make_datagram(1));
74     ck_assert(!fsq.empty());
75 }
76 END_TEST
77 
START_TEST(test_size)78 START_TEST(test_size)
79 {
80     gcomm::FairSendQueue fsq;
81     fsq.push_back(0, make_datagram(1));
82     ck_assert(fsq.size() == 1);
83     fsq.push_back(1, make_datagram(2));
84     ck_assert(fsq.size() == 2);
85 }
86 END_TEST
87 
START_TEST(test_pop_front)88 START_TEST(test_pop_front)
89 {
90     gcomm::FairSendQueue fsq;
91     fsq.push_back(0, make_datagram(1));
92     ck_assert(fsq.size() == 1);
93     fsq.pop_front();
94     ck_assert(fsq.size() == 0);
95 }
96 END_TEST
97 
START_TEST(test_pop_front_same_segments)98 START_TEST(test_pop_front_same_segments)
99 {
100     gcomm::FairSendQueue fsq;
101     fsq.push_back(0, make_datagram(1));
102     ck_assert(fsq.size() == 1);
103     fsq.push_back(0, make_datagram(2));
104     ck_assert(fsq.size() == 2);
105     ck_assert(get_header(fsq.front()) == 1);
106 
107     fsq.pop_front();
108     ck_assert(fsq.size() == 1);
109     ck_assert(get_header(fsq.front()) == 2);
110 }
111 END_TEST
112 
START_TEST(test_pop_front_different_segments)113 START_TEST(test_pop_front_different_segments)
114 {
115     gcomm::FairSendQueue fsq;
116     fsq.push_back(0, make_datagram(1));
117     ck_assert(fsq.size() == 1);
118     fsq.push_back(1, make_datagram(2));
119     ck_assert(fsq.size() == 2);
120     ck_assert(get_header(fsq.front()) == 1);
121 
122     fsq.pop_front();
123     ck_assert(fsq.size() == 1);
124     ck_assert(get_header(fsq.front()) == 2);
125 }
126 END_TEST
127 
START_TEST(test_push_pop_interleaving)128 START_TEST(test_push_pop_interleaving)
129 {
130     gcomm::FairSendQueue fsq;
131     fsq.push_back(0, make_datagram(1));
132     fsq.push_back(1, make_datagram(2));
133     fsq.push_back(0, make_datagram(3));
134     fsq.push_back(1, make_datagram(4));
135 
136     ck_assert(get_header(fsq.front()) == 1);
137     ck_assert(fsq.size() == 4);
138 
139     fsq.pop_front();
140     ck_assert(fsq.size() == 3);
141     ck_assert(get_header(fsq.front()) == 2);
142     fsq.pop_front();
143     ck_assert(fsq.size() == 2);
144     ck_assert(get_header(fsq.front()) == 3);
145     fsq.pop_front();
146     ck_assert(fsq.size() == 1);
147     ck_assert(get_header(fsq.front()) == 4);
148     fsq.pop_front();
149     ck_assert(fsq.empty());
150 }
151 END_TEST
152 
START_TEST(test_queued_bytes)153 START_TEST(test_queued_bytes)
154 {
155     gcomm::FairSendQueue fsq;
156     fsq.push_back(0, make_datagram(1));
157     ck_assert(fsq.queued_bytes() == 2);
158     fsq.push_back(1, make_datagram(2));
159     ck_assert(fsq.queued_bytes() == 4);
160     fsq.pop_front();
161     ck_assert(fsq.queued_bytes() == 2);
162     fsq.pop_front();
163     ck_assert(fsq.queued_bytes() == 0);
164 }
165 END_TEST
166 
167 
fair_send_queue_suite()168 Suite* fair_send_queue_suite()
169 {
170     Suite* ret(suite_create("fair_send_queue"));
171     TCase* tc;
172 
173     tc = tcase_create("test_datagram");
174     tcase_add_test(tc, test_datagram);
175     suite_add_tcase(ret, tc);
176 
177     tc = tcase_create("test_push_back");
178     tcase_add_test(tc, test_push_back);
179     suite_add_tcase(ret, tc);
180 
181     tc = tcase_create("test_push_back_same_segments");
182     tcase_add_test(tc, test_push_back_same_segments);
183     suite_add_tcase(ret, tc);
184 
185     tc = tcase_create("test_push_back_different_segments");
186     tcase_add_test(tc, test_push_back_different_segments);
187     suite_add_tcase(ret, tc);
188 
189     tc = tcase_create("test_empty");
190     tcase_add_test(tc, test_empty);
191     suite_add_tcase(ret, tc);
192 
193     tc = tcase_create("test_size");
194     tcase_add_test(tc, test_size);
195     suite_add_tcase(ret, tc);
196 
197     tc = tcase_create("test_pop_front");
198     tcase_add_test(tc, test_pop_front);
199     suite_add_tcase(ret, tc);
200 
201     tc = tcase_create("test_pop_front_same_segments");
202     tcase_add_test(tc, test_pop_front_same_segments);
203     suite_add_tcase(ret, tc);
204 
205     tc = tcase_create("test_pop_front_different_segments");
206     tcase_add_test(tc, test_pop_front_different_segments);
207     suite_add_tcase(ret, tc);
208 
209     tc = tcase_create("test_push_pop_interleaving");
210     tcase_add_test(tc, test_push_pop_interleaving);
211     suite_add_tcase(ret, tc);
212 
213     tc = tcase_create("test_queued_bytes");
214     tcase_add_test(tc, test_queued_bytes);
215     suite_add_tcase(ret, tc);
216 
217     return ret;
218 }
219