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