1 #include <assert.h>
2 #include <debug.h>
3 #include <err.h>
4 #include <lib/cbuf.h>
5 #include <lib/console.h>
6 #include <lib/heap.h>
7 #include <rand.h>
8 #include <stdlib.h>
9
10 #define ASSERT_EQ(a, b) \
11 do { \
12 int _a = (a); \
13 int _b = (b); \
14 if (_a != _b) { \
15 panic("%d != %d (%s:%d)\n", a, b, __FILE__, __LINE__); \
16 } \
17 } while (0);
18
19 #define ASSERT_LEQ(a, b) \
20 do { \
21 int _a = (a); \
22 int _b = (b); \
23 if (_a > _b) { \
24 panic("%d not <= %d (%s:%d)\n", a, b, __FILE__, __LINE__); \
25 } \
26 } while (0);
27
cbuf_tests(int argc,const cmd_args * argv)28 int cbuf_tests(int argc, const cmd_args *argv)
29 {
30 cbuf_t cbuf;
31
32 printf("running basic tests...\n");
33
34 cbuf_initialize(&cbuf, 16);
35
36 ASSERT_EQ(15, cbuf_space_avail(&cbuf));
37
38 ASSERT_EQ(8, cbuf_write(&cbuf, "abcdefgh", 8, false));
39
40 ASSERT_EQ(7, cbuf_space_avail(&cbuf));
41
42 // Only 7 bytes should fit since if we write all 16 bytes,
43 // head == tail and we can't distinguish it from the start case.
44 ASSERT_EQ(7, cbuf_write(&cbuf, "ijklmnop", 8, false));
45
46 ASSERT_EQ(0, cbuf_space_avail(&cbuf));
47
48 // Nothing should fit.
49 ASSERT_EQ(0, cbuf_write(&cbuf, "XXXXXXXX", 8, false));
50
51 ASSERT_EQ(0, cbuf_space_avail(&cbuf));
52
53 // Read a few bytes.
54 {
55 char buf[32];
56 ASSERT_EQ(3, cbuf_read(&cbuf, buf, 3, false));
57 for (int i = 0; i < 3; ++i) {
58 ASSERT_EQ(buf[i], 'a' + i);
59 }
60
61 // Try reading 32 bytes.
62 ASSERT_EQ(12, cbuf_read(&cbuf, buf, 32, false));
63 for (int i = 0; i < 12; ++i) {
64 ASSERT_EQ(buf[i], 'd' + i);
65 }
66 }
67
68 cbuf_reset(&cbuf);
69
70 ASSERT_EQ(15, cbuf_space_avail(&cbuf));
71
72 // Random tests. Keep writing in random chunks up to 8 bytes, then
73 // reading in chunks up to 8 bytes. Verify values.
74
75 int pos_out = 0;
76 int pos_in = 0;
77 printf("running random tests...\n");
78 while (pos_in < 256) {
79 if (pos_out < 256) {
80 // Write up to 8 bytes.
81 char buf_out[8];
82 int to_write_random = rand() & 7;
83 int to_write = MIN(to_write_random, 256 - pos_out);
84 for (int i = 0; i < to_write; ++i) {
85 buf_out[i] = pos_out + i;
86 }
87 // Advance the out pointer based on how many bytes fit.
88 int wrote = cbuf_write(&cbuf, buf_out, to_write, false);
89 ASSERT_LEQ(wrote, to_write);
90 pos_out += wrote;
91 }
92
93 // Read up to 8 bytes, make sure they are right.
94 if (pos_in < pos_out) {
95 char buf_in[8];
96 int to_read_random = rand() & 7;
97 int to_read = MIN(to_read_random, pos_out - pos_in);
98 int read = cbuf_read(&cbuf, buf_in, to_read, false);
99 ASSERT_LEQ(read, to_read);
100
101 for (int i = 0; i < read; ++i) {
102 ASSERT_EQ(pos_in + i, buf_in[i]);
103 }
104
105 pos_in += read;
106 }
107
108 ASSERT_LEQ(pos_in, pos_out);
109 }
110
111 free(cbuf.buf);
112
113 printf("cbuf tests passed\n");
114
115 return NO_ERROR;
116 }
117