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