diff options
Diffstat (limited to 'src/ats-tests/ats-testing-experiment.c')
-rw-r--r-- | src/ats-tests/ats-testing-experiment.c | 820 |
1 files changed, 0 insertions, 820 deletions
diff --git a/src/ats-tests/ats-testing-experiment.c b/src/ats-tests/ats-testing-experiment.c deleted file mode 100644 index 9f8db1be4..000000000 --- a/src/ats-tests/ats-testing-experiment.c +++ /dev/null | |||
@@ -1,820 +0,0 @@ | |||
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 it | ||
6 | under the terms of the GNU Affero General Public License as published | ||
7 | by the Free Software Foundation, either version 3 of the License, | ||
8 | or (at your 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 | Affero General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Affero General Public License | ||
16 | along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
17 | |||
18 | SPDX-License-Identifier: AGPL3.0-or-later | ||
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 "ats-testing.h" | ||
29 | |||
30 | const char * | ||
31 | print_op (enum OperationType op) | ||
32 | { | ||
33 | switch (op) | ||
34 | { | ||
35 | case START_SEND: | ||
36 | return "START_SEND"; | ||
37 | |||
38 | case STOP_SEND: | ||
39 | return "STOP_SEND"; | ||
40 | |||
41 | case START_PREFERENCE: | ||
42 | return "START_PREFERENCE"; | ||
43 | |||
44 | case STOP_PREFERENCE: | ||
45 | return "STOP_PREFERENCE"; | ||
46 | |||
47 | default: | ||
48 | break; | ||
49 | } | ||
50 | return ""; | ||
51 | } | ||
52 | |||
53 | |||
54 | static struct Experiment * | ||
55 | create_experiment () | ||
56 | { | ||
57 | struct Experiment *e; | ||
58 | |||
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 (e->name); | ||
92 | GNUNET_free (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 | |||
110 | fprintf (stderr, "Parsing episode %u\n", cur->id); | ||
111 | GNUNET_asprintf (&sec_name, "episode-%u", cur->id); | ||
112 | |||
113 | while (1) | ||
114 | { | ||
115 | /* Load operation */ | ||
116 | GNUNET_asprintf (&op_name, "op-%u-operation", op_counter); | ||
117 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg, | ||
118 | sec_name, | ||
119 | op_name, &op)) | ||
120 | { | ||
121 | GNUNET_free (op_name); | ||
122 | break; | ||
123 | } | ||
124 | o = GNUNET_new (struct GNUNET_ATS_TEST_Operation); | ||
125 | /* operations = set_rate, start_send, stop_send, set_preference */ | ||
126 | if (0 == strcmp (op, "start_send")) | ||
127 | { | ||
128 | o->type = START_SEND; | ||
129 | } | ||
130 | else if (0 == strcmp (op, "stop_send")) | ||
131 | { | ||
132 | o->type = STOP_SEND; | ||
133 | } | ||
134 | else if (0 == strcmp (op, "start_preference")) | ||
135 | { | ||
136 | o->type = START_PREFERENCE; | ||
137 | } | ||
138 | else if (0 == strcmp (op, "stop_preference")) | ||
139 | { | ||
140 | o->type = STOP_PREFERENCE; | ||
141 | } | ||
142 | else | ||
143 | { | ||
144 | fprintf (stderr, "Invalid operation %u `%s' in episode %u\n", | ||
145 | op_counter, op, cur->id); | ||
146 | GNUNET_free (op); | ||
147 | GNUNET_free (op_name); | ||
148 | GNUNET_free (o); | ||
149 | GNUNET_free (sec_name); | ||
150 | return GNUNET_SYSERR; | ||
151 | } | ||
152 | GNUNET_free (op_name); | ||
153 | |||
154 | /* Get source */ | ||
155 | GNUNET_asprintf (&op_name, "op-%u-src", op_counter); | ||
156 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg, | ||
157 | sec_name, | ||
158 | op_name, | ||
159 | &o->src_id)) | ||
160 | { | ||
161 | fprintf (stderr, "Missing src in operation %u `%s' in episode %u\n", | ||
162 | op_counter, op, cur->id); | ||
163 | GNUNET_free (op); | ||
164 | GNUNET_free (op_name); | ||
165 | GNUNET_free (o); | ||
166 | GNUNET_free (sec_name); | ||
167 | return GNUNET_SYSERR; | ||
168 | } | ||
169 | if (o->src_id > (e->num_masters - 1)) | ||
170 | { | ||
171 | fprintf (stderr, "Invalid src %llu in operation %u `%s' in episode %u\n", | ||
172 | o->src_id, op_counter, op, cur->id); | ||
173 | GNUNET_free (op); | ||
174 | GNUNET_free (op_name); | ||
175 | GNUNET_free (o); | ||
176 | GNUNET_free (sec_name); | ||
177 | return GNUNET_SYSERR; | ||
178 | } | ||
179 | GNUNET_free (op_name); | ||
180 | |||
181 | /* Get destination */ | ||
182 | GNUNET_asprintf (&op_name, "op-%u-dest", op_counter); | ||
183 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg, | ||
184 | sec_name, | ||
185 | op_name, | ||
186 | &o->dest_id)) | ||
187 | { | ||
188 | fprintf (stderr, "Missing src in operation %u `%s' in episode %u\n", | ||
189 | op_counter, op, cur->id); | ||
190 | GNUNET_free (op); | ||
191 | GNUNET_free (op_name); | ||
192 | GNUNET_free (o); | ||
193 | GNUNET_free (sec_name); | ||
194 | return GNUNET_SYSERR; | ||
195 | } | ||
196 | if (o->dest_id > (e->num_slaves - 1)) | ||
197 | { | ||
198 | fprintf (stderr, | ||
199 | "Invalid destination %llu in operation %u `%s' in episode %u\n", | ||
200 | o->dest_id, op_counter, op, cur->id); | ||
201 | GNUNET_free (op); | ||
202 | GNUNET_free (op_name); | ||
203 | GNUNET_free (o); | ||
204 | GNUNET_free (sec_name); | ||
205 | return GNUNET_SYSERR; | ||
206 | } | ||
207 | GNUNET_free (op_name); | ||
208 | |||
209 | GNUNET_asprintf (&op_name, "op-%u-type", op_counter); | ||
210 | if ((GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_string (cfg, | ||
211 | sec_name, | ||
212 | op_name, | ||
213 | &type)) && | ||
214 | (STOP_SEND != o->type) && | ||
215 | (STOP_PREFERENCE != o->type)) | ||
216 | { | ||
217 | /* Load arguments for set_rate, start_send, set_preference */ | ||
218 | if (0 == strcmp (type, "constant")) | ||
219 | { | ||
220 | o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT; | ||
221 | } | ||
222 | else if (0 == strcmp (type, "linear")) | ||
223 | { | ||
224 | o->gen_type = GNUNET_ATS_TEST_TG_LINEAR; | ||
225 | } | ||
226 | else if (0 == strcmp (type, "sinus")) | ||
227 | { | ||
228 | o->gen_type = GNUNET_ATS_TEST_TG_SINUS; | ||
229 | } | ||
230 | else if (0 == strcmp (type, "random")) | ||
231 | { | ||
232 | o->gen_type = GNUNET_ATS_TEST_TG_RANDOM; | ||
233 | } | ||
234 | else | ||
235 | { | ||
236 | fprintf (stderr, "Invalid type %u `%s' in episode %u\n", | ||
237 | op_counter, op, cur->id); | ||
238 | GNUNET_free (type); | ||
239 | GNUNET_free (op); | ||
240 | GNUNET_free (op_name); | ||
241 | GNUNET_free (sec_name); | ||
242 | GNUNET_free (o); | ||
243 | return GNUNET_SYSERR; | ||
244 | } | ||
245 | GNUNET_free (op_name); | ||
246 | |||
247 | /* Get base rate */ | ||
248 | GNUNET_asprintf (&op_name, "op-%u-base-rate", op_counter); | ||
249 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg, | ||
250 | sec_name, | ||
251 | op_name, | ||
252 | &o->base_rate)) | ||
253 | { | ||
254 | fprintf (stderr, | ||
255 | "Missing base rate in operation %u `%s' in episode %u\n", | ||
256 | op_counter, op, cur->id); | ||
257 | GNUNET_free (type); | ||
258 | GNUNET_free (op); | ||
259 | GNUNET_free (op_name); | ||
260 | GNUNET_free (sec_name); | ||
261 | GNUNET_free (o); | ||
262 | return GNUNET_SYSERR; | ||
263 | } | ||
264 | GNUNET_free (op_name); | ||
265 | |||
266 | /* Get max rate */ | ||
267 | GNUNET_asprintf (&op_name, "op-%u-max-rate", op_counter); | ||
268 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg, | ||
269 | sec_name, | ||
270 | op_name, | ||
271 | &o->max_rate)) | ||
272 | { | ||
273 | if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) || | ||
274 | (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) || | ||
275 | (GNUNET_ATS_TEST_TG_SINUS == o->gen_type)) | ||
276 | { | ||
277 | fprintf (stderr, | ||
278 | "Missing max rate in operation %u `%s' in episode %u\n", | ||
279 | op_counter, op, cur->id); | ||
280 | GNUNET_free (type); | ||
281 | GNUNET_free (op_name); | ||
282 | GNUNET_free (op); | ||
283 | GNUNET_free (o); | ||
284 | GNUNET_free (sec_name); | ||
285 | return GNUNET_SYSERR; | ||
286 | } | ||
287 | } | ||
288 | GNUNET_free (op_name); | ||
289 | |||
290 | /* Get period */ | ||
291 | GNUNET_asprintf (&op_name, "op-%u-period", op_counter); | ||
292 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg, | ||
293 | sec_name, | ||
294 | op_name, | ||
295 | &o->period)) | ||
296 | { | ||
297 | o->period = cur->duration; | ||
298 | } | ||
299 | GNUNET_free (op_name); | ||
300 | |||
301 | if (START_PREFERENCE == o->type) | ||
302 | { | ||
303 | /* Get frequency */ | ||
304 | GNUNET_asprintf (&op_name, "op-%u-frequency", op_counter); | ||
305 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg, | ||
306 | sec_name, | ||
307 | op_name, | ||
308 | &o->frequency)) | ||
309 | { | ||
310 | fprintf (stderr, | ||
311 | "Missing frequency in operation %u `%s' in episode %u\n", | ||
312 | op_counter, op, cur->id); | ||
313 | GNUNET_free (type); | ||
314 | GNUNET_free (op_name); | ||
315 | GNUNET_free (op); | ||
316 | GNUNET_free (o); | ||
317 | GNUNET_free (sec_name); | ||
318 | return GNUNET_SYSERR; | ||
319 | } | ||
320 | GNUNET_free (op_name); | ||
321 | |||
322 | /* Get preference */ | ||
323 | GNUNET_asprintf (&op_name, "op-%u-pref", op_counter); | ||
324 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg, | ||
325 | sec_name, | ||
326 | op_name, | ||
327 | &pref)) | ||
328 | { | ||
329 | fprintf (stderr, | ||
330 | "Missing preference in operation %u `%s' in episode %u\n", | ||
331 | op_counter, op, cur->id); | ||
332 | GNUNET_free (type); | ||
333 | GNUNET_free (op_name); | ||
334 | GNUNET_free (op); | ||
335 | GNUNET_free (pref); | ||
336 | GNUNET_free (o); | ||
337 | GNUNET_free (sec_name); | ||
338 | return GNUNET_SYSERR; | ||
339 | } | ||
340 | |||
341 | if (0 == strcmp (pref, "bandwidth")) | ||
342 | o->pref_type = GNUNET_ATS_PREFERENCE_BANDWIDTH; | ||
343 | else if (0 == strcmp (pref, "latency")) | ||
344 | o->pref_type = GNUNET_ATS_PREFERENCE_LATENCY; | ||
345 | else | ||
346 | { | ||
347 | fprintf (stderr, | ||
348 | "Invalid preference in operation %u `%s' in episode %u\n", | ||
349 | op_counter, op, cur->id); | ||
350 | GNUNET_free (type); | ||
351 | GNUNET_free (op_name); | ||
352 | GNUNET_free (op); | ||
353 | GNUNET_free (pref); | ||
354 | GNUNET_free (o); | ||
355 | GNUNET_free (sec_name); | ||
356 | return GNUNET_SYSERR; | ||
357 | } | ||
358 | GNUNET_free (pref); | ||
359 | GNUNET_free (op_name); | ||
360 | } | ||
361 | } | ||
362 | |||
363 | /* Safety checks */ | ||
364 | if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) || | ||
365 | (GNUNET_ATS_TEST_TG_SINUS == o->gen_type)) | ||
366 | { | ||
367 | if ((o->max_rate - o->base_rate) > o->base_rate) | ||
368 | { | ||
369 | /* This will cause an underflow */ | ||
370 | GNUNET_break (0); | ||
371 | } | ||
372 | fprintf (stderr, | ||
373 | "Selected max rate and base rate cannot be used for desired traffic form!\n"); | ||
374 | } | ||
375 | |||
376 | if ((START_SEND == o->type) || (START_PREFERENCE == o->type)) | ||
377 | fprintf (stderr, | ||
378 | "Found operation %u in episode %u: %s [%llu]->[%llu] == %s, %llu -> %llu in %s\n", | ||
379 | op_counter, cur->id, print_op (o->type), o->src_id, | ||
380 | o->dest_id, (NULL != type) ? type : "", | ||
381 | o->base_rate, o->max_rate, | ||
382 | GNUNET_STRINGS_relative_time_to_string (o->period, GNUNET_YES)); | ||
383 | else | ||
384 | fprintf (stderr, "Found operation %u in episode %u: %s [%llu]->[%llu]\n", | ||
385 | op_counter, cur->id, print_op (o->type), o->src_id, o->dest_id); | ||
386 | |||
387 | GNUNET_free (type); | ||
388 | GNUNET_free (op); | ||
389 | |||
390 | GNUNET_CONTAINER_DLL_insert (cur->head, cur->tail, o); | ||
391 | op_counter++; | ||
392 | } | ||
393 | GNUNET_free (sec_name); | ||
394 | |||
395 | return GNUNET_OK; | ||
396 | } | ||
397 | |||
398 | |||
399 | static int | ||
400 | load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg) | ||
401 | { | ||
402 | int e_counter = 0; | ||
403 | char *sec_name; | ||
404 | struct GNUNET_TIME_Relative e_duration; | ||
405 | struct Episode *cur; | ||
406 | struct Episode *last; | ||
407 | |||
408 | e_counter = 0; | ||
409 | last = NULL; | ||
410 | while (1) | ||
411 | { | ||
412 | GNUNET_asprintf (&sec_name, "episode-%u", e_counter); | ||
413 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg, | ||
414 | sec_name, | ||
415 | "duration", | ||
416 | &e_duration)) | ||
417 | { | ||
418 | GNUNET_free (sec_name); | ||
419 | break; | ||
420 | } | ||
421 | |||
422 | cur = GNUNET_new (struct Episode); | ||
423 | cur->duration = e_duration; | ||
424 | cur->id = e_counter; | ||
425 | |||
426 | if (GNUNET_OK != load_episode (e, cur, cfg)) | ||
427 | { | ||
428 | GNUNET_free (sec_name); | ||
429 | GNUNET_free (cur); | ||
430 | return GNUNET_SYSERR; | ||
431 | } | ||
432 | |||
433 | fprintf (stderr, "Found episode %u with duration %s \n", | ||
434 | e_counter, | ||
435 | GNUNET_STRINGS_relative_time_to_string (cur->duration, | ||
436 | GNUNET_YES)); | ||
437 | |||
438 | /* Update experiment */ | ||
439 | e->num_episodes++; | ||
440 | e->total_duration = GNUNET_TIME_relative_add (e->total_duration, | ||
441 | cur->duration); | ||
442 | /* Put in linked list */ | ||
443 | if (NULL == last) | ||
444 | e->start = cur; | ||
445 | else | ||
446 | last->next = cur; | ||
447 | |||
448 | GNUNET_free (sec_name); | ||
449 | e_counter++; | ||
450 | last = cur; | ||
451 | } | ||
452 | return e_counter; | ||
453 | } | ||
454 | |||
455 | |||
456 | static void | ||
457 | timeout_experiment (void *cls) | ||
458 | { | ||
459 | struct Experiment *e = cls; | ||
460 | |||
461 | e->experiment_timeout_task = NULL; | ||
462 | fprintf (stderr, "Experiment timeout!\n"); | ||
463 | |||
464 | if (NULL != e->episode_timeout_task) | ||
465 | { | ||
466 | GNUNET_SCHEDULER_cancel (e->episode_timeout_task); | ||
467 | e->episode_timeout_task = NULL; | ||
468 | } | ||
469 | |||
470 | e->e_done_cb (e, GNUNET_TIME_absolute_get_duration (e->start_time), | ||
471 | GNUNET_SYSERR); | ||
472 | } | ||
473 | |||
474 | |||
475 | static void | ||
476 | enforce_start_send (struct GNUNET_ATS_TEST_Operation *op) | ||
477 | { | ||
478 | struct BenchmarkPeer *peer; | ||
479 | struct BenchmarkPartner *partner; | ||
480 | |||
481 | peer = GNUNET_ATS_TEST_get_peer (op->src_id); | ||
482 | if (NULL == peer) | ||
483 | { | ||
484 | GNUNET_break (0); | ||
485 | return; | ||
486 | } | ||
487 | |||
488 | partner = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id); | ||
489 | if (NULL == partner) | ||
490 | { | ||
491 | GNUNET_break (0); | ||
492 | return; | ||
493 | } | ||
494 | |||
495 | fprintf (stderr, "Found master %llu slave %llu\n", op->src_id, op->dest_id); | ||
496 | |||
497 | if (NULL != partner->tg) | ||
498 | { | ||
499 | fprintf (stderr, "Stopping traffic between master %llu slave %llu\n", | ||
500 | op->src_id, op->dest_id); | ||
501 | GNUNET_ATS_TEST_generate_traffic_stop (partner->tg); | ||
502 | partner->tg = NULL; | ||
503 | } | ||
504 | |||
505 | partner->tg = GNUNET_ATS_TEST_generate_traffic_start (peer, partner, | ||
506 | op->gen_type, | ||
507 | op->base_rate, | ||
508 | op->max_rate, | ||
509 | op->period, | ||
510 | GNUNET_TIME_UNIT_FOREVER_REL); | ||
511 | } | ||
512 | |||
513 | |||
514 | static void | ||
515 | enforce_stop_send (struct GNUNET_ATS_TEST_Operation *op) | ||
516 | { | ||
517 | struct BenchmarkPartner *p; | ||
518 | |||
519 | p = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id); | ||
520 | if (NULL == p) | ||
521 | { | ||
522 | GNUNET_break (0); | ||
523 | return; | ||
524 | } | ||
525 | |||
526 | fprintf (stderr, "Found master %llu slave %llu\n", op->src_id, op->dest_id); | ||
527 | |||
528 | if (NULL != p->tg) | ||
529 | { | ||
530 | fprintf (stderr, "Stopping traffic between master %llu slave %llu\n", | ||
531 | op->src_id, op->dest_id); | ||
532 | GNUNET_ATS_TEST_generate_traffic_stop (p->tg); | ||
533 | p->tg = NULL; | ||
534 | } | ||
535 | } | ||
536 | |||
537 | |||
538 | static void | ||
539 | enforce_start_preference (struct GNUNET_ATS_TEST_Operation *op) | ||
540 | { | ||
541 | struct BenchmarkPeer *peer; | ||
542 | struct BenchmarkPartner *partner; | ||
543 | |||
544 | peer = GNUNET_ATS_TEST_get_peer (op->src_id); | ||
545 | if (NULL == peer) | ||
546 | { | ||
547 | GNUNET_break (0); | ||
548 | return; | ||
549 | } | ||
550 | |||
551 | partner = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id); | ||
552 | if (NULL == partner) | ||
553 | { | ||
554 | GNUNET_break (0); | ||
555 | return; | ||
556 | } | ||
557 | |||
558 | fprintf (stderr, "Found master %llu slave %llu\n", op->src_id, op->dest_id); | ||
559 | |||
560 | if (NULL != partner->pg) | ||
561 | { | ||
562 | fprintf (stderr, "Stopping traffic between master %llu slave %llu\n", | ||
563 | op->src_id, op->dest_id); | ||
564 | GNUNET_ATS_TEST_generate_preferences_stop (partner->pg); | ||
565 | partner->pg = NULL; | ||
566 | } | ||
567 | |||
568 | partner->pg = GNUNET_ATS_TEST_generate_preferences_start (peer, partner, | ||
569 | op->gen_type, | ||
570 | op->base_rate, | ||
571 | op->max_rate, | ||
572 | op->period, | ||
573 | op->frequency, | ||
574 | op->pref_type); | ||
575 | } | ||
576 | |||
577 | |||
578 | static void | ||
579 | enforce_stop_preference (struct GNUNET_ATS_TEST_Operation *op) | ||
580 | { | ||
581 | struct BenchmarkPartner *p; | ||
582 | |||
583 | p = GNUNET_ATS_TEST_get_partner (op->src_id, op->dest_id); | ||
584 | if (NULL == p) | ||
585 | { | ||
586 | GNUNET_break (0); | ||
587 | return; | ||
588 | } | ||
589 | |||
590 | fprintf (stderr, "Found master %llu slave %llu\n", op->src_id, op->dest_id); | ||
591 | |||
592 | if (NULL != p->pg) | ||
593 | { | ||
594 | fprintf (stderr, "Stopping preference between master %llu slave %llu\n", | ||
595 | op->src_id, op->dest_id); | ||
596 | GNUNET_ATS_TEST_generate_preferences_stop (p->pg); | ||
597 | p->pg = NULL; | ||
598 | } | ||
599 | } | ||
600 | |||
601 | |||
602 | static void | ||
603 | enforce_episode (struct Episode *ep) | ||
604 | { | ||
605 | struct GNUNET_ATS_TEST_Operation *cur; | ||
606 | |||
607 | for (cur = ep->head; NULL != cur; cur = cur->next) | ||
608 | { | ||
609 | fprintf (stderr, "Enforcing operation: %s [%llu]->[%llu] == %llu\n", | ||
610 | print_op (cur->type), cur->src_id, cur->dest_id, cur->base_rate); | ||
611 | switch (cur->type) | ||
612 | { | ||
613 | case START_SEND: | ||
614 | enforce_start_send (cur); | ||
615 | break; | ||
616 | |||
617 | case STOP_SEND: | ||
618 | enforce_stop_send (cur); | ||
619 | break; | ||
620 | |||
621 | case START_PREFERENCE: | ||
622 | enforce_start_preference (cur); | ||
623 | break; | ||
624 | |||
625 | case STOP_PREFERENCE: | ||
626 | enforce_stop_preference (cur); | ||
627 | break; | ||
628 | |||
629 | default: | ||
630 | break; | ||
631 | } | ||
632 | } | ||
633 | } | ||
634 | |||
635 | |||
636 | static void | ||
637 | timeout_episode (void *cls) | ||
638 | { | ||
639 | struct Experiment *e = cls; | ||
640 | |||
641 | e->episode_timeout_task = NULL; | ||
642 | if (NULL != e->ep_done_cb) | ||
643 | e->ep_done_cb (e->cur); | ||
644 | |||
645 | /* Scheduling next */ | ||
646 | e->cur = e->cur->next; | ||
647 | if (NULL == e->cur) | ||
648 | { | ||
649 | /* done */ | ||
650 | fprintf (stderr, "Last episode done!\n"); | ||
651 | if (NULL != e->experiment_timeout_task) | ||
652 | { | ||
653 | GNUNET_SCHEDULER_cancel (e->experiment_timeout_task); | ||
654 | e->experiment_timeout_task = NULL; | ||
655 | } | ||
656 | e->e_done_cb (e, GNUNET_TIME_absolute_get_duration (e->start_time), | ||
657 | GNUNET_OK); | ||
658 | return; | ||
659 | } | ||
660 | |||
661 | fprintf (stderr, "Running episode %u with timeout %s\n", | ||
662 | e->cur->id, | ||
663 | GNUNET_STRINGS_relative_time_to_string (e->cur->duration, | ||
664 | GNUNET_YES)); | ||
665 | enforce_episode (e->cur); | ||
666 | |||
667 | e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration, | ||
668 | &timeout_episode, e); | ||
669 | } | ||
670 | |||
671 | |||
672 | void | ||
673 | GNUNET_ATS_TEST_experimentation_run (struct Experiment *e, | ||
674 | GNUNET_ATS_TESTING_EpisodeDoneCallback | ||
675 | ep_done_cb, | ||
676 | GNUNET_ATS_TESTING_ExperimentDoneCallback | ||
677 | e_done_cb) | ||
678 | { | ||
679 | fprintf (stderr, "Running experiment `%s' with timeout %s\n", e->name, | ||
680 | GNUNET_STRINGS_relative_time_to_string (e->max_duration, | ||
681 | GNUNET_YES)); | ||
682 | e->e_done_cb = e_done_cb; | ||
683 | e->ep_done_cb = ep_done_cb; | ||
684 | e->start_time = GNUNET_TIME_absolute_get (); | ||
685 | |||
686 | /* Start total time out */ | ||
687 | e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed (e->max_duration, | ||
688 | &timeout_experiment, | ||
689 | e); | ||
690 | |||
691 | /* Start */ | ||
692 | e->cur = e->start; | ||
693 | fprintf (stderr, "Running episode %u with timeout %s\n", | ||
694 | e->cur->id, | ||
695 | GNUNET_STRINGS_relative_time_to_string (e->cur->duration, | ||
696 | GNUNET_YES)); | ||
697 | enforce_episode (e->cur); | ||
698 | e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration, | ||
699 | &timeout_episode, e); | ||
700 | } | ||
701 | |||
702 | |||
703 | struct Experiment * | ||
704 | GNUNET_ATS_TEST_experimentation_load (const char *filename) | ||
705 | { | ||
706 | struct Experiment *e; | ||
707 | struct GNUNET_CONFIGURATION_Handle *cfg; | ||
708 | |||
709 | e = NULL; | ||
710 | |||
711 | cfg = GNUNET_CONFIGURATION_create (); | ||
712 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, filename)) | ||
713 | { | ||
714 | fprintf (stderr, "Failed to load `%s'\n", filename); | ||
715 | GNUNET_CONFIGURATION_destroy (cfg); | ||
716 | return NULL; | ||
717 | } | ||
718 | |||
719 | e = create_experiment (); | ||
720 | |||
721 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string (cfg, "experiment", | ||
722 | "name", &e->name)) | ||
723 | { | ||
724 | fprintf (stderr, "Invalid %s", "name"); | ||
725 | free_experiment (e); | ||
726 | return NULL; | ||
727 | } | ||
728 | else | ||
729 | fprintf (stderr, "Experiment name: `%s'\n", e->name); | ||
730 | |||
731 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, | ||
732 | "experiment", | ||
733 | "cfg_file", | ||
734 | &e->cfg_file)) | ||
735 | { | ||
736 | fprintf (stderr, "Invalid %s", "cfg_file"); | ||
737 | free_experiment (e); | ||
738 | return NULL; | ||
739 | } | ||
740 | else | ||
741 | fprintf (stderr, "Experiment name: `%s'\n", e->cfg_file); | ||
742 | |||
743 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg, "experiment", | ||
744 | "masters", | ||
745 | &e->num_masters)) | ||
746 | { | ||
747 | fprintf (stderr, "Invalid %s", "masters"); | ||
748 | free_experiment (e); | ||
749 | return NULL; | ||
750 | } | ||
751 | else | ||
752 | fprintf (stderr, "Experiment masters: `%llu'\n", | ||
753 | e->num_masters); | ||
754 | |||
755 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number (cfg, "experiment", | ||
756 | "slaves", | ||
757 | &e->num_slaves)) | ||
758 | { | ||
759 | fprintf (stderr, "Invalid %s", "slaves"); | ||
760 | free_experiment (e); | ||
761 | return NULL; | ||
762 | } | ||
763 | else | ||
764 | fprintf (stderr, "Experiment slaves: `%llu'\n", | ||
765 | e->num_slaves); | ||
766 | |||
767 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg, "experiment", | ||
768 | "log_freq", | ||
769 | &e->log_freq)) | ||
770 | { | ||
771 | fprintf (stderr, "Invalid %s", "log_freq"); | ||
772 | free_experiment (e); | ||
773 | return NULL; | ||
774 | } | ||
775 | else | ||
776 | fprintf (stderr, "Experiment logging frequency: `%s'\n", | ||
777 | GNUNET_STRINGS_relative_time_to_string (e->log_freq, GNUNET_YES)); | ||
778 | |||
779 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time (cfg, "experiment", | ||
780 | "max_duration", | ||
781 | &e->max_duration)) | ||
782 | { | ||
783 | fprintf (stderr, "Invalid %s", "max_duration"); | ||
784 | free_experiment (e); | ||
785 | return NULL; | ||
786 | } | ||
787 | else | ||
788 | fprintf (stderr, "Experiment duration: `%s'\n", | ||
789 | GNUNET_STRINGS_relative_time_to_string (e->max_duration, | ||
790 | GNUNET_YES)); | ||
791 | |||
792 | load_episodes (e, cfg); | ||
793 | fprintf (stderr, "Loaded %u episodes with total duration %s\n", | ||
794 | e->num_episodes, | ||
795 | GNUNET_STRINGS_relative_time_to_string (e->total_duration, | ||
796 | GNUNET_YES)); | ||
797 | |||
798 | GNUNET_CONFIGURATION_destroy (cfg); | ||
799 | return e; | ||
800 | } | ||
801 | |||
802 | |||
803 | void | ||
804 | GNUNET_ATS_TEST_experimentation_stop (struct Experiment *e) | ||
805 | { | ||
806 | if (NULL != e->experiment_timeout_task) | ||
807 | { | ||
808 | GNUNET_SCHEDULER_cancel (e->experiment_timeout_task); | ||
809 | e->experiment_timeout_task = NULL; | ||
810 | } | ||
811 | if (NULL != e->episode_timeout_task) | ||
812 | { | ||
813 | GNUNET_SCHEDULER_cancel (e->episode_timeout_task); | ||
814 | e->episode_timeout_task = NULL; | ||
815 | } | ||
816 | free_experiment (e); | ||
817 | } | ||
818 | |||
819 | |||
820 | /* end of file ats-testing-experiment.c*/ | ||