1 /*
2  * libdpkg - Debian packaging suite library routines
3  * t-varbuf.c - test varbuf implementation
4  *
5  * Copyright © 2009-2011, 2013-2015 Guillem Jover <guillem@debian.org>
6  *
7  * This is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * This is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19  */
20 
21 #include <config.h>
22 #include <compat.h>
23 
24 #include <dpkg/test.h>
25 #include <dpkg/varbuf.h>
26 
27 #include <string.h>
28 #include <stdlib.h>
29 
30 static void
test_varbuf_init(void)31 test_varbuf_init(void)
32 {
33 	struct varbuf vb;
34 
35 	varbuf_init(&vb, 0);
36 	test_pass(vb.used == 0);
37 	test_pass(vb.size == 0);
38 	test_pass(vb.buf == NULL);
39 
40 	varbuf_destroy(&vb);
41 	test_pass(vb.used == 0);
42 	test_pass(vb.size == 0);
43 	test_pass(vb.buf == NULL);
44 }
45 
46 static void
test_varbuf_prealloc(void)47 test_varbuf_prealloc(void)
48 {
49 	struct varbuf vb;
50 
51 	varbuf_init(&vb, 10);
52 	test_pass(vb.used == 0);
53 	test_pass(vb.size >= 10);
54 	test_pass(vb.buf != NULL);
55 
56 	varbuf_destroy(&vb);
57 	test_pass(vb.used == 0);
58 	test_pass(vb.size == 0);
59 	test_pass(vb.buf == NULL);
60 }
61 
62 static void
test_varbuf_new(void)63 test_varbuf_new(void)
64 {
65 	struct varbuf *vb;
66 
67 	vb = varbuf_new(0);
68 	test_pass(vb != NULL);
69 	test_pass(vb->used == 0);
70 	test_pass(vb->size == 0);
71 	test_pass(vb->buf == NULL);
72 	varbuf_free(vb);
73 
74 	vb = varbuf_new(10);
75 	test_pass(vb != NULL);
76 	test_pass(vb->used == 0);
77 	test_pass(vb->size >= 10);
78 	test_pass(vb->buf != NULL);
79 	varbuf_free(vb);
80 }
81 
82 static void
test_varbuf_grow(void)83 test_varbuf_grow(void)
84 {
85 	struct varbuf vb;
86 	size_t old_size;
87 	int i;
88 
89 	varbuf_init(&vb, 10);
90 
91 	/* Test that we grow when needed. */
92 	varbuf_grow(&vb, 100);
93 	test_pass(vb.used == 0);
94 	test_pass(vb.size >= 100);
95 
96 	old_size = vb.size;
97 
98 	/* Test that we are not leaking. */
99 	for (i = 0; i < 10; i++) {
100 		varbuf_grow(&vb, 100);
101 		test_pass(vb.used == 0);
102 		test_pass(vb.size >= 100);
103 		test_pass(vb.size == old_size);
104 	}
105 
106 	/* Test that we grow when needed, with used space. */
107 	vb.used = 10;
108 	varbuf_grow(&vb, 100);
109 	test_pass(vb.used == 10);
110 	test_pass(vb.size >= 110);
111 
112 	varbuf_destroy(&vb);
113 }
114 
115 static void
test_varbuf_trunc(void)116 test_varbuf_trunc(void)
117 {
118 	struct varbuf vb;
119 
120 	varbuf_init(&vb, 50);
121 
122 	/* Test that we truncate (grow). */
123 	varbuf_trunc(&vb, 20);
124 	test_pass(vb.used == 20);
125 	test_pass(vb.size >= 50);
126 
127 	/* Test that we truncate (shrink). */
128 	varbuf_trunc(&vb, 10);
129 	test_pass(vb.used == 10);
130 	test_pass(vb.size >= 50);
131 
132 	varbuf_destroy(&vb);
133 }
134 
135 static void
test_varbuf_add_buf(void)136 test_varbuf_add_buf(void)
137 {
138 	struct varbuf vb;
139 
140 	varbuf_init(&vb, 5);
141 
142 	varbuf_add_buf(&vb, "1234567890", 10);
143 	test_pass(vb.used == 10);
144 	test_pass(vb.size >= vb.used);
145 	test_mem(vb.buf, ==, "1234567890", 10);
146 
147 	varbuf_add_buf(&vb, "abcde", 5);
148 	test_pass(vb.used == 15);
149 	test_pass(vb.size >= vb.used);
150 	test_mem(vb.buf, ==, "1234567890abcde", 15);
151 
152 	varbuf_destroy(&vb);
153 }
154 
155 static void
test_varbuf_add_char(void)156 test_varbuf_add_char(void)
157 {
158 	struct varbuf vb;
159 
160 	varbuf_init(&vb, 1);
161 
162 	varbuf_add_char(&vb, 'a');
163 	test_pass(vb.used == 1);
164 	test_pass(vb.size >= vb.used);
165 	test_pass(vb.buf[0] == 'a');
166 
167 	varbuf_add_char(&vb, 'b');
168 	test_pass(vb.used == 2);
169 	test_pass(vb.size >= vb.used);
170 	test_mem(vb.buf, ==, "ab", 2);
171 
172 	varbuf_add_char(&vb, 'c');
173 	test_pass(vb.used == 3);
174 	test_pass(vb.size >= vb.used);
175 	test_mem(vb.buf, ==, "abc", 3);
176 
177 	varbuf_add_char(&vb, 'd');
178 	test_pass(vb.used == 4);
179 	test_pass(vb.size >= vb.used);
180 	test_mem(vb.buf, ==, "abcd", 4);
181 
182 	varbuf_destroy(&vb);
183 }
184 
185 static void
test_varbuf_dup_char(void)186 test_varbuf_dup_char(void)
187 {
188 	struct varbuf vb;
189 
190 	varbuf_init(&vb, 5);
191 
192 	varbuf_dup_char(&vb, 'z', 10);
193 	test_pass(vb.used == 10);
194 	test_pass(vb.size >= vb.used);
195 	test_mem(vb.buf, ==, "zzzzzzzzzz", 10);
196 
197 	varbuf_dup_char(&vb, 'y', 5);
198 	test_pass(vb.used == 15);
199 	test_pass(vb.size >= vb.used);
200 	test_mem(vb.buf, ==, "zzzzzzzzzzyyyyy", 15);
201 
202 	varbuf_destroy(&vb);
203 }
204 
205 static void
test_varbuf_map_char(void)206 test_varbuf_map_char(void)
207 {
208 	struct varbuf vb;
209 
210 	varbuf_init(&vb, 5);
211 
212 	varbuf_add_buf(&vb, "1234a5678a9012a", 15);
213 
214 	varbuf_map_char(&vb, 'a', 'z');
215 	test_pass(vb.used == 15);
216 	test_pass(vb.size >= vb.used);
217 	test_mem(vb.buf, ==, "1234z5678z9012z", 15);
218 
219 	varbuf_destroy(&vb);
220 }
221 
222 static void
test_varbuf_end_str(void)223 test_varbuf_end_str(void)
224 {
225 	struct varbuf vb;
226 
227 	varbuf_init(&vb, 10);
228 
229 	varbuf_add_buf(&vb, "1234567890X", 11);
230 	test_pass(vb.used == 11);
231 	test_pass(vb.size >= vb.used);
232 	test_mem(vb.buf, ==, "1234567890X", 11);
233 
234 	varbuf_trunc(&vb, 10);
235 
236 	varbuf_end_str(&vb);
237 	test_pass(vb.used == 10);
238 	test_pass(vb.size >= vb.used + 1);
239 	test_pass(vb.buf[10] == '\0');
240 	test_str(vb.buf, ==, "1234567890");
241 
242 	varbuf_destroy(&vb);
243 }
244 
245 static void
test_varbuf_get_str(void)246 test_varbuf_get_str(void)
247 {
248 	struct varbuf vb;
249 	const char *str;
250 
251 	varbuf_init(&vb, 10);
252 
253 	varbuf_add_buf(&vb, "1234567890", 10);
254 	str = varbuf_get_str(&vb);
255 	test_pass(vb.buf == str);
256 	test_pass(vb.used == 10);
257 	test_pass(vb.buf[vb.used] == '\0');
258 	test_pass(str[vb.used] == '\0');
259 	test_str(vb.buf, ==, "1234567890");
260 	test_str(str, ==, "1234567890");
261 
262 	varbuf_add_buf(&vb, "abcde", 5);
263 	str = varbuf_get_str(&vb);
264 	test_pass(vb.buf == str);
265 	test_pass(vb.used == 15);
266 	test_pass(vb.buf[vb.used] == '\0');
267 	test_pass(str[vb.used] == '\0');
268 	test_str(vb.buf, ==, "1234567890abcde");
269 	test_str(str, ==, "1234567890abcde");
270 
271 	varbuf_destroy(&vb);
272 }
273 
274 static void
test_varbuf_printf(void)275 test_varbuf_printf(void)
276 {
277 	struct varbuf vb;
278 
279 	varbuf_init(&vb, 5);
280 
281 	/* Test normal format printing. */
282 	varbuf_printf(&vb, "format %s number %d", "string", 10);
283 	test_pass(vb.used == strlen("format string number 10"));
284 	test_pass(vb.size >= vb.used);
285 	test_str(vb.buf, ==, "format string number 10");
286 
287 	varbuf_reset(&vb);
288 
289 	/* Test concatenated format printing. */
290 	varbuf_printf(&vb, "format %s number %d", "string", 10);
291 	varbuf_printf(&vb, " extra %s", "string");
292 	test_pass(vb.used == strlen("format string number 10 extra string"));
293 	test_pass(vb.size >= vb.used);
294 	test_str(vb.buf, ==, "format string number 10 extra string");
295 
296 	varbuf_destroy(&vb);
297 }
298 
299 static void
test_varbuf_reset(void)300 test_varbuf_reset(void)
301 {
302 	struct varbuf vb;
303 
304 	varbuf_init(&vb, 10);
305 
306 	varbuf_add_buf(&vb, "1234567890", 10);
307 
308 	varbuf_reset(&vb);
309 	test_pass(vb.used == 0);
310 	test_pass(vb.size >= vb.used);
311 
312 	varbuf_add_buf(&vb, "abcdefghijklmno", 15);
313 	test_pass(vb.used == 15);
314 	test_pass(vb.size >= vb.used);
315 	test_mem(vb.buf, ==, "abcdefghijklmno", 15);
316 
317 	varbuf_destroy(&vb);
318 }
319 
320 static void
test_varbuf_snapshot(void)321 test_varbuf_snapshot(void)
322 {
323 	struct varbuf vb;
324 	struct varbuf_state vbs;
325 
326 	varbuf_init(&vb, 0);
327 
328 	test_pass(vb.used == 0);
329 	varbuf_snapshot(&vb, &vbs);
330 	test_pass(vb.used == 0);
331 	test_pass(vb.used == vbs.used);
332 
333 	varbuf_add_buf(&vb, "1234567890", 10);
334 	test_pass(vb.used == 10);
335 	varbuf_rollback(&vb, &vbs);
336 	test_pass(vb.used == 0);
337 
338 	varbuf_add_buf(&vb, "1234567890", 10);
339 	test_pass(vb.used == 10);
340 	varbuf_snapshot(&vb, &vbs);
341 	test_pass(vb.used == 10);
342 
343 	varbuf_add_buf(&vb, "1234567890", 10);
344 	test_pass(vb.used == 20);
345 	varbuf_rollback(&vb, &vbs);
346 	test_pass(vb.used == 10);
347 
348 	varbuf_destroy(&vb);
349 }
350 
351 static void
test_varbuf_detach(void)352 test_varbuf_detach(void)
353 {
354 	struct varbuf vb;
355 	char *str;
356 
357 	varbuf_init(&vb, 0);
358 
359 	varbuf_add_buf(&vb, "1234567890", 10);
360 
361 	str = varbuf_detach(&vb);
362 
363 	test_mem(str, ==, "1234567890", 10);
364 	test_pass(vb.used == 0);
365 	test_pass(vb.size == 0);
366 	test_pass(vb.buf == NULL);
367 
368 	free(str);
369 }
370 
TEST_ENTRY(test)371 TEST_ENTRY(test)
372 {
373 	test_plan(128);
374 
375 	test_varbuf_init();
376 	test_varbuf_prealloc();
377 	test_varbuf_new();
378 	test_varbuf_grow();
379 	test_varbuf_trunc();
380 	test_varbuf_add_buf();
381 	test_varbuf_add_char();
382 	test_varbuf_dup_char();
383 	test_varbuf_map_char();
384 	test_varbuf_end_str();
385 	test_varbuf_get_str();
386 	test_varbuf_printf();
387 	test_varbuf_reset();
388 	test_varbuf_snapshot();
389 	test_varbuf_detach();
390 
391 	/* FIXME: Complete. */
392 }
393