testsuite.c 26 KB

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