~vcs-imports/samba/main

« back to all changes in this revision

Viewing changes to source/lib/talloctort.c

  • Committer: jerry
  • Date: 2006-07-14 21:48:39 UTC
  • Revision ID: vcs-imports@canonical.com-20060714214839-586d8c489a8fcead
gutting trunk to move to svn:externals

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* 
2
 
   Unix SMB/CIFS implementation.
3
 
 
4
 
   local testing of talloc routines.
5
 
 
6
 
   Copyright (C) Andrew Tridgell 2004
7
 
   
8
 
   This program is free software; you can redistribute it and/or modify
9
 
   it under the terms of the GNU General Public License as published by
10
 
   the Free Software Foundation; either version 2 of the License, or
11
 
   (at your option) any later version.
12
 
   
13
 
   This program is distributed in the hope that it will be useful,
14
 
   but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 
   GNU General Public License for more details.
17
 
   
18
 
   You should have received a copy of the GNU General Public License
19
 
   along with this program; if not, write to the Free Software
20
 
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
 
*/
22
 
 
23
 
#ifdef _SAMBA_BUILD_
24
 
#include "includes.h"
25
 
#else
26
 
#include <stdio.h>
27
 
#include <stdlib.h>
28
 
#include <string.h>
29
 
#include <stdarg.h>
30
 
#include <sys/time.h>
31
 
#include <time.h>
32
 
#include "talloc.h"
33
 
#endif
34
 
 
35
 
/* the test suite can be built standalone, or as part of Samba */
36
 
#ifndef _SAMBA_BUILD_
37
 
typedef enum {False=0,True=1} BOOL;
38
 
#endif
39
 
 
40
 
/* Samba3 does not define the timeval functions below */
41
 
#if !defined(_SAMBA_BUILD_) || ((SAMBA_VERSION_MAJOR==3)&&(SAMBA_VERSION_MINOR<9))
42
 
 
43
 
static double timeval_elapsed(struct timeval *tv)
44
 
{
45
 
        struct timeval tv2 = timeval_current();
46
 
        return (tv2.tv_sec - tv->tv_sec) + 
47
 
               (tv2.tv_usec - tv->tv_usec)*1.0e-6;
48
 
}
49
 
#endif /* _SAMBA_BUILD_ */
50
 
 
51
 
#if SAMBA_VERSION_MAJOR<4
52
 
#ifdef malloc
53
 
#undef malloc
54
 
#endif
55
 
#ifdef strdup
56
 
#undef strdup
57
 
#endif
58
 
#endif
59
 
 
60
 
#define CHECK_SIZE(ptr, tsize) do { \
61
 
        if (talloc_total_size(ptr) != (tsize)) { \
62
 
                printf(__location__ " failed: wrong '%s' tree size: got %u  expected %u\n", \
63
 
                       #ptr, \
64
 
                       (unsigned)talloc_total_size(ptr), \
65
 
                       (unsigned)tsize); \
66
 
                talloc_report_full(ptr, stdout); \
67
 
                return False; \
68
 
        } \
69
 
} while (0)
70
 
 
71
 
#define CHECK_BLOCKS(ptr, tblocks) do { \
72
 
        if (talloc_total_blocks(ptr) != (tblocks)) { \
73
 
                printf(__location__ " failed: wrong '%s' tree blocks: got %u  expected %u\n", \
74
 
                       #ptr, \
75
 
                       (unsigned)talloc_total_blocks(ptr), \
76
 
                       (unsigned)tblocks); \
77
 
                talloc_report_full(ptr, stdout); \
78
 
                return False; \
79
 
        } \
80
 
} while (0)
81
 
 
82
 
 
83
 
/*
84
 
  test references 
85
 
*/
86
 
static BOOL test_ref1(void)
87
 
