fix timeout of test_service, misc signed/unsigned and unused argument issues
[oweals/gnunet.git] / src / util / test_service.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009, 2013, 2016 GNUnet e.V.
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., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20 /**
21  * @file util/test_service.c
22  * @brief tests for service.c
23  * @author Christian Grothoff
24  */
25 #include "platform.h"
26 #include "gnunet_util_lib.h"
27
28 /**
29  * Message type we use for testing.
30  */
31 #define MY_TYPE 256
32
33 #define TIMEOUT GNUNET_TIME_UNIT_SECONDS
34
35 static int global_ret = 1;
36
37 static struct GNUNET_MQ_Handle *mq;
38
39 /**
40  * Timeout task.
41  */
42 static struct GNUNET_SCHEDULER_Task *tt;
43
44
45 static void
46 handle_recv (void *cls,
47              const struct GNUNET_MessageHeader *message)
48 {
49   struct GNUNET_SERVICE_Client *client = cls;
50   
51   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
52               "Received client message...\n");
53   GNUNET_SERVICE_client_continue (client);
54   global_ret = 2;
55   GNUNET_MQ_destroy (mq);
56   mq = NULL;
57 }
58
59
60 /**
61  * Function called when the client connects to the service.
62  *
63  * @param cls the name of the service
64  * @param c connecting client
65  * @param mq message queue to talk to the client
66  * @return @a c so we have the client handle in the future
67  */
68 static void *
69 connect_cb (void *cls,
70             struct GNUNET_SERVICE_Client *c,
71             struct GNUNET_MQ_Handle *mq)
72 {
73   /* FIXME: in the future, do something with mq
74      to test sending messages to the client! */
75   return c;
76 }
77
78
79 /**
80  * Function called when the client disconnects.
81  *
82  * @param cls our service name
83  * @param c disconnecting client
84  * @param internal_cls must match @a c
85  */ 
86 static void
87 disconnect_cb (void *cls,
88                struct GNUNET_SERVICE_Client *c,
89                void *internal_cls)
90 {
91   GNUNET_assert (c == internal_cls);
92   if (2 == global_ret)
93   {
94     GNUNET_SCHEDULER_shutdown ();
95     global_ret = 0;
96     if (NULL != tt)
97     {
98       GNUNET_SCHEDULER_cancel (tt);
99       tt = NULL;
100     }
101   }
102 }
103
104
105 static void
106 timeout_task (void *cls)
107 {
108   tt = NULL;
109   global_ret = 33;
110   GNUNET_SCHEDULER_shutdown ();
111 }
112
113
114 /**
115  * Initialization function of the service.  Starts
116  * a client to connect to the service.
117  *
118  * @param cls the name of the service (const char *)
119  * @param cfg the configuration we use
120  * @param sh handle to the service
121  */
122 static void
123 service_init (void *cls,
124               const struct GNUNET_CONFIGURATION_Handle *cfg,
125               struct GNUNET_SERVICE_Handle *sh)
126 {
127   const char *service_name = cls;
128   struct GNUNET_MQ_Envelope *env;
129   struct GNUNET_MessageHeader *msg;
130
131   GNUNET_assert (NULL == tt);
132   tt = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
133                                      &timeout_task,
134                                      NULL);
135   mq = GNUNET_CLIENT_connect (cfg,
136                               service_name,
137                               NULL,
138                               NULL,
139                               NULL);
140   GNUNET_assert (NULL != mq);
141   env = GNUNET_MQ_msg (msg,
142                        MY_TYPE);
143   GNUNET_MQ_send (mq,
144                   env);
145 }
146
147
148 /**
149  * Main method, starts the service and initiates
150  * the running of the test.
151  *
152  * @param sname name of the service to run
153  */
154 static int
155 check (const char *sname)
156 {
157   struct GNUNET_MQ_MessageHandler myhandlers[] = {
158     GNUNET_MQ_hd_fixed_size (recv,
159                              MY_TYPE,
160                              struct GNUNET_MessageHeader,
161                              NULL),
162     GNUNET_MQ_handler_end ()
163   };
164   char *const argv[] = {
165     (char *) sname,
166     "-c",
167     "test_service_data.conf",
168     NULL
169   };
170   
171   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
172               "Starting `%s' service\n",
173               sname);
174   global_ret = 1;
175   GNUNET_assert (0 ==
176                  GNUNET_SERVICE_run_ (3,
177                                       argv,
178                                       sname,
179                                       GNUNET_SERVICE_OPTION_NONE,
180                                       &service_init,
181                                       &connect_cb,
182                                       &disconnect_cb,
183                                       (void *) sname,
184                                       myhandlers));
185   return global_ret;
186 }
187
188
189 int
190 main (int argc,
191       char *argv[])
192 {
193   int ret = 0;
194   struct GNUNET_NETWORK_Handle *s = NULL;
195
196   GNUNET_log_setup ("test-service",
197                     "WARNING",
198                     NULL);
199   ret += check ("test_service");
200   ret += check ("test_service");
201 #ifndef MINGW
202   s = GNUNET_NETWORK_socket_create (PF_INET6,
203                                     SOCK_STREAM,
204                                     0);
205 #endif
206   if (NULL == s)
207   {
208     if ( (errno == ENOBUFS) ||
209          (errno == ENOMEM) ||
210          (errno == ENFILE) ||
211          (errno == EACCES) )
212     {
213       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
214                            "socket");
215       return 1;
216     }
217     FPRINTF (stderr,
218              "IPv6 support seems to not be available (%s), not testing it!\n",
219              strerror (errno));
220   }
221   else
222   {
223     GNUNET_break (GNUNET_OK ==
224                   GNUNET_NETWORK_socket_close (s));
225     ret += check ("test_service6");
226   }
227   return ret;
228 }
229
230 /* end of test_service.c */