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