~ubuntu-branches/ubuntu/vivid/ctdb/vivid-proposed

« back to all changes in this revision

Viewing changes to lib/talloc/testsuite.c

  • Committer: Bazaar Package Importer
  • Author(s): Mathieu Parent
  • Date: 2008-04-26 15:21:27 UTC
  • Revision ID: james.westby@ubuntu.com-20080426152127-58mv5ojv5q362ise
Tags: upstream-1.0.34+git200804242206
ImportĀ upstreamĀ versionĀ 1.0.34+git200804242206

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
     ** NOTE! The following LGPL license applies to the talloc
 
9
     ** library. This does NOT imply that all of Samba is released
 
10
     ** under the LGPL
 
11
   
 
12
   This library is free software; you can redistribute it and/or
 
13
   modify it under the terms of the GNU Lesser General Public
 
14
   License as published by the Free Software Foundation; either
 
15
   version 3 of the License, or (at your option) any later version.
 
16
 
 
17
   This library is distributed in the hope that it will be useful,
 
18
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
19
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
20
   Lesser General Public License for more details.
 
21
 
 
22
   You should have received a copy of the GNU Lesser General Public
 
23
   License along with this library; if not, see <http://www.gnu.org/licenses/>.
 
24
*/
 
25
 
 
26
#include "replace.h"
 
27
#include "system/time.h"
 
28
#include "talloc.h"
 
29
 
 
30
static struct timeval timeval_current(void)
 
31
{
 
32
        struct timeval tv;
 
33
        gettimeofday(&tv, NULL);
 
34
        return tv;
 
35
}
 
36
 
 
37
static double timeval_elapsed(struct timeval *tv)
 
38
{
 
39
        struct timeval tv2 = timeval_current();
 
40
        return (tv2.tv_sec - tv->tv_sec) + 
 
41
               (tv2.tv_usec - tv->tv_usec)*1.0e-6;
 
42
}
 
43
 
 
44
#define torture_assert(test, expr, str) if (!(expr)) { \
 
45
        printf("failure: %s [\n%s: Expression %s failed: %s\n]\n", \
 
46
                test, __location__, #expr, str); \
 
47
        return false; \
 
48
}
 
49
 
 
50
#define torture_assert_str_equal(test, arg1, arg2, desc) \
 
51
        if (strcmp(arg1, arg2)) { \
 
52
                printf("failure: %s [\n%s: Expected %s, got %s: %s\n]\n", \
 
53
                   test, __location__, arg1, arg2, desc); \
 
54
                return false; \
 
55
        }
 
56
 
 
57
#if _SAMBA_BUILD_==3
 
58
#ifdef malloc
 
59
#undef malloc
 
60
#endif
 
61
#ifdef strdup
 
62
#undef strdup
 
63
#endif
 
64
#endif
 
65
 
 
66
#define CHECK_SIZE(test, ptr, tsize) do { \
 
67
        if (talloc_total_size(ptr) != (tsize)) { \
 
68
                printf("failed: %s [\nwrong '%s' tree size: got %u  expected %u\n]\n", \
 
69
                       test, #ptr, \
 
70
                       (unsigned)talloc_total_size(ptr), \
 
71
                       (unsigned)tsize); \
 
72
                talloc_report_full(ptr, stdout); \
 
73
                return false; \
 
74
        } \
 
75
} while (0)
 
76
 
 
77
#define CHECK_BLOCKS(test, ptr, tblocks) do { \
 
78
        if (talloc_total_blocks(ptr) != (tblocks)) { \
 
79
                printf("failed: %s [\nwrong '%s' tree blocks: got %u  expected %u\n]\n", \
 
80
                       test, #ptr, \
 
81
                       (unsigned)talloc_total_blocks(ptr), \
 
82
                       (unsigned)tblocks); \
 
83
                talloc_report_full(ptr, stdout); \
 
84
                return false; \
 
85
        } \
 
86
} while (0)
 
87
 
 
88
#define CHECK_PARENT(test, ptr, parent) do { \
 
89
        if (talloc_parent(ptr) != (parent)) { \
 
90
                printf("failed: %s [\n'%s' has wrong parent: got %p  expected %p\n]\n", \
 
91
                       test, #ptr, \
 
92
                       talloc_parent(ptr), \
 
93
                       (parent)); \
 
94
                talloc_report_full(ptr, stdout); \
 
95
                talloc_report_full(parent, stdout); \
 
96
                talloc_report_full(NULL, stdout); \
 
97
                return false; \
 
98
        } \
 
99
} while (0)
 
100
 
 
101
 
 
102
/*
 
103
  test references 
 
104
*/
 
105
static bool test_ref1(void)
 
106
{
 
107
        void *root, *p1, *p2, *ref, *r1;
 
108
 
 
109
        printf("test: ref1 [\nSINGLE REFERENCE FREE\n]\n");
 
110
 
 
111
        root = talloc_named_const(NULL, 0, "root");
 
112
        p1 = talloc_named_const(root, 1, "p1");
 
113
        p2 = talloc_named_const(p1, 1, "p2");
 
114
        talloc_named_const(p1, 1, "x1");
 
115
        talloc_named_const(p1, 2, "x2");
 
116
        talloc_named_const(p1, 3, "x3");
 
117
 
 
118
        r1 = talloc_named_const(root, 1, "r1"); 
 
119
        ref = talloc_reference(r1, p2);
 
120
        talloc_report_full(root, stderr);
 
121
 
 
122
        CHECK_BLOCKS("ref1", p1, 5);
 
123
        CHECK_BLOCKS("ref1", p2, 1);
 
124
        CHECK_BLOCKS("ref1", r1, 2);
 
125
 
 
126
        fprintf(stderr, "Freeing p2\n");
 
127
        talloc_free(p2);
 
128
        talloc_report_full(root, stderr);
 
129
 
 
130
        CHECK_BLOCKS("ref1", p1, 5);
 
131
        CHECK_BLOCKS("ref1", p2, 1);
 
132
        CHECK_BLOCKS("ref1", r1, 1);
 
133
 
 
134
        fprintf(stderr, "Freeing p1\n");
 
135
        talloc_free(p1);
 
136
        talloc_report_full(root, stderr);
 
137
 
 
138
        CHECK_BLOCKS("ref1", r1, 1);
 
139
 
 
140
        fprintf(stderr, "Freeing r1\n");
 
141
        talloc_free(r1);
 
142
        talloc_report_full(NULL, stderr);
 
143
 
 
144
        fprintf(stderr, "Testing NULL\n");
 
145
        if (talloc_reference(root, NULL)) {
 
146
                return false;
 
147
        }
 
148
 
 
149
        CHECK_BLOCKS("ref1", root, 1);
 
150
 
 
151
        CHECK_SIZE("ref1", root, 0);
 
152
 
 
153
        talloc_free(root);
 
154
        printf("success: ref1\n");
 
155
        return true;
 
156
}
 
