xref: /aosp_15_r20/system/nfc/tests/utils/ringbuffer_test.cc (revision 7eba2f3b06c51ae21384f6a4f14577b668a869b3)
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