HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / wmem / wmem_test.c
blob0a5ab5e936502aa6f7e983e20f4f1fc4018123e8
1 /* wmem_test.c
2 * Wireshark Memory Manager Tests
3 * Copyright 2012, Evan Huus <eapache@gmail.com>
5 * $Id$
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 #include "config.h"
28 #include <stdio.h>
29 #include <glib.h>
31 #include "wmem.h"
32 #include "wmem_allocator.h"
33 #include "wmem_allocator_block.h"
34 #include "wmem_allocator_simple.h"
35 #include "wmem_allocator_strict.h"
37 #define MAX_ALLOC_SIZE (1024*64)
38 #define MAX_SIMULTANEOUS_ALLOCS 1024
39 #define CONTAINER_ITERS 10000
41 typedef void (*wmem_verify_func)(wmem_allocator_t *allocator);
43 /* A helper for generating pseudo-random strings. Just uses glib's random number
44 * functions to generate 'numbers' in the printable character range. */
45 static gchar *
46 wmem_test_rand_string(wmem_allocator_t *allocator, gint minlen, gint maxlen)
48 gchar *str;
49 gint len, i;
51 len = g_random_int_range(minlen, maxlen);
53 /* +1 for null-terminator */
54 str = (gchar*)wmem_alloc(allocator, len + 1);
55 str[len] = '\0';
57 for (i=0; i<len; i++) {
58 /* ASCII normal printable range is 32 (space) to 126 (tilde) */
59 str[i] = (gchar) g_random_int_range(32, 126);
62 return str;
65 int
66 wmem_test_compare_guint32(const void *a, const void *b)
68 guint32 l, r;
70 l = *(guint32*)a;
71 r = *(guint32*)b;
73 return l - r;
76 /* Some helpers for properly testing callback functionality */
77 wmem_allocator_t *expected_allocator;
78 void *expected_user_data;
79 wmem_cb_event_t expected_event;
80 int cb_called_count;
81 int cb_continue_count;
82 gboolean value_seen[CONTAINER_ITERS];
84 static gboolean
85 wmem_test_cb(wmem_allocator_t *allocator, wmem_cb_event_t event,
86 void *user_data)
88 g_assert(allocator == expected_allocator);
89 g_assert(event == expected_event);
91 cb_called_count++;
93 return *(gboolean*)user_data;
96 static gboolean
97 wmem_test_foreach_cb(void *value, void *user_data)
99 g_assert(user_data == expected_user_data);
101 g_assert(! value_seen[GPOINTER_TO_INT(value)]);
102 value_seen[GPOINTER_TO_INT(value)] = TRUE;
104 cb_called_count++;
105 cb_continue_count--;
107 return (cb_continue_count == 0);
110 /* ALLOCATOR TESTING FUNCTIONS (/wmem/allocator/) */
112 static void
113 wmem_test_allocator_callbacks(void)
115 wmem_allocator_t *allocator;
116 gboolean t = TRUE;
117 gboolean f = FALSE;
118 guint cb_id;
120 allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
122 expected_allocator = allocator;
124 wmem_register_callback(expected_allocator, &wmem_test_cb, &f);
125 wmem_register_callback(expected_allocator, &wmem_test_cb, &f);
126 cb_id = wmem_register_callback(expected_allocator, &wmem_test_cb, &t);
127 wmem_register_callback(expected_allocator, &wmem_test_cb, &t);
128 wmem_register_callback(expected_allocator, &wmem_test_cb, &f);
130 expected_event = WMEM_CB_FREE_EVENT;
132 cb_called_count = 0;
133 wmem_free_all(allocator);
134 g_assert(cb_called_count == 5);
136 cb_called_count = 0;
137 wmem_free_all(allocator);
138 g_assert(cb_called_count == 2);
140 cb_called_count = 0;
141 wmem_free_all(allocator);
142 g_assert(cb_called_count == 2);
144 wmem_unregister_callback(allocator, cb_id);
145 cb_called_count = 0;
146 wmem_free_all(allocator);
147 g_assert(cb_called_count == 1);
149 cb_id = wmem_register_callback(expected_allocator, &wmem_test_cb, &f);
150 wmem_register_callback(expected_allocator, &wmem_test_cb, &t);
152 cb_called_count = 0;
153 wmem_free_all(allocator);
154 g_assert(cb_called_count == 3);
156 wmem_unregister_callback(allocator, cb_id);
157 cb_called_count = 0;
158 wmem_free_all(allocator);
159 g_assert(cb_called_count == 2);
161 wmem_register_callback(expected_allocator, &wmem_test_cb, &t);
163 expected_event = WMEM_CB_DESTROY_EVENT;
164 cb_called_count = 0;
165 wmem_destroy_allocator(allocator);
166 g_assert(cb_called_count == 3);
169 static void
170 wmem_test_allocator_det(wmem_allocator_t *allocator, wmem_verify_func verify,
171 guint len)
173 int i;
174 char *ptrs[MAX_SIMULTANEOUS_ALLOCS];
176 /* we use wmem_alloc0 in part because it tests slightly more code, but
177 * primarily so that if the allocator doesn't give us enough memory or
178 * gives us memory that includes its own metadata, we write to it and
179 * things go wrong, causing the tests to fail */
180 for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
181 ptrs[i] = (char *)wmem_alloc0(allocator, len);
183 for (i=MAX_SIMULTANEOUS_ALLOCS-1; i>=0; i--) {
184 /* no wmem_realloc0 so just use memset manually */
185 ptrs[i] = (char *)wmem_realloc(allocator, ptrs[i], 4*len);
186 memset(ptrs[i], 0, 4*len);
188 for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
189 wmem_free(allocator, ptrs[i]);
192 if (verify) (*verify)(allocator);
193 wmem_free_all(allocator);
194 wmem_gc(allocator);
195 if (verify) (*verify)(allocator);
198 static void
199 wmem_test_allocator(wmem_allocator_type_t type, wmem_verify_func verify)
201 int i;
202 char *ptrs[MAX_SIMULTANEOUS_ALLOCS];
203 wmem_allocator_t *allocator;
205 /* We never run wmem_init so we don't have to worry about overrides giving
206 * us the wrong type. */
207 allocator = wmem_allocator_new(type);
209 if (verify) (*verify)(allocator);
211 /* start with some fairly simple deterministic tests */
213 wmem_test_allocator_det(allocator, verify, 8);
215 wmem_test_allocator_det(allocator, verify, 64);
217 wmem_test_allocator_det(allocator, verify, 512);
219 for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
220 ptrs[i] = wmem_alloc0_array(allocator, char, 32);
223 if (verify) (*verify)(allocator);
224 wmem_free_all(allocator);
225 wmem_gc(allocator);
226 if (verify) (*verify)(allocator);
228 ptrs[0] = (char*)wmem_alloc0(allocator, 4*1024*1024);
229 wmem_free(allocator, ptrs[0]);
230 wmem_gc(allocator);
231 ptrs[0] = (char*)wmem_alloc0(allocator, 4*1024*1024);
233 if (verify) (*verify)(allocator);
234 wmem_free_all(allocator);
235 wmem_gc(allocator);
236 if (verify) (*verify)(allocator);
238 /* test jumbo allocations and frees */
239 ptrs[0] = (char *)wmem_alloc0(allocator, 10*1024*1024);
240 ptrs[1] = (char *)wmem_alloc0(allocator, 13*1024*1024);
241 ptrs[1] = (char *)wmem_realloc(allocator, ptrs[1], 10*1024*1024);
242 memset(ptrs[1], 0, 10*1024*1024);
243 ptrs[0] = (char *)wmem_realloc(allocator, ptrs[0], 13*1024*1024);
244 memset(ptrs[0], 0, 13*1024*1024);
245 if (verify) (*verify)(allocator);
246 wmem_gc(allocator);
247 if (verify) (*verify)(allocator);
248 wmem_free(allocator, ptrs[1]);
249 if (verify) (*verify)(allocator);
250 wmem_free_all(allocator);
251 wmem_gc(allocator);
252 if (verify) (*verify)(allocator);
254 /* now do some random fuzz-like tests */
256 /* reset our ptr array */
257 for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
258 ptrs[i] = NULL;
261 /* Run enough iterations to fill the array 64 times */
262 for (i=0; i<MAX_SIMULTANEOUS_ALLOCS*64; i++) {
263 gint ptrs_index;
264 gint new_size;
266 /* returns value 0 <= x < MAX_SIMULTANEOUS_ALLOCS which is a valid
267 * index into ptrs */
268 ptrs_index = g_test_rand_int_range(0, MAX_SIMULTANEOUS_ALLOCS);
270 if (ptrs[ptrs_index] == NULL) {
271 /* if that index is unused, allocate some random amount of memory
272 * between 0 and MAX_ALLOC_SIZE */
273 new_size = g_test_rand_int_range(0, MAX_ALLOC_SIZE);
275 ptrs[ptrs_index] = (char *) wmem_alloc0(allocator, new_size);
277 else if (g_test_rand_bit()) {
278 /* the index is used, and our random bit has determined we will be
279 * reallocating instead of freeing. Do so to some random size
280 * between 0 and MAX_ALLOC_SIZE, then manually zero the
281 * new memory */
282 new_size = g_test_rand_int_range(0, MAX_ALLOC_SIZE);
284 ptrs[ptrs_index] = (char *) wmem_realloc(allocator,
285 ptrs[ptrs_index], new_size);
287 memset(ptrs[ptrs_index], 0, new_size);
289 else {
290 /* the index is used, and our random bit has determined we will be
291 * freeing instead of reallocating. Do so and NULL the pointer for
292 * the next iteration. */
293 wmem_free(allocator, ptrs[ptrs_index]);
294 ptrs[ptrs_index] = NULL;
296 if (verify) (*verify)(allocator);
299 wmem_destroy_allocator(allocator);
302 static void
303 wmem_time_allocator(wmem_allocator_type_t type)
305 int i, j;
306 wmem_allocator_t *allocator;
308 allocator = wmem_allocator_new(type);
310 for (j=0; j<128; j++) {
311 for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
312 wmem_alloc(allocator, 8);
314 wmem_free_all(allocator);
316 for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
317 wmem_alloc(allocator, 256);
319 wmem_free_all(allocator);
321 for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
322 wmem_alloc(allocator, 1024);
326 wmem_destroy_allocator(allocator);
329 static void
330 wmem_time_allocators(void)
332 double simple_time, block_time;
334 g_test_timer_start();
335 wmem_time_allocator(WMEM_ALLOCATOR_SIMPLE);
336 simple_time = g_test_timer_elapsed();
338 g_test_timer_start();
339 wmem_time_allocator(WMEM_ALLOCATOR_BLOCK);
340 block_time = g_test_timer_elapsed();
342 printf("(simple: %lf; block: %lf) ", simple_time, block_time);
343 g_assert(simple_time > block_time);
346 static void
347 wmem_test_allocator_block(void)
349 wmem_test_allocator(WMEM_ALLOCATOR_BLOCK, &wmem_block_verify);
352 static void
353 wmem_test_allocator_simple(void)
355 wmem_test_allocator(WMEM_ALLOCATOR_SIMPLE, NULL);
358 static void
359 wmem_test_allocator_strict(void)
361 wmem_test_allocator(WMEM_ALLOCATOR_STRICT, &wmem_strict_check_canaries);
364 /* UTILITY TESTING FUNCTIONS (/wmem/utils/) */
366 static void
367 wmem_test_miscutls(void)
369 wmem_allocator_t *allocator;
370 const char *source = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
371 char *ret;
373 allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
375 ret = (char*) wmem_memdup(allocator, source, 5);
376 ret[4] = '\0';
377 g_assert_cmpstr(ret, ==, "ABCD");
379 ret = (char*) wmem_memdup(allocator, source, 1);
380 g_assert(ret[0] == 'A');
381 wmem_strict_check_canaries(allocator);
383 ret = (char*) wmem_memdup(allocator, source, 10);
384 ret[9] = '\0';
385 g_assert_cmpstr(ret, ==, "ABCDEFGHI");
387 wmem_destroy_allocator(allocator);
390 static void
391 wmem_test_strutls(void)
393 wmem_allocator_t *allocator;
394 const char *orig_str;
395 char *new_str;
396 char **split_str;
398 allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
400 orig_str = "TEST1";
401 new_str = wmem_strdup(allocator, orig_str);
402 g_assert_cmpstr(new_str, ==, orig_str);
403 new_str[0] = 'X';
404 g_assert_cmpstr(new_str, >, orig_str);
405 wmem_strict_check_canaries(allocator);
407 orig_str = "TEST123456789";
408 new_str = wmem_strndup(allocator, orig_str, 6);
409 g_assert_cmpstr(new_str, ==, "TEST12");
410 g_assert_cmpstr(new_str, <, orig_str);
411 new_str[0] = 'X';
412 g_assert_cmpstr(new_str, >, orig_str);
413 wmem_strict_check_canaries(allocator);
415 new_str = wmem_strdup_printf(allocator, "abc %s %% %d", "boo", 23);
416 g_assert_cmpstr(new_str, ==, "abc boo % 23");
417 wmem_strict_check_canaries(allocator);
419 new_str = wmem_strconcat(allocator, "ABC", NULL);
420 g_assert_cmpstr(new_str, ==, "ABC");
421 new_str = wmem_strconcat(allocator, "ABC", "DEF", NULL);
422 g_assert_cmpstr(new_str, ==, "ABCDEF");
423 wmem_strict_check_canaries(allocator);
424 new_str = wmem_strconcat(allocator, "", "", "ABCDEF", "", "GH", NULL);
425 g_assert_cmpstr(new_str, ==, "ABCDEFGH");
426 wmem_strict_check_canaries(allocator);
428 split_str = wmem_strsplit(allocator, "A-C", "-", 2);
429 g_assert_cmpstr(split_str[0], ==, "A");
430 g_assert_cmpstr(split_str[1], ==, "C");
431 split_str = wmem_strsplit(allocator, "--aslkf-asio--asfj-as--", "-", 10);
432 g_assert_cmpstr(split_str[0], ==, "aslkf");
433 g_assert_cmpstr(split_str[1], ==, "asio");
434 g_assert_cmpstr(split_str[2], ==, "asfj");
435 g_assert_cmpstr(split_str[3], ==, "as");
436 split_str = wmem_strsplit(allocator, "--aslkf-asio--asfj-as--", "-", 4);
437 g_assert_cmpstr(split_str[0], ==, "aslkf");
438 g_assert_cmpstr(split_str[1], ==, "asio");
439 g_assert_cmpstr(split_str[2], ==, "-asfj-as--");
441 wmem_destroy_allocator(allocator);
444 /* DATA STRUCTURE TESTING FUNCTIONS (/wmem/datastruct/) */
446 static void
447 wmem_test_array(void)
449 wmem_allocator_t *allocator;
450 wmem_array_t *array;
451 unsigned int i, j, k;
452 guint32 val, *buf;
453 guint32 vals[8];
455 allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
457 array = wmem_array_new(allocator, sizeof(guint32));
458 g_assert(array);
459 g_assert(wmem_array_get_count(array) == 0);
461 for (i=0; i<CONTAINER_ITERS; i++) {
462 val = i;
463 wmem_array_append_one(array, val);
464 g_assert(wmem_array_get_count(array) == i+1);
466 val = *(guint32*)wmem_array_index(array, i);
467 g_assert(val == i);
469 wmem_strict_check_canaries(allocator);
471 for (i=0; i<CONTAINER_ITERS; i++) {
472 val = *(guint32*)wmem_array_index(array, i);
473 g_assert(val == i);
476 array = wmem_array_sized_new(allocator, sizeof(guint32), 73);
478 for (i=0; i<CONTAINER_ITERS; i++) {
479 for (j=0; j<8; j++) {
480 vals[j] = i+j;
483 wmem_array_append(array, vals, 8);
484 g_assert(wmem_array_get_count(array) == 8*(i+1));
486 wmem_strict_check_canaries(allocator);
488 buf = (guint32*)wmem_array_get_raw(array);
489 for (i=0; i<CONTAINER_ITERS; i++) {
490 for (j=0; j<8; j++) {
491 g_assert(buf[i*8 + j] == i+j);
495 wmem_array_sort(array, wmem_test_compare_guint32);
496 for (i=0, k=0; i<8; i++) {
497 for (j=0; j<=i; j++, k++) {
498 val = *(guint32*)wmem_array_index(array, k);
499 g_assert(val == i);
502 for (j=k; k<8*(CONTAINER_ITERS+1)-j; k++) {
503 val = *(guint32*)wmem_array_index(array, k);
504 g_assert(val == ((k-j)/8)+8);
506 for (i=0; i<7; i++) {
507 for (j=0; j<7-i; j++, k++) {
508 val = *(guint32*)wmem_array_index(array, k);
509 g_assert(val == CONTAINER_ITERS+i);
512 g_assert(k == wmem_array_get_count(array));
514 wmem_destroy_allocator(allocator);
517 static void
518 wmem_test_list(void)
520 wmem_allocator_t *allocator;
521 wmem_list_t *list;
522 wmem_list_frame_t *frame;
523 unsigned int i;
525 allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
527 list = wmem_list_new(allocator);
528 g_assert(list);
529 g_assert(wmem_list_count(list) == 0);
531 frame = wmem_list_head(list);
532 g_assert(frame == NULL);
534 for (i=0; i<CONTAINER_ITERS; i++) {
535 wmem_list_prepend(list, GINT_TO_POINTER(i));
536 g_assert(wmem_list_count(list) == i+1);
538 frame = wmem_list_head(list);
539 g_assert(frame);
540 g_assert(wmem_list_frame_data(frame) == GINT_TO_POINTER(i));
542 wmem_strict_check_canaries(allocator);
544 i = CONTAINER_ITERS - 1;
545 frame = wmem_list_head(list);
546 while (frame) {
547 g_assert(wmem_list_frame_data(frame) == GINT_TO_POINTER(i));
548 i--;
549 frame = wmem_list_frame_next(frame);
552 i = 0;
553 frame = wmem_list_tail(list);
554 while (frame) {
555 g_assert(wmem_list_frame_data(frame) == GINT_TO_POINTER(i));
556 i++;
557 frame = wmem_list_frame_prev(frame);
560 i = CONTAINER_ITERS - 2;
561 while (wmem_list_count(list) > 1) {
562 wmem_list_remove(list, GINT_TO_POINTER(i));
563 i--;
565 wmem_list_remove(list, GINT_TO_POINTER(CONTAINER_ITERS - 1));
566 g_assert(wmem_list_count(list) == 0);
567 g_assert(wmem_list_head(list) == NULL);
568 g_assert(wmem_list_tail(list) == NULL);
570 for (i=0; i<CONTAINER_ITERS; i++) {
571 wmem_list_append(list, GINT_TO_POINTER(i));
572 g_assert(wmem_list_count(list) == i+1);
574 frame = wmem_list_head(list);
575 g_assert(frame);
577 wmem_strict_check_canaries(allocator);
579 i = 0;
580 frame = wmem_list_head(list);
581 while (frame) {
582 g_assert(wmem_list_frame_data(frame) == GINT_TO_POINTER(i));
583 i++;
584 frame = wmem_list_frame_next(frame);
587 i = CONTAINER_ITERS - 1;
588 frame = wmem_list_tail(list);
589 while (frame) {
590 g_assert(wmem_list_frame_data(frame) == GINT_TO_POINTER(i));
591 i--;
592 frame = wmem_list_frame_prev(frame);
595 wmem_destroy_allocator(allocator);
598 static void
599 wmem_test_queue(void)
601 wmem_allocator_t *allocator;
602 wmem_queue_t *queue;
603 unsigned int i;
605 allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
607 queue = wmem_queue_new(allocator);
608 g_assert(queue);
609 g_assert(wmem_queue_count(queue) == 0);
611 for (i=0; i<CONTAINER_ITERS; i++) {
612 wmem_queue_push(queue, GINT_TO_POINTER(i));
614 g_assert(wmem_queue_count(queue) == i+1);
615 g_assert(wmem_queue_peek(queue) == GINT_TO_POINTER(0));
617 wmem_strict_check_canaries(allocator);
619 for (i=0; i<CONTAINER_ITERS; i++) {
620 g_assert(wmem_queue_peek(queue) == GINT_TO_POINTER(i));
621 g_assert(wmem_queue_pop(queue) == GINT_TO_POINTER(i));
622 g_assert(wmem_queue_count(queue) == CONTAINER_ITERS-i-1);
624 g_assert(wmem_queue_count(queue) == 0);
626 wmem_destroy_allocator(allocator);
629 static void
630 wmem_test_stack(void)
632 wmem_allocator_t *allocator;
633 wmem_stack_t *stack;
634 unsigned int i;
636 allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
638 stack = wmem_stack_new(allocator);
639 g_assert(stack);
640 g_assert(wmem_stack_count(stack) == 0);
642 for (i=0; i<CONTAINER_ITERS; i++) {
643 wmem_stack_push(stack, GINT_TO_POINTER(i));
645 g_assert(wmem_stack_count(stack) == i+1);
646 g_assert(wmem_stack_peek(stack) == GINT_TO_POINTER(i));
648 wmem_strict_check_canaries(allocator);
650 for (i=CONTAINER_ITERS; i>0; i--) {
651 g_assert(wmem_stack_peek(stack) == GINT_TO_POINTER(i-1));
652 g_assert(wmem_stack_pop(stack) == GINT_TO_POINTER(i-1));
653 g_assert(wmem_stack_count(stack) == i-1);
655 g_assert(wmem_stack_count(stack) == 0);
657 wmem_destroy_allocator(allocator);
660 static void
661 wmem_test_strbuf(void)
663 wmem_allocator_t *allocator;
664 wmem_strbuf_t *strbuf;
665 int i;
667 allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
669 strbuf = wmem_strbuf_new(allocator, "TEST");
670 g_assert(strbuf);
671 g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TEST");
672 g_assert(wmem_strbuf_get_len(strbuf) == 4);
674 wmem_strbuf_append(strbuf, "FUZZ");
675 g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ");
676 g_assert(wmem_strbuf_get_len(strbuf) == 8);
678 wmem_strbuf_append_printf(strbuf, "%d%s", 3, "a");
679 g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3a");
680 g_assert(wmem_strbuf_get_len(strbuf) == 10);
682 wmem_strbuf_append_c(strbuf, 'q');
683 g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3aq");
684 g_assert(wmem_strbuf_get_len(strbuf) == 11);
686 wmem_strbuf_append_unichar(strbuf, g_utf8_get_char("\xC2\xA9"));
687 g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3aq\xC2\xA9");
688 g_assert(wmem_strbuf_get_len(strbuf) == 13);
690 wmem_strbuf_truncate(strbuf, 32);
691 wmem_strbuf_truncate(strbuf, 24);
692 wmem_strbuf_truncate(strbuf, 16);
693 wmem_strbuf_truncate(strbuf, 13);
694 g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3aq\xC2\xA9");
695 g_assert(wmem_strbuf_get_len(strbuf) == 13);
697 wmem_strbuf_truncate(strbuf, 3);
698 g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TES");
699 g_assert(wmem_strbuf_get_len(strbuf) == 3);
701 strbuf = wmem_strbuf_sized_new(allocator, 10, 10);
702 g_assert(strbuf);
703 g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "");
704 g_assert(wmem_strbuf_get_len(strbuf) == 0);
706 wmem_strbuf_append(strbuf, "FUZZ");
707 g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ");
708 g_assert(wmem_strbuf_get_len(strbuf) == 4);
710 wmem_strbuf_append_printf(strbuf, "%d%s", 3, "abcdefghijklmnop");
711 g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ3abcd");
712 g_assert(wmem_strbuf_get_len(strbuf) == 9);
714 wmem_strbuf_append(strbuf, "abcdefghijklmnopqrstuvwxyz");
715 g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ3abcd");
716 g_assert(wmem_strbuf_get_len(strbuf) == 9);
718 wmem_strbuf_append_c(strbuf, 'q');
719 g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ3abcd");
720 g_assert(wmem_strbuf_get_len(strbuf) == 9);
722 wmem_strbuf_append_unichar(strbuf, g_utf8_get_char("\xC2\xA9"));
723 g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ3abcd");
724 g_assert(wmem_strbuf_get_len(strbuf) == 9);
726 wmem_free_all(allocator);
728 strbuf = wmem_strbuf_new(allocator, "TEST");
729 for (i=0; i<1024; i++) {
730 if (g_test_rand_bit()) {
731 wmem_strbuf_append(strbuf, "ABC");
733 else {
734 wmem_strbuf_append_printf(strbuf, "%d%d", 3, 777);
736 wmem_strict_check_canaries(allocator);
738 g_assert(strlen(wmem_strbuf_get_str(strbuf)) ==
739 wmem_strbuf_get_len(strbuf));
741 wmem_destroy_allocator(allocator);
744 static void
745 wmem_test_tree(void)
747 wmem_allocator_t *allocator, *extra_allocator;
748 wmem_tree_t *tree;
749 guint32 i;
750 int seen_values = 0;
751 int j;
752 gchar *str_key;
753 #define WMEM_TREE_MAX_KEY_COUNT 8
754 #define WMEM_TREE_MAX_KEY_LEN 4
755 int key_count;
756 wmem_tree_key_t keys[WMEM_TREE_MAX_KEY_COUNT];
758 allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
759 extra_allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
761 tree = wmem_tree_new(allocator);
762 g_assert(tree);
763 g_assert(wmem_tree_is_empty(tree));
765 /* test basic 32-bit key operations */
766 for (i=0; i<CONTAINER_ITERS; i++) {
767 g_assert(wmem_tree_lookup32(tree, i) == NULL);
768 if (i > 0) {
769 g_assert(wmem_tree_lookup32_le(tree, i) == GINT_TO_POINTER(i-1));
771 wmem_tree_insert32(tree, i, GINT_TO_POINTER(i));
772 g_assert(wmem_tree_lookup32(tree, i) == GINT_TO_POINTER(i));
773 g_assert(!wmem_tree_is_empty(tree));
775 wmem_free_all(allocator);
777 tree = wmem_tree_new(allocator);
778 for (i=0; i<CONTAINER_ITERS; i++) {
779 guint32 rand = g_test_rand_int();
780 wmem_tree_insert32(tree, rand, GINT_TO_POINTER(i));
781 g_assert(wmem_tree_lookup32(tree, rand) == GINT_TO_POINTER(i));
783 wmem_free_all(allocator);
785 /* test auto-reset functionality */
786 tree = wmem_tree_new_autoreset(allocator, extra_allocator);
787 for (i=0; i<CONTAINER_ITERS; i++) {
788 g_assert(wmem_tree_lookup32(tree, i) == NULL);
789 wmem_tree_insert32(tree, i, GINT_TO_POINTER(i));
790 g_assert(wmem_tree_lookup32(tree, i) == GINT_TO_POINTER(i));
792 wmem_free_all(extra_allocator);
793 for (i=0; i<CONTAINER_ITERS; i++) {
794 g_assert(wmem_tree_lookup32(tree, i) == NULL);
795 g_assert(wmem_tree_lookup32_le(tree, i) == NULL);
797 wmem_free_all(allocator);
799 /* test array key functionality */
800 tree = wmem_tree_new(allocator);
801 key_count = g_random_int_range(1, WMEM_TREE_MAX_KEY_COUNT);
802 for (j=0; j<key_count; j++) {
803 keys[j].length = g_random_int_range(1, WMEM_TREE_MAX_KEY_LEN);
805 keys[key_count].length = 0;
806 for (i=0; i<CONTAINER_ITERS; i++) {
807 for (j=0; j<key_count; j++) {
808 keys[j].key = (guint32*)wmem_test_rand_string(allocator,
809 (keys[j].length*4), (keys[j].length*4)+1);
811 wmem_tree_insert32_array(tree, keys, GINT_TO_POINTER(i));
812 g_assert(wmem_tree_lookup32_array(tree, keys) == GINT_TO_POINTER(i));
814 wmem_free_all(allocator);
816 tree = wmem_tree_new(allocator);
817 keys[0].length = 1;
818 keys[0].key = wmem_new(allocator, guint32);
819 *(keys[0].key) = 0;
820 keys[1].length = 0;
821 for (i=0; i<CONTAINER_ITERS; i++) {
822 wmem_tree_insert32_array(tree, keys, GINT_TO_POINTER(i));
823 *(keys[0].key) += 4;
825 *(keys[0].key) = 0;
826 for (i=0; i<CONTAINER_ITERS; i++) {
827 g_assert(wmem_tree_lookup32_array(tree, keys) == GINT_TO_POINTER(i));
828 for (j=0; j<3; j++) {
829 (*(keys[0].key)) += 1;
830 g_assert(wmem_tree_lookup32_array_le(tree, keys) ==
831 GINT_TO_POINTER(i));
833 *(keys[0].key) += 1;
835 wmem_free_all(allocator);
837 /* test string key functionality */
838 tree = wmem_tree_new(allocator);
839 for (i=0; i<CONTAINER_ITERS; i++) {
840 str_key = wmem_test_rand_string(allocator, 1, 64);
841 wmem_tree_insert_string(tree, str_key, GINT_TO_POINTER(i), 0);
842 g_assert(wmem_tree_lookup_string(tree, str_key, 0) ==
843 GINT_TO_POINTER(i));
845 wmem_free_all(allocator);
847 tree = wmem_tree_new(allocator);
848 for (i=0; i<CONTAINER_ITERS; i++) {
849 str_key = wmem_test_rand_string(allocator, 1, 64);
850 wmem_tree_insert_string(tree, str_key, GINT_TO_POINTER(i),
851 WMEM_TREE_STRING_NOCASE);
852 g_assert(wmem_tree_lookup_string(tree, str_key,
853 WMEM_TREE_STRING_NOCASE) == GINT_TO_POINTER(i));
855 wmem_free_all(allocator);
857 /* test for-each functionality */
858 tree = wmem_tree_new(allocator);
859 expected_user_data = GINT_TO_POINTER(g_test_rand_int());
860 for (i=0; i<CONTAINER_ITERS; i++) {
861 gint tmp;
862 do {
863 tmp = g_test_rand_int();
864 } while (wmem_tree_lookup32(tree, tmp));
865 value_seen[i] = FALSE;
866 wmem_tree_insert32(tree, tmp, GINT_TO_POINTER(i));
869 cb_called_count = 0;
870 cb_continue_count = CONTAINER_ITERS;
871 wmem_tree_foreach(tree, wmem_test_foreach_cb, expected_user_data);
872 g_assert(cb_called_count == CONTAINER_ITERS);
873 g_assert(cb_continue_count == 0);
875 for (i=0; i<CONTAINER_ITERS; i++) {
876 g_assert(value_seen[i]);
877 value_seen[i] = FALSE;
880 cb_called_count = 0;
881 cb_continue_count = 10;
882 wmem_tree_foreach(tree, wmem_test_foreach_cb, expected_user_data);
883 g_assert(cb_called_count == 10);
884 g_assert(cb_continue_count == 0);
886 for (i=0; i<CONTAINER_ITERS; i++) {
887 if (value_seen[i]) {
888 seen_values++;
891 g_assert(seen_values == 10);
893 wmem_destroy_allocator(extra_allocator);
894 wmem_destroy_allocator(allocator);
898 main(int argc, char **argv)
900 g_test_init(&argc, &argv, NULL);
902 g_test_add_func("/wmem/allocator/block", wmem_test_allocator_block);
903 g_test_add_func("/wmem/allocator/simple", wmem_test_allocator_simple);
904 g_test_add_func("/wmem/allocator/strict", wmem_test_allocator_strict);
905 g_test_add_func("/wmem/allocator/times", wmem_time_allocators);
906 g_test_add_func("/wmem/allocator/callbacks", wmem_test_allocator_callbacks);
908 g_test_add_func("/wmem/utils/misc", wmem_test_miscutls);
909 g_test_add_func("/wmem/utils/strings", wmem_test_strutls);
911 g_test_add_func("/wmem/datastruct/array", wmem_test_array);
912 g_test_add_func("/wmem/datastruct/list", wmem_test_list);
913 g_test_add_func("/wmem/datastruct/queue", wmem_test_queue);
914 g_test_add_func("/wmem/datastruct/stack", wmem_test_stack);
915 g_test_add_func("/wmem/datastruct/strbuf", wmem_test_strbuf);
916 g_test_add_func("/wmem/datastruct/tree", wmem_test_tree);
918 return g_test_run();
922 * Editor modelines - http://www.wireshark.org/tools/modelines.html
924 * Local variables:
925 * c-basic-offset: 4
926 * tab-width: 8
927 * indent-tabs-mode: nil
928 * End:
930 * vi: set shiftwidth=4 tabstop=8 expandtab:
931 * :indentSize=4:tabSize=8:noTabs=true: