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