glitch in the license text detected by hyazinthe, thank you!
[oweals/gnunet.git] / src / arm / test_gnunet_service_arm.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009, 2014 GNUnet e.V.
4
5      GNUnet is free software: you can redistribute it and/or modify it
6      under the terms of the GNU Affero General Public License as published
7      by the Free Software Foundation, either version 3 of the License,
8      or (at your option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Affero General Public License for more details.
14 */
15 /**
16  * @file arm/test_gnunet_service_arm.c
17  * @brief testcase for gnunet-service-arm.c; tests ARM by making it start the resolver
18  * @author Safey
19  * @author Christian Grothoff
20  */
21 #include "platform.h"
22 #include "gnunet_arm_service.h"
23 #include "gnunet_resolver_service.h"
24 #include "gnunet_os_lib.h"
25 #include "gnunet_program_lib.h"
26
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 (GNUNET_TIME_UNIT_MILLISECONDS, 50)
33
34 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
35
36
37 static int ret = 1;
38
39 static int resolved_ok;
40
41 static int asked_for_a_list;
42
43 static struct GNUNET_ARM_Handle *arm;
44
45
46 static void
47 trigger_disconnect (void *cls)
48 {
49   GNUNET_ARM_disconnect (arm);
50   arm = NULL;
51 }
52
53
54 static void
55 arm_stop_cb (void *cls,
56              enum GNUNET_ARM_RequestStatus status,
57              enum GNUNET_ARM_Result result)
58 {
59   GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
60   GNUNET_break (result == GNUNET_ARM_RESULT_STOPPED);
61   if (result != GNUNET_ARM_RESULT_STOPPED)
62   {
63     GNUNET_break (0);
64     ret = 4;
65   }
66   GNUNET_SCHEDULER_add_now (&trigger_disconnect, NULL);
67 }
68
69
70 static void
71 service_list (void *cls,
72               enum GNUNET_ARM_RequestStatus rs,
73               unsigned int count,
74               const char *const*list)
75 {
76   unsigned int i;
77
78   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
79               "%u services are are currently running\n",
80               count);
81   if (GNUNET_ARM_REQUEST_SENT_OK != rs)
82     goto stop_arm;
83   for (i=0;i<count;i++)
84   {
85     if (0 == strcasecmp (list[i],
86                          "resolver (gnunet-service-resolver)"))
87     {
88       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
89                   "Got service list, now stopping arm\n");
90       ret = 0;
91     }
92   }
93
94  stop_arm:
95   GNUNET_ARM_request_service_stop (arm,
96                                    "arm",
97                                    &arm_stop_cb,
98                                    NULL);
99 }
100
101
102 static void
103 hostname_resolve_cb (void *cls,
104                      const struct sockaddr *addr,
105                      socklen_t addrlen)
106 {
107   if ((0 == ret) || (4 == ret) || (1 == resolved_ok))
108     return;
109   if (NULL == addr)
110   {
111     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
112                 "Name not resolved!\n");
113     GNUNET_break (0);
114     ret = 3;
115     GNUNET_ARM_request_service_stop (arm,
116                                      "arm",
117                                      &arm_stop_cb,
118                                      NULL);
119     return;
120   }
121   if (0 == asked_for_a_list)
122   {
123     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
124                 "Resolved hostname, now checking the service list\n");
125     GNUNET_ARM_request_service_list (arm,
126                                      &service_list,
127                                      NULL);
128     asked_for_a_list = 1;
129     resolved_ok = 1;
130   }
131 }
132
133
134 static void
135 arm_start_cb (void *cls,
136               enum GNUNET_ARM_RequestStatus status,
137               enum GNUNET_ARM_Result result)
138 {
139   GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
140   GNUNET_break (result == GNUNET_ARM_RESULT_STARTING);
141   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
142               "Trying to resolve our own hostname!\n");
143   /* connect to the resolver service */
144   if (NULL ==
145       GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC,
146                                         TIMEOUT,
147                                         &hostname_resolve_cb,
148                                         NULL))
149   {
150     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
151                 "Unable initiate connection to resolver service\n");
152     GNUNET_break (0);
153     ret = 2;
154     GNUNET_ARM_request_service_stop (arm,
155                                      "arm",
156                                      &arm_stop_cb,
157                                      NULL);
158   }
159 }
160
161
162 static void
163 run (void *cls,
164      char *const *args,
165      const char *cfgfile,
166      const struct GNUNET_CONFIGURATION_Handle *c)
167 {
168   arm = GNUNET_ARM_connect (c,
169                             NULL,
170                             NULL);
171   GNUNET_ARM_request_service_start (arm,
172                                     "arm",
173                                     GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
174                                     &arm_start_cb,
175                                     NULL);
176 }
177
178
179 int
180 main (int argc, char *av[])
181 {
182   static char *const argv[] = {
183     "test-gnunet-service-arm",
184     "-c",
185     "test_arm_api_data.conf",
186     NULL
187   };
188   static struct GNUNET_GETOPT_CommandLineOption options[] = {
189     GNUNET_GETOPT_OPTION_END
190   };
191   char hostname[GNUNET_OS_get_hostname_max_length () + 1];
192
193   if (0 != gethostname (hostname, sizeof (hostname) - 1))
194   {
195     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
196                          "gethostname");
197     FPRINTF (stderr,
198              "%s",
199              "Failed to determine my own hostname, testcase not run.\n");
200     return 0;
201   }
202   if ( (0 == strcmp (hostname,
203                      "localhost")) ||
204        (0 == strcmp (hostname,
205                      "ipv6-localnet")) )
206   {
207     /* we cannot use 'localhost' as this would not trigger the
208        resolver service (see resolver_api.c); so in this case,
209        we fall back to (ab)using gnu.org. */
210     strcpy (hostname,
211             "www.gnu.org");
212   }
213   /* trigger DNS lookup */
214 #if HAVE_GETADDRINFO
215   {
216     struct addrinfo *ai;
217     int ret;
218
219     if (0 != (ret = getaddrinfo (hostname, NULL, NULL, &ai)))
220     {
221       FPRINTF (stderr,
222                "Failed to resolve my hostname `%s', testcase not run.\n",
223                hostname);
224       return 0;
225     }
226     freeaddrinfo (ai);
227   }
228 #elif HAVE_GETHOSTBYNAME2
229   {
230     struct hostent *host;
231
232     host = gethostbyname2 (hostname, AF_INET);
233     if (NULL == host)
234       host = gethostbyname2 (hostname, AF_INET6);
235     if (NULL == host)
236       {
237         FPRINTF (stderr,
238                  "Failed to resolve my hostname `%s', testcase not run.\n",
239                  hostname);
240         return 0;
241       }
242   }
243 #elif HAVE_GETHOSTBYNAME
244   {
245     struct hostent *host;
246
247     host = gethostbyname (hostname);
248     if (NULL == host)
249       {
250         FPRINTF (stderr,
251                  "Failed to resolve my hostname `%s', testcase not run.\n",
252                  hostname);
253         return 0;
254       }
255   }
256 #else
257   FPRINTF (stderr,
258            "libc fails to have resolver function, testcase not run.\n");
259   return 0;
260 #endif
261   GNUNET_log_setup ("test-gnunet-service-arm",
262                     "WARNING",
263                     NULL);
264   GNUNET_break (GNUNET_OK ==
265                 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
266                                     argv, "test-gnunet-service-arm",
267                                     "nohelp", options,
268                                     &run, NULL));
269   if (0 != ret)
270   {
271     fprintf (stderr,
272              "Test failed with error code %d\n",
273              ret);
274   }
275   return ret;
276 }
277
278 /* end of test_gnunet_service_arm.c */