aboutsummaryrefslogtreecommitdiff
path: root/src/messenger/testing_messenger_setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/messenger/testing_messenger_setup.c')
-rw-r--r--src/messenger/testing_messenger_setup.c528
1 files changed, 0 insertions, 528 deletions
diff --git a/src/messenger/testing_messenger_setup.c b/src/messenger/testing_messenger_setup.c
deleted file mode 100644
index 98241fa08..000000000
--- a/src/messenger/testing_messenger_setup.c
+++ /dev/null
@@ -1,528 +0,0 @@
1/*
2 This file is part of GNUnet.
3 Copyright (C) 2020--2021 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 messenger/testing_messenger_barrier.c
22 * @author Tobias Frisch
23 * @brief A simple test-case setup for the messenger service
24 */
25
26#include "testing_messenger_setup.h"
27
28#include <stdio.h>
29#include "platform.h"
30#include "gnunet_util_lib.h"
31#include "gnunet_testbed_logger_service.h"
32#include "gnunet_testbed_service.h"
33#include "gnunet_testing_lib.h"
34#include "gnunet_messenger_service.h"
35#include "testing_messenger_barrier.h"
36
37#define TEST_ROOM "test"
38#define TEST_NAME "tester"
39
40struct test_properties;
41
42struct test_peer {
43 struct test_properties *props;
44 unsigned int num;
45
46 struct GNUNET_SCHEDULER_Task *op_task;
47 struct GNUNET_TESTBED_Operation *op;
48
49 struct GNUNET_TESTBED_Peer *peer;
50 struct GNUNET_PeerIdentity peer_id;
51 struct GNUNET_BarrierWaitHandle *wait;
52
53 struct GNUNET_MESSENGER_Handle *handle;
54 struct GNUNET_MESSENGER_Room *room;
55
56 unsigned int peer_messages;
57
58 const char *message;
59};
60
61struct test_properties {
62 const struct test_configuration *cfg;
63
64 unsigned int num_hosts;
65
66 struct GNUNET_SCHEDULER_Task *die_task;
67 struct GNUNET_SCHEDULER_Task *end_task;
68
69 struct GNUNET_BarrierHandle *barrier;
70
71 struct test_peer *peers;
72 unsigned int num_peer;
73
74 int status;
75};
76
77static void
78shutdown_cb (void *cls)
79{
80 struct test_properties *properties = cls;
81
82
83 for (unsigned int i = 0; i < properties->num_peer; i++)
84 {
85 struct test_peer *peer = &properties->peers[i];
86
87 GNUNET_assert(peer != NULL);
88
89 if (peer->op_task)
90 GNUNET_SCHEDULER_cancel(peer->op_task);
91
92 peer->op_task = NULL;
93
94 if (peer->op)
95 GNUNET_TESTBED_operation_done (peer->op);
96
97 peer->op = NULL;
98
99 if (peer->wait)
100 GNUNET_cancel_wait_barrier(peer->wait);
101
102 peer->wait = NULL;
103
104 if (peer->room)
105 GNUNET_MESSENGER_close_room (peer->room);
106
107 peer->room = NULL;
108
109 if (peer->handle)
110 GNUNET_MESSENGER_disconnect (peer->handle);
111
112 peer->handle = NULL;
113 }
114
115 if (properties->die_task)
116 GNUNET_SCHEDULER_cancel(properties->die_task);
117
118 properties->die_task = NULL;
119 properties->end_task = NULL;
120
121 if (properties->barrier)
122 GNUNET_cancel_barrier(properties->barrier);
123
124 properties->barrier = NULL;
125}
126
127
128
129static void
130end_cb (void *cls)
131{
132 struct test_properties *properties = cls;
133
134 GNUNET_assert(properties != NULL);
135
136 properties->die_task = NULL;
137
138 int status = 0;
139
140 for (unsigned int i = 0; i < properties->num_peer; i++)
141 {
142 struct test_peer *peer = &properties->peers[i];
143
144 GNUNET_assert(peer != NULL);
145
146 const int members = GNUNET_MESSENGER_iterate_members(peer->room, NULL, NULL);
147
148 GNUNET_assert (members >= 0);
149
150 if (peer->props->num_peer != (unsigned int) members)
151 {
152 fprintf (stderr, "Testcase failed (members: %d/%u).\n", members, peer->props->num_peer);
153 status = 1;
154 break;
155 }
156 }
157
158 GNUNET_SCHEDULER_shutdown ();
159
160 properties->status = status;
161}
162
163static void
164end_badly_cb (void *cls)
165{
166 struct test_properties *properties = cls;
167
168 GNUNET_assert(properties != NULL);
169
170 fprintf (stderr, "Testcase failed (timeout).\n");
171
172 end_cb (properties);
173
174 properties->status = 1;
175}
176
177static void
178end_operation_cb (void *cls)
179{
180 struct test_peer *peer = cls;
181
182 GNUNET_assert(peer != NULL);
183
184 peer->op_task = NULL;
185
186 fprintf (stderr, "Testcase failed (operation: '%s').\n", peer->message);
187
188 GNUNET_SCHEDULER_shutdown ();
189}
190
191static void
192end_error_cb (void *cls)
193{
194 struct test_peer *peer = cls;
195
196 GNUNET_assert(peer != NULL);
197
198 peer->op_task = NULL;
199
200 fprintf (stderr, "Testcase failed (error: '%s').\n", peer->message);
201 GNUNET_free (peer);
202
203 GNUNET_SCHEDULER_shutdown ();
204}
205
206static void
207barrier2_wait_cb (void *cls, struct GNUNET_BarrierWaitHandle *waiting, int status)
208{
209 struct test_peer *peer = cls;
210
211 GNUNET_assert(peer != NULL);
212
213 if (peer->wait == waiting)
214 peer->wait = NULL;
215}
216
217static void
218barrier_wait_cb (void *cls, struct GNUNET_BarrierWaitHandle *waiting, int status)
219{
220 struct test_peer *peer = cls;
221
222 GNUNET_assert(peer != NULL);
223
224 if (peer->wait == waiting)
225 peer->wait = NULL;
226
227 if (0 != (peer->props->cfg->stages[peer->num - 1] & 0x02))
228 {
229 unsigned int door = peer->props->cfg->doors[peer->num - 1];
230
231 if (door == 0)
232 door = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, peer->props->cfg->count);
233 else
234 door = door - 1;
235
236 struct GNUNET_HashCode hash;
237 GNUNET_CRYPTO_hash (TEST_ROOM, sizeof(TEST_ROOM), &hash);
238
239 struct GNUNET_MESSENGER_Room *room;
240 room = GNUNET_MESSENGER_enter_room(peer->handle, &(peer->props->peers[door].peer_id), &hash);
241
242 if (peer->room)
243 GNUNET_assert(room == peer->room);
244 else
245 GNUNET_assert(room != NULL);
246
247 peer->room = room;
248 }
249}
250
251/**
252 * Function called whenever a message is received or sent.
253 *
254 * @param cls Closure
255 * @param room Room
256 * @param sender Sender
257 * @param message Message
258 * @param hash Hash of message
259 * @param flags Flags of message
260 */
261static void
262on_message (void *cls, struct GNUNET_MESSENGER_Room *room, const struct GNUNET_MESSENGER_Contact *sender,
263 const struct GNUNET_MESSENGER_Message *message, const struct GNUNET_HashCode *hash,
264 enum GNUNET_MESSENGER_MessageFlags flags)
265{
266 struct test_peer *peer = cls;
267
268 GNUNET_assert(peer != NULL);
269
270 fprintf (stderr, "Peer: %s; [%s] Message: %s (%s)\n",
271 GNUNET_i2s(&(peer->peer_id)),
272 GNUNET_sh2s(&(message->header.sender_id)),
273 GNUNET_MESSENGER_name_of_kind(message->header.kind),
274 GNUNET_h2s(hash));
275
276 if (GNUNET_MESSENGER_KIND_PEER == message->header.kind)
277 peer->peer_messages++;
278
279 if (peer->props->num_hosts == peer->peer_messages)
280 peer->wait = GNUNET_wait_barrier (peer->props->barrier, &barrier2_wait_cb, peer);
281 else if (peer->props->num_hosts < peer->peer_messages)
282 {
283 if (peer->wait)
284 GNUNET_cancel_wait_barrier(peer->wait);
285
286 peer->wait = NULL;
287
288 if (peer->op_task)
289 GNUNET_SCHEDULER_cancel(peer->op_task);
290
291 peer->message = "peer";
292 peer->op_task = GNUNET_SCHEDULER_add_now (&end_operation_cb, peer);
293 }
294}
295
296static void
297second_stage (void *cls)
298{
299 struct test_peer *peer = cls;
300
301 GNUNET_assert(peer != NULL);
302
303 peer->op_task = NULL;
304
305 struct GNUNET_HashCode hash;
306 GNUNET_CRYPTO_hash (TEST_ROOM, sizeof(TEST_ROOM), &hash);
307
308 if (0 != (peer->props->cfg->stages[peer->num - 1] & 0x10))
309 {
310 struct GNUNET_MESSENGER_Room *room;
311 room = GNUNET_MESSENGER_open_room (peer->handle, &hash);
312
313 if (peer->room)
314 GNUNET_assert(room == peer->room);
315 else
316 GNUNET_assert(room != NULL);
317
318 peer->room = room;
319 }
320
321 if (0 != (peer->props->cfg->stages[peer->num - 1] & 0x20))
322 {
323 unsigned int door = peer->props->cfg->doors[peer->num - 1];
324
325 if (door == 0)
326 door = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, peer->props->cfg->count);
327 else
328 door = door - 1;
329
330 struct GNUNET_MESSENGER_Room *room;
331 room = GNUNET_MESSENGER_enter_room(peer->handle, &(peer->props->peers[door].peer_id), &hash);
332
333 if (peer->room)
334 GNUNET_assert(room == peer->room);
335 else
336 GNUNET_assert(room != NULL);
337
338 peer->room = room;
339 }
340}
341
342static void
343on_peer (void *cb_cls, struct GNUNET_TESTBED_Operation *op, const struct GNUNET_TESTBED_PeerInformation *pinfo,
344 const char *emsg)
345{
346 struct test_peer *peer = cb_cls;
347
348 GNUNET_assert(peer != NULL);
349
350 if (emsg)
351 {
352 peer->message = GNUNET_strdup(emsg);
353 peer->op_task = GNUNET_SCHEDULER_add_now (&end_error_cb, peer);
354 return;
355 }
356
357 if (!pinfo)
358 {
359 peer->message = "info";
360 peer->op_task = GNUNET_SCHEDULER_add_now (&end_operation_cb, peer);
361 return;
362 }
363
364 if (pinfo->pit != GNUNET_TESTBED_PIT_CONFIGURATION)
365 {
366 peer->message = "config";
367 peer->op_task = GNUNET_SCHEDULER_add_now (&end_operation_cb, peer);
368 return;
369 }
370
371 peer->handle = GNUNET_MESSENGER_connect (pinfo->result.cfg, TEST_NAME, NULL, NULL, &on_message, peer);
372
373 GNUNET_assert(GNUNET_OK == GNUNET_CRYPTO_get_peer_identity(
374 pinfo->result.cfg, &(peer->peer_id)
375 ));
376
377 if (0 != (peer->props->cfg->stages[peer->num - 1] & 0x01))
378 {
379 struct GNUNET_HashCode hash;
380 GNUNET_CRYPTO_hash (TEST_ROOM, sizeof(TEST_ROOM), &hash);
381
382 peer->room = GNUNET_MESSENGER_open_room (peer->handle, &hash);
383
384 GNUNET_assert(peer->room != NULL);
385 }
386 else
387 peer->room = NULL;
388
389 peer->wait = GNUNET_wait_barrier (peer->props->barrier, &barrier_wait_cb, peer);
390}
391
392/**
393 * Main function for a peer of the testcase.
394 *
395 * @param cls Closure
396 * @param event Information about the event
397 */
398static void
399run (void *cls, const struct GNUNET_TESTBED_EventInformation *event)
400{
401 struct test_properties *properties = cls;
402
403 GNUNET_assert(properties != NULL);
404
405 if (GNUNET_TESTBED_ET_PEER_START != event->type)
406 {
407 fprintf (stderr, "Testcase failed (operation: 'start').\n");
408
409 GNUNET_SCHEDULER_shutdown ();
410 return;
411 }
412
413 struct test_peer *peer = &(properties->peers[properties->num_peer++]);
414
415 peer->props = properties;
416 peer->num = properties->num_peer;
417
418 peer->peer = event->details.peer_start.peer;
419 peer->op = GNUNET_TESTBED_peer_get_information (peer->peer, GNUNET_TESTBED_PIT_CONFIGURATION, on_peer, peer);
420}
421
422static void
423barrier2_cb (void *cls, struct GNUNET_BarrierHandle *barrier, int status)
424{
425 struct test_properties *properties = cls;
426
427 GNUNET_assert(properties != NULL);
428
429 if (properties->barrier == barrier)
430 properties->barrier = NULL;
431
432 if (GNUNET_SYSERR == status)
433 {
434 fprintf (stderr, "Testcase failed (operation: 'barrier2').\n");
435
436 GNUNET_SCHEDULER_shutdown ();
437 return;
438 }
439 else if (GNUNET_OK == status)
440 {
441 if (properties->die_task)
442 GNUNET_SCHEDULER_cancel(properties->die_task);
443
444 properties->die_task = GNUNET_SCHEDULER_add_delayed (
445 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, properties->cfg->count),
446 &end_cb, properties
447 );
448 }
449}
450
451static void
452barrier_cb (void *cls, struct GNUNET_BarrierHandle *barrier, int status)
453{
454 struct test_properties *properties = cls;
455
456 GNUNET_assert(properties != NULL);
457
458 if (properties->barrier == barrier)
459 properties->barrier = NULL;
460 else if (!properties->barrier)
461 return;
462
463 if (properties->num_peer != properties->cfg->count)
464 {
465 fprintf (stderr, "Testcase failed (operation: 'process').\n");
466
467 GNUNET_SCHEDULER_shutdown ();
468 return;
469 }
470
471 if (GNUNET_SYSERR == status)
472 {
473 fprintf (stderr, "Testcase failed (operation: 'barrier').\n");
474
475 GNUNET_SCHEDULER_shutdown ();
476 return;
477 }
478 else if (GNUNET_OK == status)
479 {
480 properties->barrier = GNUNET_init_barrier (properties->num_peer, &barrier2_cb, properties);
481
482 for (unsigned int i = 0; i < properties->num_peer; i++)
483 properties->peers[i].op_task = GNUNET_SCHEDULER_add_now (&second_stage, &(properties->peers[i]));
484 }
485}
486
487static void
488init (void *cls, struct GNUNET_TESTBED_RunHandle *h, unsigned int num_peers, struct GNUNET_TESTBED_Peer **peers,
489 unsigned int links_succeeded, unsigned int links_failed)
490{
491 struct test_properties *properties = cls;
492
493 GNUNET_assert(properties != NULL);
494
495 properties->end_task = GNUNET_SCHEDULER_add_shutdown(&shutdown_cb, properties);
496 properties->die_task = GNUNET_SCHEDULER_add_delayed (
497 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, properties->cfg->count * 5),
498 &end_badly_cb, properties
499 );
500}
501
502int
503GNUNET_run_messenger_setup (const char* test_name, const struct test_configuration *cfg)
504{
505 struct test_properties properties;
506 memset(&properties, 0, sizeof(properties));
507
508 properties.cfg = cfg;
509 properties.peers = GNUNET_new_array(cfg->count, struct test_peer);
510
511 for (unsigned int i = 0; i < cfg->count; i++)
512 if (0 != (cfg->stages[i] & 0x11))
513 properties.num_hosts++;
514
515 properties.status = 1;
516 properties.barrier = GNUNET_init_barrier (cfg->count, &barrier_cb, &properties);
517
518 if (GNUNET_OK != GNUNET_TESTBED_test_run (test_name, "test_messenger_api.conf",
519 cfg->count,
520 (1LL << GNUNET_TESTBED_ET_PEER_START),
521 &run, &properties,
522 &init, &properties))
523 return 1;
524
525 GNUNET_free(properties.peers);
526
527 return properties.status;
528}