{
88
 
        void *root, *p1, *p2, *ref, *r1;
89
 
 
90
 
        printf("TESTING SINGLE REFERENCE FREE\n");
91
 
 
92
 
        root = talloc_named_const(NULL, 0, "root");
93
 
        p1 = talloc_named_const(root, 1, "p1");
94
 
        p2 = talloc_named_const(p1, 1, "p2");
95
 
        talloc_named_const(p1, 1, "x1");
96
 
        talloc_named_const(p1, 2, "x2");
97
 
        talloc_named_const(p1, 3, "x3");
98
 
 
99
 
        r1 = talloc_named_const(root, 1, "r1"); 
100
 
        ref = talloc_reference(r1, p2);
101
 
        talloc_report_full(root, stdout);
102
 
 
103
 
        CHECK_BLOCKS(p1, 5);
104
 
        CHECK_BLOCKS(p2, 1);
105
 
        CHECK_BLOCKS(r1, 2);
106
 
 
107
 
        printf("Freeing p2\n");
108
 
        talloc_free(p2);
109
 
        talloc_report_full(root, stdout);
110
 
 
111
 
        CHECK_BLOCKS(p1, 5);
112
 
        CHECK_BLOCKS(p2, 1);
113
 
        CHECK_BLOCKS(r1, 1);
114
 
 
115
 
        printf("Freeing p1\n");
116
 
        talloc_free(p1);
117
 
        talloc_report_full(root, stdout);
118
 
 
119
 
        CHECK_BLOCKS(r1, 1);
120
 
 
121
 
        printf("Freeing r1\n");
122
 
        talloc_free(r1);
123
 
        talloc_report_full(NULL, stdout);
124
 
 
125
 
        printf("Testing NULL\n");
126
 
        if (talloc_reference(root, NULL)) {
127
 
                return False;
128
 
        }
129
 
 
130
 
        CHECK_BLOCKS(root, 1);
131
 
 
132
 
        CHECK_SIZE(root, 0);
133
 
 
134
 
        talloc_free(root);
135
 
 
136
 
        return True;
137
 
}
138
 
 
139
 
/*
140
 
  test references 
141
 
*/
142
 
static BOOL test_ref2(void)
143
 
{
144
 
        void *root, *p1, *p2, *ref, *r1;
145
 
 
146
 
        printf("TESTING DOUBLE REFERENCE FREE\n");
147
 
 
148
 
        root = talloc_named_const(NULL, 0, "root");
149
 
        p1 = talloc_named_const(root, 1, "p1");
150
 
        talloc_named_const(p1, 1, "x1");
151
 
        talloc_named_const(p1, 1, "x2");
152
 
        talloc_named_const(p1, 1, "x3");
153
 
        p2 = talloc_named_const(p1, 1, "p2");
154
 
 
155
 
        r1 = talloc_named_const(root, 1, "r1"); 
156
 
        ref = talloc_reference(r1, p2);
157
 
        talloc_report_full(root, stdout);
158
 
 
159
 
        CHECK_BLOCKS(p1, 5);
160
 
        CHECK_BLOCKS(p2, 1);
161
 
        CHECK_BLOCKS(r1, 2);
162
 
 
163
 
        printf("Freeing ref\n");
164
 
        talloc_free(ref);
165
 
        talloc_report_full(root, stdout);
166
 
 
167
 
        CHECK_BLOCKS(p1, 5);
168
 
        CHECK_BLOCKS(p2, 1);
169
 
        CHECK_BLOCKS(r1, 1);
170
 
 
171
 
        printf("Freeing p2\n");
172
 
        talloc_free(p2);
173
 
        talloc_report_full(root, stdout);
174
 
 
175
 
        CHECK_BLOCKS(p1, 4);
176
 
        CHECK_BLOCKS(r1, 1);
177
 
 
178
 
        printf("Freeing p1\n");
179
 
        talloc_free(p1);
180
 
        talloc_report_full(root, stdout);
181
 
 
182
 
        CHECK_BLOCKS(r1, 1);
183
 
 
184
 
        printf("Freeing r1\n");
185
 
        talloc_free(r1);
186
 
        talloc_report_full(root, stdout);
187
 
 
188
 
        CHECK_SIZE(root, 0);
189
 
 
190
 
        talloc_free(root);
191
 
 
192
 
        return True;
193
 
}
194
 
 
195
 
/*
196
 
  test references 
197
 
*/
198
 
static BOOL test_ref3(void)
199
 
