-Merge branch 'master' of ssh://gnunet.org/gnunet into gsoc2018/rest_api
[oweals/gnunet.git] / src / util / test_client.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009, 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 util/test_client.c
20  * @brief tests for client.c
21  * @author Christian Grothoff
22  */
23 #include "platform.h"
24 #include "gnunet_util_lib.h"
25
26 static int global_ret;
27
28 static struct GNUNET_MQ_Handle *client_mq;
29
30 #define MY_TYPE 130
31
32
33 /**
34  * Callback that just bounces the message back to the sender.
35  */
36 static void
37 handle_echo (void *cls,
38              const struct GNUNET_MessageHeader *message)
39 {
40   struct GNUNET_SERVICE_Client *c = cls;
41   struct GNUNET_MQ_Handle *mq = GNUNET_SERVICE_client_get_mq (c);
42   struct GNUNET_MQ_Envelope *env;
43
44   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
45               "Receiving message from client, bouncing back\n");
46   env = GNUNET_MQ_msg_copy (message);
47   GNUNET_MQ_send (mq,
48                   env);
49   GNUNET_SERVICE_client_continue (c);
50 }
51
52
53 static void
54 handle_bounce (void *cls,
55                const struct GNUNET_MessageHeader *got)
56 {
57   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
58               "Receiving bounce, checking content\n");
59   GNUNET_assert (NULL != got);
60   global_ret = 2;
61   GNUNET_MQ_destroy (client_mq);
62   client_mq = NULL;
63 }
64
65
66 /**
67  * Generic error handler, called with the appropriate error code and
68  * the same closure specified at the creation of the message queue.
69  * Not every message queue implementation supports an error handler.
70  *
71  * @param cls closure with the `struct GNUNET_STATISTICS_Handle *`
72  * @param error error code
73  */
74 static void
75 mq_error_handler (void *cls,
76                   enum GNUNET_MQ_Error error)
77 {
78   GNUNET_assert (0); /* should never happen */
79 }
80
81
82 static void
83 task (void *cls,
84       const struct GNUNET_CONFIGURATION_Handle *cfg,
85       struct GNUNET_SERVICE_Handle *sh)
86 {
87   struct GNUNET_MQ_MessageHandler chandlers[] = {
88     GNUNET_MQ_hd_fixed_size (bounce,
89                              MY_TYPE,
90                              struct GNUNET_MessageHeader,
91                              cls),
92     GNUNET_MQ_handler_end ()
93   };
94   struct GNUNET_MQ_Envelope *env;
95   struct GNUNET_MessageHeader *msg;
96
97   /* test that ill-configured client fails instantly */
98   GNUNET_assert (NULL ==
99                  GNUNET_CLIENT_connect (cfg,
100                                         "invalid-service",
101                                         NULL,
102                                         &mq_error_handler,
103                                         NULL));
104   client_mq = GNUNET_CLIENT_connect (cfg,
105                                      "test_client",
106                                      chandlers,
107                                      &mq_error_handler,
108                                      NULL);
109   GNUNET_assert (NULL != client_mq);
110   env = GNUNET_MQ_msg (msg,
111                        MY_TYPE);
112   GNUNET_MQ_send (client_mq,
113                   env);
114 }
115
116
117 /**
118  * Function called when the client connects to the service.
119  *
120  * @param cls the name of the service
121  * @param c connecting client
122  * @param mq message queue to talk to the client
123  * @return @a c
124  */
125 static void *
126 connect_cb (void *cls,
127             struct GNUNET_SERVICE_Client *c,
128             struct GNUNET_MQ_Handle *mq)
129 {
130   return c;
131 }
132
133
134 /**
135  * Function called when the client disconnects.
136  *
137  * @param cls our service name
138  * @param c disconnecting client
139  * @param internal_cls must match @a c
140  */ 
141 static void
142 disconnect_cb (void *cls,
143                struct GNUNET_SERVICE_Client *c,
144                void *internal_cls)
145 {
146   if (2 == global_ret)
147   {
148     GNUNET_SCHEDULER_shutdown ();
149     global_ret = 0;
150   }
151 }
152
153
154 int
155 main (int argc,
156       char *argv[])
157 {
158   struct GNUNET_MQ_MessageHandler shandlers[] = {
159     GNUNET_MQ_hd_fixed_size (echo,
160                              MY_TYPE,
161                              struct GNUNET_MessageHeader,
162                              NULL),
163     GNUNET_MQ_handler_end ()
164   };
165   char * test_argv[] = {
166     (char *) "test_client",
167     "-c",
168     "test_client_data.conf",
169     NULL
170   };
171
172   GNUNET_log_setup ("test_client",
173                     "WARNING",
174                     NULL);
175   if (0 != strstr (argv[0],
176                    "unix"))
177     test_argv[2] = "test_client_unix.conf";
178   global_ret = 1;
179   if (0 !=
180       GNUNET_SERVICE_run_ (3,
181                            test_argv,
182                            "test_client",
183                            GNUNET_SERVICE_OPTION_NONE,
184                            &task,
185                            &connect_cb,
186                            &disconnect_cb,
187                            NULL,
188                            shandlers))
189     global_ret = 3;
190   return global_ret;
191 }
192
193 /* end of test_client.c */