test_testbed_logger_api.c 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. /*
  2. This file is part of GNUnet
  3. (C) 2008--2013 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 testbed/test_testbed_logger_api.c
  19. * @brief testcases for the testbed logger api
  20. * @author Sree Harsha Totakura
  21. */
  22. #include "platform.h"
  23. #include "gnunet_util_lib.h"
  24. #include "gnunet_testing_lib.h"
  25. #include "gnunet_testbed_logger_service.h"
  26. /**
  27. * Generic logging shortcut
  28. */
  29. #define LOG(kind,...) \
  30. GNUNET_log (kind, __VA_ARGS__)
  31. /**
  32. * Relative time seconds shorthand
  33. */
  34. #define TIME_REL_SECS(sec) \
  35. GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, sec)
  36. /**
  37. * Opaque handle for the logging service
  38. */
  39. static struct GNUNET_TESTBED_LOGGER_Handle *h;
  40. static struct GNUNET_TESTING_Peer *peer;
  41. static char *search_dir;
  42. /**
  43. * Abort task identifier
  44. */
  45. static GNUNET_SCHEDULER_TaskIdentifier abort_task;
  46. static GNUNET_SCHEDULER_TaskIdentifier write_task;
  47. static int result;
  48. #define CANCEL_TASK(task) do { \
  49. if (GNUNET_SCHEDULER_NO_TASK != task) \
  50. { \
  51. GNUNET_SCHEDULER_cancel (task); \
  52. task = GNUNET_SCHEDULER_NO_TASK; \
  53. } \
  54. } while (0)
  55. /**
  56. * shortcut to exit during failure
  57. */
  58. #define FAIL_TEST(cond, ret) do { \
  59. if (!(cond)) { \
  60. GNUNET_break(0); \
  61. CANCEL_TASK (abort_task); \
  62. abort_task = GNUNET_SCHEDULER_add_now (&do_abort, NULL); \
  63. ret; \
  64. } \
  65. } while (0)
  66. /**
  67. * Shutdown nicely
  68. *
  69. * @param cls NULL
  70. * @param tc the task context
  71. */
  72. static void
  73. shutdown_now ()
  74. {
  75. CANCEL_TASK (abort_task);
  76. CANCEL_TASK (write_task);
  77. GNUNET_free_non_null (search_dir);
  78. if (NULL != h)
  79. GNUNET_TESTBED_LOGGER_disconnect (h);
  80. GNUNET_SCHEDULER_shutdown ();
  81. }
  82. static void
  83. do_abort (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  84. {
  85. LOG (GNUNET_ERROR_TYPE_WARNING, "Aborting\n");
  86. abort_task = GNUNET_SCHEDULER_NO_TASK;
  87. shutdown_now ();
  88. }
  89. #define BSIZE 1024
  90. /**
  91. * Function called to iterate over a directory.
  92. *
  93. * @param cls closure
  94. * @param di argument to pass to "GNUNET_DISK_directory_iterator_next" to
  95. * get called on the next entry (or finish cleanly);
  96. * NULL on error (will be the last call in that case)
  97. * @param filename complete filename (absolute path)
  98. * @param dirname directory name (absolute path)
  99. */
  100. static void
  101. iterator_cb (void *cls, struct GNUNET_DISK_DirectoryIterator *di,
  102. const char *filename, const char *dirname)
  103. {
  104. const char *fn;
  105. size_t len;
  106. uint64_t fs;
  107. int cancel;
  108. cancel = GNUNET_NO;
  109. if (NULL == filename)
  110. goto iteration_cont;
  111. len = strlen (filename);
  112. if (len < 5) /* log file: `pid'.dat */
  113. goto iteration_cont;
  114. fn = filename + len;
  115. if (0 != strcasecmp (".dat", fn - 4))
  116. goto iteration_cont;
  117. if (GNUNET_OK != GNUNET_DISK_file_size (filename, &fs,
  118. GNUNET_NO, GNUNET_YES))
  119. goto iteration_cont;
  120. if ((BSIZE * 2) != fs) /* The file size should be equal to what we
  121. have written */
  122. goto iteration_cont;
  123. cancel = GNUNET_YES;
  124. result = GNUNET_OK;
  125. iteration_cont:
  126. if ( (NULL != di) &&
  127. (GNUNET_YES == GNUNET_DISK_directory_iterator_next (di, cancel)) )
  128. return;
  129. shutdown_now ();
  130. }
  131. /**
  132. * Functions of this type are called to notify a successful transmission of the
  133. * message to the logger service
  134. *
  135. * @param cls the closure given to GNUNET_TESTBED_LOGGER_send()
  136. * @param size the amount of data sent
  137. */
  138. static void
  139. flush_comp (void *cls, size_t size)
  140. {
  141. FAIL_TEST (&write_task == cls, return);
  142. FAIL_TEST ((BSIZE * 2) == size, return);
  143. FAIL_TEST (GNUNET_OK == GNUNET_TESTING_peer_stop (peer), return);
  144. FAIL_TEST (GNUNET_YES == GNUNET_DISK_directory_iterator_start
  145. (GNUNET_SCHEDULER_PRIORITY_DEFAULT, search_dir,
  146. &iterator_cb, NULL), return);
  147. }
  148. static void
  149. do_write (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  150. {
  151. static int i;
  152. char buf[BSIZE];
  153. write_task = GNUNET_SCHEDULER_NO_TASK;
  154. if (0 == i)
  155. write_task = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS(1), &do_write, NULL);
  156. (void) memset (buf, i, BSIZE);
  157. GNUNET_TESTBED_LOGGER_write (h, buf, BSIZE);
  158. if (0 == i++)
  159. return;
  160. GNUNET_TESTBED_LOGGER_flush (h, GNUNET_TIME_UNIT_FOREVER_REL,
  161. &flush_comp, &write_task);
  162. }
  163. /**
  164. * Signature of the 'main' function for a (single-peer) testcase that
  165. * is run using 'GNUNET_TESTING_peer_run'.
  166. *
  167. * @param cls closure
  168. * @param cfg configuration of the peer that was started
  169. * @param peer identity of the peer that was created
  170. */
  171. static void
  172. test_main (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg,
  173. struct GNUNET_TESTING_Peer *p)
  174. {
  175. FAIL_TEST (NULL != (h = GNUNET_TESTBED_LOGGER_connect (cfg)), return);
  176. FAIL_TEST (GNUNET_OK == GNUNET_CONFIGURATION_get_value_filename
  177. (cfg, "testbed-logger", "dir", &search_dir), return);
  178. peer = p;
  179. write_task = GNUNET_SCHEDULER_add_now (&do_write, NULL);
  180. abort_task = GNUNET_SCHEDULER_add_delayed (TIME_REL_SECS (10),
  181. &do_abort, NULL);
  182. }
  183. /**
  184. * Main function
  185. */
  186. int
  187. main (int argc, char **argv)
  188. {
  189. int ret;
  190. result = GNUNET_SYSERR;
  191. ret = GNUNET_TESTING_service_run ("test-testbed-logger",
  192. "testbed-logger",
  193. "test_testbed_logger_api.conf",
  194. &test_main,
  195. NULL);
  196. if (0 != ret)
  197. return 1;
  198. if (GNUNET_OK != result)
  199. return 2;
  200. return 0;
  201. }