2 This file is part of GNUnet.
3 (C) 2010-2013 Christian Grothoff (and other contributing authors)
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.
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.
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.
21 * @file ats-tests/ats-testing-experiment.c
22 * @brief ats benchmark: controlled experiment execution
23 * @author Christian Grothoff
24 * @author Matthias Wachs
27 #include "gnunet_util_lib.h"
28 #include "gnunet-ats-solver-eval.h"
31 #define BIG_M_STRING "unlimited"
33 static struct Experiment *e;
35 static struct GNUNET_ATS_TESTING_SolverHandle *sh;
38 * cmd option -e: experiment file
40 static char *opt_exp_file;
42 static char *opt_solver;
45 * cmd option -l: enable logging
50 * cmd option -p: enable plots
55 * cmd option -v: verbose logs
57 static int opt_verbose;
69 print_op (enum OperationType op)
72 case SOLVER_OP_ADD_ADDRESS:
74 case SOLVER_OP_DEL_ADDRESS:
76 case SOLVER_OP_START_SET_PREFERENCE:
77 return "START_SET_PREFERENCE";
78 case SOLVER_OP_STOP_SET_PREFERENCE:
79 return "STOP_STOP_PREFERENCE";
80 case SOLVER_OP_START_SET_PROPERTY:
81 return "START_SET_PROPERTY";
82 case SOLVER_OP_STOP_SET_PROPERTY:
83 return "STOP_SET_PROPERTY";
91 static struct Experiment *
95 e = GNUNET_new (struct Experiment);
100 e->total_duration = GNUNET_TIME_UNIT_ZERO;
105 free_experiment (struct Experiment *e)
108 struct Episode *next;
109 struct GNUNET_ATS_TEST_Operation *cur_o;
110 struct GNUNET_ATS_TEST_Operation *next_o;
113 for (cur = next; NULL != cur; cur = next)
118 for (cur_o = next_o; NULL != cur_o; cur_o = next_o)
120 next_o = cur_o->next;
126 GNUNET_free_non_null (e->name);
127 GNUNET_free_non_null (e->cfg_file);
133 load_op_add_address (struct GNUNET_ATS_TEST_Operation *o,
136 const struct GNUNET_CONFIGURATION_Handle *cfg)
141 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
142 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
143 sec_name, op_name, &o->peer_id))
145 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
146 op_counter, "ADD_ADDRESS", op_name);
147 GNUNET_free (op_name);
148 return GNUNET_SYSERR;
150 GNUNET_free (op_name);
153 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
154 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
155 sec_name, op_name, &o->address_id))
157 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
158 op_counter, "ADD_ADDRESS", op_name);
159 GNUNET_free (op_name);
160 return GNUNET_SYSERR;
162 GNUNET_free (op_name);
165 GNUNET_asprintf(&op_name, "op-%u-plugin", op_counter);
166 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
167 sec_name, op_name, &o->plugin))
169 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
170 op_counter, "ADD_ADDRESS", op_name);
171 GNUNET_free (op_name);
172 return GNUNET_SYSERR;
174 GNUNET_free (op_name);
177 GNUNET_asprintf(&op_name, "op-%u-address", op_counter);
178 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
179 sec_name, op_name, &o->address))
181 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
182 op_counter, "ADD_ADDRESS", op_name);
183 GNUNET_free (op_name);
184 return GNUNET_SYSERR;
186 GNUNET_free (op_name);
189 GNUNET_asprintf(&op_name, "op-%u-address-session", op_counter);
190 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
191 sec_name, op_name, &o->address_session))
193 fprintf (stderr, "Missing address-session in operation %u `%s' in episode `%s'\n",
194 op_counter, "ADD_ADDRESS", op_name);
195 GNUNET_free (op_name);
196 return GNUNET_SYSERR;
198 GNUNET_free (op_name);
201 GNUNET_asprintf(&op_name, "op-%u-address-network", op_counter);
202 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
203 sec_name, op_name, &o->address_network))
205 fprintf (stderr, "Missing address-network in operation %u `%s' in episode `%s'\n",
206 op_counter, "ADD_ADDRESS", op_name);
207 GNUNET_free (op_name);
208 return GNUNET_SYSERR;
210 GNUNET_free (op_name);
213 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
214 "ADD_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
220 load_op_del_address (struct GNUNET_ATS_TEST_Operation *o,
223 const struct GNUNET_CONFIGURATION_Handle *cfg)
228 GNUNET_asprintf(&op_name, "op-%u-peer-id", op_counter);
229 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
230 sec_name, op_name, &o->peer_id))
232 fprintf (stderr, "Missing peer-id in operation %u `%s' in episode `%s'\n",
233 op_counter, "DEL_ADDRESS", op_name);
234 GNUNET_free (op_name);
235 return GNUNET_SYSERR;
237 GNUNET_free (op_name);
240 GNUNET_asprintf(&op_name, "op-%u-address-id", op_counter);
241 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
242 sec_name, op_name, &o->address_id))
244 fprintf (stderr, "Missing address-id in operation %u `%s' in episode `%s'\n",
245 op_counter, "DEL_ADDRESS", op_name);
246 GNUNET_free (op_name);
247 return GNUNET_SYSERR;
249 GNUNET_free (op_name);
252 GNUNET_asprintf(&op_name, "op-%u-plugin", op_counter);
253 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
254 sec_name, op_name, &o->plugin))
256 fprintf (stderr, "Missing plugin in operation %u `%s' in episode `%s'\n",
257 op_counter, "DEL_ADDRESS", op_name);
258 GNUNET_free (op_name);
259 return GNUNET_SYSERR;
261 GNUNET_free (op_name);
264 GNUNET_asprintf(&op_name, "op-%u-address", op_counter);
265 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
266 sec_name, op_name, &o->address))
268 fprintf (stderr, "Missing address in operation %u `%s' in episode `%s'\n",
269 op_counter, "DEL_ADDRESS", op_name);
270 GNUNET_free (op_name);
271 return GNUNET_SYSERR;
273 GNUNET_free (op_name);
276 GNUNET_asprintf(&op_name, "op-%u-address-session", op_counter);
277 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
278 sec_name, op_name, &o->address_session))
280 fprintf (stderr, "Missing address-session in operation %u `%s' in episode `%s'\n",
281 op_counter, "DEL_ADDRESS", op_name);
282 GNUNET_free (op_name);
283 return GNUNET_SYSERR;
285 GNUNET_free (op_name);
288 GNUNET_asprintf(&op_name, "op-%u-address-network", op_counter);
289 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
290 sec_name, op_name, &o->address_network))
292 fprintf (stderr, "Missing address-network in operation %u `%s' in episode `%s'\n",
293 op_counter, "DEL_ADDRESS", op_name);
294 GNUNET_free (op_name);
295 return GNUNET_SYSERR;
297 GNUNET_free (op_name);
300 "Found operation %s: [%llu:%llu] address `%s' plugin `%s' \n",
301 "DEL_ADDRESS", o->peer_id, o->address_id, o->address, o->plugin);
307 load_episode (struct Experiment *e, struct Episode *cur,
308 struct GNUNET_CONFIGURATION_Handle *cfg)
310 struct GNUNET_ATS_TEST_Operation *o;
317 fprintf (stderr, "Parsing episode %u\n",cur->id);
318 GNUNET_asprintf(&sec_name, "episode-%u", cur->id);
323 GNUNET_asprintf(&op_name, "op-%u-operation", op_counter);
324 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
325 sec_name, op_name, &op))
327 GNUNET_free (op_name);
330 o = GNUNET_new (struct GNUNET_ATS_TEST_Operation);
331 /* operations = set_rate, start_send, stop_send, set_preference */
332 if (0 == strcmp (op, "address_add"))
334 o->type = SOLVER_OP_ADD_ADDRESS;
335 if (GNUNET_SYSERR == load_op_add_address (o, op_counter, sec_name, cfg))
339 GNUNET_free (op_name);
340 return GNUNET_SYSERR;
343 else if (0 == strcmp (op, "address_del"))
345 o->type = SOLVER_OP_DEL_ADDRESS;
346 if (GNUNET_SYSERR == load_op_del_address (o, op_counter, sec_name, cfg))
350 GNUNET_free (op_name);
351 return GNUNET_SYSERR;
354 else if (0 == strcmp (op, "start_set_property"))
356 o->type = SOLVER_OP_START_SET_PROPERTY;
358 else if (0 == strcmp (op, "stop_set_property"))
360 o->type = SOLVER_OP_STOP_SET_PROPERTY;
362 else if (0 == strcmp (op, "start_set_preference"))
364 o->type = SOLVER_OP_START_SET_PREFERENCE;
366 else if (0 == strcmp (op, "stop_set_preference"))
368 o->type = SOLVER_OP_STOP_SET_PREFERENCE;
372 fprintf (stderr, "Invalid operation %u `%s' in episode %u\n",
373 op_counter, op, cur->id);
375 GNUNET_free (op_name);
376 return GNUNET_SYSERR;
379 GNUNET_free (op_name);
381 GNUNET_CONTAINER_DLL_insert (cur->head,cur->tail, o);
384 GNUNET_free (sec_name);
389 GNUNET_asprintf(&op_name, "op-%u-src", op_counter);
390 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
391 sec_name, op_name, &o->src_id))
393 fprintf (stderr, "Missing src in operation %u `%s' in episode %u\n",
394 op_counter, op, cur->id);
396 GNUNET_free (op_name);
397 return GNUNET_SYSERR;
399 if (o->src_id > (e->num_masters - 1))
401 fprintf (stderr, "Invalid src %llu in operation %u `%s' in episode %u\n",
402 o->src_id, op_counter, op, cur->id);
404 GNUNET_free (op_name);
405 return GNUNET_SYSERR;
407 GNUNET_free (op_name);
409 /* Get destination */
410 GNUNET_asprintf(&op_name, "op-%u-dest", op_counter);
411 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
412 sec_name, op_name, &o->dest_id))
414 fprintf (stderr, "Missing src in operation %u `%s' in episode %u\n",
415 op_counter, op, cur->id);
417 GNUNET_free (op_name);
418 return GNUNET_SYSERR;
420 if (o->dest_id > (e->num_slaves - 1))
422 fprintf (stderr, "Invalid destination %llu in operation %u `%s' in episode %u\n",
423 o->dest_id, op_counter, op, cur->id);
425 GNUNET_free (op_name);
426 return GNUNET_SYSERR;
428 GNUNET_free (op_name);
430 GNUNET_asprintf(&op_name, "op-%u-type", op_counter);
431 if ( (GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_string(cfg,
432 sec_name, op_name, &type)) &&
433 ((STOP_SEND != o->type) || (STOP_PREFERENCE != o->type)))
435 /* Load arguments for set_rate, start_send, set_preference */
436 if (0 == strcmp (type, "constant"))
438 o->tg_type = GNUNET_ATS_TEST_TG_CONSTANT;
440 else if (0 == strcmp (type, "linear"))
442 o->tg_type = GNUNET_ATS_TEST_TG_LINEAR;
444 else if (0 == strcmp (type, "sinus"))
446 o->tg_type = GNUNET_ATS_TEST_TG_SINUS;
448 else if (0 == strcmp (type, "random"))
450 o->tg_type = GNUNET_ATS_TEST_TG_RANDOM;
454 fprintf (stderr, "Invalid type %u `%s' in episode %u\n",
455 op_counter, op, cur->id);
458 GNUNET_free (op_name);
459 return GNUNET_SYSERR;
461 GNUNET_free (op_name);
464 GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
465 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
466 sec_name, op_name, &o->base_rate))
468 fprintf (stderr, "Missing base rate in operation %u `%s' in episode %u\n",
469 op_counter, op, cur->id);
472 GNUNET_free (op_name);
473 return GNUNET_SYSERR;
475 GNUNET_free (op_name);
478 GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
479 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg,
480 sec_name, op_name, &o->max_rate))
482 if ((GNUNET_ATS_TEST_TG_LINEAR == o->tg_type) ||
483 (GNUNET_ATS_TEST_TG_RANDOM == o->tg_type) ||
484 (GNUNET_ATS_TEST_TG_SINUS == o->tg_type))
486 fprintf (stderr, "Missing max rate in operation %u `%s' in episode %u\n",
487 op_counter, op, cur->id);
489 GNUNET_free (op_name);
491 return GNUNET_SYSERR;
494 GNUNET_free (op_name);
497 GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
498 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
499 sec_name, op_name, &o->period))
501 o->period = cur->duration;
503 GNUNET_free (op_name);
505 if (START_PREFERENCE == o->type)
508 GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
509 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg,
510 sec_name, op_name, &o->frequency))
512 fprintf (stderr, "Missing frequency in operation %u `%s' in episode %u\n",
513 op_counter, op, cur->id);
515 GNUNET_free (op_name);
517 return GNUNET_SYSERR;
519 GNUNET_free (op_name);
522 GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
523 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg,
524 sec_name, op_name, &pref))
526 fprintf (stderr, "Missing preference in operation %u `%s' in episode %u\n",
527 op_counter, op, cur->id);
529 GNUNET_free (op_name);
531 GNUNET_free_non_null (pref);
532 return GNUNET_SYSERR;
535 if (0 == strcmp(pref, "bandwidth"))
536 o->pref_type = GNUNET_ATS_PREFERENCE_BANDWIDTH;
537 else if (0 == strcmp(pref, "latency"))
538 o->pref_type = GNUNET_ATS_PREFERENCE_LATENCY;
541 fprintf (stderr, "Invalid preference in operation %u `%s' in episode %u\n",
542 op_counter, op, cur->id);
544 GNUNET_free (op_name);
547 GNUNET_free_non_null (pref);
548 return GNUNET_SYSERR;
551 GNUNET_free (op_name);
556 if ((GNUNET_ATS_TEST_TG_LINEAR == o->tg_type) ||
557 (GNUNET_ATS_TEST_TG_SINUS == o->tg_type))
559 if ((o->max_rate - o->base_rate) > o->base_rate)
561 /* This will cause an underflow */
564 fprintf (stderr, "Selected max rate and base rate cannot be used for desired traffic form!\n");
567 if ((START_SEND == o->type) || (START_PREFERENCE == o->type))
568 fprintf (stderr, "Found operation %u in episode %u: %s [%llu]->[%llu] == %s, %llu -> %llu in %s\n",
569 op_counter, cur->id, print_op (o->type), o->src_id,
570 o->dest_id, (NULL != type) ? type : "",
571 o->base_rate, o->max_rate,
572 GNUNET_STRINGS_relative_time_to_string (o->period, GNUNET_YES));
574 fprintf (stderr, "Found operation %u in episode %u: %s [%llu]->[%llu]\n",
575 op_counter, cur->id, print_op (o->type), o->src_id, o->dest_id);
577 GNUNET_free_non_null (type);
585 load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
589 struct GNUNET_TIME_Relative e_duration;
591 struct Episode *last;
597 GNUNET_asprintf(&sec_name, "episode-%u", e_counter);
598 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg,
599 sec_name, "duration", &e_duration))
601 GNUNET_free (sec_name);
605 cur = GNUNET_new (struct Episode);
606 cur->duration = e_duration;
609 if (GNUNET_OK != load_episode (e, cur, cfg))
611 GNUNET_free (sec_name);
613 return GNUNET_SYSERR;
616 fprintf (stderr, "Found episode %u with duration %s \n",
618 GNUNET_STRINGS_relative_time_to_string(cur->duration, GNUNET_YES));
620 /* Update experiment */
622 e->total_duration = GNUNET_TIME_relative_add(e->total_duration, cur->duration);
623 /* Put in linked list */
629 GNUNET_free (sec_name);
637 timeout_experiment (void *cls, const struct GNUNET_SCHEDULER_TaskContext* tc)
639 struct Experiment *e = cls;
640 e->experiment_timeout_task = GNUNET_SCHEDULER_NO_TASK;
641 fprintf (stderr, "Experiment timeout!\n");
643 if (GNUNET_SCHEDULER_NO_TASK != e->episode_timeout_task)
645 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
646 e->episode_timeout_task = GNUNET_SCHEDULER_NO_TASK;
649 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time),
654 enforce_add_address (struct GNUNET_ATS_TEST_Operation *op)
657 struct BenchmarkPeer *peer;
658 struct BenchmarkPartner *partner;
660 peer = GNUNET_ATS_TEST_get_peer (op->src_id);
667 partner = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
674 fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
676 if (NULL != partner->tg)
678 fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",op->src_id, op->dest_id);
679 GNUNET_ATS_TEST_generate_traffic_stop(partner->tg);
683 partner->tg = GNUNET_ATS_TEST_generate_traffic_start(peer, partner,
684 op->tg_type, op->base_rate, op->max_rate, op->period,
685 GNUNET_TIME_UNIT_FOREVER_REL);
690 enforce_del_address (struct GNUNET_ATS_TEST_Operation *op)
693 struct BenchmarkPartner *p;
694 p = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
701 fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
705 fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",
706 op->src_id, op->dest_id);
707 GNUNET_ATS_TEST_generate_traffic_stop(p->tg);
714 enforce_start_property (struct GNUNET_ATS_TEST_Operation *op)
720 enforce_stop_property (struct GNUNET_ATS_TEST_Operation *op)
726 enforce_start_preference (struct GNUNET_ATS_TEST_Operation *op)
729 struct BenchmarkPeer *peer;
730 struct BenchmarkPartner *partner;
732 peer = GNUNET_ATS_TEST_get_peer (op->src_id);
739 partner = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
746 fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
748 if (NULL != partner->pg)
750 fprintf (stderr, "Stopping traffic between master %llu slave %llu\n",
751 op->src_id, op->dest_id);
752 GNUNET_ATS_TEST_generate_preferences_stop(partner->pg);
756 partner->pg = GNUNET_ATS_TEST_generate_preferences_start(peer, partner,
757 op->tg_type, op->base_rate, op->max_rate, op->period, op->frequency,
763 enforce_stop_preference (struct GNUNET_ATS_TEST_Operation *op)
766 struct BenchmarkPartner *p;
767 p = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id);
774 fprintf (stderr, "Found master %llu slave %llu\n",op->src_id, op->dest_id);
778 fprintf (stderr, "Stopping preference between master %llu slave %llu\n",
779 op->src_id, op->dest_id);
780 GNUNET_ATS_TEST_generate_preferences_stop (p->pg);
786 static void enforce_episode (struct Episode *ep)
788 struct GNUNET_ATS_TEST_Operation *cur;
789 for (cur = ep->head; NULL != cur; cur = cur->next)
792 case SOLVER_OP_ADD_ADDRESS:
793 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
794 print_op (cur->type), cur->peer_id, cur->address_id);
795 enforce_add_address (cur);
797 case SOLVER_OP_DEL_ADDRESS:
798 fprintf (stderr, "Enforcing operation: %s [%llu:%llu]\n",
799 print_op (cur->type), cur->peer_id, cur->address_id);
800 enforce_del_address (cur);
802 case SOLVER_OP_START_SET_PROPERTY:
803 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
804 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
805 enforce_start_property (cur);
807 case SOLVER_OP_STOP_SET_PROPERTY:
808 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
809 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
810 enforce_stop_property (cur);
812 case SOLVER_OP_START_SET_PREFERENCE:
813 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
814 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
815 enforce_start_preference (cur);
817 case SOLVER_OP_STOP_SET_PREFERENCE:
818 fprintf (stderr, "Enforcing operation: %s [%llu:%llu] == %llu\n",
819 print_op (cur->type), cur->peer_id, cur->address_id, cur->base_rate);
820 enforce_stop_preference (cur);
829 timeout_episode (void *cls, const struct GNUNET_SCHEDULER_TaskContext* tc)
831 struct Experiment *e = cls;
832 e->episode_timeout_task = GNUNET_SCHEDULER_NO_TASK;
833 if (NULL != e->ep_done_cb)
834 e->ep_done_cb (e->cur);
836 /* Scheduling next */
837 e->cur = e->cur->next;
841 fprintf (stderr, "Last episode done!\n");
842 if (GNUNET_SCHEDULER_NO_TASK != e->experiment_timeout_task)
844 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
845 e->experiment_timeout_task = GNUNET_SCHEDULER_NO_TASK;
847 e->e_done_cb (e, GNUNET_TIME_absolute_get_duration(e->start_time), GNUNET_OK);
851 fprintf (stderr, "Running episode %u with timeout %s\n",
853 GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
854 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
855 &timeout_episode, e);
856 enforce_episode(e->cur);
863 GNUNET_ATS_solvers_experimentation_run (struct Experiment *e,
864 GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb,
865 GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb)
867 fprintf (stderr, "Running experiment `%s' with timeout %s\n", e->name,
868 GNUNET_STRINGS_relative_time_to_string(e->max_duration, GNUNET_YES));
869 e->e_done_cb = e_done_cb;
870 e->ep_done_cb = ep_done_cb;
871 e->start_time = GNUNET_TIME_absolute_get();
873 /* Start total time out */
874 e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed (e->max_duration,
875 &timeout_experiment, e);
879 if (NULL == e->start)
885 fprintf (stderr, "Running episode %u with timeout %s\n",
887 GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
888 e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration,
889 &timeout_episode, e);
890 enforce_episode(e->cur);
896 GNUNET_ATS_solvers_experimentation_load (char *filename)
898 struct Experiment *e;
899 struct GNUNET_CONFIGURATION_Handle *cfg;
902 cfg = GNUNET_CONFIGURATION_create();
903 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, filename))
905 fprintf (stderr, "Failed to load `%s'\n", filename);
906 GNUNET_CONFIGURATION_destroy (cfg);
910 e = create_experiment ();
912 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
915 fprintf (stderr, "Invalid %s", "name");
920 fprintf (stderr, "Experiment name: `%s'\n", e->name);
922 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment",
923 "cfg_file", &e->cfg_file))
925 fprintf (stderr, "Invalid %s", "cfg_file");
931 fprintf (stderr, "Experiment name: `%s'\n", e->cfg_file);
932 e->cfg = GNUNET_CONFIGURATION_create();
933 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (e->cfg, e->cfg_file))
935 fprintf (stderr, "Invalid configuration %s", "cfg_file");
942 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg, "experiment",
943 "masters", &e->num_masters))
945 fprintf (stderr, "Invalid %s", "masters");
950 fprintf (stderr, "Experiment masters: `%llu'\n",
953 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg, "experiment",
954 "slaves", &e->num_slaves))
956 fprintf (stderr, "Invalid %s", "slaves");
961 fprintf (stderr, "Experiment slaves: `%llu'\n",
964 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
965 "log_freq", &e->log_freq))
967 fprintf (stderr, "Invalid %s", "log_freq");
972 fprintf (stderr, "Experiment logging frequency: `%s'\n",
973 GNUNET_STRINGS_relative_time_to_string (e->log_freq, GNUNET_YES));
975 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
976 "max_duration", &e->max_duration))
978 fprintf (stderr, "Invalid %s", "max_duration");
983 fprintf (stderr, "Experiment duration: `%s'\n",
984 GNUNET_STRINGS_relative_time_to_string (e->max_duration, GNUNET_YES));
986 load_episodes (e, cfg);
987 fprintf (stderr, "Loaded %u episodes with total duration %s\n",
989 GNUNET_STRINGS_relative_time_to_string (e->total_duration, GNUNET_YES));
991 GNUNET_CONFIGURATION_destroy (cfg);
996 GNUNET_ATS_solvers_experimentation_stop (struct Experiment *e)
998 if (GNUNET_SCHEDULER_NO_TASK != e->experiment_timeout_task)
1000 GNUNET_SCHEDULER_cancel (e->experiment_timeout_task);
1001 e->experiment_timeout_task = GNUNET_SCHEDULER_NO_TASK;
1003 if (GNUNET_SCHEDULER_NO_TASK != e->episode_timeout_task)
1005 GNUNET_SCHEDULER_cancel (e->episode_timeout_task);
1006 e->episode_timeout_task = GNUNET_SCHEDULER_NO_TASK;
1010 GNUNET_CONFIGURATION_destroy(e->cfg);
1013 free_experiment (e);
1025 struct GNUNET_ATS_TESTING_SolverHandle
1028 struct GNUNET_ATS_PluginEnvironment env;
1030 struct GNUNET_CONTAINER_MultiPeerMap *addresses;
1033 enum GNUNET_ATS_Solvers
1035 GNUNET_ATS_SOLVER_PROPORTIONAL,
1036 GNUNET_ATS_SOLVER_MLP,
1037 GNUNET_ATS_SOLVER_RIL,
1041 GNUNET_ATS_solvers_solver_stop (struct GNUNET_ATS_TESTING_SolverHandle *sh)
1043 GNUNET_PLUGIN_unload (sh->plugin, sh->solver);
1044 GNUNET_CONTAINER_multipeermap_destroy(sh->addresses);
1045 GNUNET_free (sh->plugin);
1050 * Load quotas for networks from configuration
1052 * @param cfg configuration handle
1053 * @param out_dest where to write outbound quotas
1054 * @param in_dest where to write inbound quotas
1055 * @param dest_length length of inbound and outbound arrays
1056 * @return number of networks loaded
1059 GNUNET_ATS_solvers_load_quotas (const struct GNUNET_CONFIGURATION_Handle *cfg,
1060 unsigned long long *out_dest,
1061 unsigned long long *in_dest,
1064 char *network_str[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkTypeString;
1065 char * entry_in = NULL;
1066 char * entry_out = NULL;
1067 char * quota_out_str;
1068 char * quota_in_str;
1072 for (c = 0; (c < GNUNET_ATS_NetworkTypeCount) && (c < dest_length); c++)
1076 GNUNET_asprintf (&entry_out, "%s_QUOTA_OUT", network_str[c]);
1077 GNUNET_asprintf (&entry_in, "%s_QUOTA_IN", network_str[c]);
1080 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_out, "a_out_str))
1083 if (0 == strcmp(quota_out_str, BIG_M_STRING))
1085 out_dest[c] = GNUNET_ATS_MaxBandwidth;
1088 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, &out_dest[c])))
1090 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_out, &out_dest[c])))
1093 if (GNUNET_NO == res)
1095 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
1096 network_str[c], quota_out_str, GNUNET_ATS_DefaultBandwidth);
1097 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
1101 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Outbound quota configure for network `%s' is %llu\n"),
1102 network_str[c], out_dest[c]);
1104 GNUNET_free (quota_out_str);
1108 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("No outbound quota configured for network `%s', assigning default bandwidth %llu\n"),
1109 network_str[c], GNUNET_ATS_DefaultBandwidth);
1110 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
1114 if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_in, "a_in_str))
1117 if (0 == strcmp(quota_in_str, BIG_M_STRING))
1119 in_dest[c] = GNUNET_ATS_MaxBandwidth;
1122 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, &in_dest[c])))
1124 if ((GNUNET_NO == res) && (GNUNET_OK == GNUNET_CONFIGURATION_get_value_number (cfg, "ats", entry_in, &in_dest[c])))
1127 if (GNUNET_NO == res)
1129 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Could not load quota for network `%s': `%s', assigning default bandwidth %llu\n"),
1130 network_str[c], quota_in_str, GNUNET_ATS_DefaultBandwidth);
1131 in_dest[c] = GNUNET_ATS_DefaultBandwidth;
1135 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, _("Inbound quota configured for network `%s' is %llu\n"),
1136 network_str[c], in_dest[c]);
1138 GNUNET_free (quota_in_str);
1142 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, _("No outbound quota configure for network `%s', assigning default bandwidth %llu\n"),
1143 network_str[c], GNUNET_ATS_DefaultBandwidth);
1144 out_dest[c] = GNUNET_ATS_DefaultBandwidth;
1146 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Loaded quota for network `%s' (in/out): %llu %llu\n", network_str[c], in_dest[c], out_dest[c]);
1147 GNUNET_free (entry_out);
1148 GNUNET_free (entry_in);
1150 return GNUNET_ATS_NetworkTypeCount;
1154 * Information callback for the solver
1156 * @param op the solver operation
1157 * @param stat status of the solver operation
1158 * @param add additional solver information
1161 solver_info_cb (void *cls,
1162 enum GAS_Solver_Operation op,
1163 enum GAS_Solver_Status stat,
1164 enum GAS_Solver_Additional_Information add)
1169 add_info = "GAS_INFO_NONE";
1172 add_info = "GAS_INFO_MLP_FULL";
1174 case GAS_INFO_UPDATED:
1175 add_info = "GAS_INFO_MLP_UPDATED";
1177 case GAS_INFO_PROP_ALL:
1178 add_info = "GAS_INFO_PROP_ALL";
1180 case GAS_INFO_PROP_SINGLE:
1181 add_info = "GAS_INFO_PROP_SINGLE";
1184 add_info = "INVALID";
1190 case GAS_OP_SOLVE_START:
1191 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1192 "Solver notifies `%s' with result `%s' `%s'\n", "GAS_OP_SOLVE_START",
1193 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
1195 case GAS_OP_SOLVE_STOP:
1196 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1197 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_STOP",
1198 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL", add_info);
1201 case GAS_OP_SOLVE_SETUP_START:
1202 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1203 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_START",
1204 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
1207 case GAS_OP_SOLVE_SETUP_STOP:
1208 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1209 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_SETUP_STOP",
1210 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
1213 case GAS_OP_SOLVE_MLP_LP_START:
1214 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1215 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_START",
1216 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
1218 case GAS_OP_SOLVE_MLP_LP_STOP:
1219 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1220 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_LP_STOP",
1221 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
1224 case GAS_OP_SOLVE_MLP_MLP_START:
1225 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1226 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_START",
1227 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
1229 case GAS_OP_SOLVE_MLP_MLP_STOP:
1230 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1231 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_MLP_STOP",
1232 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
1234 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_START:
1235 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1236 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_START",
1237 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
1239 case GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP:
1240 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
1241 "Solver notifies `%s' with result `%s'\n", "GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP",
1242 (GAS_STAT_SUCCESS == stat) ? "SUCCESS" : "FAIL");
1250 solver_bandwidth_changed_cb (void *cls, struct ATS_Address *address)
1252 if ( (0 == ntohl (address->assigned_bw_out.value__)) &&
1253 (0 == ntohl (address->assigned_bw_in.value__)) )
1256 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1257 "Bandwidth changed addresses %s %p to %u Bps out / %u Bps in\n",
1258 GNUNET_i2s (&address->peer),
1260 (unsigned int) ntohl (address->assigned_bw_out.value__),
1261 (unsigned int) ntohl (address->assigned_bw_in.value__));
1262 /*if (GNUNET_YES == ph.bulk_running)
1268 get_preferences_cb (void *cls, const struct GNUNET_PeerIdentity *id)
1270 return GAS_normalization_get_preferences_by_peer (id);
1275 get_property_cb (void *cls, const struct ATS_Address *address)
1277 return GAS_normalization_get_properties ((struct ATS_Address *) address);
1281 normalized_property_changed_cb (void *cls, struct ATS_Address *peer,
1282 uint32_t type, double prop_rel)
1288 struct GNUNET_ATS_TESTING_SolverHandle *
1289 GNUNET_ATS_solvers_solver_start (enum GNUNET_ATS_Solvers type)
1291 struct GNUNET_ATS_TESTING_SolverHandle *sh;
1293 unsigned long long quotas_in[GNUNET_ATS_NetworkTypeCount];
1294 unsigned long long quotas_out[GNUNET_ATS_NetworkTypeCount];
1297 case GNUNET_ATS_SOLVER_PROPORTIONAL:
1298 solver_str = "proportional";
1300 case GNUNET_ATS_SOLVER_MLP:
1303 case GNUNET_ATS_SOLVER_RIL:
1312 sh = GNUNET_new (struct GNUNET_ATS_TESTING_SolverHandle);
1313 GNUNET_asprintf (&sh->plugin, "libgnunet_plugin_ats_%s", solver_str);
1315 /* setup environment */
1316 sh->env.cfg = e->cfg;
1317 sh->env.stats = GNUNET_STATISTICS_create ("ats", e->cfg);
1318 sh->env.addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO);
1319 sh->env.bandwidth_changed_cb = &solver_bandwidth_changed_cb;
1320 sh->env.get_preferences = &get_preferences_cb;
1321 sh->env.get_property = &get_property_cb;
1322 sh->env.network_count = GNUNET_ATS_NetworkTypeCount;
1323 sh->env.info_cb = &solver_info_cb;
1324 sh->env.info_cb_cls = NULL;
1326 /* start normalization */
1327 GAS_normalization_start (NULL, NULL, &normalized_property_changed_cb, NULL );
1330 if (GNUNET_ATS_NetworkTypeCount != GNUNET_ATS_solvers_load_quotas (e->cfg,
1331 quotas_out, quotas_in, GNUNET_ATS_NetworkTypeCount))
1334 GNUNET_free (sh->plugin);
1340 sh->solver = GNUNET_PLUGIN_load (sh->plugin, &sh->env);
1341 if (NULL == sh->solver)
1343 fprintf (stderr, "Failed to load solver `%s'\n", sh->plugin);
1345 GNUNET_free (sh->plugin);
1351 sh->addresses = GNUNET_CONTAINER_multipeermap_create (10, GNUNET_NO);
1359 /* Clean up experiment */
1360 GNUNET_ATS_solvers_experimentation_stop (e);
1369 experiment_done_cb (struct Experiment *e, struct GNUNET_TIME_Relative duration,int success)
1371 if (GNUNET_OK == success)
1372 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment done successful in %s\n",
1373 GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES));
1375 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment failed \n");
1378 // GNUNET_ATS_TEST_logging_stop (l);
1380 /* Stop traffic generation */
1381 // GNUNET_ATS_TEST_generate_traffic_stop_all();
1383 /* Stop all preference generations */
1384 // GNUNET_ATS_TEST_generate_preferences_stop_all ();
1387 evaluate (duration);
1389 GNUNET_ATS_TEST_logging_write_to_file(l, opt_exp_file, opt_plot);
1393 GNUNET_ATS_TEST_logging_stop (l);
1394 GNUNET_ATS_TEST_logging_clean_up (l);
1398 GNUNET_SCHEDULER_add_now (&done, NULL);
1402 episode_done_cb (struct Episode *ep)
1404 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Episode %u done\n", ep->id);
1417 GNUNET_ATS_solvers_experimentation_stop (e);
1422 GNUNET_ATS_solvers_solver_stop (sh);
1428 run (void *cls, char * const *args, const char *cfgfile,
1429 const struct GNUNET_CONFIGURATION_Handle *cfg)
1431 enum GNUNET_ATS_Solvers solver;
1433 if (NULL == opt_exp_file)
1435 fprintf (stderr, "No experiment given ...\n");
1441 if (NULL == opt_solver)
1443 fprintf (stderr, "No solver given ...\n");
1449 if (0 == strcmp(opt_solver, "mlp"))
1451 solver = GNUNET_ATS_SOLVER_MLP;
1453 else if (0 == strcmp(opt_solver, "proportional"))
1455 solver = GNUNET_ATS_SOLVER_PROPORTIONAL;
1457 else if (0 == strcmp(opt_solver, "ril"))
1459 solver = GNUNET_ATS_SOLVER_RIL;
1463 fprintf (stderr, "No solver given ...");
1469 /* load experiment */
1470 e = GNUNET_ATS_solvers_experimentation_load (opt_exp_file);
1473 fprintf (stderr, "Failed to load experiment ...\n");
1481 sh = GNUNET_ATS_solvers_solver_start (solver);
1484 fprintf (stderr, "Failed to start solver ...\n");
1493 /* run experiment */
1494 GNUNET_ATS_solvers_experimentation_run (e, episode_done_cb,
1495 experiment_done_cb);
1502 * Main function of the benchmark
1504 * @param argc argument count
1505 * @param argv argument values
1508 main (int argc, char *argv[])
1510 opt_exp_file = NULL;
1512 opt_log = GNUNET_NO;
1513 opt_plot = GNUNET_NO;
1517 static struct GNUNET_GETOPT_CommandLineOption options[] =
1519 { 's', "solver", NULL,
1520 gettext_noop ("solver to use"),
1521 1, &GNUNET_GETOPT_set_string, &opt_solver},
1522 { 'e', "experiment", NULL,
1523 gettext_noop ("experiment to use"),
1524 1, &GNUNET_GETOPT_set_string, &opt_exp_file},
1525 { 'e', "experiment", NULL,
1526 gettext_noop ("experiment to use"),
1527 1, &GNUNET_GETOPT_set_one, &opt_verbose},
1528 GNUNET_GETOPT_OPTION_END
1531 GNUNET_PROGRAM_run (argc, argv, argv[0], NULL, options, &run, argv[0]);
1535 /* end of file ats-testing-experiment.c*/