experiment loading complete
[oweals/gnunet.git] / src / ats / gnunet-ats-solver-eval.h
1 /*
2  This file is part of GNUnet.
3  (C) 2010-2013 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 ats-tests/ats-testing-experiment.c
22  * @brief ats benchmark: controlled experiment execution
23  * @author Christian Grothoff
24  * @author Matthias Wachs
25  */
26 #include "platform.h"
27 #include "gnunet_util_lib.h"
28 #include "gnunet_ats_plugin.h"
29 #include "gnunet_ats_service.h"
30 #include "gnunet-service-ats_addresses.h"
31 #include "gnunet-service-ats_normalization.h"
32 #include "test_ats_api_common.h"
33
34 enum GeneratorType
35 {
36   GNUNET_ATS_TEST_TG_LINEAR,
37   GNUNET_ATS_TEST_TG_CONSTANT,
38   GNUNET_ATS_TEST_TG_RANDOM,
39   GNUNET_ATS_TEST_TG_SINUS
40 };
41
42
43 enum OperationType
44 {
45   SOLVER_OP_ADD_ADDRESS,
46   SOLVER_OP_DEL_ADDRESS,
47   SOLVER_OP_START_SET_PROPERTY,
48   SOLVER_OP_STOP_SET_PROPERTY,
49   SOLVER_OP_START_SET_PREFERENCE,
50   SOLVER_OP_STOP_SET_PREFERENCE
51 };
52
53 struct Episode;
54
55 struct Experiment;
56
57 typedef void (*GNUNET_ATS_TESTING_EpisodeDoneCallback) (
58     struct Episode *e);
59
60 typedef void (*GNUNET_ATS_TESTING_ExperimentDoneCallback) (struct Experiment *e,
61     struct GNUNET_TIME_Relative duration,int success);
62
63 /**
64  * An operation in an experiment
65  */
66 struct GNUNET_ATS_TEST_Operation
67 {
68   struct GNUNET_ATS_TEST_Operation *next;
69   struct GNUNET_ATS_TEST_Operation *prev;
70
71   long long unsigned int address_id;
72   long long unsigned int peer_id;
73   long long unsigned int address_session;
74   long long unsigned int address_network;
75   char*address;
76   char*plugin;
77
78
79   long long unsigned int base_rate;
80   long long unsigned int max_rate;
81   struct GNUNET_TIME_Relative period;
82   struct GNUNET_TIME_Relative frequency;
83
84   enum OperationType type;
85   enum GeneratorType tg_type;
86   enum GNUNET_ATS_PreferenceKind pref_type;
87   enum GNUNET_ATS_Property prop_type;
88 };
89
90 struct Episode
91 {
92   int id;
93   struct Episode *next;
94   struct GNUNET_TIME_Relative duration;
95
96   struct GNUNET_ATS_TEST_Operation *head;
97   struct GNUNET_ATS_TEST_Operation *tail;
98 };
99
100
101 struct Experiment
102 {
103   char *name;
104   char *cfg_file;
105   unsigned long long int num_masters;
106   unsigned long long int num_slaves;
107   struct GNUNET_TIME_Relative log_freq;
108   struct GNUNET_TIME_Relative max_duration;
109   struct GNUNET_TIME_Relative total_duration;
110   struct GNUNET_TIME_Absolute start_time;
111   unsigned int num_episodes;
112   struct Episode *start;
113
114   struct GNUNET_CONFIGURATION_Handle *cfg;
115
116   GNUNET_SCHEDULER_TaskIdentifier experiment_timeout_task;
117   GNUNET_SCHEDULER_TaskIdentifier episode_timeout_task;
118   struct Episode *cur;
119
120   GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb;
121   GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb;
122 };
123
124
125 /**
126  * A single logging time step for a partner
127  */
128 struct PartnerLoggingTimestep
129 {
130   /**
131    * Peer
132    */
133   struct BenchmarkPeer *slave;
134
135   /**
136    * Total number of messages this peer has sent
137    */
138   unsigned int total_messages_sent;
139
140   /**
141    * Total number of bytes this peer has sent
142    */
143   unsigned int total_bytes_sent;
144
145   /**
146    * Total number of messages this peer has received
147    */
148   unsigned int total_messages_received;
149
150   /**
151    * Total number of bytes this peer has received
152    */
153   unsigned int total_bytes_received;
154
155   /**
156    * Total outbound throughput for master in Bytes / s
157    */
158   unsigned int throughput_sent;
159
160   /**
161    * Total inbound throughput for master in Bytes / s
162    */
163   unsigned int throughput_recv;
164
165   /**
166    * Accumulated RTT for all messages
167    */
168   unsigned int total_app_rtt;
169
170   /**
171    * Current application level delay
172    */
173   unsigned int app_rtt;
174
175   /* Current ATS properties */
176
177   uint32_t ats_distance;
178
179   uint32_t ats_delay;
180
181   uint32_t bandwidth_in;
182
183   uint32_t bandwidth_out;
184
185   uint32_t ats_utilization_up;
186
187   uint32_t ats_utilization_down;
188
189   uint32_t ats_network_type;
190
191   uint32_t ats_cost_wan;
192
193   uint32_t ats_cost_lan;
194
195   uint32_t ats_cost_wlan;
196
197   double pref_bandwidth;
198   double pref_delay;
199 };
200
201
202 /**
203  * A single logging time step for a peer
204  */
205 struct PeerLoggingTimestep
206 {
207   /**
208    * Next in DLL
209    */
210   struct PeerLoggingTimestep *next;
211
212   /**
213    * Prev in DLL
214    */
215   struct PeerLoggingTimestep *prev;
216
217   /**
218    * Logging timestamp
219    */
220   struct GNUNET_TIME_Absolute timestamp;
221
222   /**
223    * Total number of messages this peer has sent
224    */
225   unsigned int total_messages_sent;
226
227   /**
228    * Total number of bytes this peer has sent
229    */
230   unsigned int total_bytes_sent;
231
232   /**
233    * Total number of messages this peer has received
234    */
235   unsigned int total_messages_received;
236
237   /**
238    * Total number of bytes this peer has received
239    */
240   unsigned int total_bytes_received;
241
242   /**
243    * Total outbound throughput for master in Bytes / s
244    */
245   unsigned int total_throughput_send;
246
247   /**
248    * Total inbound throughput for master in Bytes / s
249    */
250   unsigned int total_throughput_recv;
251
252   /**
253    * Logs for slaves
254    */
255   struct PartnerLoggingTimestep *slaves_log;
256 };
257
258 /**
259  * Entry for a benchmark peer
260  */
261 struct LoggingPeer
262 {
263   /**
264    * Peer
265    */
266   struct BenchmarkPeer *peer;
267
268   /**
269    * Start time
270    */
271   struct GNUNET_TIME_Absolute start;
272
273   /**
274    * DLL for logging entries: head
275    */
276   struct PeerLoggingTimestep *head;
277
278   /**
279    * DLL for logging entries: tail
280    */
281   struct PeerLoggingTimestep *tail;
282 };
283
284
285 struct LoggingHandle
286 {
287   /**
288    * Logging task
289    */
290   GNUNET_SCHEDULER_TaskIdentifier log_task;
291
292   /**
293    * Reference to perf_ats' masters
294    */
295   int num_masters;
296   int num_slaves;
297   int running;
298   int verbose;
299   char *name;
300   struct GNUNET_TIME_Relative frequency;
301
302   /**
303    * Log structure of length num_peers
304    */
305   struct LoggingPeer *lp;
306 };
307
308
309 /**
310  * Start logging
311  *
312  * @param log_frequency the logging frequency
313  * @param testname the testname
314  * @param masters the master peers used for benchmarking
315  * @param num_master the number of master peers
316  * @return the logging handle or NULL on error
317  */
318 struct LoggingHandle *
319 GNUNET_ATS_TEST_logging_start(struct GNUNET_TIME_Relative log_frequency,
320     char *testname, struct BenchmarkPeer *masters, int num_masters, int num_slaves,
321     int verbose);
322
323 /**
324  * Stop logging
325  *
326  * @param l the logging handle
327  */
328 void
329 GNUNET_ATS_TEST_logging_clean_up (struct LoggingHandle *l);
330
331 /**
332  * Stop logging
333  *
334  * @param l the logging handle
335  */
336 void
337 GNUNET_ATS_TEST_logging_stop (struct LoggingHandle *l);
338
339 /**
340  * Log all data now
341  *
342  * @param l logging handle to use
343  */
344 void
345 GNUNET_ATS_TEST_logging_now (struct LoggingHandle *l);
346
347
348 /**
349  * Write logging data to file
350  *
351  * @param l logging handle to use
352  * @param test_name name of the current test
353  * @param plots create gnuplots: GNUNET_YES or GNUNET_NO
354  */
355 void
356 GNUNET_ATS_TEST_logging_write_to_file (struct LoggingHandle *l,
357     char *test_name, int plots);
358
359
360
361
362
363
364 /* LEGACY */
365
366 #if 0
367 #define TEST_ATS_PREFERENCE_DEFAULT 1.0
368
369 /**
370  * Message type sent for traffic generation
371  */
372 #define TEST_MESSAGE_TYPE_PING 12345
373
374 /**
375  * Message type sent as response during traffic generation
376  */
377 #define TEST_MESSAGE_TYPE_PONG 12346
378
379 /**
380  * Size of test messages
381  */
382 #define TEST_MESSAGE_SIZE 100
383
384 struct BenchmarkPartner;
385
386 struct BenchmarkPeer;
387
388 struct GNUNET_ATS_TEST_Topology;
389
390 struct TrafficGenerator;
391
392
393
394
395
396 /**
397  * Callback to call when topology setup is completed
398  *
399  * @param cls the closure
400  * @param masters array of master peers
401  * @param slaves array of master peers
402  */
403 typedef void (*GNUNET_ATS_TEST_TopologySetupDoneCallback) (void *cls,
404     struct BenchmarkPeer *masters,
405     struct BenchmarkPeer *slaves);
406
407 /**
408  * Callback called when logging is required for the data contained
409  *
410  * @param cls the closure
411  * @param address an address
412  * @param address_active is address active
413  * @param bandwidth_out bandwidth outbound
414  * @param bandwidth_in bandwidth inbound
415  * @param ats ats information
416  * @param ats_count number of ats inforation
417  */
418 typedef void
419 (*GNUNET_ATS_TEST_LogRequest) (void *cls,
420     const struct GNUNET_HELLO_Address *address,
421     int address_active,
422     struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
423     struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
424     const struct GNUNET_ATS_Information *ats,
425     uint32_t ats_count);
426
427 /**
428  * Information we track for a peer in the testbed.
429  */
430 struct BenchmarkPeer
431 {
432   /**
433    * Handle with testbed.
434    */
435   struct GNUNET_TESTBED_Peer *peer;
436
437   /**
438    * Unique identifier
439    */
440   int no;
441
442   /**
443    * Is this peer a measter: GNUNET_YES/GNUNET_NO
444    */
445   int master;
446
447   /**
448    *  Peer ID
449    */
450   struct GNUNET_PeerIdentity id;
451
452   /**
453    * Testbed operation to get peer information
454    */
455   struct GNUNET_TESTBED_Operation *peer_id_op;
456
457   /**
458    * Testbed operation to connect to ATS performance service
459    */
460   struct GNUNET_TESTBED_Operation *ats_perf_op;
461
462   /**
463    * Testbed operation to connect to core
464    */
465   struct GNUNET_TESTBED_Operation *comm_op;
466
467   /**
468    * ATS performance handle
469    */
470   struct GNUNET_ATS_PerformanceHandle *ats_perf_handle;
471
472   /**
473    * Masters only:
474    * Testbed connect operations to connect masters to slaves
475    */
476   struct TestbedConnectOperation *core_connect_ops;
477
478   /**
479    *  Core handle
480    */
481   struct GNUNET_CORE_Handle *ch;
482
483   /**
484    *  Core handle
485    */
486   struct GNUNET_TRANSPORT_Handle *th;
487
488   /**
489    * Masters only:
490    * Peer to set ATS preferences for
491    */
492   struct BenchmarkPeer *pref_partner;
493
494   /**
495    * Masters only
496    * Progress task
497    */
498   GNUNET_SCHEDULER_TaskIdentifier ats_task;
499
500   /**
501    * Masters only
502    * Progress task
503    */
504   double pref_value;
505
506   /**
507    * Array of partners with num_slaves entries (if master) or
508    * num_master entries (if slave)
509    */
510   struct BenchmarkPartner *partners;
511
512   /**
513    * Number of partners
514    */
515   int num_partners;
516
517   /**
518    * Number of core connections
519    */
520   int core_connections;
521
522   /**
523    * Masters only:
524    * Number of connections to slave peers
525    */
526   int core_slave_connections;
527
528   /**
529    * Total number of messages this peer has sent
530    */
531   unsigned int total_messages_sent;
532
533   /**
534    * Total number of bytes this peer has sent
535    */
536   unsigned int total_bytes_sent;
537
538   /**
539    * Total number of messages this peer has received
540    */
541   unsigned int total_messages_received;
542
543   /**
544    * Total number of bytes this peer has received
545    */
546   unsigned int total_bytes_received;
547 };
548
549 struct TrafficGenerator
550 {
551   struct TrafficGenerator *prev;
552   struct TrafficGenerator *next;
553
554   enum GeneratorType type;
555
556   struct BenchmarkPeer *src;
557   struct BenchmarkPartner *dest;
558
559   long int base_rate;
560   long int max_rate;
561   struct GNUNET_TIME_Relative duration_period;
562
563   GNUNET_SCHEDULER_TaskIdentifier send_task;
564   struct GNUNET_TIME_Absolute next_ping_transmission;
565   struct GNUNET_TIME_Absolute time_start;
566 };
567
568
569 struct PreferenceGenerator
570 {
571   struct PreferenceGenerator *prev;
572   struct PreferenceGenerator *next;
573
574   enum GeneratorType type;
575
576   struct BenchmarkPeer *src;
577   struct BenchmarkPartner *dest;
578
579   enum GNUNET_ATS_PreferenceKind kind;
580
581   long int base_value;
582   long int max_value;
583   struct GNUNET_TIME_Relative duration_period;
584   struct GNUNET_TIME_Relative frequency;
585
586   GNUNET_SCHEDULER_TaskIdentifier set_task;
587   struct GNUNET_TIME_Absolute next_ping_transmission;
588   struct GNUNET_TIME_Absolute time_start;
589 };
590
591 /**
592  * Information about a benchmarking partner
593  */
594 struct BenchmarkPartner
595 {
596   /**
597    * The peer itself this partner belongs to
598    */
599   struct BenchmarkPeer *me;
600
601   /**
602    * The partner peer
603    */
604   struct BenchmarkPeer *dest;
605
606   /**
607    * Core transmit handles
608    */
609   struct GNUNET_CORE_TransmitHandle *cth;
610
611   /**
612    * Transport transmit handles
613    */
614   struct GNUNET_TRANSPORT_TransmitHandle *tth;
615
616   struct TrafficGenerator *tg;
617   struct PreferenceGenerator *pg;
618
619   /**
620    * Timestamp to calculate communication layer delay
621    */
622   struct GNUNET_TIME_Absolute last_message_sent;
623
624   /**
625    * Accumulated RTT for all messages
626    */
627   unsigned int total_app_rtt;
628
629   /**
630    * Number of messages sent to this partner
631    */
632   unsigned int messages_sent;
633
634   /**
635    * Number of bytes sent to this partner
636    */
637   unsigned int bytes_sent;
638
639   /**
640    * Number of messages received from this partner
641    */
642   unsigned int messages_received;
643
644   /**
645    * Number of bytes received from this partner
646    */
647   unsigned int bytes_received;
648
649   /* Current ATS properties */
650
651   uint32_t ats_distance;
652
653   uint32_t ats_delay;
654
655   uint32_t bandwidth_in;
656
657   uint32_t bandwidth_out;
658
659   uint32_t ats_utilization_up;
660
661   uint32_t ats_utilization_down;
662
663   uint32_t ats_network_type;
664
665   uint32_t ats_cost_wan;
666
667   uint32_t ats_cost_lan;
668
669   uint32_t ats_cost_wlan;
670
671   double pref_bandwidth;
672   double pref_delay;
673 };
674
675 /**
676  * Overall state of the performance benchmark
677  */
678 struct BenchmarkState
679 {
680   /**
681    * Are we connected to ATS service of all peers: GNUNET_YES/NO
682    */
683   int connected_ATS_service;
684
685   /**
686    * Are we connected to CORE service of all peers: GNUNET_YES/NO
687    */
688   int connected_COMM_service;
689
690   /**
691    * Are we connected to all peers: GNUNET_YES/NO
692    */
693   int connected_PEERS;
694
695   /**
696    * Are we connected to all slave peers on CORE level: GNUNET_YES/NO
697    */
698   int connected_CORE;
699
700   /**
701    * Are we connected to CORE service of all peers: GNUNET_YES/NO
702    */
703   int benchmarking;
704 };
705
706
707 struct GNUNET_ATS_TEST_Topology
708 {
709   /**
710    * Shutdown task
711    */
712   GNUNET_SCHEDULER_TaskIdentifier shutdown_task;
713
714   /**
715    * Progress task
716    */
717   GNUNET_SCHEDULER_TaskIdentifier progress_task;
718
719   /**
720    * Test result
721    */
722   int result;
723
724   /**Test core (GNUNET_YES) or transport (GNUNET_NO)
725    */
726   int test_core;
727
728   /**
729    * Solver string
730    */
731   char *solver;
732
733   /**
734    * Preference string
735    */
736   char *testname;
737
738   /**
739    * Preference string
740    */
741   char *pref_str;
742
743   /**
744    * ATS preference value
745    */
746   int pref_val;
747
748   /**
749    * Number master peers
750    */
751   unsigned int num_masters;
752
753   /**
754    * Array of master peers
755    */
756   struct BenchmarkPeer *mps;
757
758   /**
759    * Number slave peers
760    */
761   unsigned int num_slaves;
762
763   /**
764    * Array of slave peers
765    */
766   struct BenchmarkPeer *sps;
767
768   /**
769    * Benchmark duration
770    */
771   struct GNUNET_TIME_Relative perf_duration;
772
773   /**
774    * Logging frequency
775    */
776   struct GNUNET_TIME_Relative log_frequency;
777
778   /**
779    * Benchmark state
780    */
781   struct BenchmarkState state;
782
783   struct GNUNET_CORE_MessageHandler *handlers;
784
785   GNUNET_TRANSPORT_ReceiveCallback transport_recv_cb;
786
787   GNUNET_ATS_TEST_TopologySetupDoneCallback done_cb;
788   GNUNET_ATS_AddressInformationCallback ats_perf_cb;
789   void *done_cb_cls;
790 };
791
792
793
794 /*
795  * Experiment related functions
796  */
797
798
799 /**
800  * Execute the specified experiment
801  *
802  * @param e the Experiment
803  * @param ep_done_cb a episode is completed
804  * @param e_done_cb the experiment is completed
805  */
806 void
807 GNUNET_ATS_TEST_experimentation_run (struct Experiment *e,
808     GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb,
809     GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb);
810
811 /**
812  * Load an experiment from a file
813  *
814  * @param filename the file
815  * @return the Experiment or NULL on failure
816  */
817 struct Experiment *
818 GNUNET_ATS_TEST_experimentation_load (char *filename);
819
820
821 /**
822  * Stop an experiment
823  *
824  * @param e the experiment
825  */
826 void
827 GNUNET_ATS_TEST_experimentation_stop (struct Experiment *e);
828
829 /*
830  * Traffic related functions
831  */
832
833 void
834 GNUNET_ATS_TEST_traffic_handle_ping (struct BenchmarkPartner *p);
835
836 void
837 GNUNET_ATS_TEST_traffic_handle_pong (struct BenchmarkPartner *p);
838
839
840 /**
841  * Generate between the source master and the partner and send traffic with a
842  * maximum rate.
843  *
844  * @param src traffic source
845  * @param dest traffic partner
846  * @param type type of traffic to generate
847  * @param base_rate traffic base rate to send data with
848  * @param max_rate  traffic maximum rate to send data with
849  * @param period duration of a period of traffic generation (~ 1/frequency)
850  * @param duration how long to generate traffic
851  * @return the traffic generator
852  */
853 struct TrafficGenerator *
854 GNUNET_ATS_TEST_generate_traffic_start (struct BenchmarkPeer *src,
855     struct BenchmarkPartner *dest,
856     enum GeneratorType type,
857     long int base_rate,
858     long int max_rate,
859     struct GNUNET_TIME_Relative period,
860     struct GNUNET_TIME_Relative duration);
861
862 void
863 GNUNET_ATS_TEST_generate_traffic_stop (struct TrafficGenerator *tg);
864
865 /**
866  * Stop all traffic generators
867  */
868 void
869 GNUNET_ATS_TEST_generate_traffic_stop_all ();
870
871 struct PreferenceGenerator *
872 GNUNET_ATS_TEST_generate_preferences_start (struct BenchmarkPeer *src,
873     struct BenchmarkPartner *dest,
874     enum GeneratorType type,
875     long int base_value,
876     long int value_rate,
877     struct GNUNET_TIME_Relative period,
878     struct GNUNET_TIME_Relative frequency,
879     enum GNUNET_ATS_PreferenceKind kind);
880
881 void
882 GNUNET_ATS_TEST_generate_preferences_stop (struct PreferenceGenerator *pg);
883
884 void
885 GNUNET_ATS_TEST_generate_preferences_stop_all ();
886
887 /*
888  * Logging related functions
889  */
890
891
892
893 /*
894  * Topology related functions
895  */
896
897 struct BenchmarkPeer *
898 GNUNET_ATS_TEST_get_peer (int src);
899
900 struct BenchmarkPartner *
901 GNUNET_ATS_TEST_get_partner (int src, int dest);
902
903 /**
904  * Create a topology for ats testing
905  *
906  * @param name test name
907  * @param cfg_file configuration file to use for the peers
908  * @param num_slaves number of slaves
909  * @param num_masters number of masters
910  * @param test_core connect to CORE service (GNUNET_YES) or transport (GNUNET_NO)
911  * @param done_cb function to call when topology is setup
912  * @param done_cb_cls cls for callback
913  * @param recv_cb callback to call when data are received
914  * @param perf_cb callback to call when performance info are received
915  */
916 void
917 GNUNET_ATS_TEST_create_topology (char *name, char *cfg_file,
918     unsigned int num_slaves,
919     unsigned int num_masters,
920     int test_core,
921     GNUNET_ATS_TEST_TopologySetupDoneCallback done_cb,
922     void *done_cb_cls,
923     GNUNET_TRANSPORT_ReceiveCallback recv_cb,
924     GNUNET_ATS_TEST_LogRequest ats_perf_cb);
925
926 /**
927  * Shutdown topology
928  */
929 void
930 GNUNET_ATS_TEST_shutdown_topology (void);
931 #endif
932 /* end of file ats-testing.h */