{
200
 
        void *root, *p1, *p2, *ref, *r1;
201
 
 
202
 
        printf("TESTING PARENT REFERENCE FREE\n");
203
 
 
204
 
        root = talloc_named_const(NULL, 0, "root");
205
 
        p1 = talloc_named_const(root, 1, "p1");
206
 
        p2 = talloc_named_const(root, 1, "p2");
207
 
        r1 = talloc_named_const(p1, 1, "r1");
208
 
        ref = talloc_reference(p2, r1);
209
 
        talloc_report_full(root, stdout);
210
 
 
211
 
        CHECK_BLOCKS(p1, 2);
212
 
        CHECK_BLOCKS(p2, 2);
213
 
        CHECK_BLOCKS(r1, 1);
214
 
 
215
 
        printf("Freeing p1\n");
216
 
        talloc_free(p1);
217
 
        talloc_report_full(root, stdout);
218
 
 
219
 
        CHECK_BLOCKS(p2, 2);
220
 
        CHECK_BLOCKS(r1, 1);
221
 
 
222
 
        printf("Freeing p2\n");
223
 
        talloc_free(p2);
224
 
        talloc_report_full(root, stdout);
225
 
 
226
 
        CHECK_SIZE(root, 0);
227
 
 
228
 
        talloc_free(root);
229
 
 
230
 
        return True;
231
 
}
232
 
 
233
 
/*
234
 
  test references 
235
 
*/
236
 
static BOOL test_ref4(void)
237
 
{
238
 
        void *root, *p1, *p2, *ref, *r1;
239
 
 
240
 
        printf("TESTING REFERRER REFERENCE FREE\n");
241
 
 
242
 
        root = talloc_named_const(NULL, 0, "root");
243
 
        p1 = talloc_named_const(root, 1, "p1");
244
 
        talloc_named_const(p1, 1, "x1");
245
 
        talloc_named_const(p1, 1, "x2");
246
 
        talloc_named_const(p1, 1, "x3");
247
 
        p2 = talloc_named_const(p1, 1, "p2");
248
 
 
249
 
        r1 = talloc_named_const(root, 1, "r1"); 
250
 
        ref = talloc_reference(r1, p2);
251
 
        talloc_report_full(root, stdout);
252
 
 
253
 
        CHECK_BLOCKS(p1, 5);
254
 
        CHECK_BLOCKS(p2, 1);
255
 
        CHECK_BLOCKS(r1, 2);
256
 
 
257
 
        printf("Freeing r1\n");
258
 
        talloc_free(r1);
259
 
        talloc_report_full(root, stdout);
260
 
 
261
 
        CHECK_BLOCKS(p1, 5);
262
 
        CHECK_BLOCKS(p2, 1);
263
 
 
264
 
        printf("Freeing p2\n");
265
 
        talloc_free(p2);
266
 
        talloc_report_full(root, stdout);
267
 
 
268
 
        CHECK_BLOCKS(p1, 4);
269
 
 
270
 
        printf("Freeing p1\n");
271
 
        talloc_free(p1);
272
 
        talloc_report_full(root, stdout);
273
 
 
274
 
        CHECK_SIZE(root, 0);
275
 
 
276
 
        talloc_free(root);
277
 
 
278
 
        return True;
279
 
}
280
 
 
281
 
 
282
 
/*
283
 
  test references 
284
 
*/
285
 
static BOOL test_unlink1(void)
286
 
{
287
 
        void *root, *p1, *p2, *ref, *r1;
288
 
 
289
 
        printf("TESTING UNLINK\n");
290
 
 
291
 
        root = talloc_named_const(NULL, 0, "root");
292
 
        p1 = talloc_named_const(root, 1, "p1");
293
 
        talloc_named_const(p1, 1, "x1");
294
 
        talloc_named_const(p1, 1, "x2");
295
 
        talloc_named_const(p1, 1, "x3");
296
 
        p2 = talloc_named_const(p1, 1, "p2");
297
 
 
298
 
        r1 = talloc_named_const(p1, 1, "r1");   
299
 
        ref = talloc_reference(r1, p2);
300
 
        talloc_report_full(root, stdout);
301
 
 
302
 
        CHECK_BLOCKS(p1, 7);
303
 
        CHECK_BLOCKS(p2, 1);
304
 
        CHECK_BLOCKS(r1, 2);
305
 
 
306
 
        printf("Unreferencing r1\n");
307
 
        talloc_unlink(r1, p2);
308
 
        talloc_report_full(root, stdout);
309
 
 
310
 
        CHECK_BLOCKS(p1, 6);
311
 
        CHECK_BLOCKS(p2, 1);
312
 
        CHECK_BLOCKS(r1, 1);
313
 
 
314
 
        printf("Freeing p1\n");
315
 
        talloc_free(p1);
316
 
        talloc_report_full(root, stdout);
317
 
 
318
 
        CHECK_SIZE(root, 0);
319
 
 
320
 
        talloc_free(root);
321
 
 
322
 
        return True;
323
 
}
324
 
 
325
 
