1 /*
2  * Circular buffer tests.
3  * Copyright (C) 2017  Cumulus Networks
4  * Quentin Young
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; either version 2 of the License, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; see the file COPYING; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 #include <zebra.h>
21 #include <memory.h>
22 #include "ringbuf.h"
23 
validate_state(struct ringbuf * buf,size_t size,size_t contains)24 static void validate_state(struct ringbuf *buf, size_t size, size_t contains)
25 {
26 	assert(buf->size == size);
27 	assert(ringbuf_remain(buf) == contains);
28 	assert(ringbuf_space(buf) == buf->size - contains);
29 	assert(buf->empty != (bool)contains);
30 }
31 
main(int argc,char ** argv)32 int main(int argc, char **argv)
33 {
34 	struct ringbuf *soil = ringbuf_new(BUFSIZ);
35 
36 	validate_state(soil, BUFSIZ, 0);
37 
38 	/* verify reset functionality on clean buffer */
39 	printf("Validating reset on empty buffer...\n");
40 	ringbuf_reset(soil);
41 
42 	validate_state(soil, BUFSIZ, 0);
43 
44 	/* put one byte */
45 	printf("Validating write...\n");
46 	uint8_t walnut = 47;
47 	assert(ringbuf_put(soil, &walnut, sizeof(walnut)) == 1);
48 
49 	validate_state(soil, BUFSIZ, 1);
50 
51 	/* validate read limitations */
52 	printf("Validating read limits...\n");
53 	uint8_t nuts[2];
54 	assert(ringbuf_get(soil, &nuts, sizeof(nuts)) == 1);
55 
56 	/* reset */
57 	printf("Validating reset on full buffer...\n");
58 	ringbuf_reset(soil);
59 	validate_state(soil, BUFSIZ, 0);
60 
61 	/* copy stack garbage to buffer */
62 	printf("Validating big write...\n");
63 	uint8_t compost[BUFSIZ];
64 	assert(ringbuf_put(soil, &compost, sizeof(compost)) == BUFSIZ);
65 
66 	validate_state(soil, BUFSIZ, BUFSIZ);
67 	assert(soil->start == 0);
68 	assert(soil->end == 0);
69 
70 	/* read 15 bytes of garbage */
71 	printf("Validating read...\n");
72 	assert(ringbuf_get(soil, &compost, 15) == 15);
73 
74 	validate_state(soil, BUFSIZ, BUFSIZ - 15);
75 	assert(soil->start == 15);
76 	assert(soil->end == 0);
77 
78 	/* put another 10 bytes and validate wraparound */
79 	printf("Validating wraparound...\n");
80 	assert(ringbuf_put(soil, &compost[BUFSIZ/2], 10) == 10);
81 
82 	validate_state(soil, BUFSIZ, BUFSIZ - 15 + 10);
83 	assert(soil->start == 15);
84 	assert(soil->end == 10);
85 
86 	/* put another 15 bytes and validate state */
87 	printf("Validating size limits...\n");
88 	assert(ringbuf_put(soil, &compost, 15) == 5);
89 	validate_state(soil, BUFSIZ, BUFSIZ);
90 
91 	/* read entire buffer */
92 	printf("Validating big read...\n");
93 	assert(ringbuf_get(soil, &compost, BUFSIZ) == BUFSIZ);
94 
95 	validate_state(soil, BUFSIZ, 0);
96 	assert(soil->empty = true);
97 	assert(soil->start == soil->end);
98 	assert(soil->start == 15);
99 
100 	/* read empty buffer */
101 	printf("Validating empty read...\n");
102 	assert(ringbuf_get(soil, &compost, 1) == 0);
103 	validate_state(soil, BUFSIZ, 0);
104 
105 	/* reset, validate state */
106 	printf("Validating reset...\n");
107 	ringbuf_reset(soil);
108 	validate_state(soil, BUFSIZ, 0);
109 	assert(soil->start == 0);
110 	assert(soil->end == 0);
111 
112 	/* wipe, validate state */
113 	printf("Validating wipe...\n");
114 	memset(&compost, 0x00, sizeof(compost));
115 	ringbuf_wipe(soil);
116 	assert(memcmp(&compost, soil->data, sizeof(compost)) == 0);
117 
118 	/* validate maximum write */
119 	printf("Validating very big write...\n");
120 	const char flower[BUFSIZ * 2];
121 	assert(ringbuf_put(soil, &flower, sizeof(flower)) == BUFSIZ);
122 
123 	validate_state(soil, BUFSIZ, BUFSIZ);
124 
125 	/* wipe, validate state */
126 	printf("Validating wipe...\n");
127 	memset(&compost, 0x00, sizeof(compost));
128 	ringbuf_wipe(soil);
129 	assert(memcmp(&compost, soil->data, sizeof(compost)) == 0);
130 
131 	/* validate simple data encode / decode */
132 	const char *organ = "seed";
133 	printf("Encoding: '%s'\n", organ);
134 	assert(ringbuf_put(soil, organ, strlen(organ)) == 4);
135 	char water[strlen(organ) + 1];
136 	assert(ringbuf_get(soil, &water, strlen(organ)) == 4);
137 	water[strlen(organ)] = '\0';
138 	printf("Retrieved: '%s'\n", water);
139 
140 	validate_state(soil, BUFSIZ, 0);
141 
142 	/* validate simple data encode / decode across ring boundary */
143 	soil->start = soil->size - 2;
144 	soil->end = soil->start;
145 	const char *phloem = "root";
146 	printf("Encoding: '%s'\n", phloem);
147 	assert(ringbuf_put(soil, phloem, strlen(phloem)) == 4);
148 	char xylem[strlen(phloem) + 1];
149 	assert(ringbuf_get(soil, &xylem, 100) == 4);
150 	xylem[strlen(phloem)] = '\0';
151 	printf("Retrieved: '%s'\n", xylem);
152 
153 	ringbuf_wipe(soil);
154 
155 	/* validate simple data peek across ring boundary */
156 	soil->start = soil->size - 2;
157 	soil->end = soil->start;
158 	const char *cytoplasm = "tree";
159 	printf("Encoding: '%s'\n", cytoplasm);
160 	assert(ringbuf_put(soil, cytoplasm, strlen(cytoplasm)) == 4);
161 	char chloroplast[strlen(cytoplasm) + 1];
162 	assert(ringbuf_peek(soil, 2, &chloroplast[0], 100) == 2);
163 	assert(ringbuf_peek(soil, 0, &chloroplast[2], 2) == 2);
164 	chloroplast[strlen(cytoplasm)] = '\0';
165 	assert(!strcmp(chloroplast, "eetr"));
166 	printf("Retrieved: '%s'\n", chloroplast);
167 
168 	printf("Deleting...\n");
169 	ringbuf_del(soil);
170 
171 	printf("Creating new buffer...\n");
172 	soil = ringbuf_new(15);
173 	soil->start = soil->end = 7;
174 
175 	/* validate data encode of excessive data */
176 	const char *twenty = "vascular plants----";
177 	char sixteen[16];
178 	printf("Encoding: %s\n", twenty);
179 	assert(ringbuf_put(soil, twenty, strlen(twenty)) == 15);
180 	assert(ringbuf_get(soil, sixteen, 20));
181 	sixteen[15] = '\0';
182 	printf("Retrieved: %s\n", sixteen);
183 	assert(!strcmp(sixteen, "vascular plants"));
184 
185 	printf("Deleting...\n");
186 	ringbuf_del(soil);
187 
188 	printf("Done.\n");
189 	return 0;
190 }
191