-cleaning up client api to test for service availability
[oweals/gnunet.git] / src / arm / test_arm_api.c
1 /*
2      This file is part of GNUnet.
3      (C) 2009, 2011 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_arm_api.c
22  * @brief testcase for arm_api.c
23  */
24 #include "platform.h"
25 #include "gnunet_common.h"
26 #include "gnunet_arm_service.h"
27 #include "gnunet_client_lib.h"
28 #include "gnunet_configuration_lib.h"
29 #include "gnunet_getopt_lib.h"
30 #include "gnunet_program_lib.h"
31 #include "gnunet_resolver_service.h"
32
33 #define LOG(...) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, __VA_ARGS__)
34
35 #define START_ARM GNUNET_YES
36
37 #define START_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 1500)
38
39 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15)
40
41 static const struct GNUNET_CONFIGURATION_Handle *cfg;
42
43 static struct GNUNET_ARM_Handle *arm;
44
45 static int ok = 1;
46
47 static int phase = 0;
48
49 static void
50 arm_stop_cb (void *cls, 
51              enum GNUNET_ARM_RequestStatus status, 
52              const char *servicename, 
53              enum GNUNET_ARM_Result result)
54 {
55   /* (6), a stop request should be sent to ARM successfully */
56   /* ARM should report that it is stopping */
57   GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
58   GNUNET_break (result == GNUNET_ARM_RESULT_STOPPED);
59   GNUNET_break (phase == 6);
60   phase++;
61   LOG ("Sent 'STOP' request for arm to ARM %s\n", (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully");
62 }
63
64
65 static void
66 resolver_stop_cb (void *cls, 
67                   enum GNUNET_ARM_RequestStatus status, 
68                   const char *servicename, enum GNUNET_ARM_Result result)
69 {
70   /* (5), a stop request should be sent to ARM successfully.
71    * ARM should report that resolver is stopped.
72    */
73   GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
74   GNUNET_break (result == GNUNET_ARM_RESULT_STOPPED);
75   GNUNET_break (phase == 5);
76   LOG ("Sent 'STOP' request for resolver to ARM %s\n", (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully");
77   phase++;
78 #if START_ARM
79   GNUNET_ARM_request_service_stop (arm, "arm", TIMEOUT, arm_stop_cb, NULL);
80 #else
81   arm_stop_cb (NULL, GNUNET_ARM_STATUS_SENT_OK, "arm", GNUNET_ARM_SERVICE_STOPPING);
82   arm_conn (NULL, GNUNET_NO);
83 #endif
84 }
85
86
87 static void
88 dns_notify (void *cls, const struct sockaddr *addr, socklen_t addrlen)
89 {
90   if (addr == NULL)
91     {
92       /* (4), resolver should finish resolving localhost */
93       GNUNET_break (phase == 4);
94       phase++;
95       LOG ("Finished resolving localhost\n");
96       if (ok != 0)
97         ok = 2;
98       GNUNET_ARM_request_service_stop (arm, "resolver", TIMEOUT, resolver_stop_cb, NULL);
99       return;
100     }
101   /* (3), resolver should resolve localhost */
102   GNUNET_break (phase == 3);
103   LOG ("Resolved localhost\n");
104   phase++;
105   GNUNET_break (addr != NULL);
106   ok = 0;
107 }
108
109
110 static void
111 resolver_start_cb (void *cls, 
112                    enum GNUNET_ARM_RequestStatus status, 
113                    const char *servicename, 
114                    enum GNUNET_ARM_Result result)
115 {
116   /* (2), the start request for resolver should be sent successfully
117    * ARM should report that resolver service is starting.
118    */
119   GNUNET_assert (status == GNUNET_ARM_REQUEST_SENT_OK);
120   GNUNET_break (phase == 2);
121   GNUNET_break (result == GNUNET_ARM_RESULT_STARTING);
122   LOG ("Sent 'START' request for resolver to ARM %s\n", (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully");
123   phase++;
124   GNUNET_RESOLVER_ip_get ("localhost", AF_INET, TIMEOUT, &dns_notify, NULL);
125 }
126
127
128 static void
129 trigger_disconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
130 {
131   GNUNET_ARM_disconnect_and_free ((struct GNUNET_ARM_Handle *) cls);
132 }
133
134
135 static void
136 arm_conn (void *cls, 
137           int connected)
138 {
139   if (GNUNET_SYSERR == connected)
140   {
141     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
142                 _("Fatal error initializing ARM API.\n"));
143     GNUNET_SCHEDULER_shutdown ();
144     GNUNET_assert (0);
145     return;
146   }
147   if (GNUNET_YES == connected)
148   {
149     /* (1), arm connection should be established */
150     LOG ("Connected to ARM\n");
151     GNUNET_break (phase == 1);
152     phase++;
153     GNUNET_ARM_request_service_start (arm, "resolver", GNUNET_OS_INHERIT_STD_OUT_AND_ERR, START_TIMEOUT, resolver_start_cb, NULL);
154   }
155   else
156   {
157     /* (7), ARM should stop (we disconnect from it) */
158     LOG ("Disconnected from ARM\n");
159     GNUNET_break (phase == 7);
160     if (phase != 7)
161       ok = 3;
162     else if (ok == 1)
163       ok = 0;
164     GNUNET_SCHEDULER_add_now (trigger_disconnect, arm);
165   }
166 }
167
168
169 static void
170 arm_start_cb (void *cls, 
171               enum GNUNET_ARM_RequestStatus status, 
172               const char *servicename, 
173               enum GNUNET_ARM_Result result)
174 {
175   /* (0) The request should be "sent" successfully
176    * ("sent", because it isn't going anywhere, ARM API starts ARM service
177    * by itself).
178    * ARM API should report that ARM service is starting.
179    */
180   GNUNET_break (status == GNUNET_ARM_REQUEST_SENT_OK);
181   GNUNET_break (phase == 0);
182   LOG ("Sent 'START' request for arm to ARM %s\n", (status == GNUNET_ARM_REQUEST_SENT_OK) ? "successfully" : "unsuccessfully");
183   GNUNET_break (result == GNUNET_ARM_RESULT_STARTING);
184   phase++;
185 }
186
187
188 static void
189 task (void *cls, char *const *args, const char *cfgfile,
190       const struct GNUNET_CONFIGURATION_Handle *c)
191 {
192   char *armconfig;
193   cfg = c;
194   if (NULL != cfgfile)
195   {
196     if (GNUNET_OK !=
197         GNUNET_CONFIGURATION_get_value_filename (cfg, "arm", "CONFIG",
198                                                &armconfig))
199     {
200       GNUNET_CONFIGURATION_set_value_string ((struct GNUNET_CONFIGURATION_Handle
201                                               *) cfg, "arm", "CONFIG",
202                                              cfgfile);
203     }
204     else
205       GNUNET_free (armconfig);
206   }
207   arm = GNUNET_ARM_connect (cfg, &arm_conn, NULL);
208   if (NULL == arm)
209     return;
210 #if START_ARM
211   GNUNET_ARM_request_service_start (arm, "arm", GNUNET_OS_INHERIT_STD_OUT_AND_ERR, START_TIMEOUT, arm_start_cb, NULL);
212 #else
213   arm_start_cb (NULL, arm, GNUNET_ARM_REQUEST_SENT_OK, "arm", GNUNET_ARM_RESULT_STARTING);
214   arm_conn (NULL, arm, GNUNET_YES);
215 #endif
216 }
217
218
219 int
220 main (int argc, char *argvx[])
221 {
222   char *const argv[] = {
223     "test-arm-api",
224     "-c", "test_arm_api_data.conf",
225     NULL
226   };
227   struct GNUNET_GETOPT_CommandLineOption options[] = {
228     GNUNET_GETOPT_OPTION_END
229   };
230   GNUNET_log_setup ("test-arm-api",
231                     "WARNING",
232                     NULL);
233   GNUNET_assert (GNUNET_OK ==
234                  GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
235                                      argv, "test-arm-api", "nohelp", options,
236                                      &task, NULL));
237   return ok;
238 }
239
240 /* end of test_arm_api.c */