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