static int fail_destructor(void *ptr)
326
 
{
327
 
        return -1;
328
 
}
329
 
 
330
 
/*
331
 
  miscellaneous tests to try to get a higher test coverage percentage
332
 
*/
333
 
static BOOL test_misc(void)
334
 
{
335
 
        void *root, *p1;
336
 
        char *p2;
337
 
        double *d;
338
 
 
339
 
        printf("TESTING MISCELLANEOUS\n");
340
 
 
341
 
        root = talloc_new(NULL);
342
 
 
343
 
        p1 = talloc_size(root, 0x7fffffff);
344
 
        if (p1) {
345
 
                printf("failed: large talloc allowed\n");
346
 
                return False;
347
 
        }
348
 
 
349
 
        p1 = talloc_strdup(root, "foo");
350
 
        talloc_increase_ref_count(p1);
351
 
        talloc_increase_ref_count(p1);
352
 
        talloc_increase_ref_count(p1);
353
 
        CHECK_BLOCKS(p1, 1);
354
 
        CHECK_BLOCKS(root, 2);
355
 
        talloc_free(p1);
356
 
        CHECK_BLOCKS(p1, 1);
357
 
        CHECK_BLOCKS(root, 2);
358
 
        talloc_unlink(NULL, p1);
359
 
        CHECK_BLOCKS(p1, 1);
360
 
        CHECK_BLOCKS(root, 2);
361
 
        p2 = talloc_strdup(p1, "foo");
362
 
        if (talloc_unlink(root, p2) != -1) {
363
 
                printf("failed: talloc_unlink() of non-reference context should return -1\n");
364
 
                return False;
365
 
        }
366
 
        if (talloc_unlink(p1, p2) != 0) {
367
 
                printf("failed: talloc_unlink() of parent should succeed\n");
368
 
                return False;
369
 
        }
370
 
        talloc_free(p1);
371
 
        CHECK_BLOCKS(p1, 1);
372
 
        CHECK_BLOCKS(root, 2);
373
 
 
374
 
        talloc_set_name(p1, "my name is %s", "foo");
375
 
        if (strcmp(talloc_get_name(p1), "my name is foo") != 0) {
376
 
                printf("failed: wrong name after talloc_set_name\n");
377
 
                return False;
378
 
        }
379
 
        CHECK_BLOCKS(p1, 2);
380
 
        CHECK_BLOCKS(root, 3);
381
 
 
382
 
        talloc_set_name_const(p1, NULL);
383
 
        if (strcmp(talloc_get_name(p1), "UNNAMED") != 0) {
384
 
                printf("failed: wrong name after talloc_set_name(NULL)\n");
385
 
                return False;
386
 
        }
387
 
        CHECK_BLOCKS(p1, 2);
388
 
        CHECK_BLOCKS(root, 3);
389
 
        
390
 
 
391
 
        if (talloc_free(NULL) != -1) {
392
 
                printf("talloc_free(NULL) should give -1\n");
393
 
                return False;
394
 
        }
395
 
 
396
 
        talloc_set_destructor(p1, fail_destructor);
397
 
        if (talloc_free(p1) != -1) {
398
 
                printf("Failed destructor should cause talloc_free to fail\n");
399
 
                return False;
400
 
        }
401
 
        talloc_set_destructor(p1, NULL);
402
 
 
403
 
        talloc_report(root, stdout);
404
 
 
405
 
 
406
 
        p2 = talloc_zero_size(p1, 20);
407
 
        if (p2[19] != 0) {
408
 
                printf("Failed to give zero memory\n");
409
 
                return False;
410
 
        }
411
 
        talloc_free(p2);
412
 
 
413
 
        if (talloc_strdup(root, NULL) != NULL) {
414
 
                printf("failed: strdup on NULL should give NULL\n");
415
 
                return False;
416
 
        }
417
 
 
418
 
        p2 = talloc_strndup(p1, "foo", 2);
419
 
        if (strcmp("fo", p2) != 0) {
420
 
                printf("failed: strndup doesn't work\n");
421
 
                return False;
422
 
        }
423
 
        p2 = talloc_asprintf_append(p2, "o%c", 'd');
424
 
        if (strcmp("food", p2) != 0) {
425
 
                printf("failed: talloc_asprintf_append doesn't work\n");
426
 
                return False;
427
 
        }
428
 
        CHECK_BLOCKS(p2, 1);
429
 
        CHECK_BLOCKS(p1, 3);
430
 
 
431
 
        p2 = talloc_asprintf_append(NULL, "hello %s", "world");
432
 
        if (strcmp("hello world", p2) != 0) {
433
 
                printf("failed: talloc_asprintf_append doesn't work\n");
434
 
                return False;
435
 
        }
436
 
        CHECK_BLOCKS(p2, 1);
437
 
        CHECK_BLOCKS(p1, 3);
438
 
        talloc_free(p2);
439
 
 
440
 
        d = talloc_array(p1, double, 0x20000000);
441
 
        if (d) {
442
 
                printf("failed: integer overflow not detected\n");
443
 
                return False;
444
 
        }
445
 
 
446
 
        d = talloc_realloc(p1, d, double, 0x20000000);
447
 
        if (d) {
448
 
                printf("failed: integer overflow not detected\n");
449
 
                return False;
450
 
        }
451
 
 
452
 
        talloc_free(p1);
453
 
        CHECK_BLOCKS(root, 1);
454
 
 
455
 
        p1 = talloc_named(root, 100, "%d bytes", 100);
456
 
        CHECK_BLOCKS(p1, 2);
457
 
        CHECK_BLOCKS(root, 3);
458
 
        talloc_unlink(root, p1);
459
 
 
460
 
        p1 = talloc_init("%d bytes", 200);
461
 
        p2 = talloc_asprintf(p1, "my test '%s'", "string");
462
 
        CHECK_BLOCKS(p1, 3);
463
 
        CHECK_SIZE(p2, 17);
464
 
        CHECK_BLOCKS(root, 1);
465
 
        talloc_unlink(NULL, p1);
466
 
 
467
 
        p1 = talloc_named_const(root, 10, "p1");
468
 
        p2 = talloc_named_const(root, 20, "p2");
469
 
        talloc_reference(p1, p2);
470
 
        talloc_report_full(root, stdout);
471
 
        talloc_unlink(root, p2);
472
 
        talloc_report_full(root, stdout);
473
 
        CHECK_BLOCKS(p2, 1);
474
 
        CHECK_BLOCKS(p1, 2);
475
 
        CHECK_BLOCKS(root, 3);
476
 
        talloc_unlink(p1, p2);
477
 
        talloc_unlink(root, p1);
478
 
 
479
 
        p1 = talloc_named_const(root, 10, "p1");
480
 
        p2 = talloc_named_const(root, 20, "p2");
481
 
        talloc_reference(NULL, p2);
482
 
        talloc_report_full(root, stdout);
483
 
        talloc_unlink(root, p2);
484
 
        talloc_report_full(root, stdout);
485
 
        CHECK_BLOCKS(p2, 1);
486
 
        CHECK_BLOCKS(p1, 1);
487
 
        CHECK_BLOCKS(root, 2);
488
 
        talloc_unlink(NULL, p2);
489
 
        talloc_unlink(root, p1);
490
 
 
491
 
        /* Test that talloc_unlink is a no-op */
492
 
 
493
 
        if (talloc_unlink(root, NULL) != -1) {
494
 
                printf("failed: talloc_unlink(root, NULL) == -1\n");
495
 
                return False;
496
 
        }
497
 
 
498
 
        talloc_report(root, stdout);
499
 
        talloc_report(NULL, stdout);
500
 
 
501
 
        CHECK_SIZE(root, 0);
502
 
 
503
 
        talloc_free(root);
504
 
 
505
 
        CHECK_SIZE(NULL, 0);
506
 
 
507
 
        talloc_enable_leak_report();
508
 
        talloc_enable_leak_report_full();
509
 
 
510
 
        return True;
511
 
}
512
 
 
513
 
 
514
 
