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