test_namestore_api_zone_iteration_stop.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2009 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file namestore/test_namestore_api_zone_iteration_stop.c
  18. * @brief testcase for zone iteration functionality: stop iterating of zones
  19. */
  20. #include "platform.h"
  21. #include "gnunet_namestore_service.h"
  22. #include "gnunet_testing_lib.h"
  23. #include "namestore.h"
  24. #include "gnunet_dnsparser_lib.h"
  25. #define TEST_RECORD_TYPE GNUNET_DNSPARSER_TYPE_TXT
  26. #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 100)
  27. #define WAIT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2)
  28. static struct GNUNET_NAMESTORE_Handle *nsh;
  29. static struct GNUNET_IDENTITY_PrivateKey privkey;
  30. static struct GNUNET_IDENTITY_PrivateKey privkey2;
  31. static struct GNUNET_NAMESTORE_ZoneIterator *zi;
  32. static int res;
  33. static int returned_records;
  34. static char *s_name_1;
  35. static struct GNUNET_GNSRECORD_Data *s_rd_1;
  36. static char *s_name_2;
  37. static struct GNUNET_GNSRECORD_Data *s_rd_2;
  38. static char *s_name_3;
  39. static struct GNUNET_GNSRECORD_Data *s_rd_3;
  40. /**
  41. * Re-establish the connection to the service.
  42. *
  43. * @param cls handle to use to re-connect.
  44. */
  45. static void
  46. end (void *cls)
  47. {
  48. if (NULL != zi)
  49. {
  50. GNUNET_NAMESTORE_zone_iteration_stop (zi);
  51. zi = NULL;
  52. }
  53. if (nsh != NULL)
  54. {
  55. GNUNET_NAMESTORE_disconnect (nsh);
  56. nsh = NULL;
  57. }
  58. GNUNET_free (s_name_1);
  59. GNUNET_free (s_name_2);
  60. GNUNET_free (s_name_3);
  61. if (s_rd_1 != NULL)
  62. {
  63. GNUNET_free_nz ((void *) s_rd_1->data);
  64. GNUNET_free (s_rd_1);
  65. }
  66. if (s_rd_2 != NULL)
  67. {
  68. GNUNET_free_nz ((void *) s_rd_2->data);
  69. GNUNET_free (s_rd_2);
  70. }
  71. if (s_rd_3 != NULL)
  72. {
  73. GNUNET_free_nz ((void *) s_rd_3->data);
  74. GNUNET_free (s_rd_3);
  75. }
  76. }
  77. static void
  78. delayed_end (void *cls)
  79. {
  80. GNUNET_SCHEDULER_shutdown ();
  81. }
  82. static void
  83. fail_cb (void *cls)
  84. {
  85. GNUNET_assert (0);
  86. }
  87. static void
  88. zone_proc (void *cls,
  89. const struct GNUNET_IDENTITY_PrivateKey *zone,
  90. const char *label,
  91. unsigned int rd_count,
  92. const struct GNUNET_GNSRECORD_Data *rd)
  93. {
  94. int failed = GNUNET_NO;
  95. GNUNET_assert (NULL != zone);
  96. if (0 == GNUNET_memcmp (zone, &privkey))
  97. {
  98. if (0 == strcmp (label, s_name_1))
  99. {
  100. if (rd_count == 1)
  101. {
  102. if (GNUNET_YES != GNUNET_GNSRECORD_records_cmp (rd, s_rd_1))
  103. {
  104. failed = GNUNET_YES;
  105. GNUNET_break (0);
  106. }
  107. }
  108. else
  109. {
  110. failed = GNUNET_YES;
  111. GNUNET_break (0);
  112. }
  113. }
  114. else if (0 == strcmp (label, s_name_2))
  115. {
  116. if (rd_count == 1)
  117. {
  118. if (GNUNET_YES != GNUNET_GNSRECORD_records_cmp (rd, s_rd_2))
  119. {
  120. failed = GNUNET_YES;
  121. GNUNET_break (0);
  122. }
  123. }
  124. else
  125. {
  126. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  127. "Received invalid record count\n");
  128. failed = GNUNET_YES;
  129. GNUNET_break (0);
  130. }
  131. }
  132. else
  133. {
  134. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  135. "Comparing result failed: got name `%s' for first zone\n",
  136. label);
  137. failed = GNUNET_YES;
  138. GNUNET_break (0);
  139. }
  140. }
  141. else if (0 == GNUNET_memcmp (zone, &privkey2))
  142. {
  143. if (0 == strcmp (label, s_name_3))
  144. {
  145. if (rd_count == 1)
  146. {
  147. if (GNUNET_YES != GNUNET_GNSRECORD_records_cmp (rd, s_rd_3))
  148. {
  149. failed = GNUNET_YES;
  150. GNUNET_break (0);
  151. }
  152. }
  153. else
  154. {
  155. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  156. "Received invalid record count\n");
  157. failed = GNUNET_YES;
  158. GNUNET_break (0);
  159. }
  160. }
  161. else
  162. {
  163. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  164. "Comparing result failed: got name `%s' for first zone\n",
  165. label);
  166. failed = GNUNET_YES;
  167. GNUNET_break (0);
  168. }
  169. }
  170. else
  171. {
  172. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  173. "Received invalid zone\n");
  174. failed = GNUNET_YES;
  175. GNUNET_break (0);
  176. }
  177. if (failed == GNUNET_NO)
  178. {
  179. if (1 == returned_records)
  180. {
  181. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  182. "Telling namestore to stop zone iteration\n");
  183. GNUNET_NAMESTORE_zone_iteration_stop (zi);
  184. zi = NULL;
  185. res = 0;
  186. GNUNET_SCHEDULER_add_delayed (WAIT,
  187. &delayed_end,
  188. NULL);
  189. return;
  190. }
  191. returned_records++;
  192. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  193. "Telling namestore to send the next result\n");
  194. GNUNET_NAMESTORE_zone_iterator_next (zi,
  195. 1);
  196. }
  197. else
  198. {
  199. GNUNET_break (0);
  200. GNUNET_SCHEDULER_shutdown ();
  201. }
  202. }
  203. static void
  204. zone_proc_end (void *cls)
  205. {
  206. GNUNET_break (1 <= returned_records);
  207. if (1 >= returned_records)
  208. res = 1; /* Last iteraterator callback, we are done */
  209. else
  210. res = 0;
  211. zi = NULL;
  212. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  213. "Received last result, iteration done after receing %u results\n",
  214. returned_records);
  215. GNUNET_SCHEDULER_add_now (&end, NULL);
  216. }
  217. static void
  218. put_cont (void *cls, int32_t success, const char *emsg)
  219. {
  220. static int c = 0;
  221. if (success == GNUNET_OK)
  222. {
  223. c++;
  224. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created record %u \n", c);
  225. }
  226. else
  227. {
  228. GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to created records: `%s'\n",
  229. emsg);
  230. GNUNET_break (0);
  231. GNUNET_SCHEDULER_shutdown ();
  232. return;
  233. }
  234. if (c == 3)
  235. {
  236. res = 1;
  237. returned_records = 0;
  238. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  239. "All records created, starting iteration over all zones \n");
  240. zi = GNUNET_NAMESTORE_zone_iteration_start (nsh,
  241. NULL,
  242. &fail_cb,
  243. NULL,
  244. &zone_proc,
  245. NULL,
  246. &zone_proc_end,
  247. NULL);
  248. if (zi == NULL)
  249. {
  250. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  251. "Failed to create zone iterator\n");
  252. GNUNET_break (0);
  253. GNUNET_SCHEDULER_shutdown ();
  254. return;
  255. }
  256. }
  257. }
  258. static struct GNUNET_GNSRECORD_Data *
  259. create_record (unsigned int count)
  260. {
  261. struct GNUNET_GNSRECORD_Data *rd;
  262. rd = GNUNET_new_array (count,
  263. struct GNUNET_GNSRECORD_Data);
  264. for (unsigned int c = 0; c < count; c++)
  265. {
  266. rd[c].expiration_time = GNUNET_TIME_relative_to_absolute (
  267. GNUNET_TIME_UNIT_HOURS).abs_value_us;
  268. rd[c].record_type = TEST_RECORD_TYPE;
  269. rd[c].data_size = 50;
  270. rd[c].data = GNUNET_malloc (50);
  271. rd[c].flags = 0;
  272. memset ((char *) rd[c].data, 'a', 50);
  273. }
  274. return rd;
  275. }
  276. /**
  277. * Callback called from the zone iterator when we iterate over
  278. * the empty zone. Check that we got no records and then
  279. * start the actual tests by filling the zone.
  280. */
  281. static void
  282. empty_zone_proc (void *cls,
  283. const struct GNUNET_IDENTITY_PrivateKey *zone,
  284. const char *label,
  285. unsigned int rd_count,
  286. const struct GNUNET_GNSRECORD_Data *rd)
  287. {
  288. GNUNET_assert (nsh == cls);
  289. if (NULL != zone)
  290. {
  291. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  292. _ ("Expected empty zone but received zone private key\n"));
  293. GNUNET_break (0);
  294. GNUNET_SCHEDULER_shutdown ();
  295. return;
  296. }
  297. if ((NULL != label) || (NULL != rd) || (0 != rd_count))
  298. {
  299. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  300. _ ("Expected no zone content but received data\n"));
  301. GNUNET_break (0);
  302. GNUNET_SCHEDULER_shutdown ();
  303. return;
  304. }
  305. GNUNET_assert (0);
  306. }
  307. static void
  308. empty_zone_proc_end (void *cls)
  309. {
  310. GNUNET_assert (nsh == cls);
  311. zi = NULL;
  312. privkey.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
  313. privkey2.type = htonl (GNUNET_GNSRECORD_TYPE_PKEY);
  314. GNUNET_CRYPTO_ecdsa_key_create (&privkey.ecdsa_key);
  315. GNUNET_CRYPTO_ecdsa_key_create (&privkey2.ecdsa_key);
  316. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  317. "Created record 1\n");
  318. GNUNET_asprintf (&s_name_1,
  319. "dummy1");
  320. s_rd_1 = create_record (1);
  321. GNUNET_NAMESTORE_records_store (nsh,
  322. &privkey, s_name_1,
  323. 1, s_rd_1, &put_cont, NULL);
  324. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  325. "Created record 2 \n");
  326. GNUNET_asprintf (&s_name_2,
  327. "dummy2");
  328. s_rd_2 = create_record (1);
  329. GNUNET_NAMESTORE_records_store (nsh,
  330. &privkey,
  331. s_name_2,
  332. 1,
  333. s_rd_2,
  334. &put_cont, NULL);
  335. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  336. "Created record 3\n");
  337. /* name in different zone */
  338. GNUNET_asprintf (&s_name_3, "dummy3");
  339. s_rd_3 = create_record (1);
  340. GNUNET_NAMESTORE_records_store (nsh,
  341. &privkey2,
  342. s_name_3,
  343. 1,
  344. s_rd_3,
  345. &put_cont, NULL);
  346. }
  347. static void
  348. run (void *cls,
  349. const struct GNUNET_CONFIGURATION_Handle *cfg,
  350. struct GNUNET_TESTING_Peer *peer)
  351. {
  352. nsh = GNUNET_NAMESTORE_connect (cfg);
  353. GNUNET_break (NULL != nsh);
  354. GNUNET_SCHEDULER_add_shutdown (&end,
  355. NULL);
  356. /* first, iterate over empty namestore */
  357. zi = GNUNET_NAMESTORE_zone_iteration_start (nsh,
  358. NULL,
  359. &fail_cb,
  360. NULL,
  361. &empty_zone_proc,
  362. nsh,
  363. &empty_zone_proc_end,
  364. nsh);
  365. if (NULL == zi)
  366. {
  367. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  368. "Failed to create zone iterator\n");
  369. GNUNET_break (0);
  370. GNUNET_SCHEDULER_shutdown ();
  371. }
  372. }
  373. #include "test_common.c"
  374. int
  375. main (int argc, char *argv[])
  376. {
  377. const char *plugin_name;
  378. char *cfg_name;
  379. SETUP_CFG (plugin_name, cfg_name);
  380. res = 1;
  381. if (0 !=
  382. GNUNET_TESTING_peer_run ("test-namestore-api-zone-iteration-stop",
  383. cfg_name,
  384. &run,
  385. NULL))
  386. {
  387. res = 1;
  388. }
  389. GNUNET_DISK_purge_cfg_dir (cfg_name,
  390. "GNUNET_TEST_HOME");
  391. GNUNET_free (cfg_name);
  392. return res;
  393. }
  394. /* end of test_namestore_api_zone_iteration_stop.c */