bc831344b9275ee60a4430e0d8359b684eba47a5
[oweals/gnunet.git] / src / arm / test_gnunet_service_arm.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009, 2014 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      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      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20 /**
21  * @file arm/test_gnunet_service_arm.c
22  * @brief testcase for gnunet-service-arm.c; tests ARM by making it start the resolver
23  * @author Safey
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "gnunet_arm_service.h"
28 #include "gnunet_resolver_service.h"
29 #include "gnunet_os_lib.h"
30 #include "gnunet_program_lib.h"
31
32 /**
33  * Timeout for starting services, very short because of the strange way start works
34  * (by checking if running before starting, so really this time is always waited on
35  * startup (annoying)).
36  */
37 #define START_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 50)
38
39 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
40
41 static int ret = 1;
42
43 static int resolved_ok;
44
45 static int asked_for_a_list;
46
47 static struct GNUNET_ARM_Handle *arm;
48
49
50 static void
51 trigger_disconnect (void *cls,
52                     const struct GNUNET_SCHEDULER_TaskContext *tc)
53 {
54   GNUNET_ARM_disconnect_and_free (arm);
55   arm = NULL;
56 }
57
58
59 static void
60 arm_stop_cb (void *cls,
61              enum GNUNET_ARM_RequestStatus status,
62              const char *servicename,
63              enum GNUNET_ARM_Result result)
64 {
65   GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
66   GNUNET_break (result == GNUNET_ARM_RESULT_STOPPED);
67   if (result != GNUNET_ARM_RESULT_STOPPED)
68     ret = 4;
69   GNUNET_SCHEDULER_add_now (trigger_disconnect, NULL);
70 }
71
72
73 static void
74 service_list (void *cls,
75               enum GNUNET_ARM_RequestStatus rs,
76               unsigned int count,
77               const char *const*list)
78 {
79   unsigned int i;
80
81   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
82               "%u services are are currently running\n",
83               count);
84   if (GNUNET_ARM_REQUEST_SENT_OK != rs)
85     goto stop_arm;
86   for (i=0;i<count;i++)
87   {
88     if (0 == strcasecmp (list[i],
89                          "resolver (gnunet-service-resolver)"))
90     {
91       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
92                   "Got service list, now stopping arm\n");
93       ret = 0;
94     }
95   }
96
97  stop_arm:
98   GNUNET_ARM_request_service_stop (arm, "arm", TIMEOUT,
99                                    &arm_stop_cb, NULL);
100 }
101
102
103 static void
104 hostNameResolveCB (void *cls,
105                    const struct sockaddr *addr,
106                    socklen_t addrlen)
107 {
108   if ((ret == 0) || (ret == 4) || (resolved_ok == 1))
109     return;
110   if (NULL == addr)
111   {
112     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
113                 "Name not resolved!\n");
114     ret = 3;
115     GNUNET_ARM_request_service_stop (arm, "arm", TIMEOUT,
116                                      &arm_stop_cb, NULL);
117   }
118   else if (asked_for_a_list == 0)
119   {
120     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
121                 "Resolved hostname, now checking the service list\n");
122     GNUNET_ARM_request_service_list (arm, TIMEOUT, service_list, NULL);
123     asked_for_a_list = 1;
124     resolved_ok = 1;
125   }
126 }
127
128
129 static void
130 arm_start_cb (void *cls,
131               enum GNUNET_ARM_RequestStatus status,
132               const char *servicename,
133               enum GNUNET_ARM_Result result)
134 {
135   GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
136   GNUNET_break (result == GNUNET_ARM_RESULT_STARTING);
137   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
138               "Trying to resolve our own hostname!\n");
139   /* connect to the resolver service */
140   if (NULL ==
141       GNUNET_RESOLVER_hostname_resolve (AF_UNSPEC, TIMEOUT,
142                                         &hostNameResolveCB, NULL))
143   {
144     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
145         "Unable initiate connection to resolver service\n");
146     ret = 2;
147     GNUNET_ARM_request_service_stop (arm,
148                                      "arm", TIMEOUT,
149                                      &arm_stop_cb, NULL);
150   }
151 }
152
153
154 static void
155 run (void *cls,
156      char *const *args,
157      const char *cfgfile,
158      const struct GNUNET_CONFIGURATION_Handle *c)
159 {
160   char *armconfig;
161
162   if (NULL != cfgfile)
163   {
164     if (GNUNET_OK !=
165         GNUNET_CONFIGURATION_get_value_filename (c, "arm", "CONFIG",
166                                                  &armconfig))
167     {
168       GNUNET_CONFIGURATION_set_value_string ((struct GNUNET_CONFIGURATION_Handle *) c,
169                                              "arm", "CONFIG",
170                                              cfgfile);
171     }
172     else
173       GNUNET_free (armconfig);
174   }
175   arm = GNUNET_ARM_connect (c, NULL, NULL);
176   GNUNET_ARM_request_service_start (arm, "arm",
177                                     GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
178                                     START_TIMEOUT,
179                                     &arm_start_cb, NULL);
180 }
181
182
183 int
184 main (int argc, char *av[])
185 {
186   static char *const argv[] = {
187     "test-gnunet-service-arm",
188     "-c", "test_arm_api_data.conf",
189     NULL
190   };
191   static struct GNUNET_GETOPT_CommandLineOption options[] = {
192     GNUNET_GETOPT_OPTION_END
193   };
194   char hostname[GNUNET_OS_get_hostname_max_length () + 1];
195
196   if (0 != gethostname (hostname, sizeof (hostname) - 1))
197   {
198     GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR | GNUNET_ERROR_TYPE_BULK,
199                          "gethostname");
200     FPRINTF (stderr,
201              "%s",
202              "Failed to determine my own hostname, testcase not run.\n");
203     return 0;
204   }
205   if (NULL == gethostbyname (hostname))
206   {
207     FPRINTF (stderr,
208              "Failed to resolve my hostname `%s', testcase not run.\n",
209              hostname);
210     return 0;
211   }
212   GNUNET_log_setup ("test-gnunet-service-arm",
213                     "WARNING",
214                     NULL);
215   GNUNET_break (GNUNET_OK ==
216                 GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
217                                     argv, "test-gnunet-service-arm",
218                                     "nohelp", options,
219                                     &run, NULL));
220   return ret;
221 }
222
223 /* end of test_gnunet_service_arm.c */