87b0620eede69c2ed3555bc8cd77be493f1bcda4
[oweals/gnunet.git] / src / rps / test_rps.c
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2009, 2012 Christian Grothoff (and other contributing authors)
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., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20 /**
21  * @file rps/test_rps_multipeer.c
22  * @brief Testcase for the random peer sampling service.  Starts
23  *        a peergroup with a given number of peers, then waits to
24  *        receive size pushes/pulls from each peer.  Expects to wait
25  *        for one message from each peer.
26  */
27 #include "platform.h"
28 #include "gnunet_util_lib.h"
29 #include "gnunet_testbed_service.h"
30 #include "gnunet_rps_service.h"
31
32 #include <inttypes.h>
33
34
35 /**
36  * How many peers do we start?
37  */
38 #define NUM_PEERS 5
39
40 /**
41  * How long do we run the test?
42  */
43 #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
44
45
46 /**
47  * Portion of malicious peers
48  */
49 static double portion = .1;
50
51 /**
52  * Type of malicious peer to test
53  */
54 static unsigned int mal_type = 0;
55
56 /**
57  * Handles to all of the running peers
58  */
59 static struct GNUNET_TESTBED_Peer **testbed_peers;
60
61
62 /**
63  * Operation map entry
64  */
65 struct OpListEntry
66 {
67   /**
68    * DLL next ptr
69    */
70   struct OpListEntry *next;
71
72   /**
73    * DLL prev ptr
74    */
75   struct OpListEntry *prev;
76
77   /**
78    * The testbed operation
79    */
80   struct GNUNET_TESTBED_Operation *op;
81
82   /**
83    * Depending on whether we start or stop NSE service at the peer set this to 1
84    * or -1
85    */
86   int delta;
87
88   /**
89    * Index of the regarding peer
90    */
91   unsigned int index;
92 };
93
94 /**
95  * OpList DLL head
96  */
97 static struct OpListEntry *oplist_head;
98
99 /**
100  * OpList DLL tail
101  */
102 static struct OpListEntry *oplist_tail;
103
104
105 /**
106  * Information we track for each peer.
107  */
108 struct RPSPeer
109 {
110   /**
111    * Index of the peer.
112    */
113   unsigned int index;
114
115   /**
116    * Handle for RPS connect operation.
117    */
118   struct GNUNET_TESTBED_Operation *op;
119
120   /**
121    * Handle to RPS service.
122    */
123   struct GNUNET_RPS_Handle *rps_handle;
124
125   /**
126    * ID of the peer.
127    */
128   struct GNUNET_PeerIdentity *peer_id;
129
130   /**
131    * A request handle to check for an request
132    */
133   //struct GNUNET_RPS_Request_Handle *req_handle;
134
135   /**
136    * Peer on- or offline?
137    */
138   int online;
139
140   /**
141    * Received PeerIDs
142    */
143   struct GNUNET_PeerIdentity *rec_ids;
144
145   /**
146    * Number of received PeerIDs
147    */
148   unsigned int num_rec_ids;
149 };
150
151
152 /**
153  * Information for all the peers.
154  */
155 static struct RPSPeer rps_peers[NUM_PEERS];
156
157 /**
158  * IDs of the peers.
159  */
160 static struct GNUNET_PeerIdentity rps_peer_ids[NUM_PEERS];
161
162 /**
163  * Number of online peers.
164  */
165 static unsigned int num_peers_online;
166
167 /**
168  * Return value from 'main'.
169  */
170 static int ok;
171
172
173 /**
174  * Identifier for the churn task that runs periodically
175  */
176 static struct GNUNET_SCHEDULER_Task *churn_task;
177
178
179 /**
180  * Called directly after connecting to the service
181  */
182 typedef void (*PreTest) (void *cls, struct GNUNET_RPS_Handle *h);
183
184 /**
185  * Called from within #rps_connect_complete_cb ()
186  * Executes functions to test the api/service
187  */
188 typedef void (*MainTest) (struct RPSPeer *rps_peer);
189
190 /**
191  * Called directly before disconnecting from the service
192  */
193 typedef void (*PostTest) (void *cls, struct GNUNET_RPS_Handle *h);
194
195 /**
196  * Function called after disconnect to evaluate test success
197  */
198 typedef int (*EvaluationCallback) (void);
199
200
201 /**
202  * Structure to define a single test
203  */
204 struct SingleTestRun
205 {
206   /**
207    * Called directly after connecting to the service
208    */
209   PreTest pre_test;
210
211   /**
212    * Function to execute the functions to be tested
213    */
214   MainTest main_test;
215
216   /**
217    * Called directly before disconnecting from the service
218    */
219   PostTest post_test;
220
221   /**
222    * Function to evaluate the test results
223    */
224   EvaluationCallback eval_cb;
225 } cur_test_run;
226
227
228 /**
229  * Test the success of a single test
230  */
231 static int
232 evaluate (struct RPSPeer *loc_rps_peers,
233           unsigned int num_loc_rps_peers,
234           unsigned int expected_recv)
235 {
236   unsigned int i;
237   int tmp_ok;
238
239   tmp_ok = (1 == loc_rps_peers[0].num_rec_ids);
240
241   for (i = 0 ; i < num_loc_rps_peers ; i++)
242   {
243     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
244                 "%u. peer [%s] received %u of %u expected peer_ids: %i\n",
245                 i,
246                 GNUNET_i2s (loc_rps_peers[i].peer_id),
247                 loc_rps_peers[i].num_rec_ids,
248                 expected_recv,
249                 (1 == loc_rps_peers[i].num_rec_ids));
250     tmp_ok &= (1 == loc_rps_peers[i].num_rec_ids);
251   }
252   return tmp_ok? 0 : 1;
253 }
254
255
256 /**
257  * Creates an oplist entry and adds it to the oplist DLL
258  */
259 static struct OpListEntry *
260 make_oplist_entry ()
261 {
262   struct OpListEntry *entry;
263
264   entry = GNUNET_new (struct OpListEntry);
265   GNUNET_CONTAINER_DLL_insert_tail (oplist_head, oplist_tail, entry);
266   return entry;
267 }
268
269
270 /**
271  * Callback to be called when NSE service is started or stopped at peers
272  *
273  * @param cls NULL
274  * @param op the operation handle
275  * @param emsg NULL on success; otherwise an error description
276  */
277 static void
278 churn_cb (void *cls,
279                    struct GNUNET_TESTBED_Operation *op,
280                    const char *emsg)
281 {
282   struct OpListEntry *entry = cls;
283
284   GNUNET_TESTBED_operation_done (entry->op);
285   if (NULL != emsg)
286   {
287     //LOG (GNUNET_ERROR_TYPE_ERROR, "Failed to start/stop NSE at a peer\n");
288     GNUNET_SCHEDULER_shutdown ();
289     return;
290   }
291   GNUNET_assert (0 != entry->delta);
292
293   num_peers_online += entry->delta;
294
295   if (0 < entry->delta)
296   { /* Peer hopefully just went online */
297     GNUNET_break (GNUNET_NO == rps_peers[entry->index].online);
298     rps_peers[entry->index].online = GNUNET_YES;
299   }
300   else if (0 > entry->delta)
301   { /* Peer hopefully just went offline */
302     GNUNET_break (GNUNET_YES == rps_peers[entry->index].online);
303     rps_peers[entry->index].online = GNUNET_NO;
304   }
305
306   GNUNET_CONTAINER_DLL_remove (oplist_head, oplist_tail, entry);
307   GNUNET_free (entry);
308   //if (num_peers_in_round[current_round] == peers_running)
309   //  run_round ();
310 }
311
312
313 /**
314  * Task run on timeout to shut everything down.
315  */
316 static void
317 shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
318 {
319   unsigned int i;
320
321   if (NULL != churn_task)
322     GNUNET_SCHEDULER_cancel (churn_task);
323
324   for (i = 0 ; i < num_peers ; i++)
325     GNUNET_TESTBED_operation_done (rps_peers[i].op);
326   GNUNET_SCHEDULER_shutdown ();
327 }
328
329
330 /**
331  * Callback to call on receipt of a reply
332  *
333  * @param cls closure
334  * @param n number of peers
335  * @param recv_peers the received peers
336  */
337 static void
338 handle_reply (void *cls, uint64_t n, const struct GNUNET_PeerIdentity *recv_peers)
339 {
340   struct RPSPeer *rps_peer = (struct RPSPeer *) cls;
341   unsigned int i;
342
343   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
344               "[%s] got %" PRIu64 " peers:\n",
345               GNUNET_i2s (rps_peer->peer_id),
346               n);
347   
348   for (i = 0 ; i < n ; i++)
349   {
350     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
351                 "%u: %s\n",
352                 i,
353                 GNUNET_i2s (&recv_peers[i]));
354
355     GNUNET_array_append (rps_peer->rec_ids, rps_peer->num_rec_ids, recv_peers[i]);
356   }
357 }
358
359
360 /**
361  * Request random peers.
362  */
363   void
364 request_peers (void *cls,
365                const struct GNUNET_SCHEDULER_TaskContext *tc)
366 {
367   struct RPSPeer *rps_peer = (struct RPSPeer *) cls;
368
369   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
370               "Requesting one peer\n");
371
372   (void) GNUNET_RPS_request_peers (rps_peer->rps_handle, 1, handle_reply, rps_peer);
373   //rps_peer->req_handle = GNUNET_RPS_request_peers (rps_peer->rps_handle, 1, handle_reply, rps_peer);
374 }
375
376
377 /**
378  * Seed peers.
379  */
380   void
381 seed_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
382 {
383   unsigned int amount;
384   struct RPSPeer *peer = (struct RPSPeer *) cls;
385   unsigned int i;
386
387   // TODO if malicious don't seed mal peers
388   amount = round (.5 * NUM_PEERS);
389
390   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Seeding peers:\n");
391   for (i = 0 ; i < amount ; i++)
392     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Seeding %u. peer: %s\n",
393                 i,
394                 GNUNET_i2s (&rps_peer_ids[i]));
395
396   GNUNET_RPS_seed_ids (peer->rps_handle, amount, rps_peer_ids);
397 }
398
399
400 /**
401  * Get the id of peer i.
402  */
403   void
404 info_cb (void *cb_cls,
405          struct GNUNET_TESTBED_Operation *op,
406          const struct GNUNET_TESTBED_PeerInformation *pinfo,
407          const char *emsg)
408 {
409   unsigned int i = *((unsigned int *) cb_cls);
410
411   if (NULL == pinfo || NULL != emsg)
412   {
413     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Got Error: %s\n", emsg);
414     return;
415   }
416
417   GNUNET_free (cb_cls);
418
419   rps_peer_ids[i] = *(pinfo->result.id);
420   rps_peers[i].peer_id = &rps_peer_ids[i];
421   rps_peers[i].rec_ids = NULL;
422   rps_peers[i].num_rec_ids = 0;
423
424 }
425
426
427 /**
428  * Callback to be called when RPS service connect operation is completed
429  *
430  * @param cls the callback closure from functions generating an operation
431  * @param op the operation that has been finished
432  * @param ca_result the RPS service handle returned from rps_connect_adapter
433  * @param emsg error message in case the operation has failed; will be NULL if
434  *          operation has executed successfully.
435  */
436 static void
437 rps_connect_complete_cb (void *cls,
438                          struct GNUNET_TESTBED_Operation *op,
439                          void *ca_result,
440                          const char *emsg)
441 {
442   struct RPSPeer *rps_peer = cls;
443   struct GNUNET_RPS_Handle *rps = ca_result;
444
445   rps_peer->rps_handle = rps;
446   rps_peer->online = GNUNET_YES;
447   num_peers_online++;
448
449   GNUNET_assert (op == rps_peer->op);
450   if (NULL != emsg)
451   {
452     GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
453                 "Failed to connect to RPS service: %s\n",
454                 emsg);
455     ok = 1;
456     GNUNET_SCHEDULER_shutdown ();
457     return;
458   }
459
460   GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started client successfully\n");
461
462   cur_test_run.main_test (rps_peer);
463 }
464
465
466 /**
467  * Adapter function called to establish a connection to
468  * the RPS service.
469  *
470  * @param cls closure
471  * @param cfg configuration of the peer to connect to; will be available until
472  *          GNUNET_TESTBED_operation_done() is called on the operation returned
473  *          from GNUNET_TESTBED_service_connect()
474  * @return service handle to return in 'op_result', NULL on error
475  */
476 static void *
477 rps_connect_adapter (void *cls,
478                                  const struct GNUNET_CONFIGURATION_Handle *cfg)
479 {
480   struct GNUNET_RPS_Handle *h;
481
482   h = GNUNET_RPS_connect (cfg);
483
484   if (NULL != cur_test_run.pre_test)
485     cur_test_run.pre_test (cls, h);
486
487   return h;
488 }
489
490
491 /**
492  * Adapter function called to destroy connection to
493  * RPS service.
494  *
495  * @param cls closure
496  * @param op_result service handle returned from the connect adapter
497  */
498 static void
499 rps_disconnect_adapter (void *cls,
500                                           void *op_result)
501 {
502   struct GNUNET_RPS_Handle *h = op_result;
503   GNUNET_RPS_disconnect (h);
504 }
505
506
507 /***********************************************************************
508  * Definition of tests
509 ***********************************************************************/
510
511 static int
512 default_eval_cb (void)
513 {
514   return evaluate (rps_peers, NUM_PEERS, 1);
515 }
516 /***********************************
517  * MALICIOUS
518 ***********************************/
519 static void
520 mal_pre (void *cls, struct GNUNET_RPS_Handle *h)
521 {
522   #ifdef ENABLE_MALICIOUS
523   uint32_t num_mal_peers;
524   struct RPSPeer *rps_peer = (struct RPSPeer *) cls;
525
526   GNUNET_assert (1 >= portion
527                  && 0 <  portion);
528   num_mal_peers = round (portion * NUM_PEERS);
529
530   if (rps_peer->index < num_mal_peers)
531   {
532     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
533                 "%u. peer [%s] of %" PRIu32 " malicious peers turning malicious\n",
534                 rps_peer->index,
535                 GNUNET_i2s (rps_peer->peer_id),
536                 num_mal_peers);
537
538     GNUNET_RPS_act_malicious (h, mal_type, num_mal_peers, rps_peer_ids);
539   }
540   #endif /* ENABLE_MALICIOUS */
541 }
542
543 static void
544 mal_cb (struct RPSPeer *rps_peer)
545 {
546   uint32_t num_mal_peers;
547
548   #ifdef ENABLE_MALICIOUS
549   GNUNET_assert (1 >= portion
550                  && 0 <  portion);
551   num_mal_peers = round (portion * NUM_PEERS);
552
553   if (rps_peer->index >= num_mal_peers)
554   { /* It's useless to ask a malicious peer about a random sample -
555        it's not sampling */
556     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2),
557                                   seed_peers, rps_peer);
558     GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10),
559                                   request_peers, rps_peer);
560   }
561   #endif /* ENABLE_MALICIOUS */
562 }
563
564 static int
565 mal_eval (void)
566 {
567   unsigned int num_mal_peers;
568
569   num_mal_peers = round (NUM_PEERS * portion);
570   return evaluate (&rps_peers[num_mal_peers],
571                    NUM_PEERS - (num_mal_peers),
572                    1);
573 }
574
575
576 /***********************************
577  * SINGLE_REQUEST
578 ***********************************/
579 static void
580 single_req_cb (struct RPSPeer *rps_peer)
581 {
582   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5),
583                                 request_peers, rps_peer);
584 }
585
586 /***********************************
587  * DELAYED_REQUESTS
588 ***********************************/
589 static void
590 delay_req_cb (struct RPSPeer *rps_peer)
591 {
592   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5),
593                                 request_peers, rps_peer);
594   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10),
595                                 request_peers, rps_peer);
596 }
597
598 /***********************************
599  * SEED
600 ***********************************/
601 static void
602 seed_cb (struct RPSPeer *rps_peer)
603 {
604   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10),
605                                 seed_peers, rps_peer);
606 }
607
608 static int
609 seed_eval (void)
610 {
611   return 1;
612 }
613
614 /***********************************
615  * SEED_BIG
616 ***********************************/
617 static void
618 seed_big_cb (struct RPSPeer *rps_peer)
619 {
620   // TODO test seeding > GNUNET_SERVER_MAX_MESSAGE_SIZE peers
621 }
622
623 /***********************************
624  * SINGLE_PEER_SEED
625 ***********************************/
626 static void
627 single_peer_seed_cb (struct RPSPeer *rps_peer)
628 {
629   // TODO
630 }
631
632 /***********************************
633  * SEED_REQUEST
634 ***********************************/
635 static void
636 seed_req_cb (struct RPSPeer *rps_peer)
637 {
638   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 2),
639                                 seed_peers, rps_peer);
640   GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 15),
641                                 request_peers, rps_peer);
642 }
643
644 //TODO start big mal
645
646 /***********************************
647  * REQUEST_CANCEL
648 ***********************************/
649 static void
650 req_cancel_cb (struct RPSPeer *rps_peer)
651 {
652   // TODO
653 }
654
655 /***********************************
656  * PROFILER
657 ***********************************/
658 static void
659 churn (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
660 {
661   struct OpListEntry *entry;
662   unsigned int i;
663   unsigned int j;
664   double portion_online;
665   unsigned int *permut;
666   double prob_go_offline;
667   double portion_go_online;
668   double portion_go_offline;
669   uint32_t prob;
670
671   portion_online = num_peers_online / NUM_PEERS;
672   portion_go_online = ((1 - portion_online) * .5 * .66);
673   portion_go_offline = (portion_online + portion_go_online) - .75;
674   prob_go_offline = portion_go_offline / (portion_online * .5);
675
676   permut = GNUNET_CRYPTO_random_permute (GNUNET_CRYPTO_QUALITY_WEAK,
677                                          (unsigned int) NUM_PEERS);
678
679   for (i = 0 ; i < .5 * NUM_PEERS ; i++)
680   {
681     j = permut[i];
682
683     if (GNUNET_YES == rps_peers[j].online)
684     {
685        prob = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
686                                         UINT32_MAX);
687       if (prob < prob_go_offline * UINT32_MAX)
688       {
689         entry = make_oplist_entry ();
690         entry->delta = 1;
691         entry->index = j;
692         entry->op =  GNUNET_TESTBED_peer_manage_service (NULL,
693                                                          testbed_peers[j],
694                                                          "rps",
695                                                          &churn_cb,
696                                                          entry,
697                                                          1);
698       }
699    }
700
701     else if (GNUNET_NO == rps_peers[j].online)
702     {
703       prob = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
704                                        UINT32_MAX);
705       if (prob < .66 * UINT32_MAX)
706       {
707         entry = make_oplist_entry ();
708         entry->delta = -1;
709         entry->index = j;
710         entry->op =  GNUNET_TESTBED_peer_manage_service (NULL,
711                                                          testbed_peers[j],
712                                                          "rps",
713                                                          &churn_cb,
714                                                          entry,
715                                                          0);
716       }
717     }
718   }
719
720   churn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
721                                                                             10),
722                                              churn, NULL);
723 }
724
725 static void
726 profiler_pre (void *cls, struct GNUNET_RPS_Handle *h)
727 {
728   churn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
729                                                                             10),
730                                              churn, NULL);
731   mal_pre (cls, h);
732 }
733
734 static void
735 profiler_cb (struct RPSPeer *rps_peer)
736 {
737   // We're not requesting peers
738   // TODO maybe seed
739 }
740
741
742 /***********************************************************************
743  * /Definition of tests
744 ***********************************************************************/
745
746
747 /**
748  * Actual "main" function for the testcase.
749  *
750  * @param cls closure
751  * @param h the run handle
752  * @param num_peers number of peers in 'peers'
753  * @param peers handle to peers run in the testbed
754  * @param links_succeeded the number of overlay link connection attempts that
755  *          succeeded
756  * @param links_failed the number of overlay link connection attempts that
757  *          failed
758  */
759 static void
760 run (void *cls,
761      struct GNUNET_TESTBED_RunHandle *h,
762      unsigned int num_peers,
763      struct GNUNET_TESTBED_Peer **peers,
764      unsigned int links_succeeded,
765      unsigned int links_failed)
766 {
767   unsigned int i;
768   unsigned int *tmp_i;
769
770   testbed_peers = peers;
771   num_peers_online = 0;
772
773   for (i = 0 ; i < NUM_PEERS ; i++)
774   {
775     tmp_i = GNUNET_new (unsigned int);
776     *tmp_i = i;
777
778     (void) GNUNET_TESTBED_peer_get_information (peers[i],
779                                                 GNUNET_TESTBED_PIT_IDENTITY,
780                                                 &info_cb,
781                                                 tmp_i);
782   }
783
784   GNUNET_assert (NUM_PEERS == num_peers);
785   for (i = 0 ; i < num_peers ; i++)
786   {
787     rps_peers[i].index = i;
788     rps_peers[i].op =
789       GNUNET_TESTBED_service_connect (&rps_peers[i],
790                                                                           peers[i],
791                                                                           "rps",
792                                                                           &rps_connect_complete_cb,
793                                                                           &rps_peers[i],
794                                                                           &rps_connect_adapter,
795                                                                           &rps_disconnect_adapter,
796                                                                           &rps_peers[i]);
797   }
798   GNUNET_SCHEDULER_add_delayed (TIMEOUT, &shutdown_task, NULL);
799 }
800
801
802 /**
803  * Entry point for the testcase, sets up the testbed.
804  *
805  * @param argc unused
806  * @param argv unused
807  * @return 0 on success
808  */
809 int
810 main (int argc, char *argv[])
811 {
812   cur_test_run.pre_test = NULL;
813   cur_test_run.eval_cb = default_eval_cb;
814   churn_task = NULL;
815
816   if (strstr (argv[0], "malicious") != NULL)
817   {
818     cur_test_run.pre_test = mal_pre;
819     cur_test_run.main_test = mal_cb;
820     cur_test_run.eval_cb = mal_eval;
821
822     if (strstr (argv[0], "_1") != NULL)
823     {
824       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test malicious peer type 1\n");
825       mal_type = 1;
826     }
827     else if (strstr (argv[0], "_2") != NULL)
828     {
829       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test malicious peer type 2\n");
830       mal_type = 2;
831     }
832     else if (strstr (argv[0], "_3") != NULL)
833     {
834       GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test malicious peer type 3\n");
835       mal_type = 3;
836     }
837   }
838
839   else if (strstr (argv[0], "_single_req") != NULL)
840   {
841     GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Test single request\n");
842     cur_test_run.main_test = single_req_cb;
843   }
844   else if (strstr (argv[0], "_delayed_reqs") != NULL)
845   {
846     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test delayed requests\n");
847     cur_test_run.main_test = delay_req_cb;
848   }
849   else if (strstr (argv[0], "_seed_big") != NULL)
850   {
851     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test seeding (num_peers > GNUNET_SERVER_MAX_MESSAGE_SIZE)\n");
852     cur_test_run.main_test = seed_big_cb;
853   }
854   else if (strstr (argv[0], "_single_peer_seed") != NULL)
855   {
856     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test seeding and requesting on a single peer\n");
857     cur_test_run.main_test = single_peer_seed_cb;
858   }
859   else if (strstr (argv[0], "_seed_request") != NULL)
860   {
861     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test seeding and requesting on multiple peers\n");
862     cur_test_run.main_test = seed_req_cb;
863   }
864   else if (strstr (argv[0], "_seed") != NULL)
865   {
866     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test seeding\n");
867     cur_test_run.main_test = seed_cb;
868     cur_test_run.eval_cb = seed_eval;
869   }
870   else if (strstr (argv[0], "_req_cancel") != NULL)
871   {
872     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test cancelling a request\n");
873     cur_test_run.main_test = req_cancel_cb;
874   }
875   else if (strstr (argv[0], "profiler") != NULL)
876   {
877     GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "This is the profiler\n");
878     mal_type = 3;
879     cur_test_run.pre_test = profiler_pre;
880     cur_test_run.main_test = profiler_cb;
881     churn_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS,
882                                                                               10),
883                                                churn, NULL);
884   }
885
886   ok = 1;
887   (void) GNUNET_TESTBED_test_run ("test-rps-multipeer",
888                                   "test_rps.conf",
889                                   NUM_PEERS,
890                                   0, NULL, NULL,
891                                   &run, NULL);
892
893   if (NULL != churn_task)
894     GNUNET_SCHEDULER_cancel (churn_task);
895
896   return cur_test_run.eval_cb();
897 }
898
899 /* end of test_rps_multipeer.c */