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