GNUnet  0.11.x
cadet_test_lib.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2012, 2017 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  */
25 #include "platform.h"
26 #include "gnunet_util_lib.h"
27 #include "cadet_test_lib.h"
28 #include "gnunet_cadet_service.h"
29 
30 
35 {
40 
45 
50 
54  unsigned int num_peers;
55 
60 
64  void *app_main_cls;
65 
70 
75 
80 
85 
89  const struct GNUNET_HashCode **ports;
90 
94  unsigned int port_count;
95 };
96 
97 
102 {
106  unsigned int peer;
107 
112 
117 };
118 
119 
130 static void *
132  const struct GNUNET_CONFIGURATION_Handle *cfg)
133 {
134  struct GNUNET_CADET_TEST_AdapterContext *actx = cls;
135  struct GNUNET_CADET_TEST_Context *ctx = actx->ctx;
136  struct GNUNET_CADET_Handle *h;
137 
138  h = GNUNET_CADET_connect (cfg);
139  if (NULL == h)
140  {
141  GNUNET_break (0);
142  return NULL;
143  }
144  if (NULL == ctx->ports)
145  return h;
146  actx->ports = GNUNET_new_array (ctx->port_count,
147  struct GNUNET_CADET_Port *);
148  for (unsigned int i = 0; i < ctx->port_count; i++)
149  {
150  actx->ports[i] = GNUNET_CADET_open_port (h,
151  ctx->ports[i],
152  ctx->connects,
153  (void *) (long) actx->peer,
154  ctx->window_changes,
155  ctx->disconnects,
156  ctx->handlers);
157  }
158  return h;
159 }
160 
161 
169 static void
171  void *op_result)
172 {
174  struct GNUNET_CADET_TEST_AdapterContext *actx = cls;
175 
176  if (NULL != actx->ports)
177  {
178  for (unsigned int i = 0; i < actx->ctx->port_count; i++)
179  {
180  GNUNET_CADET_close_port (actx->ports[i]);
181  actx->ports[i] = NULL;
182  }
183  GNUNET_free (actx->ports);
184  }
185  GNUNET_free (actx);
186  GNUNET_CADET_disconnect (cadet);
187 }
188 
189 
200 static void
201 cadet_connect_cb (void *cls,
203  void *ca_result,
204  const char *emsg)
205 {
206  struct GNUNET_CADET_TEST_Context *ctx = cls;
207 
208  if (NULL != emsg)
209  {
210  fprintf (stderr,
211  "Failed to connect to CADET service: %s\n",
212  emsg);
214  return;
215  }
216  for (unsigned int i = 0; i < ctx->num_peers; i++)
217  if (op == ctx->ops[i])
218  {
219  ctx->cadets[i] = ca_result;
221  "...cadet %u connected\n",
222  i);
223  }
224  for (unsigned int i = 0; i < ctx->num_peers; i++)
225  if (NULL == ctx->cadets[i])
226  return;
227  /* still some CADET connections missing */
228  /* all CADET connections ready! */
229  ctx->app_main (ctx->app_main_cls,
230  ctx,
231  ctx->num_peers,
232  ctx->peers,
233  ctx->cadets);
234 }
235 
236 
237 void
239 {
240  for (unsigned int i = 0; i < ctx->num_peers; i++)
241  {
242  GNUNET_assert (NULL != ctx->ops[i]);
244  ctx->ops[i] = NULL;
245  }
246  GNUNET_free (ctx->ops);
247  GNUNET_free (ctx->cadets);
248  GNUNET_free (ctx->handlers);
249  GNUNET_free (ctx);
251 }
252 
253 
267 static void
268 cadet_test_run (void *cls,
269  struct GNUNET_TESTBED_RunHandle *h,
270  unsigned int num_peers,
271  struct GNUNET_TESTBED_Peer **peers,
272  unsigned int links_succeeded,
273  unsigned int links_failed)
274 {
275  struct GNUNET_CADET_TEST_Context *ctx = cls;
276 
277  if (0 != links_failed)
278  {
280  "Some links failed (%u), ending\n",
281  links_failed);
282  exit (77);
283  }
284  if (num_peers != ctx->num_peers)
285  {
287  "Peers started %u/%u, ending\n",
288  num_peers,
289  ctx->num_peers);
290  exit (1);
291  }
293  "Testbed up, %u peers and %u links\n",
294  num_peers,
295  links_succeeded);
296  ctx->peers = peers;
297  for (unsigned int i = 0; i < num_peers; i++)
298  {
299  struct GNUNET_CADET_TEST_AdapterContext *newctx;
300 
302  newctx->peer = i;
303  newctx->ctx = ctx;
305  "Connecting to cadet %u\n",
306  i);
307  ctx->ops[i] = GNUNET_TESTBED_service_connect (ctx,
308  peers[i],
309  "cadet",
311  ctx,
314  newctx);
316  "op handle %p\n",
317  ctx->ops[i]);
318  }
319 }
320 
321 
337 void
338 GNUNET_CADET_TEST_ruN (const char *testname,
339  const char *cfgfile,
340  unsigned int num_peers,
342  void *tmain_cls,
347  const struct GNUNET_HashCode **ports)
348 {
350 
351  ctx = GNUNET_new (struct GNUNET_CADET_TEST_Context);
352  ctx->num_peers = num_peers;
353  ctx->ops = GNUNET_new_array (num_peers,
354  struct GNUNET_TESTBED_Operation *);
355  ctx->cadets = GNUNET_new_array (num_peers,
356  struct GNUNET_CADET_Handle *);
357  ctx->app_main = tmain;
358  ctx->app_main_cls = tmain_cls;
359  ctx->connects = connects;
361  ctx->disconnects = disconnects;
362  ctx->handlers = GNUNET_MQ_copy_handlers (handlers);
363  ctx->ports = ports;
364  ctx->port_count = 0;
365  while (NULL != ctx->ports[ctx->port_count])
366  ctx->port_count++;
367  GNUNET_TESTBED_test_run (testname,
368  cfgfile,
369  num_peers,
370  0LL, NULL, NULL,
372  ctx);
373 }
374 
375 
376 /* end of cadet_test_lib.c */
static void cadet_connect_cb(void *cls, struct GNUNET_TESTBED_Operation *op, void *ca_result, const char *emsg)
Callback to be called when a service connect operation is completed.
static struct GNUNET_CADET_Handle * cadet
Handle for cadet.
void GNUNET_CADET_disconnect(struct GNUNET_CADET_Handle *handle)
Disconnect from the cadet service.
Definition: cadet_api.c:841
void GNUNET_CADET_TEST_cleanup(struct GNUNET_CADET_TEST_Context *ctx)
Clean up the testbed.
static const struct GNUNET_CONFIGURATION_Handle * cfg
Configuration we are using.
Definition: gnunet-abd.c:36
struct GNUNET_TESTBED_Operation ** ops
Operation associated with the connection to the CADET.
struct GNUNET_TESTBED_Peer ** peers
Array of running peers.
Context for a cadet adapter callback.
Opaque handle to the service.
Definition: cadet_api.c:38
void *(* GNUNET_CADET_ConnectEventHandler)(void *cls, struct GNUNET_CADET_Channel *channel, const struct GNUNET_PeerIdentity *source)
Method called whenever a peer connects to a port in MQ-based CADET.
int GNUNET_TESTBED_test_run(const char *testname, const char *cfg_filename, unsigned int num_peers, uint64_t event_mask, GNUNET_TESTBED_ControllerCallback cc, void *cc_cls, GNUNET_TESTBED_TestMaster test_master, void *test_master_cls)
Convenience method for running a "simple" test on the local system with a single call from &#39;main&#39;...
void(* GNUNET_CADET_WindowSizeEventHandler)(void *cls, const struct GNUNET_CADET_Channel *channel, int window_size)
Function called whenever an MQ-channel&#39;s transmission window size changes.
#define GNUNET_assert(cond)
Use this for fatal errors that cannot be handled.
static int op_result(struct GNUNET_OP_Handle *h, uint64_t op_id, int64_t result_code, const void *data, uint16_t data_size, void **ctx, uint8_t cancel)
Remove an operation, and call its result callback (unless it was cancelled).
Definition: op.c:245
struct GNUNET_MQ_MessageHandler * GNUNET_MQ_copy_handlers(const struct GNUNET_MQ_MessageHandler *handlers)
Copy an array of handlers.
Definition: mq.c:1214
struct GNUNET_CADET_Handle ** cadets
Array of handles to the CADET for each peer.
GNUNET_CADET_ConnectEventHandler connects
Handler for incoming tunnels.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
Test context for a CADET Test.
void GNUNET_SCHEDULER_shutdown(void)
Request the shutdown of a scheduler.
Definition: scheduler.c:526
static void * cadet_connect_adapter(void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg)
Adapter function called to establish a connection to the CADET service.
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:99
static struct GNUNET_DNSSTUB_Context * ctx
Context for DNS resolution.
struct GNUNET_CADET_Handle * GNUNET_CADET_connect(const struct GNUNET_CONFIGURATION_Handle *cfg)
Connect to the MQ-based cadet service.
Definition: cadet_api.c:976
Opaque handle to an abstract operation to be executed by the testing framework.
GNUNET_CADET_DisconnectEventHandler disconnects
Cleaner for destroyed incoming tunnels.
struct GNUNET_MQ_MessageHandler * handlers
Message handlers.
static void tmain(void *cls, struct GNUNET_CADET_TEST_Context *ctx, unsigned int num_peers, struct GNUNET_TESTBED_Peer **testbed_peers, struct GNUNET_CADET_Handle **cadetes)
test main: start test when all peers are connected
struct GNUNET_TESTBED_Operation * GNUNET_TESTBED_service_connect(void *op_cls, struct GNUNET_TESTBED_Peer *peer, const char *service_name, GNUNET_TESTBED_ServiceConnectCompletionCallback cb, void *cb_cls, GNUNET_TESTBED_ConnectAdapter ca, GNUNET_TESTBED_DisconnectAdapter da, void *cada_cls)
Connect to a service offered by the given peer.
GNUNET_CADET_WindowSizeEventHandler window_changes
Function called when the transmit window size changes.
unsigned int num_peers
Number of peers running, size of the arrays above.
struct GNUNET_CADET_Port * GNUNET_CADET_open_port(struct GNUNET_CADET_Handle *h, const struct GNUNET_HashCode *port, GNUNET_CADET_ConnectEventHandler connects, void *connects_cls, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, const struct GNUNET_MQ_MessageHandler *handlers)
Open a port to receive incomming MQ-based channels.
Definition: cadet_api.c:1010
void GNUNET_CADET_TEST_ruN(const char *testname, const char *cfgfile, unsigned int num_peers, GNUNET_CADET_TEST_AppMain tmain, void *tmain_cls, GNUNET_CADET_ConnectEventHandler connects, GNUNET_CADET_WindowSizeEventHandler window_changes, GNUNET_CADET_DisconnectEventHandler disconnects, struct GNUNET_MQ_MessageHandler *handlers, const struct GNUNET_HashCode **ports)
Run a test using the given name, configuration file and number of peers.
#define GNUNET_new_array(n, type)
Allocate a size n array with structs or unions of the given type.
unsigned int peer
Peer number for the particular peer.
const struct GNUNET_HashCode ** ports
Application ports.
void GNUNET_TESTBED_operation_done(struct GNUNET_TESTBED_Operation *operation)
This function is used to signal that the event information (struct GNUNET_TESTBED_EventInformation) f...
Definition: testbed_api.c:2044
A 512-bit hashcode.
unsigned int port_count
Number of ports in ports.
Message handler for a specific message type.
void(* GNUNET_CADET_TEST_AppMain)(void *cls, struct GNUNET_CADET_TEST_Context *ctx, unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers, struct GNUNET_CADET_Handle **cadets)
Main function of a CADET test.
struct GNUNET_CADET_TEST_Context * ctx
General context.
static void cadet_disconnect_adapter(void *cls, void *op_result)
Adapter function called to destroy a connection to the CADET service.
struct GNUNET_CADET_Port ** ports
Port handlers for open ports.
configuration data
Definition: configuration.c:85
#define GNUNET_log(kind,...)
void * app_main_cls
Closure for &#39;app_main&#39;.
Opaque handle to a port.
Definition: cadet_api.c:145
void GNUNET_CADET_close_port(struct GNUNET_CADET_Port *p)
Close a port opened with GNUNET_CADET_open_port().
Definition: cadet_api.c:874
static void cadet_test_run(void *cls, struct GNUNET_TESTBED_RunHandle *h, unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers, unsigned int links_succeeded, unsigned int links_failed)
Callback run when the testbed is ready (peers running and connected to each other) ...
void(* GNUNET_CADET_DisconnectEventHandler)(void *cls, const struct GNUNET_CADET_Channel *channel)
Function called whenever an MQ-channel is destroyed, unless the destruction was requested by GNUNET_C...
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:144
A peer controlled by the testing framework.
GNUNET_CADET_TEST_AppMain app_main
Main function of the test to run once all CADETs are available.
library for writing CADET tests
#define GNUNET_free(ptr)
Wrapper around free.