fixed stupid copy paste
[oweals/gnunet.git] / src / multicast / test_multicast.c
1 /*
2  * This file is part of GNUnet
3  * Copyright (C) 2013 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 /**
22  * @file multicast/test_multicast.c
23  * @brief Tests for the Multicast API.
24  * @author Gabor X Toth
25  */
26
27 #include <inttypes.h>
28
29 #include "platform.h"
30 #include "gnunet_crypto_lib.h"
31 #include "gnunet_common.h"
32 #include "gnunet_util_lib.h"
33 #include "gnunet_testing_lib.h"
34 #include "gnunet_multicast_service.h"
35
36 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
37
38 /**
39  * Return value from 'main'.
40  */
41 static int res;
42
43 /**
44  * Handle for task for timeout termination.
45  */
46 static struct GNUNET_SCHEDULER_Task * end_badly_task;
47
48 static const struct GNUNET_CONFIGURATION_Handle *cfg;
49
50 struct GNUNET_PeerIdentity this_peer;
51
52 struct GNUNET_MULTICAST_Origin *origin;
53 struct GNUNET_MULTICAST_Member *member;
54
55 struct GNUNET_CRYPTO_EddsaPrivateKey *group_key;
56 struct GNUNET_CRYPTO_EddsaPublicKey group_pub_key;
57
58 struct GNUNET_CRYPTO_EcdsaPrivateKey *member_key;
59 struct GNUNET_CRYPTO_EcdsaPublicKey member_pub_key;
60
61 struct TransmitClosure {
62   struct GNUNET_MULTICAST_OriginTransmitHandle *orig_tmit;
63   struct GNUNET_MULTICAST_MemberTransmitHandle *mem_tmit;
64   char * data[16];
65   uint8_t data_delay[16];
66   uint8_t data_count;
67   uint8_t paused;
68   uint8_t n;
69 } tmit_cls;
70
71 struct OriginClosure {
72   uint8_t msgs_expected;
73   uint8_t n;
74 } origin_cls;
75
76 struct MemberClosure {
77   uint8_t msgs_expected;
78   size_t n;
79 } member_cls;
80
81 struct GNUNET_MessageHeader *join_req, *join_resp;
82
83 enum
84 {
85   TEST_NONE                = 0,
86   TEST_ORIGIN_START        = 1,
87   TEST_MEMBER_JOIN_REFUSE  = 2,
88   TEST_MEMBER_JOIN_ADMIT   = 3,
89   TEST_ORIGIN_TO_ALL       = 4,
90   TEST_ORIGIN_TO_ALL_RECV  = 5,
91   TEST_MEMBER_TO_ORIGIN    = 6,
92   TEST_MEMBER_REPLAY_ERROR = 7,
93   TEST_MEMBER_REPLAY_OK    = 8,
94   TEST_MEMBER_PART         = 9,
95   TEST_ORIGIN_STOP        = 10,
96 } test;
97
98 uint64_t replay_fragment_id;
99 uint64_t replay_flags;
100
101 static void
102 member_join (int t);
103
104
105 /**
106  * Clean up all resources used.
107  */
108 static void
109 cleanup ()
110 {
111   if (NULL != member)
112   {
113     GNUNET_MULTICAST_member_part (member, NULL, NULL);
114     member = NULL;
115   }
116   if (NULL != origin)
117   {
118     GNUNET_MULTICAST_origin_stop (origin, NULL, NULL);
119     origin = NULL;
120   }
121 }
122
123
124 /**
125  * Terminate the test case (failure).
126  *
127  * @param cls NULL
128  */
129 static void
130 end_badly (void *cls)
131 {
132   res = 1;
133   cleanup ();
134   GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Test FAILED.\n");
135 }
136
137
138 /**
139  * Terminate the test case (success).
140  *
141  * @param cls NULL
142  */
143 static void
144 end_normally (void *cls)
145 {
146   res = 0;
147   cleanup ();
148   GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Test PASSED.\n");
149 }
150
151
152 /**
153  * Finish the test case (successfully).
154  */
155 static void
156 end ()
157 {
158   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending tests.\n");
159
160   if (end_badly_task != NULL)
161   {
162     GNUNET_SCHEDULER_cancel (end_badly_task);
163     end_badly_task = NULL;
164   }
165   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MILLISECONDS,
166                                 &end_normally, NULL);
167 }
168
169
170 static void
171 tmit_resume (void *cls)
172 {
173   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission resumed.\n");
174   struct TransmitClosure *tmit = cls;
175   if (NULL != tmit->orig_tmit)
176     GNUNET_MULTICAST_origin_to_all_resume (tmit->orig_tmit);
177   else if (NULL != tmit->mem_tmit)
178     GNUNET_MULTICAST_member_to_origin_resume (tmit->mem_tmit);
179 }
180
181
182 static int
183 tmit_notify (void *cls, size_t *data_size, void *data)
184 {
185   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
186               "Test #%u: origin_tmit_notify()\n", test);
187   struct TransmitClosure *tmit = cls;
188
189   if (0 == tmit->data_count)
190   {
191     *data_size = 0;
192     return GNUNET_YES;
193   }
194
195   uint16_t size = strlen (tmit->data[tmit->n]);
196   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
197               "Transmit notify data: %u bytes available, processing fragment %u/%u (size %u).\n",
198               (unsigned int) *data_size,
199               tmit->n + 1,
200               tmit->data_count,
201               size);
202   if (*data_size < size)
203   {
204     *data_size = 0;
205     GNUNET_assert (0);
206     return GNUNET_SYSERR;
207   }
208
209   if (GNUNET_YES != tmit->paused && 0 < tmit->data_delay[tmit->n])
210   {
211     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission paused.\n");
212     tmit->paused = GNUNET_YES;
213     GNUNET_SCHEDULER_add_delayed (
214       GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
215                                      tmit->data_delay[tmit->n]),
216       tmit_resume, tmit);
217     *data_size = 0;
218     return GNUNET_NO;
219   }
220   tmit->paused = GNUNET_NO;
221
222   *data_size = size;
223   GNUNET_memcpy (data, tmit->data[tmit->n], size);
224
225   return ++tmit->n < tmit->data_count ? GNUNET_NO : GNUNET_YES;
226 }
227
228
229 static void
230 member_recv_join_request (void *cls,
231                           const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
232                           const struct GNUNET_MessageHeader *join_msg,
233                           struct GNUNET_MULTICAST_JoinHandle *jh)
234 {
235   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
236               "Test #%u: member_recv_join_request()\n", test);
237 }
238
239
240 static void
241 origin_stopped (void *cls)
242 {
243   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
244               "Test #%u: origin_stopped()\n", test);
245   end ();
246 }
247
248
249 static void
250 schedule_origin_stop (void *cls)
251 {
252   test = TEST_ORIGIN_STOP;
253   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
254               "Test #%u: origin_stop()\n", test);
255   GNUNET_MULTICAST_origin_stop (origin, origin_stopped, NULL);
256   origin = NULL;
257 }
258
259
260 static void
261 member_parted (void *cls)
262 {
263   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
264               "Test #%u: member_parted()\n", test);
265   member = NULL;
266
267   switch (test)
268   {
269   case TEST_MEMBER_JOIN_REFUSE:
270     // Test 3 starts here
271     member_join (TEST_MEMBER_JOIN_ADMIT);
272     break;
273
274   case TEST_MEMBER_PART:
275     GNUNET_SCHEDULER_add_now (&schedule_origin_stop, NULL);
276     break;
277
278   default:
279     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
280                 "Invalid test #%d in member_parted()\n", test);
281     GNUNET_assert (0);
282   }
283 }
284
285
286 static void
287 schedule_member_part (void *cls)
288 {
289   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
290               "Test #%u: schedule_member_part()\n", test);
291   GNUNET_MULTICAST_member_part (member, member_parted, NULL);
292 }
293
294
295 static void
296 member_part ()
297 {
298   test = TEST_MEMBER_PART;
299   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
300               "Test #%u: member_part()\n", test);
301   // Test 10 starts here
302   GNUNET_SCHEDULER_add_now (&schedule_member_part, NULL);
303 }
304
305
306 static void
307 member_replay_ok ()
308 {
309   // Execution of test 8 here
310   test = TEST_MEMBER_REPLAY_OK;
311   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
312               "Test #%u: member_replay_ok()\n", test);
313   replay_fragment_id = 1;
314   replay_flags = 1 | 1<<11;
315   GNUNET_MULTICAST_member_replay_fragment (member, replay_fragment_id,
316                                            replay_flags);
317 }
318
319
320 static void
321 member_replay_error ()
322 {
323   test = TEST_MEMBER_REPLAY_ERROR;
324   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
325               "Test #%u: member_replay_error()\n", test);
326   replay_fragment_id = 1234;
327   replay_flags = 11 | 1<<11;
328   GNUNET_MULTICAST_member_replay_fragment (member, replay_fragment_id,
329                                            replay_flags);
330 }
331
332
333 static void
334 origin_recv_replay_msg (void *cls,
335                         const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
336                         uint64_t message_id,
337                         uint64_t fragment_offset,
338                         uint64_t flags,
339                         struct GNUNET_MULTICAST_ReplayHandle *rh)
340 {
341   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
342               "Test #%u: origin_recv_replay_msg()\n", test);
343   GNUNET_assert (0);
344 }
345
346
347 static void
348 member_recv_replay_msg (void *cls,
349                         const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
350                         uint64_t message_id,
351                         uint64_t fragment_offset,
352                         uint64_t flags,
353                         struct GNUNET_MULTICAST_ReplayHandle *rh)
354 {
355   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
356               "Test #%u: member_recv_replay_msg()\n", test);
357   GNUNET_assert (0);
358 }
359
360
361 static void
362 origin_recv_replay_frag (void *cls,
363                          const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
364                          uint64_t fragment_id,
365                          uint64_t flags,
366                          struct GNUNET_MULTICAST_ReplayHandle *rh)
367 {
368   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
369               "Test #%u: origin_recv_replay_frag()"
370               " - fragment_id=%" PRIu64 " flags=%" PRIu64 "\n",
371               test, fragment_id, flags);
372   GNUNET_assert (replay_fragment_id == fragment_id && replay_flags == flags);
373   switch (test)
374   {
375   case TEST_MEMBER_REPLAY_ERROR:
376     // Test 8 starts here
377     GNUNET_MULTICAST_replay_response (rh, NULL, GNUNET_SYSERR);
378     member_replay_ok ();
379     break;
380
381   case TEST_MEMBER_REPLAY_OK:
382   {
383     struct GNUNET_MULTICAST_MessageHeader mmsg = {
384       .header = {
385         .type = htons (GNUNET_MESSAGE_TYPE_MULTICAST_MESSAGE),
386         .size = htons (sizeof (mmsg)),
387       },
388       .fragment_id = GNUNET_htonll (1),
389       .message_id = GNUNET_htonll (1),
390       .fragment_offset = 0,
391       .group_generation = GNUNET_htonll (1),
392       .flags = 0,
393     };
394     member_cls.n = 0;
395     member_cls.msgs_expected = 1;
396     GNUNET_MULTICAST_replay_response (rh, &mmsg.header, GNUNET_MULTICAST_REC_OK);
397     GNUNET_MULTICAST_replay_response_end (rh);
398     break;
399   }
400
401   default:
402     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
403                 "Invalid test #%d in origin_recv_replay_frag()\n", test);
404     GNUNET_assert (0);
405   }
406 }
407
408
409 static void
410 member_recv_replay_frag (void *cls,
411                          const struct GNUNET_CRYPTO_EcdsaPublicKey *member_key,
412                          uint64_t fragment_id,
413                          uint64_t flags,
414                          struct GNUNET_MULTICAST_ReplayHandle *rh)
415 {
416   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
417               "Test #%u: member_recv_replay_frag()\n", test);
418   GNUNET_assert (0);
419 }
420
421
422 static void
423 origin_recv_request (void *cls,
424                      const struct GNUNET_MULTICAST_RequestHeader *req)
425 {
426   struct OriginClosure *ocls = cls;
427   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
428               "Test #%u: origin_recv_request()\n", test);
429   if (++ocls->n != ocls->msgs_expected)
430     return;
431
432   GNUNET_assert (0 == memcmp (&req->member_pub_key,
433                               &member_pub_key, sizeof (member_pub_key)));
434
435   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
436               "Test #%u: verify message content, take first 3 bytes: %.3s\n",
437               test, (char *)&req[1]);
438   GNUNET_assert (0 == memcmp (&req[1], "abc", 3));
439
440   // Test 7 starts here
441   member_replay_error ();
442 }
443
444
445 static void
446 member_to_origin ()
447 {
448   test = TEST_MEMBER_TO_ORIGIN;
449   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
450               "Test #%u: member_to_origin()\n", test);
451
452   struct TransmitClosure *tmit = &tmit_cls;
453   *tmit = (struct TransmitClosure) {};
454   tmit->data[0] = "abc def";
455   tmit->data[1] = "ghi jkl mno";
456   tmit->data_delay[1] = 2;
457   tmit->data[2] = "pqr stuw xyz";
458   tmit->data_count = 3;
459
460   origin_cls.n = 0;
461   origin_cls.msgs_expected = 1;
462
463   tmit->mem_tmit = GNUNET_MULTICAST_member_to_origin (member, 1,
464                                                       tmit_notify, tmit);
465 }
466
467
468 static void
469 member_recv_message (void *cls,
470                      const struct GNUNET_MULTICAST_MessageHeader *msg)
471 {
472   struct MemberClosure *mcls = cls;
473
474   // Test 5 starts here after message has been received from origin
475   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
476               "Test #%u: member_recv_message() %u/%u\n",
477               test,
478               (unsigned int) (mcls->n + 1),
479               mcls->msgs_expected);
480   if (++mcls->n != mcls->msgs_expected)
481     return;
482
483   // FIXME: check message content
484
485   switch (test)
486   {
487   case TEST_ORIGIN_TO_ALL:
488     test = TEST_ORIGIN_TO_ALL_RECV;
489     break;
490
491   case TEST_ORIGIN_TO_ALL_RECV:
492     // Test 6 starts here
493     member_to_origin ();
494     break;
495
496   case TEST_MEMBER_REPLAY_OK:
497     // Test 9 starts here
498     GNUNET_assert (replay_fragment_id == GNUNET_ntohll (msg->fragment_id));
499     member_part ();
500     break;
501
502   default:
503     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
504                 "Invalid test #%d in origin_recv_message()\n", test);
505     GNUNET_assert (0);
506   }
507 }
508
509
510 static void
511 origin_recv_message (void *cls,
512                      const struct GNUNET_MULTICAST_MessageHeader *msg)
513 {
514   struct OriginClosure *ocls = cls;
515   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
516               "Test #%u: origin_recv_message() %u/%u\n",
517               test, ocls->n + 1, ocls->msgs_expected);
518   if (++ocls->n != ocls->msgs_expected)
519     return;
520
521   // FIXME: check message content
522
523   switch (test)
524   {
525   case TEST_ORIGIN_TO_ALL:
526     // Prepare to execute test 5
527     test = TEST_ORIGIN_TO_ALL_RECV;
528     break;
529
530   case TEST_ORIGIN_TO_ALL_RECV:
531     // Test 6 starts here
532     member_to_origin ();
533     break;
534
535   default:
536     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
537                 "Invalid test #%d in origin_recv_message()\n", test);
538     GNUNET_assert (0);
539   }
540 }
541
542
543 static void
544 origin_to_all ()
545 {
546   test = TEST_ORIGIN_TO_ALL;
547   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
548               "Test #%u: origin_to_all()\n", test);
549
550   struct TransmitClosure *tmit = &tmit_cls;
551   *tmit = (struct TransmitClosure) {};
552   tmit->data[0] = "ABC DEF";
553   tmit->data[1] =  GNUNET_malloc (GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD + 1);
554   uint16_t i;
555   for (i = 0; i < GNUNET_MULTICAST_FRAGMENT_MAX_PAYLOAD; i++)
556     tmit->data[1][i] = (0 == i % 10000) ? '0' + i / 10000 : '_';
557   tmit->data[2] = "GHI JKL MNO";
558   tmit->data_delay[2] = 2;
559   tmit->data[3] = "PQR STUW XYZ";
560   tmit->data_count = 4;
561
562   origin_cls.n = member_cls.n = 0;
563   origin_cls.msgs_expected = member_cls.msgs_expected = tmit->data_count;
564
565   tmit->orig_tmit = GNUNET_MULTICAST_origin_to_all (origin, 1, 1,
566                                                     tmit_notify, tmit);
567 }
568
569
570 static void
571 member_recv_join_decision (void *cls,
572                            int is_admitted,
573                            const struct GNUNET_PeerIdentity *peer,
574                            uint16_t relay_count,
575                            const struct GNUNET_PeerIdentity *relays,
576                            const struct GNUNET_MessageHeader *join_msg)
577 {
578   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
579               "Test #%u: member_recv_join_decision() - is_admitted: %d\n",
580               test, is_admitted);
581
582   GNUNET_assert (join_msg->size == join_resp->size);
583   GNUNET_assert (join_msg->type == join_resp->type);
584   GNUNET_assert (0 == memcmp (join_msg, join_resp, ntohs (join_resp->size)));
585
586   switch (test)
587   {
588   case TEST_MEMBER_JOIN_REFUSE:
589     GNUNET_assert (0 == relay_count);
590     // Test 3 starts here
591     GNUNET_SCHEDULER_add_now (&schedule_member_part, NULL);
592     break;
593
594   case TEST_MEMBER_JOIN_ADMIT:
595     GNUNET_assert (1 == relay_count);
596     GNUNET_assert (0 == memcmp (relays, &this_peer, sizeof (this_peer)));
597     // Test 4 starts here
598     origin_to_all ();
599     break;
600
601   default:
602     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
603                 "Invalid test #%d in member_recv_join_decision()\n", test);
604     GNUNET_assert (0);
605   }
606 }
607
608 /**
609  * Test: origin receives join request
610  */
611 static void
612 origin_recv_join_request (void *cls,
613                           const struct GNUNET_CRYPTO_EcdsaPublicKey *mem_key,
614                           const struct GNUNET_MessageHeader *join_msg,
615                           struct GNUNET_MULTICAST_JoinHandle *jh)
616 {
617   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
618               "Test #%u: origin_recv_join_request()\n", test);
619
620   GNUNET_assert (0 == memcmp (mem_key, &member_pub_key, sizeof (member_pub_key)));
621   GNUNET_assert (join_msg->size == join_req->size);
622   GNUNET_assert (join_msg->type == join_req->type);
623   GNUNET_assert (0 == memcmp (join_msg, join_req, ntohs (join_req->size)));
624
625   char data[] = "here's the decision";
626   uint8_t data_size = strlen (data) + 1;
627   join_resp = GNUNET_malloc (sizeof (join_resp) + data_size);
628   join_resp->size = htons (sizeof (join_resp) + data_size);
629   join_resp->type = htons (456);
630   GNUNET_memcpy (&join_resp[1], data, data_size);
631
632   switch (test)
633   {
634   case TEST_MEMBER_JOIN_REFUSE:
635     // Test 3 starts here
636     GNUNET_MULTICAST_join_decision (jh, GNUNET_NO, 0, NULL, join_resp);
637     break;
638
639   case TEST_MEMBER_JOIN_ADMIT:
640     // Test 3 is running
641     GNUNET_MULTICAST_join_decision (jh, GNUNET_YES, 1, &this_peer, join_resp);
642     break;
643
644   default:
645     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
646                 "Invalid test #%d in origin_recv_join_request()\n", test);
647     GNUNET_assert (0);
648     break;
649   }
650 }
651
652 /**
653  * Test: member joins multicast group
654  */
655 static void
656 member_join (int t)
657 {
658   test = t;
659   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
660               "Test #%u: member_join()\n", test);
661
662   member_key = GNUNET_CRYPTO_ecdsa_key_create ();
663   GNUNET_CRYPTO_ecdsa_key_get_public (member_key, &member_pub_key);
664
665   if (NULL != join_req)
666     GNUNET_free (join_req);
667
668   char data[] = "let me in!";
669   uint8_t data_size = strlen (data) + 1;
670   join_req = GNUNET_malloc (sizeof (join_req) + data_size);
671   join_req->size = htons (sizeof (join_req) + data_size);
672   join_req->type = htons (123);
673   GNUNET_memcpy (&join_req[1], data, data_size);
674
675   member = GNUNET_MULTICAST_member_join (cfg, &group_pub_key, member_key,
676                                          &this_peer, 1, &this_peer, join_req,
677                                          member_recv_join_request,
678                                          member_recv_join_decision,
679                                          member_recv_replay_frag,
680                                          member_recv_replay_msg,
681                                          member_recv_message,
682                                          &member_cls);
683 }
684
685 /**
686  * Test: Start a multicast group as origin
687  */
688 static void
689 origin_start ()
690 {
691   test = TEST_ORIGIN_START;
692   GNUNET_log (GNUNET_ERROR_TYPE_INFO,
693               "Test #%u: origin_start()\n", test);
694
695   group_key = GNUNET_CRYPTO_eddsa_key_create ();
696   GNUNET_CRYPTO_eddsa_key_get_public (group_key, &group_pub_key);
697
698   origin = GNUNET_MULTICAST_origin_start (cfg, group_key, 0,
699                                           origin_recv_join_request,
700                                           origin_recv_replay_frag,
701                                           origin_recv_replay_msg,
702                                           origin_recv_request,
703                                           origin_recv_message,
704                                           &origin_cls);
705   // Test 2 starts here
706   member_join (TEST_MEMBER_JOIN_REFUSE);
707 }
708
709
710 /**
711  * Main function of the test, run from scheduler.
712  *
713  * @param cls NULL
714  * @param cfg configuration we use (also to connect to Multicast service)
715  * @param peer handle to access more of the peer (not used)
716  */
717 static void
718 #if DEBUG_TEST_MULTICAST
719 run (void *cls,
720      char *const *args,
721      const char *cfgfile,
722      const struct GNUNET_CONFIGURATION_Handle *c)
723 #else
724 run (void *cls,
725      const struct GNUNET_CONFIGURATION_Handle *c,
726      struct GNUNET_TESTING_Peer *peer)
727 #endif
728 {
729   cfg = c;
730   end_badly_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
731                                                  &end_badly, NULL);
732   GNUNET_CRYPTO_get_peer_identity (cfg, &this_peer);
733
734   // Test 1 starts here
735   origin_start ();
736 }
737
738
739 int
740 main (int argc, char *argv[])
741 {
742   res = 1;
743 #if DEBUG_TEST_MULTICAST
744   const struct GNUNET_GETOPT_CommandLineOption opts[] = {
745     GNUNET_GETOPT_OPTION_END
746   };
747   if (GNUNET_OK != GNUNET_PROGRAM_run (argc, argv, "test-multicast",
748                                        "test-multicast [options]",
749                                        opts, &run, NULL))
750     return 1;
751 #else
752   if (0 != GNUNET_TESTING_peer_run ("test-multicast", "test_multicast.conf", &run, NULL))
753     return 1;
754 #endif
755   return res;
756 }
757
758 /* end of test_multicast.c */