testsuite.c 26 KB

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