1 /*
2 * Copyright (c) 2021 Intel Corporation
3 * SPDX-License-Identifier: Apache-2.0
4 */
5 #include <zephyr/ztest.h>
6 #include <zephyr/sys/winstream.h>
7
8 /* This, uh, seems to be the standard way to unit test library code.
9 * Or so I gather from tests/unit/rbtree ...
10 */
11 #include "../../../lib/utils/winstream.c"
12
13 #define BUFLEN 64
14
15 const char *msg = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
16 char wsmem[BUFLEN + 1]; /* Extra 1 to have a null for easier debugging */
17
ZTEST(winstream,test_winstream)18 ZTEST(winstream, test_winstream)
19 {
20 struct sys_winstream *ws = sys_winstream_init(wsmem, BUFLEN);
21
22 /* Write one byte */
23 sys_winstream_write(ws, "a", 1);
24
25 uint32_t seq = 0;
26 char c;
27
28 /* Read the byte back */
29 uint32_t bytes = sys_winstream_read(ws, &seq, &c, 1);
30
31 zassert_true(bytes == 1, "");
32 zassert_true(seq == 1, "");
33 zassert_true(c == 'a', "");
34
35 /* Read from an empty buffer */
36 bytes = sys_winstream_read(ws, &seq, &c, 1);
37 zassert_true(bytes == 0, "");
38 zassert_true(seq == 1, "");
39
40 /* Write an overflowing string */
41 sys_winstream_write(ws, msg, strlen(msg));
42 zassert_true(ws->seq == 1 + strlen(msg), "");
43 zassert_true(ws->start == 1, "");
44 zassert_true(ws->end == 0, "");
45
46 /* Read after underflow, verify empty string comes back with the
47 * correct sequence number
48 */
49 char readback[BUFLEN + 1];
50
51 memset(readback, 0, sizeof(readback));
52 bytes = sys_winstream_read(ws, &seq, readback, sizeof(readback));
53 zassert_true(seq == ws->seq, "");
54 zassert_true(bytes == 0, "");
55
56 /* Read back from empty buffer */
57 uint32_t seq0 = seq;
58
59 bytes = sys_winstream_read(ws, &seq, readback, sizeof(readback));
60 zassert_true(seq == seq0, "");
61 zassert_true(bytes == 0, "");
62
63 /* Write a "short-enough" string that fits in before the wrap,
64 * then read it out
65 */
66 seq0 = seq;
67 sys_winstream_write(ws, msg, ws->len / 2);
68 bytes = sys_winstream_read(ws, &seq, readback, sizeof(readback));
69 zassert_true(bytes == ws->len / 2, "");
70 zassert_true(seq == seq0 + ws->len / 2, "");
71 zassert_true(strncmp(readback, msg, ws->len / 2) == 0, "");
72
73 /* Do it again, this time it will need to wrap around the buffer */
74 memset(readback, 0, sizeof(readback));
75 seq0 = seq;
76 sys_winstream_write(ws, msg, ws->len / 2);
77 bytes = sys_winstream_read(ws, &seq, readback, sizeof(readback));
78 zassert_true(bytes == ws->len / 2, "");
79 zassert_true(seq == seq0 + ws->len / 2, "");
80 zassert_true(strncmp(readback, msg, ws->len / 2) == 0, "");
81
82 /* Finally loop with a relatively prime (actually prime prime)
83 * buffer size to stress for edges.
84 */
85 int n = 13;
86 char msg2[13];
87
88 for (int i = 0; i < (n + 1) * (ws->len + 1); i++) {
89 memset(msg2, 'A' + (i % 26), n);
90 seq0 = seq;
91 memset(readback, 0, sizeof(readback));
92 sys_winstream_write(ws, msg2, n);
93 bytes = sys_winstream_read(ws, &seq, readback, sizeof(readback));
94 zassert_true(bytes == n, "");
95 zassert_true(seq == seq0 + n, "");
96 zassert_true(strncmp(readback, msg2, n) == 0, "");
97 }
98 }
99
100 ZTEST_SUITE(winstream, NULL, NULL, NULL, NULL, NULL);
101