1 //
2 // Copyright (C) 2024 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 #include <gtest/gtest.h>
17 #include <ringbuffer.h>
18
TEST(RingbufferTest,test_new_simple)19 TEST(RingbufferTest, test_new_simple) {
20 ringbuffer_t* rb = ringbuffer_init(4096);
21 ASSERT_TRUE(rb != nullptr);
22 EXPECT_EQ((size_t)4096, ringbuffer_available(rb));
23 EXPECT_EQ((size_t)0, ringbuffer_size(rb));
24 ringbuffer_free(rb);
25 }
26
TEST(RingbufferTest,test_insert_basic)27 TEST(RingbufferTest, test_insert_basic) {
28 ringbuffer_t* rb = ringbuffer_init(16);
29 uint8_t buffer[10] = {0x01, 0x02, 0x03, 0x04, 0x05,
30 0x06, 0x07, 0x08, 0x09, 0x0A};
31 ringbuffer_insert(rb, buffer, 10);
32 EXPECT_EQ((size_t)10, ringbuffer_size(rb));
33 EXPECT_EQ((size_t)6, ringbuffer_available(rb));
34 uint8_t peek[10] = {0};
35 size_t peeked = ringbuffer_peek(rb, 0, peek, 10);
36 EXPECT_EQ((size_t)10, ringbuffer_size(rb)); // Ensure size doesn't change
37 EXPECT_EQ((size_t)6, ringbuffer_available(rb));
38 EXPECT_EQ((size_t)10, peeked);
39 ASSERT_TRUE(0 == memcmp(buffer, peek, peeked));
40 ringbuffer_free(rb);
41 }
42
TEST(RingbufferTest,test_insert_full)43 TEST(RingbufferTest, test_insert_full) {
44 ringbuffer_t* rb = ringbuffer_init(5);
45 uint8_t aa[] = {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
46 uint8_t bb[] = {0xBB, 0xBB, 0xBB, 0xBB, 0xBB};
47 uint8_t peek[5] = {0};
48 size_t added = ringbuffer_insert(rb, aa, 7);
49 EXPECT_EQ((size_t)5, added);
50 EXPECT_EQ((size_t)0, ringbuffer_available(rb));
51 EXPECT_EQ((size_t)5, ringbuffer_size(rb));
52 added = ringbuffer_insert(rb, bb, 5);
53 EXPECT_EQ((size_t)0, added);
54 EXPECT_EQ((size_t)0, ringbuffer_available(rb));
55 EXPECT_EQ((size_t)5, ringbuffer_size(rb));
56 size_t peeked = ringbuffer_peek(rb, 0, peek, 5);
57 EXPECT_EQ((size_t)5, peeked);
58 EXPECT_EQ((size_t)0, ringbuffer_available(rb));
59 EXPECT_EQ((size_t)5, ringbuffer_size(rb));
60 ASSERT_TRUE(0 == memcmp(aa, peek, peeked));
61 ringbuffer_free(rb);
62 }
63
TEST(RingbufferTest,test_multi_insert_delete)64 TEST(RingbufferTest, test_multi_insert_delete) {
65 ringbuffer_t* rb = ringbuffer_init(16);
66 EXPECT_EQ((size_t)16, ringbuffer_available(rb));
67 EXPECT_EQ((size_t)0, ringbuffer_size(rb));
68 // Insert some bytes
69 uint8_t aa[] = {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA};
70 size_t added = ringbuffer_insert(rb, aa, sizeof(aa));
71 EXPECT_EQ((size_t)8, added);
72 EXPECT_EQ((size_t)8, ringbuffer_available(rb));
73 EXPECT_EQ((size_t)8, ringbuffer_size(rb));
74 uint8_t bb[] = {0xBB, 0xBB, 0xBB, 0xBB, 0xBB};
75 ringbuffer_insert(rb, bb, sizeof(bb));
76 EXPECT_EQ((size_t)3, ringbuffer_available(rb));
77 EXPECT_EQ((size_t)13, ringbuffer_size(rb));
78 uint8_t content[] = {0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA,
79 0xAA, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB};
80 uint8_t peek[16] = {0};
81 size_t peeked = ringbuffer_peek(rb, 0, peek, 16);
82 EXPECT_EQ((size_t)13, peeked);
83 ASSERT_TRUE(0 == memcmp(content, peek, peeked));
84
85 // Delete some bytes
86 ringbuffer_delete(rb, sizeof(aa));
87 EXPECT_EQ((size_t)11, ringbuffer_available(rb));
88 EXPECT_EQ((size_t)5, ringbuffer_size(rb));
89
90 // Add some more to wrap buffer
91 uint8_t cc[] = {0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC};
92 ringbuffer_insert(rb, cc, sizeof(cc));
93 EXPECT_EQ((size_t)2, ringbuffer_available(rb));
94 EXPECT_EQ((size_t)14, ringbuffer_size(rb));
95
96 uint8_t content2[] = {0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xCC, 0xCC};
97 peeked = ringbuffer_peek(rb, 0, peek, 7);
98 EXPECT_EQ((size_t)7, peeked);
99 ASSERT_TRUE(0 == memcmp(content2, peek, peeked));
100
101 // Pop buffer
102
103 memset(peek, 0, 16);
104 size_t popped = ringbuffer_pop(rb, peek, 7);
105 EXPECT_EQ((size_t)7, popped);
106 EXPECT_EQ((size_t)9, ringbuffer_available(rb));
107 ASSERT_TRUE(0 == memcmp(content2, peek, peeked));
108
109 // Add more again to check head motion
110
111 uint8_t dd[] = {0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD, 0xDD};
112 added = ringbuffer_insert(rb, dd, sizeof(dd));
113 EXPECT_EQ((size_t)8, added);
114 EXPECT_EQ((size_t)1, ringbuffer_available(rb));
115
116 // Delete everything
117
118 ringbuffer_delete(rb, 16);
119 EXPECT_EQ((size_t)16, ringbuffer_available(rb));
120 EXPECT_EQ((size_t)0, ringbuffer_size(rb));
121
122 // Add small token
123
124 uint8_t ae[] = {0xAE, 0xAE, 0xAE};
125 added = ringbuffer_insert(rb, ae, sizeof(ae));
126 EXPECT_EQ((size_t)13, ringbuffer_available(rb));
127
128 // Get everything
129
130 popped = ringbuffer_pop(rb, peek, 16);
131 EXPECT_EQ(added, popped);
132 EXPECT_EQ((size_t)16, ringbuffer_available(rb));
133 EXPECT_EQ((size_t)0, ringbuffer_size(rb));
134 ASSERT_TRUE(0 == memcmp(ae, peek, popped));
135
136 ringbuffer_free(rb);
137 }
138
TEST(RingbufferTest,test_delete)139 TEST(RingbufferTest, test_delete) {
140 ringbuffer_t* rb = ringbuffer_init(16);
141 uint8_t data[] = {0x01, 0x02, 0x03, 0x04};
142 ringbuffer_insert(rb, data, sizeof(data));
143
144 EXPECT_EQ((size_t)4, ringbuffer_size(rb));
145 EXPECT_EQ((size_t)12, ringbuffer_available(rb));
146
147 ringbuffer_delete(rb, 2); // Delete 2 bytes
148 EXPECT_EQ((size_t)2, ringbuffer_size(rb));
149 EXPECT_EQ((size_t)14, ringbuffer_available(rb));
150
151 ringbuffer_free(rb);
152 }
153
TEST(RingbufferTest,test_delete_after_basic_insert)154 TEST(RingbufferTest, test_delete_after_basic_insert) {
155 ringbuffer_t* rb = ringbuffer_init(16);
156 uint8_t buffer[10] = {0x01, 0x02, 0x03, 0x04, 0x05,
157 0x06, 0x07, 0x08, 0x09, 0x0A};
158 ringbuffer_insert(rb, buffer, 10);
159 // Delete 5 bytes
160 ringbuffer_delete(rb, 5);
161 EXPECT_EQ((size_t)11,
162 ringbuffer_available(rb)); // Available should increase by 5
163 EXPECT_EQ((size_t)5, ringbuffer_size(rb)); // Size should decrease to 5
164
165 uint8_t peek[10] = {0};
166 size_t peeked = ringbuffer_peek(rb, 0, peek, 10);
167 uint8_t expected[] = {0x06, 0x07, 0x08, 0x09, 0x0A};
168 ASSERT_TRUE(0 == memcmp(expected, peek, peeked)); // Check remaining bytes
169 ringbuffer_free(rb);
170 }
171
TEST(RingbufferTest,test_delete_after_insert_full)172 TEST(RingbufferTest, test_delete_after_insert_full) {
173 ringbuffer_t* rb = ringbuffer_init(16);
174 uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
175 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10};
176
177 // Insert data
178 ringbuffer_insert(rb, data, sizeof(data));
179 EXPECT_EQ((size_t)16, ringbuffer_size(rb));
180 EXPECT_EQ((size_t)0, ringbuffer_available(rb)); // Should be full
181 // Now delete some bytes
182 ringbuffer_delete(rb, 8); // Delete half of the buffer
183 EXPECT_EQ((size_t)8, ringbuffer_size(rb)); // Should have 8 left
184 EXPECT_EQ((size_t)8, ringbuffer_available(rb)); // 8 should be available now
185 ringbuffer_free(rb);
186 }
187
TEST(RingbufferTest,test_multi_insert_followed_by_delete)188 TEST(RingbufferTest, test_multi_insert_followed_by_delete) {
189 ringbuffer_t* rb = ringbuffer_init(16);
190 uint8_t data1[] = {0x01, 0x02, 0x03, 0x04};
191 uint8_t data2[] = {0x05, 0x06, 0x07, 0x08};
192 ringbuffer_insert(rb, data1, sizeof(data1));
193 EXPECT_EQ((size_t)4, ringbuffer_size(rb)); // 4 bytes
194 EXPECT_EQ((size_t)12, ringbuffer_available(rb)); // 12 bytes available
195 ringbuffer_insert(rb, data2, sizeof(data2));
196 EXPECT_EQ((size_t)8, ringbuffer_size(rb)); // 8 bytes
197 EXPECT_EQ((size_t)8, ringbuffer_available(rb)); // 8 bytes available
198 // Delete some bytes
199 ringbuffer_delete(rb, 3); // Delete 3 bytes
200 EXPECT_EQ((size_t)5, ringbuffer_size(rb)); // Should have 5 left
201 EXPECT_EQ((size_t)11, ringbuffer_available(rb)); // 11 should be available
202 // Verify contents
203 uint8_t peek[16] = {0};
204 size_t peeked = ringbuffer_peek(rb, 0, peek, 16);
205 uint8_t expected[] = {0x04, 0x05, 0x06, 0x07,
206 0x08}; // Remaining bytes after deletion
207 ASSERT_TRUE(0 == memcmp(expected, peek, 5));
208 ringbuffer_free(rb);
209 }
210
TEST(RingbufferTest,test_free_empty)211 TEST(RingbufferTest, test_free_empty) {
212 ringbuffer_t* rb = ringbuffer_init(16);
213 ASSERT_TRUE(rb != nullptr);
214 ringbuffer_free(rb); // Freeing an empty ringbuffer should not cause issues
215 }
216
TEST(RingbufferTest,test_free_after_inserts)217 TEST(RingbufferTest, test_free_after_inserts) {
218 ringbuffer_t* rb = ringbuffer_init(16);
219 uint8_t data[] = {0x01, 0x02, 0x03, 0x04};
220 ringbuffer_insert(rb, data, sizeof(data));
221 EXPECT_EQ((size_t)4, ringbuffer_size(rb));
222 ringbuffer_free(rb); // Ensure freeing works after inserts
223 }
224
TEST(RingbufferTest,test_free_multiple_times)225 TEST(RingbufferTest, test_free_multiple_times) {
226 ringbuffer_t* rb = ringbuffer_init(16);
227 ASSERT_TRUE(rb != nullptr);
228 ringbuffer_free(rb); // First free should be fine
229
230 // Set pointer to null to prevent double free
231 rb = nullptr;
232
233 // The second free should not cause an issue as rb is now null
234 ringbuffer_free(rb); // This should safely do nothing
235 }
236
TEST(RingbufferTest,test_peek_empty)237 TEST(RingbufferTest, test_peek_empty) {
238 ringbuffer_t* rb = ringbuffer_init(16);
239 uint8_t peek[16] = {0};
240 size_t peeked = ringbuffer_peek(rb, 0, peek, sizeof(peek));
241 EXPECT_EQ((size_t)0, peeked); // Nothing to peek
242 EXPECT_EQ((size_t)0, ringbuffer_size(rb)); // Size should remain 0
243 ringbuffer_free(rb);
244 }
245
TEST(RingbufferTest,test_peek_after_insert)246 TEST(RingbufferTest, test_peek_after_insert) {
247 ringbuffer_t* rb = ringbuffer_init(16);
248 uint8_t data[] = {0x01, 0x02, 0x03, 0x04};
249 ringbuffer_insert(rb, data, sizeof(data));
250 uint8_t peek[4] = {0};
251 size_t peeked = ringbuffer_peek(rb, 0, peek, sizeof(peek));
252 EXPECT_EQ((size_t)4, peeked);
253 ASSERT_TRUE(0 == memcmp(data, peek, peeked));
254 EXPECT_EQ((size_t)4, ringbuffer_size(rb)); // Size should remain unchanged
255 ringbuffer_free(rb);
256 }
257
TEST(RingbufferTest,test_peek_with_offset)258 TEST(RingbufferTest, test_peek_with_offset) {
259 ringbuffer_t* rb = ringbuffer_init(16);
260 uint8_t data[] = {0x01, 0x02, 0x03, 0x04};
261 ringbuffer_insert(rb, data, sizeof(data));
262 uint8_t peek[3] = {0};
263 size_t peeked =
264 ringbuffer_peek(rb, 1, peek, sizeof(peek)); // Peek with offset 1
265
266 EXPECT_EQ((size_t)3, peeked);
267 uint8_t expected[] = {0x02, 0x03, 0x04};
268 ASSERT_TRUE(0 == memcmp(expected, peek, peeked));
269 ringbuffer_free(rb);
270 }
271
TEST(RingbufferTest,test_peek_with_wrap)272 TEST(RingbufferTest, test_peek_with_wrap) {
273 ringbuffer_t* rb = ringbuffer_init(16);
274 ASSERT_TRUE(rb != nullptr);
275 uint8_t data1[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
276 ringbuffer_insert(rb, data1, sizeof(data1)); // Insert 8 bytes
277 uint8_t data2[] = {0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10};
278 ringbuffer_insert(rb, data2,
279 sizeof(data2)); // Insert another 8 bytes (total 16 bytes)
280 uint8_t peeked[10] = {0};
281 size_t peeked_size = ringbuffer_peek(rb, 0, peeked, 10); // Peek 10 bytes
282 EXPECT_EQ((size_t)10, peeked_size); // Should successfully peek 10 bytes
283 uint8_t expected[10] = {0x01, 0x02, 0x03, 0x04, 0x05,
284 0x06, 0x07, 0x08, 0x09, 0x0A};
285 EXPECT_EQ(0, memcmp(expected, peeked,
286 peeked_size)); // Check if peeked data is correct
287 ringbuffer_free(rb);
288 }
289
TEST(RingbufferTest,test_pop_empty)290 TEST(RingbufferTest, test_pop_empty) {
291 ringbuffer_t* rb = ringbuffer_init(16);
292 uint8_t peek[16] = {0};
293 size_t popped = ringbuffer_pop(rb, peek, sizeof(peek));
294 EXPECT_EQ((size_t)0, popped); // Nothing to pop
295 EXPECT_EQ((size_t)0, ringbuffer_size(rb)); // Size should remain 0
296 ringbuffer_free(rb);
297 }
298
TEST(RingbufferTest,test_pop_after_insert)299 TEST(RingbufferTest, test_pop_after_insert) {
300 ringbuffer_t* rb = ringbuffer_init(16);
301 uint8_t data[] = {0x01, 0x02, 0x03, 0x04};
302 ringbuffer_insert(rb, data, sizeof(data));
303 uint8_t peek[4] = {0};
304 size_t popped = ringbuffer_pop(rb, peek, sizeof(peek));
305 EXPECT_EQ((size_t)4, popped);
306 ASSERT_TRUE(0 == memcmp(data, peek, popped));
307 EXPECT_EQ((size_t)0, ringbuffer_size(rb)); // Size should now be 0
308
309 ringbuffer_free(rb);
310 }
311
TEST(RingbufferTest,test_pop_partial)312 TEST(RingbufferTest, test_pop_partial) {
313 ringbuffer_t* rb = ringbuffer_init(16);
314 uint8_t data[] = {0x01, 0x02, 0x03, 0x04};
315 ringbuffer_insert(rb, data, sizeof(data));
316 uint8_t peek[2] = {0};
317 size_t popped = ringbuffer_pop(rb, peek, 2);
318 EXPECT_EQ((size_t)2, popped);
319 uint8_t expected[] = {0x01, 0x02};
320 ASSERT_TRUE(0 == memcmp(expected, peek, popped));
321 EXPECT_EQ((size_t)2, ringbuffer_size(rb)); // Remaining size should be 2
322 ringbuffer_free(rb);
323 }
TEST(RingbufferTest,test_pop_with_wrap)324 TEST(RingbufferTest, test_pop_with_wrap) {
325 ringbuffer_t* rb = ringbuffer_init(16);
326 ASSERT_TRUE(rb != nullptr);
327
328 uint8_t data1[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
329 ringbuffer_insert(rb, data1, sizeof(data1)); // Insert 8 bytes
330
331 uint8_t data2[] = {0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10};
332 ringbuffer_insert(rb, data2,
333 sizeof(data2)); // Insert another 8 bytes (total 16 bytes)
334
335 uint8_t popped[10] = {0};
336 size_t popped_size = ringbuffer_pop(rb, popped, 10); // Pop 10 bytes
337
338 EXPECT_EQ((size_t)10, popped_size); // Should successfully pop 10 bytes
339 uint8_t expected[10] = {0x01, 0x02, 0x03, 0x04, 0x05,
340 0x06, 0x07, 0x08, 0x09, 0x0A};
341 EXPECT_EQ(0, memcmp(expected, popped,
342 popped_size)); // Check if popped data is correct
343
344 ringbuffer_free(rb);
345 }
346
TEST(RingbufferTest,test_initial_size)347 TEST(RingbufferTest, test_initial_size) {
348 ringbuffer_t* rb = ringbuffer_init(16);
349 ASSERT_TRUE(rb != nullptr);
350 EXPECT_EQ((size_t)0, ringbuffer_size(rb)); // Should be 0
351 ringbuffer_free(rb);
352 }
353
TEST(RingbufferTest,test_size_after_insert)354 TEST(RingbufferTest, test_size_after_insert) {
355 ringbuffer_t* rb = ringbuffer_init(16);
356 ASSERT_TRUE(rb != nullptr);
357
358 uint8_t data1[] = {0x01, 0x02, 0x03};
359 ringbuffer_insert(rb, data1, sizeof(data1)); // Insert 3 bytes
360
361 EXPECT_EQ((size_t)3, ringbuffer_size(rb)); // Should be 3
362
363 uint8_t data2[] = {0x04, 0x05, 0x06, 0x07};
364 ringbuffer_insert(rb, data2, sizeof(data2)); // Insert 4 more bytes
365
366 EXPECT_EQ((size_t)7, ringbuffer_size(rb)); // Should be
367 ringbuffer_free(rb);
368 }
369
TEST(RingbufferTest,test_size_after_delete)370 TEST(RingbufferTest, test_size_after_delete) {
371 ringbuffer_t* rb = ringbuffer_init(16);
372 ASSERT_TRUE(rb != nullptr);
373
374 uint8_t data[] = {0x01, 0x02, 0x03, 0x04, 0x05};
375 ringbuffer_insert(rb, data, sizeof(data)); // Insert 5 bytes
376
377 EXPECT_EQ((size_t)5, ringbuffer_size(rb)); // Should be 5
378
379 ringbuffer_delete(rb, 3); // Delete 3 bytes
380 EXPECT_EQ((size_t)2, ringbuffer_size(rb)); // Should be 2
381 ringbuffer_free(rb);
382 }
383
TEST(RingbufferTest,test_size_after_wrap_around)384 TEST(RingbufferTest, test_size_after_wrap_around) {
385 ringbuffer_t* rb = ringbuffer_init(8); // Small buffer for testing
386 ASSERT_TRUE(rb != nullptr);
387 uint8_t data1[] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
388 ringbuffer_insert(rb, data1, sizeof(data1)); // Fill the buffer
389 EXPECT_EQ((size_t)8, ringbuffer_size(rb)); // Should be 8
390 ringbuffer_delete(rb, 4); // Delete 4 bytes
391 EXPECT_EQ((size_t)4, ringbuffer_size(rb)); // Should be 4
392 uint8_t data2[] = {0x09, 0x0A};
393 ringbuffer_insert(rb, data2, sizeof(data2)); // Insert 2 more bytes
394 EXPECT_EQ((size_t)6, ringbuffer_size(rb)); // Should be 6
395 ringbuffer_free(rb);
396 }
397