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