test_fs_namespace.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410
  1. /*
  2. This file is part of GNUnet.
  3. (C) 2005, 2006, 2008, 2009 Christian Grothoff (and other contributing authors)
  4. GNUnet is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published
  6. by the Free Software Foundation; either version 3, or (at your
  7. 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. General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GNUnet; see the file COPYING. If not, write to the
  14. Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  15. Boston, MA 02111-1307, USA.
  16. */
  17. /**
  18. * @file fs/test_fs_namespace.c
  19. * @brief Test for fs_namespace.c
  20. * @author Christian Grothoff
  21. */
  22. #include "platform.h"
  23. #include "gnunet_util_lib.h"
  24. #include "gnunet_arm_service.h"
  25. #include "gnunet_fs_service.h"
  26. #define VERBOSE GNUNET_NO
  27. #define START_ARM GNUNET_YES
  28. static struct PeerContext p1;
  29. static GNUNET_HashCode nsid;
  30. static struct GNUNET_FS_Uri *sks_expect_uri;
  31. static struct GNUNET_FS_Uri *ksk_expect_uri;
  32. static struct GNUNET_FS_Handle *fs;
  33. static struct GNUNET_FS_SearchContext *sks_search;
  34. static struct GNUNET_FS_SearchContext *ksk_search;
  35. static GNUNET_SCHEDULER_TaskIdentifier kill_task;
  36. static int update_started;
  37. static int err;
  38. struct PeerContext
  39. {
  40. struct GNUNET_CONFIGURATION_Handle *cfg;
  41. #if START_ARM
  42. struct GNUNET_OS_Process *arm_proc;
  43. #endif
  44. };
  45. static void
  46. setup_peer (struct PeerContext *p, const char *cfgname)
  47. {
  48. p->cfg = GNUNET_CONFIGURATION_create ();
  49. #if START_ARM
  50. p->arm_proc =
  51. GNUNET_OS_start_process (NULL, NULL, "gnunet-service-arm",
  52. "gnunet-service-arm",
  53. #if VERBOSE
  54. "-L", "DEBUG",
  55. #endif
  56. "-c", cfgname, NULL);
  57. #endif
  58. GNUNET_assert (GNUNET_OK == GNUNET_CONFIGURATION_load (p->cfg, cfgname));
  59. }
  60. static void
  61. stop_arm (struct PeerContext *p)
  62. {
  63. #if START_ARM
  64. if (NULL != p->arm_proc)
  65. {
  66. if (0 != GNUNET_OS_process_kill (p->arm_proc, SIGTERM))
  67. GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
  68. if (GNUNET_OS_process_wait (p->arm_proc) != GNUNET_OK)
  69. GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "waitpid");
  70. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ARM process %u stopped\n",
  71. GNUNET_OS_process_get_pid (p->arm_proc));
  72. GNUNET_OS_process_close (p->arm_proc);
  73. p->arm_proc = NULL;
  74. }
  75. #endif
  76. GNUNET_CONFIGURATION_destroy (p->cfg);
  77. }
  78. static void
  79. abort_ksk_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  80. {
  81. if (ksk_search != NULL)
  82. {
  83. GNUNET_FS_search_stop (ksk_search);
  84. ksk_search = NULL;
  85. if (sks_search == NULL)
  86. {
  87. GNUNET_FS_stop (fs);
  88. if (GNUNET_SCHEDULER_NO_TASK != kill_task)
  89. GNUNET_SCHEDULER_cancel (kill_task);
  90. }
  91. }
  92. }
  93. static void
  94. abort_sks_search_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  95. {
  96. struct GNUNET_FS_Namespace *ns;
  97. if (sks_search == NULL)
  98. return;
  99. GNUNET_FS_search_stop (sks_search);
  100. sks_search = NULL;
  101. ns = GNUNET_FS_namespace_create (fs, "testNamespace");
  102. GNUNET_assert (NULL != ns);
  103. GNUNET_assert (GNUNET_OK == GNUNET_FS_namespace_delete (ns, GNUNET_YES));
  104. if (ksk_search == NULL)
  105. {
  106. GNUNET_FS_stop (fs);
  107. if (GNUNET_SCHEDULER_NO_TASK != kill_task)
  108. GNUNET_SCHEDULER_cancel (kill_task);
  109. }
  110. }
  111. static void
  112. do_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  113. {
  114. fprintf (stderr, "Operation timed out\n");
  115. kill_task = GNUNET_SCHEDULER_NO_TASK;
  116. abort_sks_search_task (NULL, tc);
  117. abort_ksk_search_task (NULL, tc);
  118. }
  119. static void *
  120. progress_cb (void *cls, const struct GNUNET_FS_ProgressInfo *event)
  121. {
  122. switch (event->status)
  123. {
  124. case GNUNET_FS_STATUS_SEARCH_RESULT:
  125. if (sks_search == event->value.search.sc)
  126. {
  127. if (!GNUNET_FS_uri_test_equal
  128. (sks_expect_uri, event->value.search.specifics.result.uri))
  129. {
  130. fprintf (stderr, "Wrong result for sks search!\n");
  131. err = 1;
  132. }
  133. /* give system 1ms to initiate update search! */
  134. GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
  135. &abort_sks_search_task, NULL);
  136. }
  137. else if (ksk_search == event->value.search.sc)
  138. {
  139. if (!GNUNET_FS_uri_test_equal
  140. (ksk_expect_uri, event->value.search.specifics.result.uri))
  141. {
  142. fprintf (stderr, "Wrong result for ksk search!\n");
  143. err = 1;
  144. }
  145. GNUNET_SCHEDULER_add_continuation (&abort_ksk_search_task, NULL,
  146. GNUNET_SCHEDULER_REASON_PREREQ_DONE);
  147. }
  148. else
  149. {
  150. fprintf (stderr, "Unexpected search result received!\n");
  151. GNUNET_break (0);
  152. }
  153. break;
  154. case GNUNET_FS_STATUS_SEARCH_ERROR:
  155. fprintf (stderr, "Error searching file: %s\n",
  156. event->value.search.specifics.error.message);
  157. if (sks_search == event->value.search.sc)
  158. GNUNET_SCHEDULER_add_continuation (&abort_sks_search_task, NULL,
  159. GNUNET_SCHEDULER_REASON_PREREQ_DONE);
  160. else if (ksk_search == event->value.search.sc)
  161. GNUNET_SCHEDULER_add_continuation (&abort_ksk_search_task, NULL,
  162. GNUNET_SCHEDULER_REASON_PREREQ_DONE);
  163. else
  164. GNUNET_break (0);
  165. break;
  166. case GNUNET_FS_STATUS_SEARCH_START:
  167. GNUNET_assert ((NULL == event->value.search.cctx) ||
  168. (0 == strcmp ("sks_search", event->value.search.cctx)) ||
  169. (0 == strcmp ("ksk_search", event->value.search.cctx)));
  170. if (NULL == event->value.search.cctx)
  171. {
  172. GNUNET_assert (0 == strcmp ("sks_search", event->value.search.pctx));
  173. update_started = GNUNET_YES;
  174. }
  175. GNUNET_assert (1 == event->value.search.anonymity);
  176. break;
  177. case GNUNET_FS_STATUS_SEARCH_RESULT_STOPPED:
  178. return NULL;
  179. case GNUNET_FS_STATUS_SEARCH_STOPPED:
  180. return NULL;
  181. default:
  182. fprintf (stderr, "Unexpected event: %d\n", event->status);
  183. break;
  184. }
  185. return event->value.search.cctx;
  186. }
  187. static void
  188. publish_cont (void *cls, const struct GNUNET_FS_Uri *ksk_uri, const char *emsg)
  189. {
  190. char *msg;
  191. struct GNUNET_FS_Uri *sks_uri;
  192. char sbuf[1024];
  193. struct GNUNET_CRYPTO_HashAsciiEncoded enc;
  194. if (NULL != emsg)
  195. {
  196. fprintf (stderr, "Error publishing: %s\n", emsg);
  197. err = 1;
  198. GNUNET_FS_stop (fs);
  199. return;
  200. }
  201. GNUNET_CRYPTO_hash_to_enc (&nsid, &enc);
  202. GNUNET_snprintf (sbuf, sizeof (sbuf), "gnunet://fs/sks/%s/this", &enc);
  203. sks_uri = GNUNET_FS_uri_parse (sbuf, &msg);
  204. if (msg != NULL)
  205. {
  206. fprintf (stderr, "failed to parse URI `%s': %s\n", sbuf, msg);
  207. err = 1;
  208. GNUNET_FS_stop (fs);
  209. GNUNET_free (msg);
  210. return;
  211. }
  212. ksk_search =
  213. GNUNET_FS_search_start (fs, ksk_uri, 1, GNUNET_FS_SEARCH_OPTION_NONE,
  214. "ksk_search");
  215. sks_search =
  216. GNUNET_FS_search_start (fs, sks_uri, 1, GNUNET_FS_SEARCH_OPTION_NONE,
  217. "sks_search");
  218. GNUNET_FS_uri_destroy (sks_uri);
  219. }
  220. static void
  221. sks_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
  222. {
  223. struct GNUNET_CONTAINER_MetaData *meta;
  224. struct GNUNET_FS_Uri *ksk_uri;
  225. char *msg;
  226. struct GNUNET_FS_BlockOptions bo;
  227. meta = GNUNET_CONTAINER_meta_data_create ();
  228. msg = NULL;
  229. ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/ns-search", &msg);
  230. GNUNET_assert (NULL == msg);
  231. ksk_expect_uri = GNUNET_FS_uri_dup (uri);
  232. bo.content_priority = 1;
  233. bo.anonymity_level = 1;
  234. bo.replication_level = 0;
  235. bo.expiration_time =
  236. GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
  237. GNUNET_FS_publish_ksk (fs, ksk_uri, meta, uri, &bo,
  238. GNUNET_FS_PUBLISH_OPTION_NONE, &publish_cont, NULL);
  239. GNUNET_FS_uri_destroy (ksk_uri);
  240. GNUNET_CONTAINER_meta_data_destroy (meta);
  241. }
  242. static void
  243. adv_cont (void *cls, const struct GNUNET_FS_Uri *uri, const char *emsg)
  244. {
  245. struct GNUNET_CONTAINER_MetaData *meta;
  246. struct GNUNET_FS_Namespace *ns;
  247. struct GNUNET_FS_BlockOptions bo;
  248. if (NULL != emsg)
  249. {
  250. fprintf (stderr, "Error publishing: %s\n", emsg);
  251. err = 1;
  252. GNUNET_FS_stop (fs);
  253. return;
  254. }
  255. ns = GNUNET_FS_namespace_create (fs, "testNamespace");
  256. GNUNET_assert (NULL != ns);
  257. meta = GNUNET_CONTAINER_meta_data_create ();
  258. GNUNET_assert (NULL == emsg);
  259. sks_expect_uri = GNUNET_FS_uri_dup (uri);
  260. bo.content_priority = 1;
  261. bo.anonymity_level = 1;
  262. bo.replication_level = 0;
  263. bo.expiration_time =
  264. GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
  265. GNUNET_FS_publish_sks (fs, ns, "this", "next", meta, uri, /* FIXME: this is non-sense (use CHK URI!?) */
  266. &bo, GNUNET_FS_PUBLISH_OPTION_NONE, &sks_cont, NULL);
  267. GNUNET_CONTAINER_meta_data_destroy (meta);
  268. GNUNET_FS_namespace_delete (ns, GNUNET_NO);
  269. }
  270. static void
  271. ns_iterator (void *cls, const char *name, const GNUNET_HashCode * id)
  272. {
  273. int *ok = cls;
  274. if (0 != strcmp (name, "testNamespace"))
  275. return;
  276. *ok = GNUNET_YES;
  277. nsid = *id;
  278. }
  279. static void
  280. testNamespace ()
  281. {
  282. struct GNUNET_FS_Namespace *ns;
  283. struct GNUNET_FS_BlockOptions bo;
  284. struct GNUNET_CONTAINER_MetaData *meta;
  285. struct GNUNET_FS_Uri *ksk_uri;
  286. int ok;
  287. ns = GNUNET_FS_namespace_create (fs, "testNamespace");
  288. GNUNET_assert (NULL != ns);
  289. ok = GNUNET_NO;
  290. GNUNET_FS_namespace_list (fs, &ns_iterator, &ok);
  291. if (GNUNET_NO == ok)
  292. {
  293. fprintf (stderr, "namespace_list failed to find namespace!\n");
  294. GNUNET_FS_namespace_delete (ns, GNUNET_YES);
  295. GNUNET_FS_stop (fs);
  296. err = 1;
  297. return;
  298. }
  299. meta = GNUNET_CONTAINER_meta_data_create ();
  300. ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/testnsa", NULL);
  301. bo.content_priority = 1;
  302. bo.anonymity_level = 1;
  303. bo.replication_level = 0;
  304. bo.expiration_time =
  305. GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
  306. GNUNET_FS_namespace_advertise (fs, ksk_uri, ns, meta, &bo, "root", &adv_cont,
  307. NULL);
  308. kill_task =
  309. GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &do_timeout,
  310. NULL);
  311. GNUNET_FS_uri_destroy (ksk_uri);
  312. GNUNET_FS_namespace_delete (ns, GNUNET_NO);
  313. GNUNET_CONTAINER_meta_data_destroy (meta);
  314. }
  315. static void
  316. run (void *cls, char *const *args, const char *cfgfile,
  317. const struct GNUNET_CONFIGURATION_Handle *cfg)
  318. {
  319. setup_peer (&p1, "test_fs_namespace_data.conf");
  320. fs = GNUNET_FS_start (cfg, "test-fs-namespace", &progress_cb, NULL,
  321. GNUNET_FS_FLAGS_NONE, GNUNET_FS_OPTIONS_END);
  322. testNamespace ();
  323. }
  324. int
  325. main (int argc, char *argv[])
  326. {
  327. char *const argvx[] = {
  328. "test-fs-namespace",
  329. "-c",
  330. "test_fs_namespace_data.conf",
  331. #if VERBOSE
  332. "-L", "DEBUG",
  333. #endif
  334. NULL
  335. };
  336. struct GNUNET_GETOPT_CommandLineOption options[] = {
  337. GNUNET_GETOPT_OPTION_END
  338. };
  339. GNUNET_log_setup ("test_fs_namespace",
  340. #if VERBOSE
  341. "DEBUG",
  342. #else
  343. "WARNING",
  344. #endif
  345. NULL);
  346. GNUNET_PROGRAM_run ((sizeof (argvx) / sizeof (char *)) - 1, argvx,
  347. "test-fs-namespace", "nohelp", options, &run, NULL);
  348. stop_arm (&p1);
  349. if (GNUNET_YES != update_started)
  350. {
  351. fprintf (stderr, "Update search never started!\n");
  352. err = 1;
  353. }
  354. GNUNET_DISK_directory_remove ("/tmp/gnunet-test-fs-namespace/");
  355. return err;
  356. }
  357. /* end of test_fs_namespace.c */