/*
515
 
  test realloc
516
 
*/
517
 
static BOOL test_realloc(void)
518
 
{
519
 
        void *root, *p1, *p2;
520
 
 
521
 
        printf("TESTING REALLOC\n");
522
 
 
523
 
        root = talloc_new(NULL);
524
 
 
525
 
        p1 = talloc_size(root, 10);
526
 
        CHECK_SIZE(p1, 10);
527
 
 
528
 
        p1 = talloc_realloc_size(NULL, p1, 20);
529
 
        CHECK_SIZE(p1, 20);
530
 
 
531
 
        talloc_new(p1);
532
 
 
533
 
        p2 = talloc_realloc_size(p1, NULL, 30);
534
 
 
535
 
        talloc_new(p1);
536
 
 
537
 
        p2 = talloc_realloc_size(p1, p2, 40);
538
 
 
539
 
        CHECK_SIZE(p2, 40);
540
 
        CHECK_SIZE(root, 60);
541
 
        CHECK_BLOCKS(p1, 4);
542
 
 
543
 
        p1 = talloc_realloc_size(NULL, p1, 20);
544
 
        CHECK_SIZE(p1, 60);
545
 
 
546
 
        talloc_increase_ref_count(p2);
547
 
        if (talloc_realloc_size(NULL, p2, 5) != NULL) {
548
 
                printf("failed: talloc_realloc() on a referenced pointer should fail\n");
549
 
                return False;
550
 
        }
551
 
        CHECK_BLOCKS(p1, 4);
552
 
 
553
 
        talloc_realloc_size(NULL, p2, 0);
554
 
        talloc_realloc_size(NULL, p2, 0);
555
 
        CHECK_BLOCKS(p1, 3);
556
 
 
557
 
        if (talloc_realloc_size(NULL, p1, 0x7fffffff) != NULL) {
558
 
                printf("failed: oversize talloc should fail\n");
559
 
                return False;
560
 
        }
561
 
 
562
 
        talloc_realloc_size(NULL, p1, 0);
563
 
 
564
 
        CHECK_BLOCKS(root, 1);
565
 
        CHECK_SIZE(root, 0);
566
 
 
567
 
        talloc_free(root);
568
 
 
569
 
        return True;
570
 
}
571
 
 
572
 
 
573
 