157
 
 
158
/*
 
159
  test references 
 
160
*/
 
161
static bool test_ref2(void)
 
162
{
 
163
        void *root, *p1, *p2, *ref, *r1;
 
164
 
 
165
        printf("test: ref2 [\nDOUBLE REFERENCE FREE\n]\n");
 
166
        root = talloc_named_const(NULL, 0, "root");
 
167
        p1 = talloc_named_const(root, 1, "p1");
 
168
        talloc_named_const(p1, 1, "x1");
 
169
        talloc_named_const(p1, 1, "x2");
 
170
        talloc_named_const(p1, 1, "x3");
 
171
        p2 = talloc_named_const(p1, 1, "p2");
 
172
 
 
173
        r1 = talloc_named_const(root, 1, "r1"); 
 
174
        ref = talloc_reference(r1, p2);
 
175
        talloc_report_full(root, stderr);
 
176
 
 
177
        CHECK_BLOCKS("ref2", p1, 5);
 
178
        CHECK_BLOCKS("ref2", p2, 1);
 
179
        CHECK_BLOCKS("ref2", r1, 2);
 
180
 
 
181
        fprintf(stderr, "Freeing ref\n");
 
182
        talloc_free(ref);
 
183
        talloc_report_full(root, stderr);
 
184
 
 
185
        CHECK_BLOCKS("ref2", p1, 5);
 
186
        CHECK_BLOCKS("ref2", p2, 1);
 
187
        CHECK_BLOCKS("ref2", r1, 1);
 
188
 
 
189
        fprintf(stderr, "Freeing p2\n");
 
190
        talloc_free(p2);
 
191
        talloc_report_full(root, stderr);
 
192
 
 
193
        CHECK_BLOCKS("ref2", p1, 4);
 
194
        CHECK_BLOCKS("ref2", r1, 1);
 
195
 
 
196
        fprintf(stderr, "Freeing p1\n");
 
197
        talloc_free(p1);
 
198
        talloc_report_full(root, stderr);
 
199
 
 
200
        CHECK_BLOCKS("ref2", r1, 1);
 
201
 
 
202
        fprintf(stderr, "Freeing r1\n");
 
203
        talloc_free(r1);
 
204
        talloc_report_full(root, stderr);
 
205
 
 
206
        CHECK_SIZE("ref2", root, 0);
 
207
 
 
208
        talloc_free(root);
 
209
        printf("success: ref2\n");
 
210
        return true;
 
211
}
 
212
 
 
213
/*
 
214
  test references 
 
215
*/
 
216
static bool test_ref3(void)
 
217
{
 
218
        void *root, *p1, *p2, *ref, *r1;
 
219
 
 
220
        printf("test: ref3 [\nPARENT REFERENCE FREE\n]\n");
 
221
 
 
222
        root = talloc_named_const(NULL, 0, "root");
 
223
        p1 = talloc_named_const(root, 1, "p1");
 
224
        p2 = talloc_named_const(root, 1, "p2");
 
225
        r1 = talloc_named_const(p1, 1, "r1");
 
226
        ref = talloc_reference(p2, r1);
 
227
        talloc_report_full(root, stderr);
 
228
 
 
229
        CHECK_BLOCKS("ref3", p1, 2);
 
230
        CHECK_BLOCKS("ref3", p2, 2);
 
231
        CHECK_BLOCKS("ref3", r1, 1);
 
232
 
 
233
        fprintf(stderr, "Freeing p1\n");
 
234
        talloc_free(p1);
 
235
        talloc_report_full(root, stderr);
 
236
 
 
237
        CHECK_BLOCKS("ref3", p2, 2);
 
238
        CHECK_BLOCKS("ref3", r1, 1);
 
239
 
 
240
        fprintf(stderr, "Freeing p2\n");
 
241
        talloc_free(p2);
 
242
        talloc_report_full(root, stderr);
 
243
 
 
244
        CHECK_SIZE("ref3", root, 0);
 
245
 
 
246
        talloc_free(root);
 
247
 
 
248
        printf("success: ref3\n");
 
249
        return true;
 
250
}
 
251
 
 
252
/*
 
253
  test references 
 
254
*/
 
255
static bool test_ref4(void)
 
