run.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871
  1. /*
  2. Unix SMB/CIFS implementation.
  3. local testing of talloc routines.
  4. Copyright (C) Andrew Tridgell 2004
  5. Converted to ccan tests by Rusty Russell 2008
  6. ** NOTE! The following LGPL license applies to the talloc
  7. ** library. This does NOT imply that all of Samba is released
  8. ** under the LGPL
  9. This library is free software; you can redistribute it and/or
  10. modify it under the terms of the GNU Lesser General Public
  11. License as published by the Free Software Foundation; either
  12. version 2 of the License, or (at your option) any later version.
  13. This library 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 GNU
  16. Lesser General Public License for more details.
  17. You should have received a copy of the GNU Lesser General Public
  18. License along with this library; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. */
  21. #include "talloc/talloc.c"
  22. #include <stdbool.h>
  23. #include "tap/tap.h"
  24. #define torture_assert(test, expr, str) \
  25. ok(expr, "failure: %s [\n%s: Expression %s failed: %s\n]\n", \
  26. test, __location__, #expr, str)
  27. #define torture_assert_str_equal(test, arg1, arg2, desc) \
  28. ok(strcmp(arg1, arg2) == 0, \
  29. "failure: %s [\n%s: Expected %s, got %s: %s\n]\n", \
  30. test, __location__, arg1, arg2, desc)
  31. #define CHECK_SIZE(test, ptr, tsize) \
  32. ok(talloc_total_size(ptr) == (tsize), \
  33. "failed: %s [\nwrong '%s' tree size: got %u expected %u\n]\n", \
  34. test, #ptr, \
  35. (unsigned)talloc_total_size(ptr), \
  36. (unsigned)tsize)
  37. #define CHECK_BLOCKS(test, ptr, tblocks) \
  38. ok(talloc_total_blocks(ptr) == (tblocks), \
  39. "failed: %s [\nwrong '%s' tree blocks: got %u expected %u\n]\n", \
  40. test, #ptr, \
  41. (unsigned)talloc_total_blocks(ptr), \
  42. (unsigned)tblocks)
  43. #define CHECK_PARENT(test, ptr, parent) \
  44. ok(talloc_parent(ptr) == (parent), \
  45. "failed: %s [\n'%s' has wrong parent: got %p expected %p\n]\n", \
  46. test, #ptr, \
  47. talloc_parent(ptr), \
  48. (parent))
  49. /*
  50. test references
  51. */
  52. static bool test_ref1(void)
  53. {
  54. void *root, *p1, *p2, *ref, *r1;
  55. root = talloc_named_const(NULL, 0, "root");
  56. p1 = talloc_named_const(root, 1, "p1");
  57. p2 = talloc_named_const(p1, 1, "p2");
  58. talloc_named_const(p1, 1, "x1");
  59. talloc_named_const(p1, 2, "x2");
  60. talloc_named_const(p1, 3, "x3");
  61. r1 = talloc_named_const(root, 1, "r1");
  62. ref = talloc_reference(r1, p2);
  63. CHECK_BLOCKS("ref1", p1, 5);
  64. CHECK_BLOCKS("ref1", p2, 1);
  65. CHECK_BLOCKS("ref1", r1, 2);
  66. talloc_free(p2);
  67. CHECK_BLOCKS("ref1", p1, 5);
  68. CHECK_BLOCKS("ref1", p2, 1);
  69. CHECK_BLOCKS("ref1", r1, 1);
  70. talloc_free(p1);
  71. CHECK_BLOCKS("ref1", r1, 1);
  72. talloc_free(r1);
  73. if (talloc_reference(root, NULL)) {
  74. return false;
  75. }
  76. CHECK_BLOCKS("ref1", root, 1);
  77. CHECK_SIZE("ref1", root, 0);
  78. talloc_free(root);
  79. return true;
  80. }
  81. /*
  82. test references
  83. */
  84. static bool test_ref2(void)
  85. {
  86. void *root, *p1, *p2, *ref, *r1;
  87. root = talloc_named_const(NULL, 0, "root");
  88. p1 = talloc_named_const(root, 1, "p1");
  89. talloc_named_const(p1, 1, "x1");
  90. talloc_named_const(p1, 1, "x2");
  91. talloc_named_const(p1, 1, "x3");
  92. p2 = talloc_named_const(p1, 1, "p2");
  93. r1 = talloc_named_const(root, 1, "r1");
  94. ref = talloc_reference(r1, p2);
  95. CHECK_BLOCKS("ref2", p1, 5);
  96. CHECK_BLOCKS("ref2", p2, 1);
  97. CHECK_BLOCKS("ref2", r1, 2);
  98. talloc_free(ref);
  99. CHECK_BLOCKS("ref2", p1, 5);
  100. CHECK_BLOCKS("ref2", p2, 1);
  101. CHECK_BLOCKS("ref2", r1, 1);
  102. talloc_free(p2);
  103. CHECK_BLOCKS("ref2", p1, 4);
  104. CHECK_BLOCKS("ref2", r1, 1);
  105. talloc_free(p1);
  106. CHECK_BLOCKS("ref2", r1, 1);
  107. talloc_free(r1);
  108. CHECK_SIZE("ref2", root, 0);
  109. talloc_free(root);
  110. return true;
  111. }
  112. /*
  113. test references
  114. */
  115. static bool test_ref3(void)
  116. {
  117. void *root, *p1, *p2, *ref, *r1;
  118. root = talloc_named_const(NULL, 0, "root");
  119. p1 = talloc_named_const(root, 1, "p1");
  120. p2 = talloc_named_const(root, 1, "p2");
  121. r1 = talloc_named_const(p1, 1, "r1");
  122. ref = talloc_reference(p2, r1);
  123. CHECK_BLOCKS("ref3", p1, 2);
  124. CHECK_BLOCKS("ref3", p2, 2);
  125. CHECK_BLOCKS("ref3", r1, 1);
  126. talloc_free(p1);
  127. CHECK_BLOCKS("ref3", p2, 2);
  128. CHECK_BLOCKS("ref3", r1, 1);
  129. talloc_free(p2);
  130. CHECK_SIZE("ref3", root, 0);
  131. talloc_free(root);
  132. return true;
  133. }
  134. /*
  135. test references
  136. */
  137. static bool test_ref4(void)
  138. {
  139. void *root, *p1, *p2, *ref, *r1;
  140. root = talloc_named_const(NULL, 0, "root");
  141. p1 = talloc_named_const(root, 1, "p1");
  142. talloc_named_const(p1, 1, "x1");
  143. talloc_named_const(p1, 1, "x2");
  144. talloc_named_const(p1, 1, "x3");
  145. p2 = talloc_named_const(p1, 1, "p2");
  146. r1 = talloc_named_const(root, 1, "r1");
  147. ref = talloc_reference(r1, p2);
  148. CHECK_BLOCKS("ref4", p1, 5);
  149. CHECK_BLOCKS("ref4", p2, 1);
  150. CHECK_BLOCKS("ref4", r1, 2);
  151. talloc_free(r1);
  152. CHECK_BLOCKS("ref4", p1, 5);
  153. CHECK_BLOCKS("ref4", p2, 1);
  154. talloc_free(p2);
  155. CHECK_BLOCKS("ref4", p1, 4);
  156. talloc_free(p1);
  157. CHECK_SIZE("ref4", root, 0);
  158. talloc_free(root);
  159. return true;
  160. }
  161. /*
  162. test references
  163. */
  164. static bool test_unlink1(void)
  165. {
  166. void *root, *p1, *p2, *ref, *r1;
  167. root = talloc_named_const(NULL, 0, "root");
  168. p1 = talloc_named_const(root, 1, "p1");
  169. talloc_named_const(p1, 1, "x1");
  170. talloc_named_const(p1, 1, "x2");
  171. talloc_named_const(p1, 1, "x3");
  172. p2 = talloc_named_const(p1, 1, "p2");
  173. r1 = talloc_named_const(p1, 1, "r1");
  174. ref = talloc_reference(r1, p2);
  175. CHECK_BLOCKS("unlink", p1, 7);
  176. CHECK_BLOCKS("unlink", p2, 1);
  177. CHECK_BLOCKS("unlink", r1, 2);
  178. talloc_unlink(r1, p2);
  179. CHECK_BLOCKS("unlink", p1, 6);
  180. CHECK_BLOCKS("unlink", p2, 1);
  181. CHECK_BLOCKS("unlink", r1, 1);
  182. talloc_free(p1);
  183. CHECK_SIZE("unlink", root, 0);
  184. talloc_free(root);
  185. return true;
  186. }
  187. static int fail_destructor(void *ptr)
  188. {
  189. return -1;
  190. }
  191. /*
  192. miscellaneous tests to try to get a higher test coverage percentage
  193. */
  194. static bool test_misc(void)
  195. {
  196. void *root, *p1;
  197. char *p2;
  198. double *d;
  199. const char *name;
  200. root = talloc_new(NULL);
  201. p1 = talloc_size(root, 0x7fffffff);
  202. torture_assert("misc", !p1, "failed: large talloc allowed\n");
  203. p1 = talloc_strdup(root, "foo");
  204. talloc_increase_ref_count(p1);
  205. talloc_increase_ref_count(p1);
  206. talloc_increase_ref_count(p1);
  207. CHECK_BLOCKS("misc", p1, 1);
  208. CHECK_BLOCKS("misc", root, 2);
  209. talloc_free(p1);
  210. CHECK_BLOCKS("misc", p1, 1);
  211. CHECK_BLOCKS("misc", root, 2);
  212. talloc_unlink(NULL, p1);
  213. CHECK_BLOCKS("misc", p1, 1);
  214. CHECK_BLOCKS("misc", root, 2);
  215. p2 = talloc_strdup(p1, "foo");
  216. torture_assert("misc", talloc_unlink(root, p2) == -1,
  217. "failed: talloc_unlink() of non-reference context should return -1\n");
  218. torture_assert("misc", talloc_unlink(p1, p2) == 0,
  219. "failed: talloc_unlink() of parent should succeed\n");
  220. talloc_free(p1);
  221. CHECK_BLOCKS("misc", p1, 1);
  222. CHECK_BLOCKS("misc", root, 2);
  223. name = talloc_set_name(p1, "my name is %s", "foo");
  224. torture_assert_str_equal("misc", talloc_get_name(p1), "my name is foo",
  225. "failed: wrong name after talloc_set_name(my name is foo)");
  226. CHECK_BLOCKS("misc", p1, 2);
  227. CHECK_BLOCKS("misc", root, 3);
  228. talloc_set_name_const(p1, NULL);
  229. torture_assert_str_equal ("misc", talloc_get_name(p1), "UNNAMED",
  230. "failed: wrong name after talloc_set_name(NULL)");
  231. CHECK_BLOCKS("misc", p1, 2);
  232. CHECK_BLOCKS("misc", root, 3);
  233. torture_assert("misc", talloc_free(NULL) == -1,
  234. "talloc_free(NULL) should give -1\n");
  235. talloc_set_destructor(p1, fail_destructor);
  236. torture_assert("misc", talloc_free(p1) == -1,
  237. "Failed destructor should cause talloc_free to fail\n");
  238. talloc_set_destructor(p1, NULL);
  239. p2 = (char *)talloc_zero_size(p1, 20);
  240. torture_assert("misc", p2[19] == 0, "Failed to give zero memory\n");
  241. talloc_free(p2);
  242. torture_assert("misc", talloc_strdup(root, NULL) == NULL,
  243. "failed: strdup on NULL should give NULL\n");
  244. p2 = talloc_strndup(p1, "foo", 2);
  245. torture_assert("misc", strcmp("fo", p2) == 0,
  246. "strndup doesn't work\n");
  247. p2 = talloc_asprintf_append(p2, "o%c", 'd');
  248. torture_assert("misc", strcmp("food", p2) == 0,
  249. "talloc_asprintf_append doesn't work\n");
  250. CHECK_BLOCKS("misc", p2, 1);
  251. CHECK_BLOCKS("misc", p1, 3);
  252. p2 = talloc_asprintf_append(NULL, "hello %s", "world");
  253. torture_assert("misc", strcmp("hello world", p2) == 0,
  254. "talloc_asprintf_append doesn't work\n");
  255. CHECK_BLOCKS("misc", p2, 1);
  256. CHECK_BLOCKS("misc", p1, 3);
  257. talloc_free(p2);
  258. d = talloc_array(p1, double, 0x20000000);
  259. torture_assert("misc", !d, "failed: integer overflow not detected\n");
  260. d = talloc_realloc(p1, d, double, 0x20000000);
  261. torture_assert("misc", !d, "failed: integer overflow not detected\n");
  262. talloc_free(p1);
  263. CHECK_BLOCKS("misc", root, 1);
  264. p1 = talloc_named(root, 100, "%d bytes", 100);
  265. CHECK_BLOCKS("misc", p1, 2);
  266. CHECK_BLOCKS("misc", root, 3);
  267. talloc_unlink(root, p1);
  268. p1 = talloc_init("%d bytes", 200);
  269. p2 = talloc_asprintf(p1, "my test '%s'", "string");
  270. torture_assert_str_equal("misc", p2, "my test 'string'",
  271. "failed: talloc_asprintf(\"my test '%%s'\", \"string\") gave: \"%s\"");
  272. CHECK_BLOCKS("misc", p1, 3);
  273. CHECK_SIZE("misc", p2, 17);
  274. CHECK_BLOCKS("misc", root, 1);
  275. talloc_unlink(NULL, p1);
  276. p1 = talloc_named_const(root, 10, "p1");
  277. p2 = (char *)talloc_named_const(root, 20, "p2");
  278. (void)talloc_reference(p1, p2);
  279. talloc_unlink(root, p2);
  280. CHECK_BLOCKS("misc", p2, 1);
  281. CHECK_BLOCKS("misc", p1, 2);
  282. CHECK_BLOCKS("misc", root, 3);
  283. talloc_unlink(p1, p2);
  284. talloc_unlink(root, p1);
  285. p1 = talloc_named_const(root, 10, "p1");
  286. p2 = (char *)talloc_named_const(root, 20, "p2");
  287. (void)talloc_reference(NULL, p2);
  288. talloc_unlink(root, p2);
  289. CHECK_BLOCKS("misc", p2, 1);
  290. CHECK_BLOCKS("misc", p1, 1);
  291. CHECK_BLOCKS("misc", root, 2);
  292. talloc_unlink(NULL, p2);
  293. talloc_unlink(root, p1);
  294. /* Test that talloc_unlink is a no-op */
  295. torture_assert("misc", talloc_unlink(root, NULL) == -1,
  296. "failed: talloc_unlink(root, NULL) == -1\n");
  297. CHECK_SIZE("misc", root, 0);
  298. talloc_free(root);
  299. CHECK_SIZE("misc", NULL, 0);
  300. talloc_enable_leak_report();
  301. talloc_enable_leak_report_full();
  302. return true;
  303. }
  304. /*
  305. test realloc
  306. */
  307. static bool test_realloc(void)
  308. {
  309. void *root, *p1, *p2;
  310. root = talloc_new(NULL);
  311. p1 = talloc_size(root, 10);
  312. CHECK_SIZE("realloc", p1, 10);
  313. p1 = talloc_realloc_size(NULL, p1, 20);
  314. CHECK_SIZE("realloc", p1, 20);
  315. talloc_new(p1);
  316. p2 = talloc_realloc_size(p1, NULL, 30);
  317. talloc_new(p1);
  318. p2 = talloc_realloc_size(p1, p2, 40);
  319. CHECK_SIZE("realloc", p2, 40);
  320. CHECK_SIZE("realloc", root, 60);
  321. CHECK_BLOCKS("realloc", p1, 4);
  322. p1 = talloc_realloc_size(NULL, p1, 20);
  323. CHECK_SIZE("realloc", p1, 60);
  324. talloc_increase_ref_count(p2);
  325. torture_assert("realloc", talloc_realloc_size(NULL, p2, 5) == NULL,
  326. "failed: talloc_realloc() on a referenced pointer should fail\n");
  327. CHECK_BLOCKS("realloc", p1, 4);
  328. talloc_realloc_size(NULL, p2, 0);
  329. talloc_realloc_size(NULL, p2, 0);
  330. CHECK_BLOCKS("realloc", p1, 3);
  331. torture_assert("realloc", talloc_realloc_size(NULL, p1, 0x7fffffff) == NULL,
  332. "failed: oversize talloc should fail\n");
  333. talloc_realloc_size(NULL, p1, 0);
  334. CHECK_BLOCKS("realloc", root, 1);
  335. CHECK_SIZE("realloc", root, 0);
  336. talloc_free(root);
  337. return true;
  338. }
  339. /*
  340. test realloc with a child
  341. */
  342. static bool test_realloc_child(void)
  343. {
  344. void *root;
  345. struct el2 {
  346. const char *name;
  347. } *el2;
  348. struct el1 {
  349. int count;
  350. struct el2 **list, **list2, **list3;
  351. } *el1;
  352. root = talloc_new(NULL);
  353. el1 = talloc(root, struct el1);
  354. el1->list = talloc(el1, struct el2 *);
  355. el1->list[0] = talloc(el1->list, struct el2);
  356. el1->list[0]->name = talloc_strdup(el1->list[0], "testing");
  357. el1->list2 = talloc(el1, struct el2 *);
  358. el1->list2[0] = talloc(el1->list2, struct el2);
  359. el1->list2[0]->name = talloc_strdup(el1->list2[0], "testing2");
  360. el1->list3 = talloc(el1, struct el2 *);
  361. el1->list3[0] = talloc(el1->list3, struct el2);
  362. el1->list3[0]->name = talloc_strdup(el1->list3[0], "testing2");
  363. el2 = talloc(el1->list, struct el2);
  364. el2 = talloc(el1->list2, struct el2);
  365. el2 = talloc(el1->list3, struct el2);
  366. el1->list = talloc_realloc(el1, el1->list, struct el2 *, 100);
  367. el1->list2 = talloc_realloc(el1, el1->list2, struct el2 *, 200);
  368. el1->list3 = talloc_realloc(el1, el1->list3, struct el2 *, 300);
  369. talloc_free(root);
  370. return true;
  371. }
  372. /*
  373. test type checking
  374. */
  375. static bool test_type(void)
  376. {
  377. void *root;
  378. struct el1 {
  379. int count;
  380. };
  381. struct el2 {
  382. int count;
  383. };
  384. struct el1 *el1;
  385. root = talloc_new(NULL);
  386. el1 = talloc(root, struct el1);
  387. el1->count = 1;
  388. torture_assert("type", talloc_get_type(el1, struct el1) == el1,
  389. "type check failed on el1\n");
  390. torture_assert("type", talloc_get_type(el1, struct el2) == NULL,
  391. "type check failed on el1 with el2\n");
  392. talloc_set_type(el1, struct el2);
  393. torture_assert("type", talloc_get_type(el1, struct el2) == (struct el2 *)el1,
  394. "type set failed on el1 with el2\n");
  395. talloc_free(root);
  396. return true;
  397. }
  398. /*
  399. test steal
  400. */
  401. static bool test_steal(void)
  402. {
  403. void *root, *p1, *p2;
  404. root = talloc_new(NULL);
  405. p1 = talloc_array(root, char, 10);
  406. CHECK_SIZE("steal", p1, 10);
  407. p2 = talloc_realloc(root, NULL, char, 20);
  408. CHECK_SIZE("steal", p1, 10);
  409. CHECK_SIZE("steal", root, 30);
  410. torture_assert("steal", talloc_steal(p1, NULL) == NULL,
  411. "failed: stealing NULL should give NULL\n");
  412. torture_assert("steal", talloc_steal(p1, p1) == p1,
  413. "failed: stealing to ourselves is a nop\n");
  414. CHECK_BLOCKS("steal", root, 3);
  415. CHECK_SIZE("steal", root, 30);
  416. talloc_steal(NULL, p1);
  417. talloc_steal(NULL, p2);
  418. CHECK_BLOCKS("steal", root, 1);
  419. CHECK_SIZE("steal", root, 0);
  420. talloc_free(p1);
  421. talloc_steal(root, p2);
  422. CHECK_BLOCKS("steal", root, 2);
  423. CHECK_SIZE("steal", root, 20);
  424. talloc_free(p2);
  425. CHECK_BLOCKS("steal", root, 1);
  426. CHECK_SIZE("steal", root, 0);
  427. talloc_free(root);
  428. p1 = talloc_size(NULL, 3);
  429. CHECK_SIZE("steal", NULL, 3);
  430. talloc_free(p1);
  431. return true;
  432. }
  433. /*
  434. test move
  435. */
  436. static bool test_move(void)
  437. {
  438. void *root;
  439. struct t_move {
  440. char *p;
  441. int *x;
  442. } *t1, *t2;
  443. root = talloc_new(NULL);
  444. t1 = talloc(root, struct t_move);
  445. t2 = talloc(root, struct t_move);
  446. t1->p = talloc_strdup(t1, "foo");
  447. t1->x = talloc(t1, int);
  448. *t1->x = 42;
  449. t2->p = talloc_move(t2, &t1->p);
  450. t2->x = talloc_move(t2, &t1->x);
  451. torture_assert("move", t1->p == NULL && t1->x == NULL &&
  452. strcmp(t2->p, "foo") == 0 && *t2->x == 42,
  453. "talloc move failed");
  454. talloc_free(root);
  455. return true;
  456. }
  457. /*
  458. test talloc_realloc_fn
  459. */
  460. static bool test_realloc_fn(void)
  461. {
  462. void *root, *p1;
  463. root = talloc_new(NULL);
  464. p1 = talloc_realloc_fn(root, NULL, 10);
  465. CHECK_BLOCKS("realloc_fn", root, 2);
  466. CHECK_SIZE("realloc_fn", root, 10);
  467. p1 = talloc_realloc_fn(root, p1, 20);
  468. CHECK_BLOCKS("realloc_fn", root, 2);
  469. CHECK_SIZE("realloc_fn", root, 20);
  470. p1 = talloc_realloc_fn(root, p1, 0);
  471. CHECK_BLOCKS("realloc_fn", root, 1);
  472. CHECK_SIZE("realloc_fn", root, 0);
  473. talloc_free(root);
  474. return true;
  475. }
  476. static bool test_unref_reparent(void)
  477. {
  478. void *root, *p1, *p2, *c1;
  479. root = talloc_named_const(NULL, 0, "root");
  480. p1 = talloc_named_const(root, 1, "orig parent");
  481. p2 = talloc_named_const(root, 1, "parent by reference");
  482. c1 = talloc_named_const(p1, 1, "child");
  483. talloc_reference(p2, c1);
  484. CHECK_PARENT("unref_reparent", c1, p1);
  485. talloc_free(p1);
  486. CHECK_PARENT("unref_reparent", c1, p2);
  487. talloc_unlink(p2, c1);
  488. CHECK_SIZE("unref_reparent", root, 1);
  489. talloc_free(p2);
  490. talloc_free(root);
  491. return true;
  492. }
  493. static bool test_lifeless(void)
  494. {
  495. void *top = talloc_new(NULL);
  496. char *parent, *child;
  497. void *child_owner = talloc_new(NULL);
  498. parent = talloc_strdup(top, "parent");
  499. child = talloc_strdup(parent, "child");
  500. (void)talloc_reference(child, parent);
  501. (void)talloc_reference(child_owner, child);
  502. talloc_unlink(top, parent);
  503. talloc_free(child);
  504. talloc_free(top);
  505. talloc_free(child_owner);
  506. talloc_free(child);
  507. return true;
  508. }
  509. static int loop_destructor_count;
  510. static int test_loop_destructor(char *ptr)
  511. {
  512. loop_destructor_count++;
  513. return 0;
  514. }
  515. static bool test_loop(void)
  516. {
  517. void *top = talloc_new(NULL);
  518. char *parent;
  519. struct req1 {
  520. char *req2, *req3;
  521. } *req1;
  522. parent = talloc_strdup(top, "parent");
  523. req1 = talloc(parent, struct req1);
  524. req1->req2 = talloc_strdup(req1, "req2");
  525. talloc_set_destructor(req1->req2, test_loop_destructor);
  526. req1->req3 = talloc_strdup(req1, "req3");
  527. (void)talloc_reference(req1->req3, req1);
  528. talloc_free(parent);
  529. talloc_free(top);
  530. torture_assert("loop", loop_destructor_count == 1,
  531. "FAILED TO FIRE LOOP DESTRUCTOR\n");
  532. loop_destructor_count = 0;
  533. return true;
  534. }
  535. static int fail_destructor_str(char *ptr)
  536. {
  537. return -1;
  538. }
  539. static bool test_free_parent_deny_child(void)
  540. {
  541. void *top = talloc_new(NULL);
  542. char *level1;
  543. char *level2;
  544. char *level3;
  545. level1 = talloc_strdup(top, "level1");
  546. level2 = talloc_strdup(level1, "level2");
  547. level3 = talloc_strdup(level2, "level3");
  548. talloc_set_destructor(level3, fail_destructor_str);
  549. talloc_free(level1);
  550. talloc_set_destructor(level3, NULL);
  551. CHECK_PARENT("free_parent_deny_child", level3, top);
  552. talloc_free(top);
  553. return true;
  554. }
  555. static bool test_talloc_ptrtype(void)
  556. {
  557. void *top = talloc_new(NULL);
  558. struct struct1 {
  559. int foo;
  560. int bar;
  561. } *s1, *s2, **s3, ***s4;
  562. const char *location1;
  563. const char *location2;
  564. const char *location3;
  565. const char *location4;
  566. s1 = talloc_ptrtype(top, s1);location1 = __location__;
  567. ok1(talloc_get_size(s1) == sizeof(struct struct1));
  568. ok1(strcmp(location1, talloc_get_name(s1)) == 0);
  569. s2 = talloc_array_ptrtype(top, s2, 10);location2 = __location__;
  570. ok1(talloc_get_size(s2) == (sizeof(struct struct1) * 10));
  571. ok1(strcmp(location2, talloc_get_name(s2)) == 0);
  572. s3 = talloc_array_ptrtype(top, s3, 10);location3 = __location__;
  573. ok1(talloc_get_size(s3) == (sizeof(struct struct1 *) * 10));
  574. torture_assert_str_equal("ptrtype", location3, talloc_get_name(s3),
  575. "talloc_array_ptrtype() sets the wrong name");
  576. s4 = talloc_array_ptrtype(top, s4, 10);location4 = __location__;
  577. ok1(talloc_get_size(s4) == (sizeof(struct struct1 **) * 10));
  578. torture_assert_str_equal("ptrtype", location4, talloc_get_name(s4),
  579. "talloc_array_ptrtype() sets the wrong name");
  580. talloc_free(top);
  581. return true;
  582. }
  583. static int _test_talloc_free_in_destructor(void **ptr)
  584. {
  585. talloc_free(*ptr);
  586. return 0;
  587. }
  588. static bool test_talloc_free_in_destructor(void)
  589. {
  590. void *level0;
  591. void *level1;
  592. void *level2;
  593. void *level3;
  594. void *level4;
  595. void **level5;
  596. level0 = talloc_new(NULL);
  597. level1 = talloc_new(level0);
  598. level2 = talloc_new(level1);
  599. level3 = talloc_new(level2);
  600. level4 = talloc_new(level3);
  601. level5 = talloc(level4, void *);
  602. *level5 = level3;
  603. (void)talloc_reference(level0, level3);
  604. (void)talloc_reference(level3, level3);
  605. (void)talloc_reference(level5, level3);
  606. talloc_set_destructor(level5, _test_talloc_free_in_destructor);
  607. talloc_free(level1);
  608. talloc_free(level0);
  609. return true;
  610. }
  611. static bool test_autofree(void)
  612. {
  613. /* autofree test would kill smbtorture */
  614. void *p;
  615. p = talloc_autofree_context();
  616. talloc_free(p);
  617. p = talloc_autofree_context();
  618. talloc_free(p);
  619. return true;
  620. }
  621. struct torture_context;
  622. static bool torture_local_talloc(struct torture_context *tctx)
  623. {
  624. bool ret = true;
  625. setlinebuf(stdout);
  626. talloc_disable_null_tracking();
  627. talloc_enable_null_tracking();
  628. ret &= test_ref1();
  629. ret &= test_ref2();
  630. ret &= test_ref3();
  631. ret &= test_ref4();
  632. ret &= test_unlink1();
  633. ret &= test_misc();
  634. ret &= test_realloc();
  635. ret &= test_realloc_child();
  636. ret &= test_steal();
  637. ret &= test_move();
  638. ret &= test_unref_reparent();
  639. ret &= test_realloc_fn();
  640. ret &= test_type();
  641. ret &= test_lifeless();
  642. ret &= test_loop();
  643. ret &= test_free_parent_deny_child();
  644. ret &= test_talloc_ptrtype();
  645. ret &= test_talloc_free_in_destructor();
  646. ret &= test_autofree();
  647. return ret;
  648. }
  649. int main(void)
  650. {
  651. plan_tests(134);
  652. torture_local_talloc(NULL);
  653. return exit_status();
  654. }