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