psycstore: postgres: remove size modifier from BYTEA fields
[oweals/gnunet.git] / src / ats-tests / gnunet-solver-eval.c
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
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., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, 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 "ats-testing.h"
31
32
33 /**
34  * Experiments
35  */
36 const char *
37 print_op (enum OperationType op)
38 {
39   switch (op) {
40     case START_SEND:
41       return "START_SEND";
42     case STOP_SEND:
43       return "STOP_SEND";
44     case START_PREFERENCE:
45       return "START_PREFERENCE";
46     case STOP_PREFERENCE:
47       return "STOP_PREFERENCE";
48     default:
49       break;
50   }
51   return "";
52 }
53
54
55 static struct Experiment *
56 create_experiment ()
57 {
58   struct Experiment *e;
59   e = GNUNET_new (struct Experiment);
60   e->name = NULL;
61   e->num_masters = 0;
62   e->num_slaves = 0;
63   e->start = NULL;
64   e->total_duration = GNUNET_TIME_UNIT_ZERO;
65   return e;
66 }
67
68
69 static void
70 free_experiment (struct Experiment *e)
71 {
72   struct Episode *cur;
73   struct Episode *next;
74   struct GNUNET_ATS_TEST_Operation *cur_o;
75   struct GNUNET_ATS_TEST_Operation *next_o;
76
77   next = e->start;
78   for (cur = next; NULL != cur; cur = next)
79   {
80     next = cur->next;
81
82     next_o = cur->head;
83     for (cur_o = next_o; NULL != cur_o; cur_o = next_o)
84     {
85       next_o = cur_o->next;
86       GNUNET_free (cur_o);
87     }
88     GNUNET_free (cur);
89   }
90
91   GNUNET_free_non_null (e->name);
92   GNUNET_free_non_null (e->cfg_file);
93   GNUNET_free (e);
94 }
95
96
97 static int
98 load_episode (struct Experiment *e,
99               struct Episode *cur,
100               struct GNUNET_CONFIGURATION_Handle *cfg)
101 {
102   struct GNUNET_ATS_TEST_Operation *o;
103   char *sec_name;
104   char *op_name;
105   char *op;
106   char *type;
107   char *pref;
108   int op_counter = 0;
109   fprintf (stderr, "Parsing episode %u\n",cur->id);
110   GNUNET_asprintf(&sec_name, "episode-%u", cur->id);
111
112   while (1)
113   {
114     /* Load operation */
115     GNUNET_asprintf(&op_name, "op-%u-operation", op_counter);
116     if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
117         sec_name, op_name, &op))
118     {
119       GNUNET_free (op_name);
120       break;
121     }
122     o = GNUNET_new (struct GNUNET_ATS_TEST_Operation);
123     /* operations = set_rate, start_send, stop_send, set_preference */
124     if (0 == strcmp (op, "start_send"))
125     {
126       o->type = START_SEND;
127     }
128     else if (0 == strcmp (op, "stop_send"))
129     {
130       o->type = STOP_SEND;
131     }
132     else if (0 == strcmp (op, "start_preference"))
133     {
134       o->type = START_PREFERENCE;
135     }
136     else if (0 == strcmp (op, "stop_preference"))
137     {
138       o->type = STOP_PREFERENCE;
139     }
140     else
141     {
142       fprintf (stderr, "Invalid operation %u `%s' in episode %u\n",
143           op_counter, op, cur->id);
144       GNUNET_free (op);
145       GNUNET_free (op_name);
146       GNUNET_free (sec_name);
147       GNUNET_free (o);
148       return GNUNET_SYSERR;
149     }
150     GNUNET_free (op_name);
151
152     /* Get source */
153     GNUNET_asprintf(&op_name, "op-%u-src", op_counter);
154     if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
155         sec_name, op_name, &o->src_id))
156     {
157       fprintf (stderr, "Missing src in operation %u `%s' in episode %u\n",
158           op_counter, op, cur->id);
159       GNUNET_free (op);
160       GNUNET_free (op_name);
161       GNUNET_free (sec_name);
162       GNUNET_free (o);
163       return GNUNET_SYSERR;
164     }
165     if (o->src_id > (e->num_masters - 1))
166     {
167       fprintf (stderr, "Invalid src %llu in operation %u `%s' in episode %u\n",
168           o->src_id, op_counter, op, cur->id);
169       GNUNET_free (op);
170       GNUNET_free (op_name);
171       GNUNET_free (sec_name);
172       GNUNET_free (o);
173       return GNUNET_SYSERR;
174     }
175     GNUNET_free (op_name);
176
177     /* Get destination */
178     GNUNET_asprintf(&op_name, "op-%u-dest", op_counter);
179     if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
180         sec_name, op_name, &o->dest_id))
181     {
182       fprintf (stderr, "Missing src in operation %u `%s' in episode %u\n",
183           op_counter, op, cur->id);
184       GNUNET_free (op);
185       GNUNET_free (op_name);
186       GNUNET_free (sec_name);
187       GNUNET_free (o);
188       return GNUNET_SYSERR;
189     }
190     if (o->dest_id > (e->num_slaves - 1))
191     {
192       fprintf (stderr,
193                "Invalid destination %llu in operation %u `%s' in episode %u\n",
194                o->dest_id,
195                op_counter,
196                op,
197                cur->id);
198       GNUNET_free (op);
199       GNUNET_free (op_name);
200       GNUNET_free (sec_name);
201       GNUNET_free (o);
202       return GNUNET_SYSERR;
203     }
204     GNUNET_free (op_name);
205
206     GNUNET_asprintf(&op_name, "op-%u-type", op_counter);
207     if ( (GNUNET_SYSERR !=
208           GNUNET_CONFIGURATION_get_value_string(cfg,
209                                                 sec_name,
210                                                 op_name,
211                                                 &type)) &&
212          (STOP_SEND != o->type) &&
213          (STOP_PREFERENCE != o->type) )
214     {
215       /* Load arguments for set_rate, start_send, set_preference */
216       if (0 == strcmp (type, "constant"))
217       {
218         o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
219       }
220       else if (0 == strcmp (type, "linear"))
221       {
222         o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
223       }
224       else if (0 == strcmp (type, "sinus"))
225       {
226         o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
227       }
228       else if (0 == strcmp (type, "random"))
229       {
230         o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
231       }
232       else
233       {
234         fprintf (stderr, "Invalid type %u `%s' in episode %u\n",
235             op_counter, op, cur->id);
236         GNUNET_free (type);
237         GNUNET_free (op);
238         GNUNET_free (op_name);
239         GNUNET_free (sec_name);
240         GNUNET_free (o);
241         return GNUNET_SYSERR;
242       }
243       GNUNET_free (op_name);
244
245       /* Get base rate */
246       GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
247       if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
248           sec_name, op_name, &o->base_rate))
249       {
250         fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
251             op_counter, op, cur->id);
252         GNUNET_free (type);
253         GNUNET_free (op);
254         GNUNET_free (op_name);
255         GNUNET_free (sec_name);
256         GNUNET_free (o);
257         return GNUNET_SYSERR;
258       }
259       GNUNET_free (op_name);
260
261       /* Get max rate */
262       GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
263       if (GNUNET_SYSERR ==
264           GNUNET_CONFIGURATION_get_value_number (cfg,
265                                                  sec_name,
266                                                  op_name,
267                                                  &o->max_rate))
268       {
269         if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
270             (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
271             (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
272         {
273           fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
274               op_counter, op, cur->id);
275           GNUNET_free (type);
276           GNUNET_free (op_name);
277           GNUNET_free (op);
278           GNUNET_free (sec_name);
279           GNUNET_free (o);
280           return GNUNET_SYSERR;
281         }
282       }
283       GNUNET_free (op_name);
284
285       /* Get period */
286       GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
287       if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
288           sec_name, op_name, &o->period))
289       {
290         o->period = cur->duration;
291       }
292       GNUNET_free (op_name);
293
294       if (START_PREFERENCE == o->type)
295       {
296           /* Get frequency */
297           GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
298           if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
299               sec_name, op_name, &o->frequency))
300           {
301               fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
302                   op_counter, op, cur->id);
303               GNUNET_free (type);
304               GNUNET_free (op_name);
305               GNUNET_free (op);
306               GNUNET_free (sec_name);
307               GNUNET_free (o);
308               return GNUNET_SYSERR;
309           }
310           GNUNET_free (op_name);
311
312           /* Get preference */
313           GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
314           if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
315               sec_name, op_name, &pref))
316           {
317               fprintf (stderr, "Missing preference in operation %u `%s' in episode %u\n",
318                   op_counter, op, cur->id);
319               GNUNET_free (type);
320               GNUNET_free (op_name);
321               GNUNET_free (op);
322               GNUNET_free (sec_name);
323               GNUNET_free_non_null (pref);
324               GNUNET_free (o);
325               return GNUNET_SYSERR;
326           }
327
328           if (0 == strcmp(pref, "bandwidth"))
329             o->pref_type = GNUNET_ATS_PREFERENCE_BANDWIDTH;
330           else if (0 == strcmp(pref, "latency"))
331             o->pref_type = GNUNET_ATS_PREFERENCE_LATENCY;
332           else
333           {
334               fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
335                   op_counter, op, cur->id);
336               GNUNET_free (type);
337               GNUNET_free (op_name);
338               GNUNET_free (op);
339               GNUNET_free (pref);
340               GNUNET_free (sec_name);
341               GNUNET_free_non_null (pref);
342               GNUNET_free (o);
343               return GNUNET_SYSERR;
344           }
345           GNUNET_free (pref);
346           GNUNET_free (op_name);
347       }
348     }
349
350     /* Safety checks */
351     if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
352         (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
353     {
354       if ((o->max_rate - o->base_rate) > o->base_rate)
355       {
356         /* This will cause an underflow */
357         GNUNET_break (0);
358       }
359       fprintf (stderr, "Selected max rate and base rate cannot be used for desired traffic form!\n");
360     }
361
362     if ((START_SEND == o->type) || (START_PREFERENCE == o->type))
363       fprintf (stderr, "Found operation %u in episode %u: %s [%llu]->[%llu] == %s, %llu -> %llu in %s\n",
364         op_counter, cur->id, print_op (o->type), o->src_id,
365         o->dest_id, (NULL != type) ? type : "",
366         o->base_rate, o->max_rate,
367         GNUNET_STRINGS_relative_time_to_string (o->period, GNUNET_YES));
368     else
369       fprintf (stderr, "Found operation %u in episode %u: %s [%llu]->[%llu]\n",
370         op_counter, cur->id, print_op (o->type), o->src_id, o->dest_id);
371
372     GNUNET_free_non_null (type);
373     GNUNET_free (op);
374
375     GNUNET_CONTAINER_DLL_insert (cur->head,cur->tail, o);
376     op_counter++;
377   }
378   GNUNET_free (sec_name);
379
380   return GNUNET_OK;
381 }
382
383 static int
384 load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
385 {
386   int e_counter = 0;
387   char *sec_name;
388   struct GNUNET_TIME_Relative e_duration;
389   struct Episode *cur;
390   struct Episode *last;
391
392   e_counter = 0;
393   last = NULL;
394   while (1)
395   {
396     GNUNET_asprintf(&sec_name, "episode-%u", e_counter);
397     if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg,
398         sec_name, "duration", &e_duration))
399     {
400       GNUNET_free (sec_name);
401       break;
402     }
403
404     cur = GNUNET_new (struct Episode);
405     cur->duration = e_duration;
406     cur->id = e_counter;
407
408     if (GNUNET_OK != load_episode (e, cur, cfg))
409     {
410       GNUNET_free (sec_name);
411       GNUNET_free (cur);
412       return GNUNET_SYSERR;
413     }
414
415     fprintf (stderr, "Found episode %u with duration %s \n",
416         e_counter,
417         GNUNET_STRINGS_relative_time_to_string(cur->duration, GNUNET_YES));
418
419     /* Update experiment */
420     e->num_episodes ++;
421     e->total_duration = GNUNET_TIME_relative_add(e->total_duration, cur->duration);
422     /* Put in linked list */
423     if (NULL == last)
424       e->start = cur;
425     else
426     last->next = cur;
427
428     GNUNET_free (sec_name);
429     e_counter ++;
430     last = cur;
431   }
432   return e_counter;
433 }
434
435
436 static void
437 timeout_experiment (void *cls)
438 {
439   struct Experiment *e = cls;
440   e->experiment_timeout_task = NULL;
441   fprintf (stderr, "Experiment timeout!\n");
442
443   if (NULL != e->episode_timeout_task)
444   {
445     GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
446     e->episode_timeout_task = NULL;
447   }
448
449   e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time),
450       GNUNET_SYSERR);
451 }
452
453
454 static void
455 enforce_start_send (struct GNUNET_ATS_TEST_Operation *op)
456 {
457   /*
458   struct BenchmarkPeer *peer;
459   struct BenchmarkPartner *partner;
460
461   peer = GNUNET_ATS_TEST_get_peer (op->src_id);
462   if (NULL == peer)
463   {
464     GNUNET_break (0);
465     return;
466   }
467
468   partner = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
469   if (NULL == partner)
470   {
471     GNUNET_break (0);
472     return;
473   }
474
475   fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
476
477   if (NULL != partner->tg)
478   {
479     fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",op->src_id, op->dest_id);
480     GNUNET_ATS_TEST_generate_traffic_stop(partner->tg);
481     partner->tg = NULL;
482   }
483
484   partner->tg = GNUNET_ATS_TEST_generate_traffic_start(peer, partner,
485       op->tg_type, op->base_rate, op->max_rate, op->period,
486       GNUNET_TIME_UNIT_FOREVER_REL);
487    */
488 }
489
490 static void
491 enforce_stop_send (struct GNUNET_ATS_TEST_Operation *op)
492 {
493   /*
494   struct BenchmarkPartner *p;
495   p = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
496   if (NULL == p)
497   {
498     GNUNET_break (0);
499     return;
500   }
501
502   fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
503
504   if (NULL != p->tg)
505   {
506     fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",
507         op->src_id, op->dest_id);
508     GNUNET_ATS_TEST_generate_traffic_stop(p->tg);
509     p->tg = NULL;
510   }
511   */
512 }
513
514
515 static void
516 enforce_start_preference (struct GNUNET_ATS_TEST_Operation *op)
517 {
518   /*
519   struct BenchmarkPeer *peer;
520   struct BenchmarkPartner *partner;
521
522   peer = GNUNET_ATS_TEST_get_peer (op->src_id);
523   if (NULL == peer)
524   {
525     GNUNET_break (0);
526     return;
527   }
528
529   partner = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
530   if (NULL == partner)
531   {
532     GNUNET_break (0);
533     return;
534   }
535
536   fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
537
538   if (NULL != partner->pg)
539   {
540     fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",
541         op->src_id, op->dest_id);
542     GNUNET_ATS_TEST_generate_preferences_stop(partner->pg);
543     partner->pg = NULL;
544   }
545
546   partner->pg = GNUNET_ATS_TEST_generate_preferences_start(peer, partner,
547       op->tg_type, op->base_rate, op->max_rate, op->period, op->frequency,
548       op->pref_type);
549       */
550 }
551
552 static void
553 enforce_stop_preference (struct GNUNET_ATS_TEST_Operation *op)
554 {
555   /*
556   struct BenchmarkPartner *p;
557   p = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
558   if (NULL == p)
559   {
560     GNUNET_break (0);
561     return;
562   }
563
564   fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
565
566   if (NULL != p->pg)
567   {
568     fprintf (stderr, "Stopping preference between master %llu slave %llu\n",
569         op->src_id, op->dest_id);
570     GNUNET_ATS_TEST_generate_preferences_stop (p->pg);
571     p->pg = NULL;
572   }
573   */
574 }
575
576 static void enforce_episode (struct Episode *ep)
577 {
578   struct GNUNET_ATS_TEST_Operation *cur;
579   for (cur = ep->head; NULL != cur; cur = cur->next)
580   {
581
582     fprintf (stderr, "Enforcing operation: %s [%llu]->[%llu] == %llu\n",
583         print_op (cur->type), cur->src_id, cur->dest_id, cur->base_rate);
584     switch (cur->type) {
585       case START_SEND:
586         enforce_start_send (cur);
587         break;
588       case STOP_SEND:
589         enforce_stop_send (cur);
590         break;
591       case START_PREFERENCE:
592         enforce_start_preference (cur);
593         break;
594       case STOP_PREFERENCE:
595         enforce_stop_preference (cur);
596         break;
597       default:
598         break;
599     }
600   }
601 }
602
603
604 static void
605 timeout_episode (void *cls)
606 {
607   struct Experiment *e = cls;
608   e->episode_timeout_task = NULL;
609   if (NULL != e->ep_done_cb)
610     e->ep_done_cb (e->cur);
611
612   /* Scheduling next */
613   e->cur = e->cur->next;
614   if (NULL == e->cur)
615   {
616     /* done */
617     fprintf (stderr, "Last episode done!\n");
618     if (NULL != e->experiment_timeout_task)
619     {
620       GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
621       e->experiment_timeout_task = NULL;
622     }
623     e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time), GNUNET_OK);
624     return;
625   }
626
627   fprintf (stderr, "Running episode %u with timeout %s\n",
628       e->cur->id,
629       GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
630   enforce_episode(e->cur);
631
632   e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
633       &timeout_episode, e);
634 }
635
636
637 void
638 GNUNET_ATS_solvers_experimentation_run (struct Experiment *e,
639     GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb,
640     GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb)
641 {
642   fprintf (stderr, "Running experiment `%s'  with timeout %s\n", e->name,
643       GNUNET_STRINGS_relative_time_to_string(e->max_duration, GNUNET_YES));
644   e->e_done_cb = e_done_cb;
645   e->ep_done_cb = ep_done_cb;
646   e->start_time = GNUNET_TIME_absolute_get();
647
648   /* Start total time out */
649   e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed (e->max_duration,
650       &timeout_experiment, e);
651
652   /* Start */
653   e->cur = e->start;
654   fprintf (stderr, "Running episode %u with timeout %s\n",
655       e->cur->id,
656       GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
657   enforce_episode(e->cur);
658   e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
659       &timeout_episode, e);
660
661
662 }
663
664
665 struct Experiment *
666 GNUNET_ATS_solvers_experimentation_load (char *filename)
667 {
668   struct Experiment *e;
669   struct GNUNET_CONFIGURATION_Handle *cfg;
670   e = NULL;
671
672   cfg = GNUNET_CONFIGURATION_create();
673   if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, filename))
674   {
675     fprintf (stderr, "Failed to load `%s'\n", filename);
676     GNUNET_CONFIGURATION_destroy (cfg);
677     return NULL;
678   }
679
680   e = create_experiment ();
681
682   if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
683       "name", &e->name))
684   {
685     fprintf (stderr, "Invalid %s", "name");
686     free_experiment (e);
687     return NULL;
688   }
689   else
690     fprintf (stderr, "Experiment name: `%s'\n", e->name);
691
692   if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment",
693       "cfg_file", &e->cfg_file))
694   {
695     fprintf (stderr, "Invalid %s", "cfg_file");
696     free_experiment (e);
697     return NULL;
698   }
699   else
700     fprintf (stderr, "Experiment name: `%s'\n", e->cfg_file);
701
702   if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg, "experiment",
703       "masters", &e->num_masters))
704   {
705     fprintf (stderr, "Invalid %s", "masters");
706     free_experiment (e);
707     return NULL;
708   }
709   else
710     fprintf (stderr, "Experiment masters: `%llu'\n",
711         e->num_masters);
712
713   if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg, "experiment",
714       "slaves", &e->num_slaves))
715   {
716     fprintf (stderr, "Invalid %s", "slaves");
717     free_experiment (e);
718     return NULL;
719   }
720   else
721     fprintf (stderr, "Experiment slaves: `%llu'\n",
722         e->num_slaves);
723
724   if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
725       "log_freq", &e->log_freq))
726   {
727     fprintf (stderr, "Invalid %s", "log_freq");
728     free_experiment (e);
729     return NULL;
730   }
731   else
732     fprintf (stderr, "Experiment logging frequency: `%s'\n",
733         GNUNET_STRINGS_relative_time_to_string (e->log_freq, GNUNET_YES));
734
735   if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
736       "max_duration", &e->max_duration))
737   {
738     fprintf (stderr, "Invalid %s", "max_duration");
739     free_experiment (e);
740     return NULL;
741   }
742   else
743     fprintf (stderr, "Experiment duration: `%s'\n",
744         GNUNET_STRINGS_relative_time_to_string (e->max_duration, GNUNET_YES));
745
746   load_episodes (e, cfg);
747   fprintf (stderr, "Loaded %u episodes with total duration %s\n",
748       e->num_episodes,
749       GNUNET_STRINGS_relative_time_to_string (e->total_duration, GNUNET_YES));
750
751   GNUNET_CONFIGURATION_destroy (cfg);
752   return e;
753 }
754
755 void
756 GNUNET_ATS_solvers_experimentation_stop (struct Experiment *e)
757 {
758   if (NULL != e->experiment_timeout_task)
759   {
760     GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
761     e->experiment_timeout_task = NULL;
762   }
763   if (NULL != e->episode_timeout_task)
764   {
765     GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
766     e->episode_timeout_task = NULL;
767   }
768   free_experiment (e);
769 }
770
771 /**
772  * Solver
773  */
774
775 struct GNUNET_ATS_TESTING_SolverHandle
776 {
777   char * plugin;
778   struct GNUNET_ATS_PluginEnvironment env;
779   void *solver;
780 };
781
782 enum GNUNET_ATS_Solvers
783 {
784   GNUNET_ATS_SOLVER_PROPORTIONAL,
785   GNUNET_ATS_SOLVER_MLP,
786   GNUNET_ATS_SOLVER_RIL,
787 };
788
789 void
790 GNUNET_ATS_solvers_solver_stop (struct GNUNET_ATS_TESTING_SolverHandle *sh)
791 {
792  GNUNET_PLUGIN_unload (sh->plugin, sh->solver);
793  GNUNET_free (sh->plugin);
794  GNUNET_free (sh);
795 }
796
797 struct GNUNET_ATS_TESTING_SolverHandle *
798 GNUNET_ATS_solvers_solver_start (enum GNUNET_ATS_Solvers type)
799 {
800   struct GNUNET_ATS_TESTING_SolverHandle *sh;
801   char * solver_str;
802
803   switch (type) {
804     case GNUNET_ATS_SOLVER_PROPORTIONAL:
805       solver_str = "proportional";
806       break;
807     case GNUNET_ATS_SOLVER_MLP:
808       solver_str = "mlp";
809       break;
810     case GNUNET_ATS_SOLVER_RIL:
811       solver_str = "ril";
812       break;
813     default:
814       GNUNET_break (0);
815       return NULL;
816       break;
817   }
818
819   sh = GNUNET_new (struct GNUNET_ATS_TESTING_SolverHandle);
820   GNUNET_asprintf (&sh->plugin, "libgnunet_plugin_ats_%s", solver_str);
821   //sh->solver = GNUNET_PLUGIN_load (sh->plugin, &sh->env);
822   if (NULL == sh->solver)
823   {
824     fprintf (stderr, "Failed to load solver `%s'\n", sh->plugin);
825     exit (1);
826   }
827
828   return sh;
829 }
830
831 static struct Experiment *e;
832
833 static struct GNUNET_ATS_TESTING_SolverHandle *sh;
834
835 /**
836  * cmd option -e: experiment file
837  */
838 static char *opt_exp_file;
839
840 static char *opt_solver;
841
842 /**
843  * cmd option -l: enable logging
844  */
845 static int opt_log;
846
847 /**
848  * cmd option -p: enable plots
849  */
850 static int opt_plot;
851
852 /**
853  * cmd option -v: verbose logs
854  */
855 static int opt_verbose;
856
857 static void
858 run (void *cls, char * const *args, const char *cfgfile,
859     const struct GNUNET_CONFIGURATION_Handle *cfg)
860 {
861   enum GNUNET_ATS_Solvers solver;
862
863   if (NULL == opt_exp_file)
864   {
865     fprintf (stderr, "No experiment given ...\n");
866     exit (1);
867   }
868
869   if (NULL == opt_solver)
870   {
871     fprintf (stderr, "No solver given ...\n");
872     exit (1);
873   }
874
875   if (0 == strcmp(opt_solver, "mlp"))
876   {
877     solver = GNUNET_ATS_SOLVER_MLP;
878   }
879   else if (0 == strcmp(opt_solver, "proportional"))
880   {
881     solver = GNUNET_ATS_SOLVER_PROPORTIONAL;
882   }
883   else if (0 == strcmp(opt_solver, "ril"))
884   {
885     solver = GNUNET_ATS_SOLVER_RIL;
886   }
887   else
888   {
889     fprintf (stderr, "No solver given ...");
890     return;
891   }
892
893   /* load experiment */
894   e = GNUNET_ATS_solvers_experimentation_load (opt_exp_file);
895   if (NULL == e)
896   {
897     fprintf (stderr, "Failed to load experiment ...\n");
898     return;
899   }
900
901   /* load solver */
902   sh = GNUNET_ATS_solvers_solver_start (solver);
903   if (NULL == sh)
904   {
905     fprintf (stderr, "Failed to start solver ...\n");
906     return;
907   }
908
909   /* start logging */
910
911   /* run experiment */
912
913   /* WAIT */
914 }
915
916
917 /**
918  * Main function of the benchmark
919  *
920  * @param argc argument count
921  * @param argv argument values
922  */
923 int
924 main (int argc, char *argv[])
925 {
926
927   opt_exp_file = NULL;
928   opt_solver = NULL;
929   opt_log = GNUNET_NO;
930   opt_plot = GNUNET_NO;
931
932   static struct GNUNET_GETOPT_CommandLineOption options[] =
933   {
934     { 's', "solver", NULL,
935         gettext_noop ("solver to use"),
936         1, &GNUNET_GETOPT_set_string, &opt_solver},
937     {  'e', "experiment", NULL,
938       gettext_noop ("experiment to use"),
939       1, &GNUNET_GETOPT_set_string, &opt_exp_file},
940     {  'e', "experiment", NULL,
941       gettext_noop ("experiment to use"),
942       1, &GNUNET_GETOPT_set_one, &opt_verbose},
943     GNUNET_GETOPT_OPTION_END
944   };
945
946   GNUNET_PROGRAM_run (argc, argv, argv[0], NULL, options, &run, argv[0]);
947
948   return 0;
949 }
950 /* end of file ats-testing-experiment.c*/