256
{
 
257
        void *root, *p1, *p2, *ref, *r1;
 
258
 
 
259
        printf("test: ref4 [\nREFERRER REFERENCE FREE\n]\n");
 
260
 
 
261
        root = talloc_named_const(NULL, 0, "root");
 
262
        p1 = talloc_named_const(root, 1, "p1");
 
263
        talloc_named_const(p1, 1, "x1");
 
264
        talloc_named_const(p1, 1, "x2");
 
265
        talloc_named_const(p1, 1, "x3");
 
266
        p2 = talloc_named_const(p1, 1, "p2");
 
267
 
 
268
        r1 = talloc_named_const(root, 1, "r1"); 
 
269
        ref = talloc_reference(r1, p2);
 
270
        talloc_report_full(root, stderr);
 
271
 
 
272
        CHECK_BLOCKS("ref4", p1, 5);
 
273
        CHECK_BLOCKS("ref4", p2, 1);
 
274
        CHECK_BLOCKS("ref4", r1, 2);
 
275
 
 
276
        fprintf(stderr, "Freeing r1\n");
 
277
        talloc_free(r1);
 
278
        talloc_report_full(root, stderr);
 
279
 
 
280
        CHECK_BLOCKS("ref4", p1, 5);
 
281
        CHECK_BLOCKS("ref4", p2, 1);
 
282
 
 
283
        fprintf(stderr, "Freeing p2\n");
 
284
        talloc_free(p2);
 
285
        talloc_report_full(root, stderr);
 
286
 
 
287
        CHECK_BLOCKS("ref4", p1, 4);
 
288
 
 
289
        fprintf(stderr, "Freeing p1\n");
 
290
        talloc_free(p1);
 
291
        talloc_report_full(root, stderr);
 
292
 
 
293
        CHECK_SIZE("ref4", root, 0);
 
294
 
 
295
        talloc_free(root);
 
296
 
 
297
        printf("success: ref4\n");
 
298
        return true;
 
299
}
 
300
 
 
301
 
 
302
/*
 
303
  test references 
 
304
*/
 
305
static bool test_unlink1(void)
 
306
{
 
307
        void *root, *p1, *p2, *ref, *r1;
 
308
 
 
309
        printf("test: unlink [\nUNLINK\n]\n");
 
310
 
 
311
        root = talloc_named_const(NULL, 0, "root");
 
312
        p1 = talloc_named_const(root, 1, "p1");
 
313
        talloc_named_const(p1, 1, "x1");
 
314
        talloc_named_const(p1, 1, "x2");
 
315
        talloc_named_const(p1, 1, "x3");
 
316
        p2 = talloc_named_const(p1, 1, "p2");
 
317
 
 
318
        r1 = talloc_named_const(p1, 1, "r1");   
 
319
        ref = talloc_reference(r1, p2);
 
320
        talloc_report_full(root, stderr);
 
321
 
 
322
        CHECK_BLOCKS("unlink", p1, 7);
 
323
        CHECK_BLOCKS("unlink", p2, 1);
 
324
        CHECK_BLOCKS("unlink", r1, 2);
 
325
 
 
326
        fprintf(stderr, "Unreferencing r1\n");
 
327
        talloc_unlink(r1, p2);
 
328
        talloc_report_full(root, stderr);
 
329
 
 
330
        CHECK_BLOCKS("unlink", p1, 6);
 
331
        CHECK_BLOCKS("unlink", p2, 1);
 
332
        CHECK_BLOCKS("unlink", r1, 1);
 
333
 
 
334
        fprintf(stderr, "Freeing p1\n");
 
335
        talloc_free(p1);
 
336
        talloc_report_full(root, stderr);
 
337
 
 
338
        CHECK_SIZE("unlink", root, 0);
 
339
 
 
340
        talloc_free(root);
 
341
 
 
342
        printf("success: unlink\n");
 
343
        return true;
 
344
}
 
345
 
 
346
static int fail_destructor(void *ptr)
 
347
{
 
348
        return -1;
 
349
}
 
350
 
 
351
/*
 
352
  miscellaneous tests to try to get a higher test coverage percentage
 
353
*/
 
354
static bool test_misc(void)
 
355
{
 
356
        void *root, *p1;
 
357
        char *p2;
 
358
        double *d;
 
359
        const char *name;
 
360
 
 
361
        printf("test: misc [\nMISCELLANEOUS\n]\n");
 
362
 
 
363
        root = talloc_new(NULL);
 
364
 
 
365
        p1 = talloc_size(root, 0x7fffffff);
 
366
        torture_assert("misc", !p1, "failed: large talloc allowed\n");
 
367
 
 
368
        p1 = talloc_strdup(root, "foo");
 
369
        talloc_increase_ref_count(p1);
 
370
        talloc_increase_ref_count(p1);
 
371
        talloc_increase_ref_count(p1);
 
372
        CHECK_BLOCKS("misc", p1, 1);
 
373
        CHECK_BLOCKS("misc", root, 2);
 
374
        talloc_free(p1);
 
375
        CHECK_BLOCKS("misc", p1, 1);
 
376
        CHECK_BLOCKS("misc", root, 2);
 
377
        talloc_unlink(NULL, p1);
 
378
        CHECK_BLOCKS("misc", p1, 1);
 
379
        CHECK_BLOCKS("misc", root, 2);
 
380
        p2 = talloc_strdup(p1, "foo");
 
381
        torture_assert("misc", talloc_unlink(root, p2) == -1,
 
382
                                   "failed: talloc_unlink() of non-reference context should return -1\n");
 
383
        torture_assert("misc", talloc_unlink(p1, p2) == 0,
 
384
                "failed: talloc_unlink() of parent should succeed\n");
 
385
        talloc_free(p1);
 
386
        CHECK_BLOCKS("misc", p1, 1);
 
387
        CHECK_BLOCKS("misc", root, 2);
 
388
 
 
389
        name = talloc_set_name(p1, "my name is %s", "foo");
 
390
        torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo",
 
391
                "failed: wrong name after talloc_set_name(my name is foo)");
 
392
        CHECK_BLOCKS("misc", p1, 2);
 
393
        CHECK_BLOCKS("misc", root, 3);
 
394
 
 
395
        talloc_set_name_const(p1, NULL);
 
396
        torture_assert_str_equal ("misc", talloc_get_name(p1), "UNNAMED",
 
397
                "failed: wrong name after talloc_set_name(NULL)");
 
398
        CHECK_BLOCKS("misc", p1, 2);
 
399
        CHECK_BLOCKS("misc", root, 3);
 
400
 
 
401
        torture_assert("misc", talloc_free(NULL) == -1, 
 
402
                                   "talloc_free(NULL) should give -1\n");
 
