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