/*
574
 
  test realloc with a child
575
 
*/
576
 
static BOOL test_realloc_child(void)
577
 
{
578
 
        void *root;
579
 
        struct el1 {
580
 
                int count;
581
 
                struct el2 {
582
 
                        const char *name;
583
 
                } **list, **list2, **list3;
584
 
        } *el1;
585
 
        struct el2 *el2;
586
 
 
587
 
        printf("TESTING REALLOC WITH CHILD\n");
588
 
 
589
 
        root = talloc_new(NULL);
590
 
 
591
 
        el1 = talloc(root, struct el1);
592
 
        el1->list = talloc(el1, struct el2 *);
593
 
        el1->list[0] = talloc(el1->list, struct el2);
594
 
        el1->list[0]->name = talloc_strdup(el1->list[0], "testing");
595
 
 
596
 
        el1->list2 = talloc(el1, struct el2 *);
597
 
        el1->list2[0] = talloc(el1->list2, struct el2);
598
 
        el1->list2[0]->name = talloc_strdup(el1->list2[0], "testing2");
599
 
 
600
 
        el1->list3 = talloc(el1, struct el2 *);
601
 
        el1->list3[0] = talloc(el1->list3, struct el2);
602
 
        el1->list3[0]->name = talloc_strdup(el1->list3[0], "testing2");
603
 
        
604
 
        el2 = talloc(el1->list, struct el2);
605
 
        el2 = talloc(el1->list2, struct el2);
606
 
        el2 = talloc(el1->list3, struct el2);
607
 
 
608
 
        el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100);
