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