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