609
 
        el1->list2 = talloc_realloc(el1, el1->list2, struct el2 *, 200);
610
 
        el1->list3 = talloc_realloc(el1, el1->list3, struct el2 *, 300);
611
 
 
612
 
        talloc_free(root);
613
 
 
614
 
        return True;
615
 
}
616
 
 
617
 
 
618
 
/*
619
 
  test type checking
620
 
*/
621
 
static BOOL test_type(void)
622
 
{
623
 
        void *root;
624
 
        struct el1 {
625
 
                int count;
626
 
        };
627
 
        struct el2 {
628
 
                int count;
629
 
        };
630
 
        struct el1 *el1;
631
 
 
632
 
        printf("TESTING talloc type checking\n");
633
 
 
634
 
        root = talloc_new(NULL);
635
 
 
636
 
        el1 = talloc(root, struct el1);
637
 
 
638
 
        el1->count = 1;
639
 
 
640
 
        if (talloc_get_type(el1, struct el1) != el1) {
641
 
                printf("type check failed on el1\n");
642
 
                return False;
643
 
        }
644
 
        if (talloc_get_type(el1, struct el2) != NULL) {
645
 
                printf("type check failed on el1 with el2\n");
646
 
                return False;
647
 
        }
648
 
        talloc_set_type(el1, struct el2);
649
 
        if (talloc_get_type(el1, struct el2) != (struct el2 *)el1) {
650
 
                printf("type set failed on el1 with el2\n");
651
 
                return False;
652
 
        }
653
 
 
654
 
        talloc_free(root);
655
 
 
656
 
        return True;
657
 
}
658
 
 
659
 
#if 0
660
 
/*
661
 
  test steal
662
 
*/
663
 
static BOOL test_steal(void)
664
 
{
665
 
        void *root, *p1, *p2;
666
 
 
667
 
        printf("TESTING STEAL\n");
668
 
 
669
 
        root = talloc_new(NULL);
670
 
 
671
 
        p1 = talloc_array(root, char, 10);
672
 
        CHECK_SIZE(p1, 10);
673
 
 
674
 
        p2 = talloc_realloc(root, NULL, char, 20);
675
 
        CHECK_SIZE(p1, 10);
676
 
        CHECK_SIZE(root, 30);
677
 
 
678
 
        if (talloc_steal(p1, NULL) != NULL) {
679
 
                printf("failed: stealing NULL should give NULL\n");
680
 
                return False;
681
 
        }
682
 
 
683
 
        if (talloc_steal(p1, p1) != p1) {
684
 
                printf("failed: stealing to ourselves is a nop\n");
685
 
                return False;
686
 
        }
687
 
        CHECK_BLOCKS(root, 3);
688
 
        CHECK_SIZE(root, 30);
689
 
 
690
 
        talloc_steal(NULL, p1);
691
 
        talloc_steal(NULL, p2);
692
 
        CHECK_BLOCKS(root, 1);
693
 
        CHECK_SIZE(root, 0);
694
 
 
695
 
        talloc_free(p1);
696
 
        talloc_steal(root, p2);
697
 
        CHECK_BLOCKS(root, 2);
698
 
        CHECK_SIZE(root, 20);
699
 
        
700
 
        talloc_free(p2);
701
 
 
702
 
        CHECK_BLOCKS(root, 1);
703
 
        CHECK_SIZE(root, 0);
704
 
 
705
 
        talloc_free(root);
706
 
 
707
 
        p1 = talloc_size(NULL, 3);
708
 
        CHECK_SIZE(NULL, 3);
709
 
        talloc_free(p1);
710
 
 
711
 
        return True;
712
 
}
713
 
#endif
714
 
 
715
 
/*
716
 
  test talloc_realloc_fn
717
 
*/
718
 
static BOOL test_realloc_fn(void)
719
 