403
 
 
404
        talloc_set_destructor(p1, fail_destructor);
 
405
        torture_assert("misc", talloc_free(p1) == -1, 
 
406
                "Failed destructor should cause talloc_free to fail\n");
 
407
        talloc_set_destructor(p1, NULL);
 
408
 
 
409
        talloc_report(root, stderr);
 
410
 
 
411
 
 
412
        p2 = (char *)talloc_zero_size(p1, 20);
 
413
        torture_assert("misc", p2[19] == 0, "Failed to give zero memory\n");
 
414
        talloc_free(p2);
 
415
 
 
416
        torture_assert("misc", talloc_strdup(root, NULL) == NULL,
 
417
                "failed: strdup on NULL should give NULL\n");
 
418
 
 
419
        p2 = talloc_strndup(p1, "foo", 2);
 
420
        torture_assert("misc", strcmp("fo", p2) == 0, 
 
421
                                   "strndup doesn't work\n");
 
422
        p2 = talloc_asprintf_append(p2, "o%c", 'd');
 
423
        torture_assert("misc", strcmp("food", p2) == 0, 
 
424
                                   "talloc_asprintf_append doesn't work\n");
 
425
        CHECK_BLOCKS("misc", p2, 1);
 
426
        CHECK_BLOCKS("misc", p1, 3);
 
427
 
 
428
        p2 = talloc_asprintf_append(NULL, "hello %s", "world");
 
429
        torture_assert("misc", strcmp("hello world", p2) == 0,
 
430
                "talloc_asprintf_append doesn't work\n");
 
431
        CHECK_BLOCKS("misc", p2, 1);
 
432
        CHECK_BLOCKS("misc", p1, 3);
 
433
        talloc_free(p2);
 
434
 
 
435
        d = talloc_array(p1, double, 0x20000000);
 
436
        torture_assert("misc", !d, "failed: integer overflow not detected\n");
 
437
 
 
438
        d = talloc_realloc(p1, d, double, 0x20000000);
 
439
        torture_assert("misc", !d, "failed: integer overflow not detected\n");
 
440
 
 
441
        talloc_free(p1);
 
442
        CHECK_BLOCKS("misc", root, 1);
 
443
 
 
444
        p1 = talloc_named(root, 100, "%d bytes", 100);
 
445
        CHECK_BLOCKS("misc", p1, 2);
 
446
        CHECK_BLOCKS("misc", root, 3);
 
447
        talloc_unlink(root, p1);
 
448
 
 
449
        p1 = talloc_init("%d bytes", 200);
 
450
        p2 = talloc_asprintf(p1, "my test '%s'", "string");
 
451
        torture_assert_str_equal("misc", p2, "my test 'string'",
 
452
                "failed: talloc_asprintf(\"my test '%%s'\", \"string\") gave: \"%s\"");
 
453
        CHECK_BLOCKS("misc", p1, 3);
 
454
        CHECK_SIZE("misc", p2, 17);
 
455
        CHECK_BLOCKS("misc", root, 1);
 
456
        talloc_unlink(NULL, p1);
 
457
 
 
458
        p1 = talloc_named_const(root, 10, "p1");
 
459
        p2 = (char *)talloc_named_const(root, 20, "p2");
 
460
        (void)talloc_reference(p1, p2);
 
461
        talloc_report_full(root, stderr);
 
462
        talloc_unlink(root, p2);
 
463
        talloc_report_full(root, stderr);
 
464
        CHECK_BLOCKS("misc", p2, 1);
 
465
        CHECK_BLOCKS("misc", p1, 2);
 
466
        CHECK_BLOCKS("misc", root, 3);
 
467
        talloc_unlink(p1, p2);
 
468
        talloc_unlink(root, p1);
 
469
 
 
470
        p1 = talloc_named_const(root, 10, "p1");
 
471
        p2 = (char *)talloc_named_const(root, 20, "p2");
 
472
        (void)talloc_reference(NULL, p2);
 
473
        talloc_report_full(root, stderr);
 
474
        talloc_unlink(root, p2);
 
475
        talloc_report_full(root, stderr);
 
476
        CHECK_BLOCKS("misc", p2, 1);
 
477
        CHECK_BLOCKS("misc", p1, 1);
 
478
        CHECK_BLOCKS("misc", root, 2);
 
479
        talloc_unlink(NULL, p2);
 
480
        talloc_unlink(root, p1);
 
481
 
 
482
        /* Test that talloc_unlink is a no-op */
 
483
 
 
484
        torture_assert("misc", talloc_unlink(root, NULL) == -1,
 
485
                "failed: talloc_unlink(root, NULL) == -1\n");
 
486
 
 
487
        talloc_report(root, stderr);
 
488
        talloc_report(NULL, stderr);
 
489
 
 
490
        CHECK_SIZE("misc", root, 0);
 
491
 
 
492
        talloc_free(root);
 
493
 
 
494
        CHECK_SIZE("misc", NULL, 0);
 
495
 
 
496
        talloc_enable_leak_report();
 
497
        talloc_enable_leak_report_full();
 
498
 
 
499
        printf("success: misc\n");
 
500
 
 
501
        return true;
 
502
}
 
503
 
 
504
 
 
505
/*
 
506
  test realloc
 
507
*/
 
508
static bool test_realloc(void)
 
