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