{
720
 
        void *root, *p1;
721
 
 
722
 
        printf("TESTING talloc_realloc_fn\n");
723
 
 
724
 
        root = talloc_new(NULL);
725
 
 
726
 
        p1 = talloc_realloc_fn(root, NULL, 10);
727
 
        CHECK_BLOCKS(root, 2);
728
 
        CHECK_SIZE(root, 10);
729
 
        p1 = talloc_realloc_fn(root, p1, 20);
730
 
        CHECK_BLOCKS(root, 2);
731
 
        CHECK_SIZE(root, 20);
732
 
        p1 = talloc_realloc_fn(root, p1, 0);
733
 
        CHECK_BLOCKS(root, 1);
734
 
        CHECK_SIZE(root, 0);
735
 
 
736
 
        talloc_free(root);
737
 
 
738
 
 
739
 
        return True;
740
 
}
741
 
 
742
 
 
743
 
static BOOL test_unref_reparent(void)
744
 
{
745
 
        void *root, *p1, *p2, *c1;
746
 
 
747
 
        printf("TESTING UNREFERENCE AFTER PARENT FREED\n");
748
 
 
749
 
        root = talloc_named_const(NULL, 0, "root");
750
 
        p1 = talloc_named_const(root, 1, "orig parent");
751
 
        p2 = talloc_named_const(root, 1, "parent by reference");
752
 
 
753
 
        c1 = talloc_named_const(p1, 1, "child");
754
 
        talloc_reference(p2, c1);
755
 
 
756
 
        talloc_free(p1);
757
 
        talloc_unlink(p2, c1);
758
 
 
759
 
        CHECK_SIZE(root, 1);
760
 
 
761
 
        talloc_free(p2);
762
 
        talloc_free(root);
763
 
 
764
 
        return True;
765
 
}
766
 
 
767
 
/*
768
 
  measure the speed of talloc versus malloc
769
 
*/
770
 
static BOOL test_speed(void)
771
 
{
772
 
        void *ctx = talloc_new(NULL);
773
 
        unsigned count;
774
 
        struct timeval tv;
775
 
 
776
 
        printf("MEASURING TALLOC VS MALLOC SPEED\n");
777
 
 
778
 
        tv = timeval_current();
779
 
        count = 0;
780
 
        do {
781
 
                void *p1, *p2, *p3;
782
 
                p1 = talloc_size(ctx, count);
783
 
                p2 = talloc_strdup(p1, "foo bar");
784
 
                p3 = talloc_size(p1, 300);
785
 
                talloc_free(p1);
786
 
                count += 3;
787
 
        } while (timeval_elapsed(&tv) < 5.0);
788
 
 
789
 
        printf("talloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));
790
 
 
791
 
        talloc_free(ctx);
792
 
 
793
 
        tv = timeval_current();
794
 
        count = 0;
795
 
        do {
796
 
                void *p1, *p2, *p3;
797
 
                p1 = malloc(count);
798
 
                p2 = strdup("foo bar");
799
 
                p3 = malloc(300);
800
 
                free(p1);
801
 
                free(p2);
802
 
                free(p3);
803
 
                count += 3;
804
 
        } while (timeval_elapsed(&tv) < 5.0);
805
 
 
806
 
        printf("malloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));
807
 
 
808
 
        return True;    
809
 
}
810
 
 
811
 
 
812
 
BOOL torture_local_talloc(void) 
813
 
{
814
 
        BOOL ret = True;
815
 
 
816
 
        ret &= test_ref1();
817
 
        ret &= test_ref2();
818
 
        ret &= test_ref3();
819
 
        ret &= test_ref4();
820
 
        ret &= test_unlink1();
821
 
        ret &= test_misc();
822
 
        ret &= test_realloc();
823
 
        ret &= test_realloc_child();
824
 
/*      ret &= test_steal(); */
825
 
        ret &= test_unref_reparent();
826
 
        ret &= test_realloc_fn();
827
 
        ret &= test_type();
828
 
        if (ret) {
829
 
                ret &= test_speed();
830
 
        }
831
 
 
832
 
        return ret;
833
 
}
834
 
 
835
 
 
836
 
 
837
 
#if !defined(_SAMBA_BUILD_) || ((SAMBA_VERSION_MAJOR==3)&&(SAMBA_VERSION_MINOR<9))
838
 
 int main(void)
839
 
{
840
 
        if (!torture_local_talloc()) {
841
 
                printf("ERROR: TESTSUIE FAILED\n");
842
 
                return -1;
843
 
        }
844
 
        return 0;
845
 
}
846
 
#endif