Merge branch 'master' of ssh://gnunet.org/gnunet
[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 static int global_ret = 1;
34
35 static struct GNUNET_MQ_Handle *mq;
36
37
38 static void
39 handle_recv (void *cls,
40              const struct GNUNET_MessageHeader *message)
41 {
42   struct GNUNET_SERVICE_Client *client = cls;
43   
44   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
45               "Received client message...\n");
46   GNUNET_SERVICE_client_continue (client);
47   global_ret = 2;
48   GNUNET_MQ_destroy (mq);
49   mq = NULL;
50 }
51
52
53 /**
54  * Function called when the client connects to the service.
55  *
56  * @param cls the name of the service
57  * @param c connecting client
58  * @param mq message queue to talk to the client
59  * @return @a c so we have the client handle in the future
60  */
61 static void *
62 connect_cb (void *cls,
63             struct GNUNET_SERVICE_Client *c,
64             struct GNUNET_MQ_Handle *mq)
65 {
66   /* FIXME: in the future, do something with mq
67      to test sending messages to the client! */
68   return c;
69 }
70
71
72 /**
73  * Function called when the client disconnects.
74  *
75  * @param cls our service name
76  * @param c disconnecting client
77  * @param internal_cls must match @a c
78  */ 
79 static void
80 disconnect_cb (void *cls,
81                struct GNUNET_SERVICE_Client *c,
82                void *internal_cls)
83 {
84   GNUNET_assert (c == internal_cls);
85   if (2 == global_ret)
86   {
87     GNUNET_SCHEDULER_shutdown ();
88     global_ret = 0;
89   }
90 }
91
92
93 /**
94  * Initialization function of the service.  Starts
95  * a client to connect to the service.
96  *
97  * @param cls the name of the service (const char *)
98  * @param cfg the configuration we use
99  * @param sh handle to the service
100  */
101 static void
102 service_init (void *cls,
103               const struct GNUNET_CONFIGURATION_Handle *cfg,
104               struct GNUNET_SERVICE_Handle *sh)
105 {
106   const char *service_name = cls;
107   struct GNUNET_MQ_Envelope *env;
108   struct GNUNET_MessageHeader *msg;
109   
110   mq = GNUNET_CLIENT_connect (cfg,
111                               service_name,
112                               NULL,
113                               NULL,
114                               NULL);
115   GNUNET_assert (NULL != mq);
116   env = GNUNET_MQ_msg (msg,
117                        MY_TYPE);
118   GNUNET_MQ_send (mq,
119                   env);
120 }
121
122
123 /**
124  * Main method, starts the service and initiates
125  * the running of the test.
126  *
127  * @param sname name of the service to run
128  */
129 static int
130 check (const char *sname)
131 {
132   struct GNUNET_MQ_MessageHandler myhandlers[] = {
133     GNUNET_MQ_hd_fixed_size (recv,
134                              MY_TYPE,
135                              struct GNUNET_MessageHeader,
136                              NULL),
137     GNUNET_MQ_handler_end ()
138   };
139   char *const argv[] = {
140     (char *) sname,
141     "-c",
142     "test_service_data.conf",
143     NULL
144   };
145   
146   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
147               "Starting `%s' service\n",
148               sname);
149   global_ret = 1;
150   GNUNET_assert (0 ==
151                  GNUNET_SERVICE_run_ (3,
152                                       argv,
153                                       sname,
154                                       GNUNET_SERVICE_OPTION_NONE,
155                                       &service_init,
156                                       &connect_cb,
157                                       &disconnect_cb,
158                                       (void *) sname,
159                                       myhandlers));
160   return global_ret;
161 }
162
163
164 int
165 main (int argc,
166       char *argv[])
167 {
168   int ret = 0;
169   struct GNUNET_NETWORK_Handle *s = NULL;
170
171   GNUNET_log_setup ("test-service",
172                     "WARNING",
173                     NULL);
174   ret += check ("test_service");
175   ret += check ("test_service");
176 #ifndef MINGW
177   s = GNUNET_NETWORK_socket_create (PF_INET6,
178                                     SOCK_STREAM,
179                                     0);
180 #endif
181   if (NULL == s)
182   {
183     if ( (errno == ENOBUFS) ||
184          (errno == ENOMEM) ||
185          (errno == ENFILE) ||
186          (errno == EACCES) )
187     {
188       GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR,
189                            "socket");
190       return 1;
191     }
192     FPRINTF (stderr,
193              "IPv6 support seems to not be available (%s), not testing it!\n",
194              strerror (errno));
195   }
196   else
197   {
198     GNUNET_break (GNUNET_OK ==
199                   GNUNET_NETWORK_socket_close (s));
200     ret += check ("test_service6");
201   }
202   return ret;
203 }
204
205 /* end of test_service.c */