509
{
 
510
        void *root, *p1, *p2;
 
511
 
 
512
        printf("test: realloc [\nREALLOC\n]\n");
 
513
 
 
514
        root = talloc_new(NULL);
 
515
 
 
516
        p1 = talloc_size(root, 10);
 
517
        CHECK_SIZE("realloc", p1, 10);
 
518
 
 
519
        p1 = talloc_realloc_size(NULL, p1, 20);
 
520
        CHECK_SIZE("realloc", p1, 20);
 
521
 
 
522
        talloc_new(p1);
 
523
 
 
524
        p2 = talloc_realloc_size(p1, NULL, 30);
 
525
 
 
526
        talloc_new(p1);
 
527
 
 
528
        p2 = talloc_realloc_size(p1, p2, 40);
 
529
 
 
530
        CHECK_SIZE("realloc", p2, 40);
 
531
        CHECK_SIZE("realloc", root, 60);
 
532
        CHECK_BLOCKS("realloc", p1, 4);
 
533
 
 
534
        p1 = talloc_realloc_size(NULL, p1, 20);
 
535
        CHECK_SIZE("realloc", p1, 60);
 
536
 
 
537
        talloc_increase_ref_count(p2);
 
538
        torture_assert("realloc", talloc_realloc_size(NULL, p2, 5) == NULL,
 
539
                "failed: talloc_realloc() on a referenced pointer should fail\n");
 
540
        CHECK_BLOCKS("realloc", p1, 4);
 
541
 
 
542
        talloc_realloc_size(NULL, p2, 0);
 
543
        talloc_realloc_size(NULL, p2, 0);
 
544
        CHECK_BLOCKS("realloc", p1, 3);
 
545
 
 
546
        torture_assert("realloc", talloc_realloc_size(NULL, p1, 0x7fffffff) == NULL,
 
547
                "failed: oversize talloc should fail\n");
 
548
 
 
549
        talloc_realloc_size(NULL, p1, 0);
 
550
 
 
551
        CHECK_BLOCKS("realloc", root, 1);
 
552
        CHECK_SIZE("realloc", root, 0);
 
553
 
 
554
        talloc_free(root);
 
555
 
 
556
        printf("success: REALLOC\n");
 
557
 
 
558
        return true;
 
559
}
 
560
 
 
561
/*
 
562
  test realloc with a child
 
563
*/
 
564
static bool test_realloc_child(void)
 
565
{
 
566
        void *root;
 
567
        struct el2 {
 
568
                const char *name;
 
569
        } *el2; 
 
570
        struct el1 {
 
571
                int count;
 
572
                struct el2 **list, **list2, **list3;
 
573
        } *el1;
 
574
 
 
575
        printf("test: REALLOC WITH CHILD\n");
 
576
 
 
577
        root = talloc_new(NULL);
 
578
 
 
579
        el1 = talloc(root, struct el1);
 
580
        el1->list = talloc(el1, struct el2 *);
 
581
        el1->list[0] = talloc(el1->list, struct el2);
 
582
        el1->list[0]->name = talloc_strdup(el1->list[0], "testing");
 
583
 
 
584
        el1->list2 = talloc(el1, struct el2 *);
 
585
        el1->list2[0] = talloc(el1->list2, struct el2);
 
586
        el1->list2[0]->name = talloc_strdup(el1->list2[0], "testing2");
 
587
 
 
588
        el1->list3 = talloc(el1, struct el2 *);
 
589
        el1->list3[0] = talloc(el1->list3, struct el2);
 
590
        el1->list3[0]->name = talloc_strdup(el1->list3[0], "testing2");
 
591
        
 
592
        el2 = talloc(el1->list, struct el2);
 
593
        el2 = talloc(el1->list2, struct el2);
 
594
        el2 = talloc(el1->list3, struct el2);
 
595
 
 
596
        el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100);
 
597
        el1->list2 = talloc_realloc(el1, el1->list2, struct el2 *, 200);
 
598
        el1->list3 = talloc_realloc(el1, el1->list3, struct el2 *, 300);
 
599
 
 
600
        talloc_free(root);
 
601
 
 
602
        printf("success: REALLOC WITH CHILD\n");
 
603
        return true;
 
604
}
 
605
 
 
606
/*
 
607
  test type checking
 
608
*/
 
609
static bool test_type(void)
 
610
{
 
611
        void *root;
 
612
        struct el1 {
 
613
                int count;
 
614
        };
 
615
        struct el2 {
 
616
                int count;
 
617
        };
 
618
        struct el1 *el1;
 
619
 
 
620
        printf("test: type [\ntalloc type checking\n]\n");
 
621
 
 
622
        root = talloc_new(NULL);
 
623
 
 
624
        el1 = talloc(root, struct el1);
 
625
 
 
626
        el1->count = 1;
 
627
 
 
628
        torture_assert("type", talloc_get_type(el1, struct el1) == el1,
 
629
                "type check failed on el1\n");
 
630
        torture_assert("type", talloc_get_type(el1, struct el2) == NULL,
 
631
                "type check failed on el1 with el2\n");
 
632
        talloc_set_type(el1, struct el2);
 
633
        torture_assert("type", talloc_get_type(el1, struct el2) == (struct el2 *)el1,
 
634
                "type set failed on el1 with el2\n");
 
635
 
 
636
        talloc_free(root);
 
637
 
 
638
        printf("success: type\n");
 
639
        return true;
 
640
}
 
641
 
 
642
/*
 
643
  test steal
 
644
*/
 
645
static bool test_steal(void)
 
646
{
 
647
        void *root, *p1, *p2;
 
648
 
 
649
        printf("test: steal [\nSTEAL\n]\n");
 
650
 
 
651
        root = talloc_new(NULL);
 
652
 
 
653
        p1 = talloc_array(root, char, 10);
 
654
        CHECK_SIZE("steal", p1, 10);
 
655
 
 
656
        p2 = talloc_realloc(root, NULL, char, 20);
 
657
        CHECK_SIZE("steal", p1, 10);
 
658
        CHECK_SIZE("steal", root, 30);
 
659
 
 
660
        torture_assert("steal", talloc_steal(p1, NULL) == NULL,
 
661
                "failed: stealing NULL should give NULL\n");
 
662
 
 
663
        torture_assert("steal", talloc_steal(p1, p1) == p1,
 
664
                "failed: stealing to ourselves is a nop\n");
 
665
        CHECK_BLOCKS("steal", root, 3);
 
666
        CHECK_SIZE("steal", root, 30);
 
667
 
 
668
        talloc_steal(NULL, p1);
 
669
        talloc_steal(NULL, p2);
 
670
        CHECK_BLOCKS("steal", root, 1);
 
671
        CHECK_SIZE("steal", root, 0);
 
672
 
 
673
        talloc_free(p1);
 
674
        talloc_steal(root, p2);
 
675
        CHECK_BLOCKS("steal", root, 2);
 
676
        CHECK_SIZE("steal", root, 20);
 
677
        
 
678
        talloc_free(p2);
 
679
 
 
680
        CHECK_BLOCKS("steal", root, 1);
 
681
        CHECK_SIZE("steal", root, 0);
 
682
 
 
683
        talloc_free(root);
 
684
 
 
685
        p1 = talloc_size(NULL, 3);
 
686
        talloc_report_full(NULL, stderr);
 
687
        CHECK_SIZE("steal", NULL, 3);
 
688
        talloc_free(p1);
 
689
 
 
690
        printf("success: steal\n");
 
691
        return true;
 
692
}
 
