test_setu_api.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2012 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 set/test_setu_api.c
  18. * @brief testcase for setu_api.c
  19. * @author Florian Dold
  20. */
  21. #include "platform.h"
  22. #include "gnunet_util_lib.h"
  23. #include "gnunet_testing_lib.h"
  24. #include "gnunet_setu_service.h"
  25. static struct GNUNET_PeerIdentity local_id;
  26. static struct GNUNET_HashCode app_id;
  27. static struct GNUNET_SETU_Handle *set1;
  28. static struct GNUNET_SETU_Handle *set2;
  29. static struct GNUNET_SETU_ListenHandle *listen_handle;
  30. static struct GNUNET_SETU_OperationHandle *oh1;
  31. static struct GNUNET_SETU_OperationHandle *oh2;
  32. static const struct GNUNET_CONFIGURATION_Handle *config;
  33. static int ret;
  34. static struct GNUNET_SCHEDULER_Task *tt;
  35. static void
  36. result_cb_set1 (void *cls,
  37. const struct GNUNET_SETU_Element *element,
  38. uint64_t size,
  39. enum GNUNET_SETU_Status status)
  40. {
  41. switch (status)
  42. {
  43. case GNUNET_SETU_STATUS_ADD_LOCAL:
  44. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "set 1: got element\n");
  45. break;
  46. case GNUNET_SETU_STATUS_FAILURE:
  47. GNUNET_break (0);
  48. oh1 = NULL;
  49. fprintf (stderr, "set 1: received failure status!\n");
  50. ret = 1;
  51. if (NULL != tt)
  52. {
  53. GNUNET_SCHEDULER_cancel (tt);
  54. tt = NULL;
  55. }
  56. GNUNET_SCHEDULER_shutdown ();
  57. break;
  58. case GNUNET_SETU_STATUS_DONE:
  59. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "set 1: done\n");
  60. oh1 = NULL;
  61. if (NULL != set1)
  62. {
  63. GNUNET_SETU_destroy (set1);
  64. set1 = NULL;
  65. }
  66. if (NULL == set2)
  67. {
  68. GNUNET_SCHEDULER_cancel (tt);
  69. tt = NULL;
  70. GNUNET_SCHEDULER_shutdown ();
  71. }
  72. break;
  73. default:
  74. GNUNET_assert (0);
  75. }
  76. }
  77. static void
  78. result_cb_set2 (void *cls,
  79. const struct GNUNET_SETU_Element *element,
  80. uint64_t size,
  81. enum GNUNET_SETU_Status status)
  82. {
  83. switch (status)
  84. {
  85. case GNUNET_SETU_STATUS_ADD_LOCAL:
  86. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "set 2: got element\n");
  87. break;
  88. case GNUNET_SETU_STATUS_FAILURE:
  89. GNUNET_break (0);
  90. oh2 = NULL;
  91. fprintf (stderr, "set 2: received failure status\n");
  92. GNUNET_SCHEDULER_shutdown ();
  93. ret = 1;
  94. break;
  95. case GNUNET_SETU_STATUS_DONE:
  96. oh2 = NULL;
  97. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "set 2: done\n");
  98. GNUNET_SETU_destroy (set2);
  99. set2 = NULL;
  100. if (NULL == set1)
  101. {
  102. GNUNET_SCHEDULER_cancel (tt);
  103. tt = NULL;
  104. GNUNET_SCHEDULER_shutdown ();
  105. }
  106. break;
  107. default:
  108. GNUNET_assert (0);
  109. }
  110. }
  111. static void
  112. listen_cb (void *cls,
  113. const struct GNUNET_PeerIdentity *other_peer,
  114. const struct GNUNET_MessageHeader *context_msg,
  115. struct GNUNET_SETU_Request *request)
  116. {
  117. GNUNET_assert (NULL != context_msg);
  118. GNUNET_assert (ntohs (context_msg->type) == GNUNET_MESSAGE_TYPE_DUMMY);
  119. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "listen cb called\n");
  120. oh2 = GNUNET_SETU_accept (request,
  121. (struct GNUNET_SETU_Option[]){ 0 },
  122. &result_cb_set2,
  123. NULL);
  124. GNUNET_SETU_commit (oh2, set2);
  125. }
  126. /**
  127. * Start the set operation.
  128. *
  129. * @param cls closure, unused
  130. */
  131. static void
  132. start (void *cls)
  133. {
  134. struct GNUNET_MessageHeader context_msg;
  135. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting reconciliation\n");
  136. context_msg.size = htons (sizeof context_msg);
  137. context_msg.type = htons (GNUNET_MESSAGE_TYPE_DUMMY);
  138. listen_handle = GNUNET_SETU_listen (config,
  139. &app_id,
  140. &listen_cb,
  141. NULL);
  142. oh1 = GNUNET_SETU_prepare (&local_id,
  143. &app_id,
  144. &context_msg,
  145. (struct GNUNET_SETU_Option[]){ 0 },
  146. &result_cb_set1,
  147. NULL);
  148. GNUNET_SETU_commit (oh1, set1);
  149. }
  150. /**
  151. * Initialize the second set, continue
  152. *
  153. * @param cls closure, unused
  154. */
  155. static void
  156. init_set2 (void *cls)
  157. {
  158. struct GNUNET_SETU_Element element;
  159. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initializing set 2\n");
  160. element.element_type = 0;
  161. element.data = "hello1";
  162. element.size = strlen (element.data);
  163. GNUNET_SETU_add_element (set2, &element, NULL, NULL);
  164. element.data = "quux";
  165. element.size = strlen (element.data);
  166. GNUNET_SETU_add_element (set2, &element, NULL, NULL);
  167. element.data = "baz";
  168. element.size = strlen (element.data);
  169. GNUNET_SETU_add_element (set2, &element, &start, NULL);
  170. }
  171. /**
  172. * Generate random byte stream
  173. */
  174. unsigned char *gen_rdm_bytestream (size_t num_bytes)
  175. {
  176. unsigned char *stream = GNUNET_malloc (num_bytes);
  177. GNUNET_CRYPTO_random_block(GNUNET_CRYPTO_QUALITY_WEAK, stream, num_bytes);
  178. return stream;
  179. }
  180. /**
  181. * Generate random sets
  182. */
  183. static void
  184. initRandomSets(int overlap, int set1_size, int set2_size, int element_size_in_bytes)
  185. {
  186. struct GNUNET_SETU_Element element;
  187. element.element_type = 0;
  188. // Add elements to both sets
  189. for (int i = 0; i < overlap; i++) {
  190. element.data = gen_rdm_bytestream(element_size_in_bytes);
  191. element.size = element_size_in_bytes;
  192. GNUNET_SETU_add_element (set1, &element, NULL, NULL);
  193. GNUNET_SETU_add_element (set2, &element, NULL, NULL);
  194. set1_size--;
  195. set2_size--;
  196. }
  197. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initialized elements in both sets\n");
  198. // Add other elements to set 1
  199. while(set1_size>0) {
  200. element.data = gen_rdm_bytestream(element_size_in_bytes);
  201. element.size = element_size_in_bytes;
  202. GNUNET_SETU_add_element (set1, &element, NULL, NULL);
  203. set1_size--;
  204. }
  205. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initialized elements in set1\n");
  206. // Add other elements to set 2
  207. while(set2_size > 0) {
  208. element.data = gen_rdm_bytestream(element_size_in_bytes);
  209. element.size = element_size_in_bytes;
  210. if(set2_size != 1) {
  211. GNUNET_SETU_add_element (set2, &element,NULL, NULL);
  212. } else {
  213. GNUNET_SETU_add_element (set2, &element,&start, NULL);
  214. }
  215. set2_size--;
  216. }
  217. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initialized elements in set2\n");
  218. }
  219. /**
  220. * Initialize the first set, continue.
  221. */
  222. static void
  223. init_set1 (void)
  224. {
  225. struct GNUNET_SETU_Element element;
  226. element.element_type = 0;
  227. element.data = "hello";
  228. element.size = strlen (element.data);
  229. GNUNET_SETU_add_element (set1, &element, NULL, NULL);
  230. element.data = "bar";
  231. element.size = strlen (element.data);
  232. GNUNET_SETU_add_element (set1, &element, &init_set2, NULL);
  233. GNUNET_log (GNUNET_ERROR_TYPE_INFO, "initialized set 1\n");
  234. }
  235. /**
  236. * Function run on timeout.
  237. *
  238. * @param cls closure
  239. */
  240. static void
  241. timeout_fail (void *cls)
  242. {
  243. tt = NULL;
  244. GNUNET_log (GNUNET_ERROR_TYPE_MESSAGE, "Testcase failed with timeout\n");
  245. GNUNET_SCHEDULER_shutdown ();
  246. ret = 1;
  247. }
  248. /**
  249. * Function run on shutdown.
  250. *
  251. * @param cls closure
  252. */
  253. static void
  254. do_shutdown (void *cls)
  255. {
  256. if (NULL != tt)
  257. {
  258. GNUNET_SCHEDULER_cancel (tt);
  259. tt = NULL;
  260. }
  261. if (NULL != oh1)
  262. {
  263. GNUNET_SETU_operation_cancel (oh1);
  264. oh1 = NULL;
  265. }
  266. if (NULL != oh2)
  267. {
  268. GNUNET_SETU_operation_cancel (oh2);
  269. oh2 = NULL;
  270. }
  271. if (NULL != set1)
  272. {
  273. GNUNET_SETU_destroy (set1);
  274. set1 = NULL;
  275. }
  276. if (NULL != set2)
  277. {
  278. GNUNET_SETU_destroy (set2);
  279. set2 = NULL;
  280. }
  281. if (NULL != listen_handle)
  282. {
  283. GNUNET_SETU_listen_cancel (listen_handle);
  284. listen_handle = NULL;
  285. }
  286. }
  287. /**
  288. * Signature of the 'main' function for a (single-peer) testcase that
  289. * is run using 'GNUNET_TESTING_peer_run'.
  290. *
  291. * @param cls closure
  292. * @param cfg configuration of the peer that was started
  293. * @param peer identity of the peer that was created
  294. */
  295. static void
  296. run (void *cls,
  297. const struct GNUNET_CONFIGURATION_Handle *cfg,
  298. struct GNUNET_TESTING_Peer *peer)
  299. {
  300. struct GNUNET_SETU_OperationHandle *my_oh;
  301. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  302. "Running preparatory tests\n");
  303. tt = GNUNET_SCHEDULER_add_delayed (
  304. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5),
  305. &timeout_fail,
  306. NULL);
  307. GNUNET_SCHEDULER_add_shutdown (&do_shutdown, NULL);
  308. config = cfg;
  309. GNUNET_assert (GNUNET_OK == GNUNET_CRYPTO_get_peer_identity (cfg,
  310. &local_id));
  311. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  312. "my id (from CRYPTO): %s\n",
  313. GNUNET_i2s (&local_id));
  314. GNUNET_TESTING_peer_get_identity (peer,
  315. &local_id);
  316. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  317. "my id (from TESTING): %s\n",
  318. GNUNET_i2s (&local_id));
  319. set1 = GNUNET_SETU_create (cfg);
  320. set2 = GNUNET_SETU_create (cfg);
  321. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  322. "Created sets %p and %p for union operation\n",
  323. set1,
  324. set2);
  325. GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK, &app_id);
  326. /* test if canceling an uncommitted request works! */
  327. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  328. "Launching and instantly stopping set operation\n");
  329. my_oh = GNUNET_SETU_prepare (&local_id,
  330. &app_id,
  331. NULL,
  332. (struct GNUNET_SETU_Option[]){ 0 },
  333. NULL,
  334. NULL);
  335. GNUNET_SETU_operation_cancel (my_oh);
  336. /* test the real set reconciliation */
  337. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  338. "Running real set-reconciliation\n");
  339. //init_set1 ();
  340. initRandomSets(19500,20000,20000,4096);
  341. //initRandomSets(19500,20000,20000,32);
  342. }
  343. int
  344. main (int argc, char **argv)
  345. {
  346. GNUNET_log_setup ("test_setu_api",
  347. "WARNING",
  348. NULL);
  349. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  350. "Launching peer\n");
  351. if (0 !=
  352. GNUNET_TESTING_peer_run ("test_setu_api",
  353. "test_setu.conf",
  354. &run,
  355. NULL))
  356. {
  357. return 1;
  358. }
  359. return ret;
  360. }