-ensure stats queues do not grow too big
[oweals/gnunet.git] / src / ats-tests / ats-testing.h
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2010-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  * @file ats-tests/ats-testing.h
22  * @brief ats testing library: setup topology and provide logging to test ats
23  * @author Christian Grothoff
24  * @author Matthias Wachs
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_testbed_service.h"
29 #include "gnunet_ats_service.h"
30 #include "gnunet_core_service.h"
31
32 #define TEST_ATS_PREFERENCE_DEFAULT 1.0
33
34 /**
35  * Message type sent for traffic generation
36  */
37 #define TEST_MESSAGE_TYPE_PING 12345
38
39 /**
40  * Message type sent as response during traffic generation
41  */
42 #define TEST_MESSAGE_TYPE_PONG 12346
43
44 /**
45  * Size of test messages
46  */
47 #define TEST_MESSAGE_SIZE 100
48
49 struct BenchmarkPartner;
50
51 struct BenchmarkPeer;
52
53 struct GNUNET_ATS_TEST_Topology;
54
55 struct TrafficGenerator;
56
57 struct LoggingHandle;
58
59 enum GeneratorType
60 {
61   GNUNET_ATS_TEST_TG_LINEAR,
62   GNUNET_ATS_TEST_TG_CONSTANT,
63   GNUNET_ATS_TEST_TG_RANDOM,
64   GNUNET_ATS_TEST_TG_SINUS
65 };
66
67
68 /**
69  * Callback to call when topology setup is completed
70  *
71  * @param cls the closure
72  * @param masters array of master peers
73  * @param slaves array of master peers
74  */
75 typedef void (*GNUNET_ATS_TEST_TopologySetupDoneCallback) (void *cls,
76     struct BenchmarkPeer *masters,
77     struct BenchmarkPeer *slaves);
78
79 /**
80  * Callback called when logging is required for the data contained
81  *
82  * @param cls the closure
83  * @param address an address
84  * @param address_active is address active
85  * @param bandwidth_out bandwidth outbound
86  * @param bandwidth_in bandwidth inbound
87  * @param prop performance information
88  */
89 typedef void
90 (*GNUNET_ATS_TEST_LogRequest) (void *cls,
91     const struct GNUNET_HELLO_Address *address,
92     int address_active,
93     struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
94     struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
95     const struct GNUNET_ATS_Properties *prop);
96
97 /**
98  * Information we track for a peer in the testbed.
99  */
100 struct BenchmarkPeer
101 {
102   /**
103    * Handle with testbed.
104    */
105   struct GNUNET_TESTBED_Peer *peer;
106
107   /**
108    * Unique identifier
109    */
110   int no;
111
112   /**
113    * Is this peer a measter: GNUNET_YES/GNUNET_NO
114    */
115   int master;
116
117   /**
118    *  Peer ID
119    */
120   struct GNUNET_PeerIdentity id;
121
122   /**
123    * Testbed operation to get peer information
124    */
125   struct GNUNET_TESTBED_Operation *peer_id_op;
126
127   /**
128    * Testbed operation to connect to ATS performance service
129    */
130   struct GNUNET_TESTBED_Operation *ats_perf_op;
131
132   /**
133    * Testbed operation to connect to core
134    */
135   struct GNUNET_TESTBED_Operation *comm_op;
136
137   /**
138    * ATS performance handle
139    */
140   struct GNUNET_ATS_PerformanceHandle *ats_perf_handle;
141
142   /**
143    * Masters only:
144    * Testbed connect operations to connect masters to slaves
145    */
146   struct TestbedConnectOperation *core_connect_ops;
147
148   /**
149    *  Core handle
150    */
151   struct GNUNET_CORE_Handle *ch;
152
153   /**
154    *  Core handle
155    */
156   struct GNUNET_TRANSPORT_Handle *th;
157
158   /**
159    * Masters only:
160    * Peer to set ATS preferences for
161    */
162   struct BenchmarkPeer *pref_partner;
163
164   /**
165    * Masters only
166    * Progress task
167    */
168   struct GNUNET_SCHEDULER_Task * ats_task;
169
170   /**
171    * Masters only
172    * Progress task
173    */
174   double pref_value;
175
176   /**
177    * Array of partners with num_slaves entries (if master) or
178    * num_master entries (if slave)
179    */
180   struct BenchmarkPartner *partners;
181
182   /**
183    * Number of partners
184    */
185   int num_partners;
186
187   /**
188    * Number of core connections
189    */
190   int core_connections;
191
192   /**
193    * Masters only:
194    * Number of connections to slave peers
195    */
196   int core_slave_connections;
197
198   /**
199    * Total number of messages this peer has sent
200    */
201   unsigned int total_messages_sent;
202
203   /**
204    * Total number of bytes this peer has sent
205    */
206   unsigned int total_bytes_sent;
207
208   /**
209    * Total number of messages this peer has received
210    */
211   unsigned int total_messages_received;
212
213   /**
214    * Total number of bytes this peer has received
215    */
216   unsigned int total_bytes_received;
217 };
218
219 struct TrafficGenerator
220 {
221   struct TrafficGenerator *prev;
222   struct TrafficGenerator *next;
223
224   enum GeneratorType type;
225
226   struct BenchmarkPeer *src;
227   struct BenchmarkPartner *dest;
228
229   long int base_rate;
230   long int max_rate;
231   struct GNUNET_TIME_Relative duration_period;
232
233   struct GNUNET_SCHEDULER_Task * send_task;
234   struct GNUNET_TIME_Absolute next_ping_transmission;
235   struct GNUNET_TIME_Absolute time_start;
236 };
237
238
239 struct PreferenceGenerator
240 {
241   struct PreferenceGenerator *prev;
242   struct PreferenceGenerator *next;
243
244   enum GeneratorType type;
245
246   struct BenchmarkPeer *src;
247   struct BenchmarkPartner *dest;
248
249   enum GNUNET_ATS_PreferenceKind kind;
250
251   long int base_value;
252   long int max_value;
253   struct GNUNET_TIME_Relative duration_period;
254   struct GNUNET_TIME_Relative frequency;
255
256   struct GNUNET_SCHEDULER_Task * set_task;
257   struct GNUNET_TIME_Absolute next_ping_transmission;
258   struct GNUNET_TIME_Absolute time_start;
259 };
260
261 /**
262  * Information about a benchmarking partner
263  */
264 struct BenchmarkPartner
265 {
266   /**
267    * The peer itself this partner belongs to
268    */
269   struct BenchmarkPeer *me;
270
271   /**
272    * The partner peer
273    */
274   struct BenchmarkPeer *dest;
275
276   /**
277    * Core transmit handles
278    */
279   struct GNUNET_CORE_TransmitHandle *cth;
280
281   /**
282    * Transport transmit handles
283    */
284   struct GNUNET_TRANSPORT_TransmitHandle *tth;
285
286
287   /**
288    * Handle for traffic generator
289    */
290   struct TrafficGenerator *tg;
291
292   /**
293    * Handle for preference generator
294    */
295   struct PreferenceGenerator *pg;
296
297   /**
298    * Timestamp to calculate communication layer delay
299    */
300   struct GNUNET_TIME_Absolute last_message_sent;
301
302   /**
303    * Accumulated RTT for all messages
304    */
305   unsigned int total_app_rtt;
306
307   /**
308    * Number of messages sent to this partner
309    */
310   unsigned int messages_sent;
311
312   /**
313    * Number of bytes sent to this partner
314    */
315   unsigned int bytes_sent;
316
317   /**
318    * Number of messages received from this partner
319    */
320   unsigned int messages_received;
321
322   /**
323    * Number of bytes received from this partner
324    */
325   unsigned int bytes_received;
326
327   /* Current ATS properties */
328   struct GNUNET_ATS_Properties props;
329
330   /* Bandwidth assigned inbound */
331   uint32_t bandwidth_in;
332
333   /* Bandwidth assigned outbound */
334   uint32_t bandwidth_out;
335
336   /* Current preference values for bandwidth */
337   double pref_bandwidth;
338
339   /* Current preference values for delay */
340   double pref_delay;
341
342
343 };
344
345 /**
346  * Overall state of the performance benchmark
347  */
348 struct BenchmarkState
349 {
350   /**
351    * Are we connected to ATS service of all peers: GNUNET_YES/NO
352    */
353   int connected_ATS_service;
354
355   /**
356    * Are we connected to CORE service of all peers: GNUNET_YES/NO
357    */
358   int connected_COMM_service;
359
360   /**
361    * Are we connected to all peers: GNUNET_YES/NO
362    */
363   int connected_PEERS;
364
365   /**
366    * Are we connected to all slave peers on CORE level: GNUNET_YES/NO
367    */
368   int connected_CORE;
369
370   /**
371    * Are we connected to CORE service of all peers: GNUNET_YES/NO
372    */
373   int benchmarking;
374 };
375
376
377 struct GNUNET_ATS_TEST_Topology
378 {
379   /**
380    * Progress task
381    */
382   struct GNUNET_SCHEDULER_Task *progress_task;
383
384   /**
385    * Test result
386    */
387   int result;
388
389   /**Test core (GNUNET_YES) or transport (GNUNET_NO)
390    */
391   int test_core;
392
393   /**
394    * Solver string
395    */
396   char *solver;
397
398   /**
399    * Preference string
400    */
401   char *testname;
402
403   /**
404    * Preference string
405    */
406   char *pref_str;
407
408   /**
409    * ATS preference value
410    */
411   int pref_val;
412
413   /**
414    * Number master peers
415    */
416   unsigned int num_masters;
417
418   /**
419    * Array of master peers
420    */
421   struct BenchmarkPeer *mps;
422
423   /**
424    * Number slave peers
425    */
426   unsigned int num_slaves;
427
428   /**
429    * Array of slave peers
430    */
431   struct BenchmarkPeer *sps;
432
433   /**
434    * Benchmark duration
435    */
436   struct GNUNET_TIME_Relative perf_duration;
437
438   /**
439    * Logging frequency
440    */
441   struct GNUNET_TIME_Relative log_frequency;
442
443   /**
444    * Benchmark state
445    */
446   struct BenchmarkState state;
447
448   struct GNUNET_CORE_MessageHandler *handlers;
449
450   GNUNET_TRANSPORT_ReceiveCallback transport_recv_cb;
451
452   GNUNET_ATS_TEST_TopologySetupDoneCallback done_cb;
453   GNUNET_ATS_AddressInformationCallback ats_perf_cb;
454   void *done_cb_cls;
455 };
456
457 enum OperationType
458 {
459   START_SEND,
460   STOP_SEND,
461   START_PREFERENCE,
462   STOP_PREFERENCE
463 };
464
465 struct Episode;
466
467 struct Experiment;
468
469 typedef void (*GNUNET_ATS_TESTING_EpisodeDoneCallback) (
470     struct Episode *e);
471
472 typedef void (*GNUNET_ATS_TESTING_ExperimentDoneCallback) (struct Experiment *e,
473     struct GNUNET_TIME_Relative duration,int success);
474
475 /**
476  * An operation in an experiment
477  */
478 struct GNUNET_ATS_TEST_Operation
479 {
480   struct GNUNET_ATS_TEST_Operation *next;
481   struct GNUNET_ATS_TEST_Operation *prev;
482
483   long long unsigned int src_id;
484   long long unsigned int dest_id;
485
486   long long unsigned int base_rate;
487   long long unsigned int max_rate;
488   struct GNUNET_TIME_Relative period;
489   struct GNUNET_TIME_Relative frequency;
490
491   enum OperationType type;
492   enum GeneratorType gen_type;
493   enum GNUNET_ATS_PreferenceKind pref_type;
494 };
495
496 struct Episode
497 {
498   int id;
499   struct Episode *next;
500   struct GNUNET_TIME_Relative duration;
501
502   struct GNUNET_ATS_TEST_Operation *head;
503   struct GNUNET_ATS_TEST_Operation *tail;
504 };
505
506
507 struct Experiment
508 {
509   char *name;
510   char *cfg_file;
511   unsigned long long int num_masters;
512   unsigned long long int num_slaves;
513   struct GNUNET_TIME_Relative log_freq;
514   struct GNUNET_TIME_Relative max_duration;
515   struct GNUNET_TIME_Relative total_duration;
516   struct GNUNET_TIME_Absolute start_time;
517   unsigned int num_episodes;
518   struct Episode *start;
519
520   struct GNUNET_SCHEDULER_Task * experiment_timeout_task;
521   struct GNUNET_SCHEDULER_Task * episode_timeout_task;
522   struct Episode *cur;
523
524   GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb;
525   GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb;
526 };
527
528 /*
529  * Experiment related functions
530  */
531 extern struct GNUNET_CONFIGURATION_Handle *cfg;
532
533 /**
534  * Execute the specified experiment
535  *
536  * @param e the Experiment
537  * @param ep_done_cb a episode is completed
538  * @param e_done_cb the experiment is completed
539  */
540 void
541 GNUNET_ATS_TEST_experimentation_run (struct Experiment *e,
542                                      GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb,
543                                      GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb);
544
545
546 /**
547  * Load an experiment from a file
548  *
549  * @param filename the file
550  * @return the Experiment or NULL on failure
551  */
552 struct Experiment *
553 GNUNET_ATS_TEST_experimentation_load (const char *filename);
554
555
556 /**
557  * Stop an experiment
558  *
559  * @param e the experiment
560  */
561 void
562 GNUNET_ATS_TEST_experimentation_stop (struct Experiment *e);
563
564 /*
565  * Traffic related functions
566  */
567
568 void
569 GNUNET_ATS_TEST_traffic_handle_ping (struct BenchmarkPartner *p);
570
571 void
572 GNUNET_ATS_TEST_traffic_handle_pong (struct BenchmarkPartner *p);
573
574
575 /**
576  * Generate between the source master and the partner and send traffic with a
577  * maximum rate.
578  *
579  * @param src traffic source
580  * @param dest traffic partner
581  * @param type type of traffic to generate
582  * @param base_rate traffic base rate to send data with
583  * @param max_rate  traffic maximum rate to send data with
584  * @param period duration of a period of traffic generation (~ 1/frequency)
585  * @param duration how long to generate traffic
586  * @return the traffic generator
587  */
588 struct TrafficGenerator *
589 GNUNET_ATS_TEST_generate_traffic_start (struct BenchmarkPeer *src,
590                                         struct BenchmarkPartner *dest,
591                                         enum GeneratorType type,
592                                         unsigned int base_rate,
593                                         unsigned int max_rate,
594                                         struct GNUNET_TIME_Relative period,
595                                         struct GNUNET_TIME_Relative duration);
596
597
598 void
599 GNUNET_ATS_TEST_generate_traffic_stop (struct TrafficGenerator *tg);
600
601 /**
602  * Stop all traffic generators
603  */
604 void
605 GNUNET_ATS_TEST_generate_traffic_stop_all (void);
606
607
608 /**
609  * Generate between the source master and the partner and set preferences with a
610  * value depending on the generator.
611  *
612  * @param src source
613  * @param dest partner
614  * @param type type of preferences to generate
615  * @param base_value traffic base rate to send data with
616  * @param value_rate  traffic maximum rate to send data with
617  * @param period duration of a period of preferences generation (~ 1/frequency)
618  * @param frequency how long to generate preferences
619  * @param kind ATS preference to generate
620  * @return the traffic generator
621  */
622 struct PreferenceGenerator *
623 GNUNET_ATS_TEST_generate_preferences_start (struct BenchmarkPeer *src,
624                                             struct BenchmarkPartner *dest,
625                                             enum GeneratorType type,
626                                             unsigned int base_value,
627                                             unsigned int value_rate,
628                                             struct GNUNET_TIME_Relative period,
629                                             struct GNUNET_TIME_Relative frequency,
630                                             enum GNUNET_ATS_PreferenceKind kind);
631
632 void
633 GNUNET_ATS_TEST_generate_preferences_stop (struct PreferenceGenerator *pg);
634
635
636 void
637 GNUNET_ATS_TEST_generate_preferences_stop_all (void);
638
639 /*
640  * Logging related functions
641  */
642
643 /**
644  * Start logging
645  *
646  * @param log_frequency the logging frequency
647  * @param testname the testname
648  * @param masters the master peers used for benchmarking
649  * @param num_masters the number of master peers
650  * @param num_slaves the number of slave peers
651  * @param verbose verbose logging
652  * @return the logging handle or NULL on error
653  */
654 struct LoggingHandle *
655 GNUNET_ATS_TEST_logging_start(struct GNUNET_TIME_Relative log_frequency,
656                               const char *testname,
657                               struct BenchmarkPeer *masters,
658                               int num_masters,
659                               int num_slaves,
660                               int verbose);
661
662
663 /**
664  * Stop logging
665  *
666  * @param l the logging handle
667  */
668 void
669 GNUNET_ATS_TEST_logging_clean_up (struct LoggingHandle *l);
670
671
672 /**
673  * Stop logging
674  *
675  * @param l the logging handle
676  */
677 void
678 GNUNET_ATS_TEST_logging_stop (struct LoggingHandle *l);
679
680
681 /**
682  * Log all data now
683  *
684  * @param l logging handle to use
685  */
686 void
687 GNUNET_ATS_TEST_logging_now (struct LoggingHandle *l);
688
689
690 /**
691  * Write logging data to file
692  *
693  * @param l logging handle to use
694  * @param test_name name of the current test
695  * @param plots create gnuplots: #GNUNET_YES or #GNUNET_NO
696  */
697 void
698 GNUNET_ATS_TEST_logging_write_to_file (struct LoggingHandle *l,
699                                        const char *test_name,
700                                        int plots);
701
702
703 /**
704  * Topology related functions
705  */
706 struct BenchmarkPeer *
707 GNUNET_ATS_TEST_get_peer (int src);
708
709
710 struct BenchmarkPartner *
711 GNUNET_ATS_TEST_get_partner (int src, int dest);
712
713
714 /**
715  * Create a topology for ats testing
716  *
717  * @param name test name
718  * @param cfg_file configuration file to use for the peers
719  * @param num_slaves number of slaves
720  * @param num_masters number of masters
721  * @param test_core connect to CORE service (#GNUNET_YES) or transport (#GNUNET_NO)
722  * @param done_cb function to call when topology is setup
723  * @param done_cb_cls cls for callback
724  * @param transport_recv_cb callback to call when data are received
725  * @param log_request_cb callback to call when logging is required
726  */
727 void
728 GNUNET_ATS_TEST_create_topology (char *name,
729                                  char *cfg_file,
730                                  unsigned int num_slaves,
731                                  unsigned int num_masters,
732                                  int test_core,
733                                  GNUNET_ATS_TEST_TopologySetupDoneCallback done_cb,
734                                  void *done_cb_cls,
735                                  GNUNET_TRANSPORT_ReceiveCallback recv_cb,
736                                  GNUNET_ATS_TEST_LogRequest ats_perf_cb);
737
738
739 /**
740  * Shutdown topology
741  */
742 void
743 GNUNET_ATS_TEST_shutdown_topology (void);
744
745
746 /* end of file ats-testing.h */