693
 
 
694
/*
 
695
  test move
 
696
*/
 
697
static bool test_move(void)
 
698
{
 
699
        void *root;
 
700
        struct t_move {
 
701
                char *p;
 
702
                int *x;
 
703
        } *t1, *t2;
 
704
 
 
705
        printf("test: move [\nMOVE\n]\n");
 
706
 
 
707
        root = talloc_new(NULL);
 
708
 
 
709
        t1 = talloc(root, struct t_move);
 
710
        t2 = talloc(root, struct t_move);
 
711
        t1->p = talloc_strdup(t1, "foo");
 
712
        t1->x = talloc(t1, int);
 
713
        *t1->x = 42;
 
714
 
 
715
        t2->p = talloc_move(t2, &t1->p);
 
716
        t2->x = talloc_move(t2, &t1->x);
 
717
        torture_assert("move", t1->p == NULL && t1->x == NULL &&
 
718
            strcmp(t2->p, "foo") == 0 && *t2->x == 42,
 
719
                "talloc move failed");
 
720
 
 
721
        talloc_free(root);
 
722
 
 
723
        printf("success: move\n");
 
724
 
 
725
        return true;
 
726
}
 
727
 
 
728
/*
 
729
  test talloc_realloc_fn
 
730
*/
 
731
static bool test_realloc_fn(void)
 
732
{
 
733
        void *root, *p1;
 
734
 
 
735
        printf("test: realloc_fn [\ntalloc_realloc_fn\n]\n");
 
736
 
 
737
        root = talloc_new(NULL);
 
738
 
 
739
        p1 = talloc_realloc_fn(root, NULL, 10);
 
740
        CHECK_BLOCKS("realloc_fn", root, 2);
 
741
        CHECK_SIZE("realloc_fn", root, 10);
 
742
        p1 = talloc_realloc_fn(root, p1, 20);
 
743
        CHECK_BLOCKS("realloc_fn", root, 2);
 
744
        CHECK_SIZE("realloc_fn", root, 20);
 
745
        p1 = talloc_realloc_fn(root, p1, 0);
 
746
        CHECK_BLOCKS("realloc_fn", root, 1);
 
747
        CHECK_SIZE("realloc_fn", root, 0);
 
748
 
 
749
        talloc_free(root);
 
750
 
 
751
        printf("success: realloc_fn\n");
 
752
        return true;
 
753
}
 
754
 
 
755
 
 
756
static bool test_unref_reparent(void)
 
757
{
 
758
        void *root, *p1, *p2, *c1;
 
759
 
 
760
        printf("test: unref_reparent [\nUNREFERENCE AFTER PARENT FREED\n]\n");
 
761
 
 
762
        root = talloc_named_const(NULL, 0, "root");
 
763
        p1 = talloc_named_const(root, 1, "orig parent");
 
764
        p2 = talloc_named_const(root, 1, "parent by reference");
 
765
 
 
766
        c1 = talloc_named_const(p1, 1, "child");
 
767
        talloc_reference(p2, c1);
 
768
 
 
769
        CHECK_PARENT("unref_reparent", c1, p1);
 
770
 
 
771
        talloc_free(p1);
 
772
 
 
773
        CHECK_PARENT("unref_reparent", c1, p2);
 
774
 
 
775
        talloc_unlink(p2, c1);
 
776
 
 
777
        CHECK_SIZE("unref_reparent", root, 1);
 
778
 
 
779
        talloc_free(p2);
 
780
        talloc_free(root);
 
781
 
 
782
        printf("success: unref_reparent\n");
 
783
        return true;
 
784
}
 
785
 
 
786
/*
 
787
  measure the speed of talloc versus malloc
 
788
*/
 
789
static bool test_speed(void)
 
