test_gnunet_service_arm.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2009, 2014 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 arm/test_gnunet_service_arm.c
  18. * @brief testcase for gnunet-service-arm.c; tests ARM by making it start the resolver
  19. * @author Safey
  20. * @author Christian Grothoff
  21. */
  22. #include "platform.h"
  23. #include "gnunet_arm_service.h"
  24. #include "gnunet_resolver_service.h"
  25. #include "gnunet_os_lib.h"
  26. #include "gnunet_program_lib.h"
  27. /**
  28. * Timeout for starting services, very short because of the strange way start works
  29. * (by checking if running before starting, so really this time is always waited on
  30. * startup (annoying)).
  31. */
  32. #define START_TIMEOUT GNUNET_TIME_relative_multiply ( \
  33. GNUNET_TIME_UNIT_MILLISECONDS, 50)
  34. #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
  35. static int ret = 1;
  36. static int resolved_ok;
  37. static int asked_for_a_list;
  38. static struct GNUNET_ARM_Handle *arm;
  39. static const char hostname[] = "www.gnu.org"; /* any domain should do */
  40. static void
  41. trigger_disconnect (void *cls)
  42. {
  43. GNUNET_ARM_disconnect (arm);
  44. arm = NULL;
  45. }
  46. static void
  47. arm_stop_cb (void *cls,
  48. enum GNUNET_ARM_RequestStatus status,
  49. enum GNUNET_ARM_Result result)
  50. {
  51. GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
  52. GNUNET_break (result == GNUNET_ARM_RESULT_STOPPED);
  53. if (result != GNUNET_ARM_RESULT_STOPPED)
  54. {
  55. GNUNET_break (0);
  56. ret = 4;
  57. }
  58. GNUNET_SCHEDULER_add_now (&trigger_disconnect, NULL);
  59. }
  60. static void
  61. service_list (void *cls,
  62. enum GNUNET_ARM_RequestStatus rs,
  63. unsigned int count,
  64. const struct GNUNET_ARM_ServiceInfo *list)
  65. {
  66. unsigned int i;
  67. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  68. "%u services are are currently running\n",
  69. count);
  70. if (GNUNET_ARM_REQUEST_SENT_OK != rs)
  71. goto stop_arm;
  72. for (i = 0; i < count; i++)
  73. {
  74. if ((0 == strcasecmp (list[i].name, "resolver")) &&
  75. (0 == strcasecmp (list[i].binary, "gnunet-service-resolver")))
  76. {
  77. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  78. "Got service list, now stopping arm\n");
  79. ret = 0;
  80. }
  81. }
  82. stop_arm:
  83. GNUNET_ARM_request_service_stop (arm,
  84. "arm",
  85. &arm_stop_cb,
  86. NULL);
  87. }
  88. static void
  89. hostname_resolve_cb (void *cls,
  90. const struct sockaddr *addr,
  91. socklen_t addrlen)
  92. {
  93. if ((0 == ret) || (4 == ret) || (1 == resolved_ok))
  94. return;
  95. if (NULL == addr)
  96. {
  97. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  98. "Failed to resolve hostname!\n");
  99. GNUNET_break (0);
  100. ret = 3;
  101. GNUNET_ARM_request_service_stop (arm,
  102. "arm",
  103. &arm_stop_cb,
  104. NULL);
  105. return;
  106. }
  107. if (0 == asked_for_a_list)
  108. {
  109. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  110. "Resolved hostname, now checking the service list\n");
  111. GNUNET_ARM_request_service_list (arm,
  112. &service_list,
  113. NULL);
  114. asked_for_a_list = 1;
  115. resolved_ok = 1;
  116. }
  117. }
  118. static void
  119. arm_start_cb (void *cls,
  120. enum GNUNET_ARM_RequestStatus status,
  121. enum GNUNET_ARM_Result result)
  122. {
  123. GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
  124. GNUNET_break (result == GNUNET_ARM_RESULT_STARTING);
  125. GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
  126. "Trying to resolve a hostname via the resolver service!\n");
  127. /* connect to the resolver service */
  128. if (NULL ==
  129. GNUNET_RESOLVER_ip_get (hostname,
  130. AF_UNSPEC,
  131. TIMEOUT,
  132. &hostname_resolve_cb,
  133. NULL))
  134. {
  135. GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
  136. "Unable initiate connection to resolver service\n");
  137. GNUNET_break (0);
  138. ret = 2;
  139. GNUNET_ARM_request_service_stop (arm,
  140. "arm",
  141. &arm_stop_cb,
  142. NULL);
  143. }
  144. }
  145. static void
  146. run (void *cls,
  147. char *const *args,
  148. const char *cfgfile,
  149. const struct GNUNET_CONFIGURATION_Handle *c)
  150. {
  151. arm = GNUNET_ARM_connect (c,
  152. NULL,
  153. NULL);
  154. GNUNET_ARM_request_service_start (arm,
  155. "arm",
  156. GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
  157. &arm_start_cb,
  158. NULL);
  159. }
  160. int
  161. main (int argc, char *av[])
  162. {
  163. static char *const argv[] = {
  164. "test-gnunet-service-arm",
  165. "-c",
  166. "test_arm_api_data.conf",
  167. NULL
  168. };
  169. static struct GNUNET_GETOPT_CommandLineOption options[] = {
  170. GNUNET_GETOPT_OPTION_END
  171. };
  172. /* trigger DNS lookup */
  173. #if HAVE_GETADDRINFO
  174. {
  175. struct addrinfo *ai;
  176. int ret;
  177. if (0 != (ret = getaddrinfo (hostname, NULL, NULL, &ai)))
  178. {
  179. fprintf (stderr,
  180. "Failed to resolve `%s', testcase not run.\n",
  181. hostname);
  182. return 77;
  183. }
  184. freeaddrinfo (ai);
  185. }
  186. #elif HAVE_GETHOSTBYNAME2
  187. {
  188. struct hostent *host;
  189. host = gethostbyname2 (hostname, AF_INET);
  190. if (NULL == host)
  191. host = gethostbyname2 (hostname, AF_INET6);
  192. if (NULL == host)
  193. {
  194. fprintf (stderr,
  195. "Failed to resolve `%s', testcase not run.\n",
  196. hostname);
  197. return 77;
  198. }
  199. }
  200. #elif HAVE_GETHOSTBYNAME
  201. {
  202. struct hostent *host;
  203. host = gethostbyname (hostname);
  204. if (NULL == host)
  205. {
  206. fprintf (stderr,
  207. "Failed to resolve `%s', testcase not run.\n",
  208. hostname);
  209. return 77;
  210. }
  211. }
  212. #else
  213. fprintf (stderr,
  214. "libc fails to have resolver function, testcase not run.\n");
  215. return 77;
  216. #endif
  217. GNUNET_log_setup ("test-gnunet-service-arm",
  218. "WARNING",
  219. NULL);
  220. GNUNET_break (GNUNET_OK ==
  221. GNUNET_PROGRAM_run ((sizeof(argv) / sizeof(char *)) - 1,
  222. argv, "test-gnunet-service-arm",
  223. "nohelp", options,
  224. &run, NULL));
  225. if (0 != ret)
  226. {
  227. fprintf (stderr,
  228. "Test failed with error code %d\n",
  229. ret);
  230. }
  231. return ret;
  232. }
  233. /* end of test_gnunet_service_arm.c */