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