790
{
 
791
        void *ctx = talloc_new(NULL);
 
792
        unsigned count;
 
793
        const int loop = 1000;
 
794
        int i;
 
795
        struct timeval tv;
 
796
 
 
797
        printf("test: speed [\nTALLOC VS MALLOC SPEED\n]\n");
 
798
 
 
799
        tv = timeval_current();
 
800
        count = 0;
 
801
        do {
 
802
                void *p1, *p2, *p3;
 
803
                for (i=0;i<loop;i++) {
 
804
                        p1 = talloc_size(ctx, loop % 100);
 
805
                        p2 = talloc_strdup(p1, "foo bar");
 
806
                        p3 = talloc_size(p1, 300);
 
807
                        talloc_free(p1);
 
808
                }
 
809
                count += 3 * loop;
 
810
        } while (timeval_elapsed(&tv) < 5.0);
 
811
 
 
812
        fprintf(stderr, "talloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));
 
813
 
 
814
        talloc_free(ctx);
 
815
 
 
816
        tv = timeval_current();
 
817
        count = 0;
 
818
        do {
 
819
                void *p1, *p2, *p3;
 
820
                for (i=0;i<loop;i++) {
 
821
                        p1 = malloc(loop % 100);
 
822
                        p2 = strdup("foo bar");
 
823
                        p3 = malloc(300);
 
824
                        free(p1);
 
825
                        free(p2);
 
826
                        free(p3);
 
827
                }
 
828
                count += 3 * loop;
 
829
        } while (timeval_elapsed(&tv) < 5.0);
 
830
        fprintf(stderr, "malloc: %.0f ops/sec\n", count/timeval_elapsed(&tv));
 
831
 
 
832
        printf("success: speed\n");
 
833
 
 
834
        return true;
 
835
}
 
836
 
 
837
static bool test_lifeless(void)
 
838
{
 
839
        void *top = talloc_new(NULL);
 
840
        char *parent, *child; 
 
841
        void *child_owner = talloc_new(NULL);
 
842
 
 
843
        printf("test: lifeless [\nTALLOC_UNLINK LOOP\n]\n");
 
844
 
 
845
        parent = talloc_strdup(top, "parent");
 
846
        child = talloc_strdup(parent, "child");  
 
847
        (void)talloc_reference(child, parent);
 
848
        (void)talloc_reference(child_owner, child); 
 
849
        talloc_report_full(top, stderr);
 
850
        talloc_unlink(top, parent);
 
851
        talloc_free(child);
 
852
        talloc_report_full(top, stderr);
 
853
        talloc_free(top);
 
854
        talloc_free(child_owner);
 
855
        talloc_free(child);
 
856
 
 
857
        printf("success: lifeless\n");
 
858
        return true;
 
859
}
 
860
 
 
861
static int loop_destructor_count;
 
862
 
 
863
static int test_loop_destructor(char *ptr)
 
864
{
 
865
        loop_destructor_count++;
 
866
        return 0;
 
867
}
 
868
 
 
869
static bool test_loop(void)
 
870
{
 
871
        void *top = talloc_new(NULL);
 
872
        char *parent;
 
873
        struct req1 {
 
874
                char *req2, *req3;
 
875
        } *req1;
 
876
 
 
877
        printf("test: loop [\nTALLOC LOOP DESTRUCTION\n]\n");
 
878
 
 
879
        parent = talloc_strdup(top, "parent");
 
880
        req1 = talloc(parent, struct req1);
 
881
        req1->req2 = talloc_strdup(req1, "req2");  
 
882
        talloc_set_destructor(req1->req2, test_loop_destructor);
 
883
        req1->req3 = talloc_strdup(req1, "req3");
 
884
        (void)talloc_reference(req1->req3, req1);
 
885
        talloc_report_full(top, stderr);
 
886
        talloc_free(parent);
 
887
        talloc_report_full(top, stderr);
 
888
        talloc_report_full(NULL, stderr);
 
889
        talloc_free(top);
 
890
 
 
891
        torture_assert("loop", loop_destructor_count == 1, 
 
892
                                   "FAILED TO FIRE LOOP DESTRUCTOR\n");
 
893
        loop_destructor_count = 0;
 
894
 
 
895
        printf("success: loop\n");
 
896
        return true;
 
897
}
 
898
 
 
899
static int fail_destructor_str(char *ptr)
 
900
{
 
901
        return -1;
 
902
}
 
903
 
 
904
static bool test_free_parent_deny_child(void)
 
905
{
 
906
        void *top = talloc_new(NULL);
 
907
        char *level1;
 
908
        char *level2;
 
909
        char *level3;
 
910
 
 
911
        printf("test: free_parent_deny_child [\nTALLOC FREE PARENT DENY CHILD\n]\n");
 
912
 
 
913
        level1 = talloc_strdup(top, "level1");
 
914
        level2 = talloc_strdup(level1, "level2");
 
915
        level3 = talloc_strdup(level2, "level3");
 
916
 
 
917
        talloc_set_destructor(level3, fail_destructor_str);
 
918
        talloc_free(level1);
 
919
        talloc_set_destructor(level3, NULL);
 
920
 
 
921
        CHECK_PARENT("free_parent_deny_child", level3, top);
 
922
 
 
923
        talloc_free(top);
 
924
 
 
925
        printf("success: free_parent_deny_child\n");
 
926
        return true;
 
927
}
 
928
 
 
929
static bool test_talloc_ptrtype(void)
 
930
{
 
931
        void *top = talloc_new(NULL);
 
932
        struct struct1 {
 
933
                int foo;
 
934
                int bar;
 
935
        } *s1, *s2, **s3, ***s4;
 
936
        const char *location1;
 
937
        const char *location2;
 
938
        const char *location3;
 
939
        const char *location4;
 
940
 
 
941
        printf("test: ptrtype [\nTALLOC PTRTYPE\n]\n");
 
942
 
 
943
        s1 = talloc_ptrtype(top, s1);location1 = __location__;
 
944
 
 
945
        if (talloc_get_size(s1) != sizeof(struct struct1)) {
 
946
                printf("failure: ptrtype [\n"
 
947
                  "talloc_ptrtype() allocated the wrong size %lu (should be %lu)\n"
 
948
                  "]\n", (unsigned long)talloc_get_size(s1),
 
949
                           (unsigned long)sizeof(struct struct1));
 
950
                return false;
 
951
        }
 
952
 
 
953
        if (strcmp(location1, talloc_get_name(s1)) != 0) {
 
954
                printf("failure: ptrtype [\n"
 
955
                  "talloc_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n",
 
956
                        talloc_get_name(s1), location1);
 
957
                return false;
 
958
        }
 
959
 
 
960
        s2 = talloc_array_ptrtype(top, s2, 10);location2 = __location__;
 
961
 
 
962
        if (talloc_get_size(s2) != (sizeof(struct struct1) * 10)) {
 
963
                printf("failure: ptrtype [\n"
 
964
                           "talloc_array_ptrtype() allocated the wrong size "
 
965
                       "%lu (should be %lu)\n]\n",
 
966
                        (unsigned long)talloc_get_size(s2),
 
967
                    (unsigned long)(sizeof(struct struct1)*10));
 
968
                return false;
 
969
        }
 
970
 
 
971
        if (strcmp(location2, talloc_get_name(s2)) != 0) {
 
972
                printf("failure: ptrtype [\n"
 
973
                "talloc_array_ptrtype() sets the wrong name '%s' (should be '%s')\n]\n",
 
974
                        talloc_get_name(s2), location2);
 
975
                return false;
 
976
        }
 
977
 
 
978
        s3 = talloc_array_ptrtype(top, s3, 10);location3 = __location__;
 
979
 
 
980
        if (talloc_get_size(s3) != (sizeof(struct struct1 *) * 10)) {
 
981
                printf("failure: ptrtype [\n"
 
982
                           "talloc_array_ptrtype() allocated the wrong size "
 
983
                       "%lu (should be %lu)\n]\n",
 
984
                           (unsigned long)talloc_get_size(s3),
 
985
                       (unsigned long)(sizeof(struct struct1 *)*10));
 
986
                return false;
 
987
        }
 
988
 
 
989
        torture_assert_str_equal("ptrtype", location3, talloc_get_name(s3),
 
990
                "talloc_array_ptrtype() sets the wrong name");
 
991
 
 
992
        s4 = talloc_array_ptrtype(top, s4, 10);location4 = __location__;
 
993
 
 
994
        if (talloc_get_size(s4) != (sizeof(struct struct1 **) * 10)) {
 
995
                printf("failure: ptrtype [\n"
 
996
                      "talloc_array_ptrtype() allocated the wrong size "
 
997
                       "%lu (should be %lu)\n]\n",
 
998
                           (unsigned long)talloc_get_size(s4),
 
999
                       (unsigned long)(sizeof(struct struct1 **)*10));
 
1000
                return false;
 
1001
        }
 
1002
 
 
1003
        torture_assert_str_equal("ptrtype", location4, talloc_get_name(s4),
 
1004
                "talloc_array_ptrtype() sets the wrong name");
 
1005
 
 
1006
        talloc_free(top);
 
1007
 
 
1008
        printf("success: ptrtype\n");
 
1009
        return true;
 
1010
}
 
1011
 
 
1012
static int _test_talloc_free_in_destructor(void **ptr)
 
1013
{
 
1014
        talloc_free(*ptr);
 
1015
        return 0;
 
1016
}
 
1017
 
 
1018
static bool test_talloc_free_in_destructor(void)
 
1019
{
 
1020
        void *level0;
 
1021
        void *level1;
 
1022
        void *level2;
 
1023
        void *level3;
 
1024
        void *level4;
 
1025
        void **level5;
 
1026
 
 
1027
        printf("test: free_in_destructor [\nTALLOC FREE IN DESTRUCTOR\n]\n");
 
1028
 
 
1029
        level0 = talloc_new(NULL);
 
1030
        level1 = talloc_new(level0);
 
1031
        level2 = talloc_new(level1);
 
1032
        level3 = talloc_new(level2);
 
1033
        level4 = talloc_new(level3);
 
1034
        level5 = talloc(level4, void *);
 
1035
 
 
1036
        *level5 = level3;
 
1037
        (void)talloc_reference(level0, level3);
 
1038
        (void)talloc_reference(level3, level3);
 
1039
        (void)talloc_reference(level5, level3);
 
1040
 
 
1041
        talloc_set_destructor(level5, _test_talloc_free_in_destructor);
 
1042
 
 
1043
        talloc_free(level1);
 
1044
 
 
1045
        talloc_free(level0);
 
1046
 
 
1047
        printf("success: free_in_destructor\n");
 
1048
        return true;
 
1049
}
 
1050
 
 
1051
static bool test_autofree(void)
 
1052
{
 
1053
#if _SAMBA_BUILD_ < 4
 
1054
        /* autofree test would kill smbtorture */
 
1055
        void *p;
 
1056
        printf("test: autofree [\nTALLOC AUTOFREE CONTEXT\n]\n");
 
1057
 
 
1058
        p = talloc_autofree_context();
 
1059
        talloc_free(p);
 
1060
 
 
1061
        p = talloc_autofree_context();
 
1062
        talloc_free(p);
 
1063
 
 
1064
        printf("success: autofree\n");
 
1065
#endif
 
1066
        return true;
 
1067
}
 
1068
 
 
1069
struct torture_context;
 
1070
bool torture_local_talloc(struct torture_context *tctx)
 
1071
{
 
1072
        bool ret = true;
 
1073
 
 
1074
        setlinebuf(stdout);
 
1075
 
 
1076
        talloc_disable_null_tracking();
 
1077
        talloc_enable_null_tracking();
 
1078
 
 
1079
        ret &= test_ref1();
 
1080
        ret &= test_ref2();
 
1081
        ret &= test_ref3();
 
1082
        ret &= test_ref4();
 
1083
        ret &= test_unlink1(); 
 
1084
        ret &= test_misc();
 
1085
        ret &= test_realloc();
 
1086
        ret &= test_realloc_child(); 
 
1087
        ret &= test_steal(); 
 
1088
        ret &= test_move(); 
 
1089
        ret &= test_unref_reparent();
 
1090
        ret &= test_realloc_fn(); 
 
1091
        ret &= test_type();
 
1092
        ret &= test_lifeless(); 
 
1093
        ret &= test_loop();
 
1094
        ret &= test_free_parent_deny_child(); 
 
1095
        ret &= test_talloc_ptrtype();
 
1096
        ret &= test_talloc_free_in_destructor();
 
1097
 
 
1098
        if (ret) {
 
1099
                ret &= test_speed();
 
1100
        }
 
1101
        ret &= test_autofree();
 
1102
 
 
1103
        return ret;
 
1104
}
 
1105
 
 
1106
#if _SAMBA_BUILD_ < 4
 
1107
int main(void)
 
1108
{
 
1109
        bool ret = torture_local_talloc(NULL);
 
1110
        if (!ret)
 
1111
                return -1;
 
1112
        return 0;
 
1113
}
 
1114
#endif