ats-testing-experiment.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761
  1. /*
  2. This file is part of GNUnet.
  3. Copyright (C) 2010-2013 GNUnet e.V.
  4. GNUnet is free software: you can redistribute it and/or modify it
  5. under the terms of the GNU Affero General Public License as published
  6. by the Free Software Foundation, either version 3 of the License,
  7. or (at your option) any later version.
  8. GNUnet is distributed in the hope that it will be useful, but
  9. WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Affero General Public License for more details.
  12. You should have received a copy of the GNU Affero General Public License
  13. along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. SPDX-License-Identifier: AGPL3.0-or-later
  15. */
  16. /**
  17. * @file ats-tests/ats-testing-experiment.c
  18. * @brief ats benchmark: controlled experiment execution
  19. * @author Christian Grothoff
  20. * @author Matthias Wachs
  21. */
  22. #include "platform.h"
  23. #include "gnunet_util_lib.h"
  24. #include "ats-testing.h"
  25. const char *
  26. print_op(enum OperationType op)
  27. {
  28. switch (op)
  29. {
  30. case START_SEND:
  31. return "START_SEND";
  32. case STOP_SEND:
  33. return "STOP_SEND";
  34. case START_PREFERENCE:
  35. return "START_PREFERENCE";
  36. case STOP_PREFERENCE:
  37. return "STOP_PREFERENCE";
  38. default:
  39. break;
  40. }
  41. return "";
  42. }
  43. static struct Experiment *
  44. create_experiment()
  45. {
  46. struct Experiment *e;
  47. e = GNUNET_new(struct Experiment);
  48. e->name = NULL;
  49. e->num_masters = 0;
  50. e->num_slaves = 0;
  51. e->start = NULL;
  52. e->total_duration = GNUNET_TIME_UNIT_ZERO;
  53. return e;
  54. }
  55. static void
  56. free_experiment(struct Experiment *e)
  57. {
  58. struct Episode *cur;
  59. struct Episode *next;
  60. struct GNUNET_ATS_TEST_Operation *cur_o;
  61. struct GNUNET_ATS_TEST_Operation *next_o;
  62. next = e->start;
  63. for (cur = next; NULL != cur; cur = next)
  64. {
  65. next = cur->next;
  66. next_o = cur->head;
  67. for (cur_o = next_o; NULL != cur_o; cur_o = next_o)
  68. {
  69. next_o = cur_o->next;
  70. GNUNET_free(cur_o);
  71. }
  72. GNUNET_free(cur);
  73. }
  74. GNUNET_free_non_null(e->name);
  75. GNUNET_free_non_null(e->cfg_file);
  76. GNUNET_free(e);
  77. }
  78. static int
  79. load_episode(struct Experiment *e,
  80. struct Episode *cur,
  81. struct GNUNET_CONFIGURATION_Handle *cfg)
  82. {
  83. struct GNUNET_ATS_TEST_Operation *o;
  84. char *sec_name;
  85. char *op_name;
  86. char *op;
  87. char *type;
  88. char *pref;
  89. int op_counter = 0;
  90. fprintf(stderr, "Parsing episode %u\n", cur->id);
  91. GNUNET_asprintf(&sec_name, "episode-%u", cur->id);
  92. while (1)
  93. {
  94. /* Load operation */
  95. GNUNET_asprintf(&op_name, "op-%u-operation", op_counter);
  96. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
  97. sec_name, op_name, &op))
  98. {
  99. GNUNET_free(op_name);
  100. break;
  101. }
  102. o = GNUNET_new(struct GNUNET_ATS_TEST_Operation);
  103. /* operations = set_rate, start_send, stop_send, set_preference */
  104. if (0 == strcmp(op, "start_send"))
  105. {
  106. o->type = START_SEND;
  107. }
  108. else if (0 == strcmp(op, "stop_send"))
  109. {
  110. o->type = STOP_SEND;
  111. }
  112. else if (0 == strcmp(op, "start_preference"))
  113. {
  114. o->type = START_PREFERENCE;
  115. }
  116. else if (0 == strcmp(op, "stop_preference"))
  117. {
  118. o->type = STOP_PREFERENCE;
  119. }
  120. else
  121. {
  122. fprintf(stderr, "Invalid operation %u `%s' in episode %u\n",
  123. op_counter, op, cur->id);
  124. GNUNET_free(op);
  125. GNUNET_free(op_name);
  126. GNUNET_free(o);
  127. GNUNET_free(sec_name);
  128. return GNUNET_SYSERR;
  129. }
  130. GNUNET_free(op_name);
  131. /* Get source */
  132. GNUNET_asprintf(&op_name, "op-%u-src", op_counter);
  133. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg,
  134. sec_name, op_name, &o->src_id))
  135. {
  136. fprintf(stderr, "Missing src in operation %u `%s' in episode %u\n",
  137. op_counter, op, cur->id);
  138. GNUNET_free(op);
  139. GNUNET_free(op_name);
  140. GNUNET_free(o);
  141. GNUNET_free(sec_name);
  142. return GNUNET_SYSERR;
  143. }
  144. if (o->src_id > (e->num_masters - 1))
  145. {
  146. fprintf(stderr, "Invalid src %llu in operation %u `%s' in episode %u\n",
  147. o->src_id, op_counter, op, cur->id);
  148. GNUNET_free(op);
  149. GNUNET_free(op_name);
  150. GNUNET_free(o);
  151. GNUNET_free(sec_name);
  152. return GNUNET_SYSERR;
  153. }
  154. GNUNET_free(op_name);
  155. /* Get destination */
  156. GNUNET_asprintf(&op_name, "op-%u-dest", op_counter);
  157. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg,
  158. sec_name, op_name, &o->dest_id))
  159. {
  160. fprintf(stderr, "Missing src in operation %u `%s' in episode %u\n",
  161. op_counter, op, cur->id);
  162. GNUNET_free(op);
  163. GNUNET_free(op_name);
  164. GNUNET_free(o);
  165. GNUNET_free(sec_name);
  166. return GNUNET_SYSERR;
  167. }
  168. if (o->dest_id > (e->num_slaves - 1))
  169. {
  170. fprintf(stderr, "Invalid destination %llu in operation %u `%s' in episode %u\n",
  171. o->dest_id, op_counter, op, cur->id);
  172. GNUNET_free(op);
  173. GNUNET_free(op_name);
  174. GNUNET_free(o);
  175. GNUNET_free(sec_name);
  176. return GNUNET_SYSERR;
  177. }
  178. GNUNET_free(op_name);
  179. GNUNET_asprintf(&op_name, "op-%u-type", op_counter);
  180. if ((GNUNET_SYSERR != GNUNET_CONFIGURATION_get_value_string(cfg,
  181. sec_name, op_name, &type)) &&
  182. (STOP_SEND != o->type) &&
  183. (STOP_PREFERENCE != o->type))
  184. {
  185. /* Load arguments for set_rate, start_send, set_preference */
  186. if (0 == strcmp(type, "constant"))
  187. {
  188. o->gen_type = GNUNET_ATS_TEST_TG_CONSTANT;
  189. }
  190. else if (0 == strcmp(type, "linear"))
  191. {
  192. o->gen_type = GNUNET_ATS_TEST_TG_LINEAR;
  193. }
  194. else if (0 == strcmp(type, "sinus"))
  195. {
  196. o->gen_type = GNUNET_ATS_TEST_TG_SINUS;
  197. }
  198. else if (0 == strcmp(type, "random"))
  199. {
  200. o->gen_type = GNUNET_ATS_TEST_TG_RANDOM;
  201. }
  202. else
  203. {
  204. fprintf(stderr, "Invalid type %u `%s' in episode %u\n",
  205. op_counter, op, cur->id);
  206. GNUNET_free(type);
  207. GNUNET_free(op);
  208. GNUNET_free(op_name);
  209. GNUNET_free(sec_name);
  210. GNUNET_free(o);
  211. return GNUNET_SYSERR;
  212. }
  213. GNUNET_free(op_name);
  214. /* Get base rate */
  215. GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
  216. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg,
  217. sec_name, op_name, &o->base_rate))
  218. {
  219. fprintf(stderr, "Missing base rate in operation %u `%s' in episode %u\n",
  220. op_counter, op, cur->id);
  221. GNUNET_free(type);
  222. GNUNET_free(op);
  223. GNUNET_free(op_name);
  224. GNUNET_free(sec_name);
  225. GNUNET_free(o);
  226. return GNUNET_SYSERR;
  227. }
  228. GNUNET_free(op_name);
  229. /* Get max rate */
  230. GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
  231. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg,
  232. sec_name, op_name, &o->max_rate))
  233. {
  234. if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
  235. (GNUNET_ATS_TEST_TG_RANDOM == o->gen_type) ||
  236. (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
  237. {
  238. fprintf(stderr, "Missing max rate in operation %u `%s' in episode %u\n",
  239. op_counter, op, cur->id);
  240. GNUNET_free(type);
  241. GNUNET_free(op_name);
  242. GNUNET_free(op);
  243. GNUNET_free(o);
  244. GNUNET_free(sec_name);
  245. return GNUNET_SYSERR;
  246. }
  247. }
  248. GNUNET_free(op_name);
  249. /* Get period */
  250. GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
  251. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg,
  252. sec_name, op_name, &o->period))
  253. {
  254. o->period = cur->duration;
  255. }
  256. GNUNET_free(op_name);
  257. if (START_PREFERENCE == o->type)
  258. {
  259. /* Get frequency */
  260. GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
  261. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg,
  262. sec_name, op_name, &o->frequency))
  263. {
  264. fprintf(stderr, "Missing frequency in operation %u `%s' in episode %u\n",
  265. op_counter, op, cur->id);
  266. GNUNET_free(type);
  267. GNUNET_free(op_name);
  268. GNUNET_free(op);
  269. GNUNET_free(o);
  270. GNUNET_free(sec_name);
  271. return GNUNET_SYSERR;
  272. }
  273. GNUNET_free(op_name);
  274. /* Get preference */
  275. GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
  276. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg,
  277. sec_name, op_name, &pref))
  278. {
  279. fprintf(stderr, "Missing preference in operation %u `%s' in episode %u\n",
  280. op_counter, op, cur->id);
  281. GNUNET_free(type);
  282. GNUNET_free(op_name);
  283. GNUNET_free(op);
  284. GNUNET_free_non_null(pref);
  285. GNUNET_free(o);
  286. GNUNET_free(sec_name);
  287. return GNUNET_SYSERR;
  288. }
  289. if (0 == strcmp(pref, "bandwidth"))
  290. o->pref_type = GNUNET_ATS_PREFERENCE_BANDWIDTH;
  291. else if (0 == strcmp(pref, "latency"))
  292. o->pref_type = GNUNET_ATS_PREFERENCE_LATENCY;
  293. else
  294. {
  295. fprintf(stderr, "Invalid preference in operation %u `%s' in episode %u\n",
  296. op_counter, op, cur->id);
  297. GNUNET_free(type);
  298. GNUNET_free(op_name);
  299. GNUNET_free(op);
  300. GNUNET_free_non_null(pref);
  301. GNUNET_free(o);
  302. GNUNET_free(sec_name);
  303. return GNUNET_SYSERR;
  304. }
  305. GNUNET_free(pref);
  306. GNUNET_free(op_name);
  307. }
  308. }
  309. /* Safety checks */
  310. if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
  311. (GNUNET_ATS_TEST_TG_SINUS == o->gen_type))
  312. {
  313. if ((o->max_rate - o->base_rate) > o->base_rate)
  314. {
  315. /* This will cause an underflow */
  316. GNUNET_break(0);
  317. }
  318. fprintf(stderr, "Selected max rate and base rate cannot be used for desired traffic form!\n");
  319. }
  320. if ((START_SEND == o->type) || (START_PREFERENCE == o->type))
  321. fprintf(stderr, "Found operation %u in episode %u: %s [%llu]->[%llu] == %s, %llu -> %llu in %s\n",
  322. op_counter, cur->id, print_op(o->type), o->src_id,
  323. o->dest_id, (NULL != type) ? type : "",
  324. o->base_rate, o->max_rate,
  325. GNUNET_STRINGS_relative_time_to_string(o->period, GNUNET_YES));
  326. else
  327. fprintf(stderr, "Found operation %u in episode %u: %s [%llu]->[%llu]\n",
  328. op_counter, cur->id, print_op(o->type), o->src_id, o->dest_id);
  329. GNUNET_free_non_null(type);
  330. GNUNET_free(op);
  331. GNUNET_CONTAINER_DLL_insert(cur->head, cur->tail, o);
  332. op_counter++;
  333. }
  334. GNUNET_free(sec_name);
  335. return GNUNET_OK;
  336. }
  337. static int
  338. load_episodes(struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
  339. {
  340. int e_counter = 0;
  341. char *sec_name;
  342. struct GNUNET_TIME_Relative e_duration;
  343. struct Episode *cur;
  344. struct Episode *last;
  345. e_counter = 0;
  346. last = NULL;
  347. while (1)
  348. {
  349. GNUNET_asprintf(&sec_name, "episode-%u", e_counter);
  350. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg,
  351. sec_name, "duration", &e_duration))
  352. {
  353. GNUNET_free(sec_name);
  354. break;
  355. }
  356. cur = GNUNET_new(struct Episode);
  357. cur->duration = e_duration;
  358. cur->id = e_counter;
  359. if (GNUNET_OK != load_episode(e, cur, cfg))
  360. {
  361. GNUNET_free(sec_name);
  362. GNUNET_free(cur);
  363. return GNUNET_SYSERR;
  364. }
  365. fprintf(stderr, "Found episode %u with duration %s \n",
  366. e_counter,
  367. GNUNET_STRINGS_relative_time_to_string(cur->duration, GNUNET_YES));
  368. /* Update experiment */
  369. e->num_episodes++;
  370. e->total_duration = GNUNET_TIME_relative_add(e->total_duration, cur->duration);
  371. /* Put in linked list */
  372. if (NULL == last)
  373. e->start = cur;
  374. else
  375. last->next = cur;
  376. GNUNET_free(sec_name);
  377. e_counter++;
  378. last = cur;
  379. }
  380. return e_counter;
  381. }
  382. static void
  383. timeout_experiment(void *cls)
  384. {
  385. struct Experiment *e = cls;
  386. e->experiment_timeout_task = NULL;
  387. fprintf(stderr, "Experiment timeout!\n");
  388. if (NULL != e->episode_timeout_task)
  389. {
  390. GNUNET_SCHEDULER_cancel(e->episode_timeout_task);
  391. e->episode_timeout_task = NULL;
  392. }
  393. e->e_done_cb(e, GNUNET_TIME_absolute_get_duration(e->start_time),
  394. GNUNET_SYSERR);
  395. }
  396. static void
  397. enforce_start_send(struct GNUNET_ATS_TEST_Operation *op)
  398. {
  399. struct BenchmarkPeer *peer;
  400. struct BenchmarkPartner *partner;
  401. peer = GNUNET_ATS_TEST_get_peer(op->src_id);
  402. if (NULL == peer)
  403. {
  404. GNUNET_break(0);
  405. return;
  406. }
  407. partner = GNUNET_ATS_TEST_get_partner(op->src_id, op->dest_id);
  408. if (NULL == partner)
  409. {
  410. GNUNET_break(0);
  411. return;
  412. }
  413. fprintf(stderr, "Found master %llu slave %llu\n", op->src_id, op->dest_id);
  414. if (NULL != partner->tg)
  415. {
  416. fprintf(stderr, "Stopping traffic between master %llu slave %llu\n", op->src_id, op->dest_id);
  417. GNUNET_ATS_TEST_generate_traffic_stop(partner->tg);
  418. partner->tg = NULL;
  419. }
  420. partner->tg = GNUNET_ATS_TEST_generate_traffic_start(peer, partner,
  421. op->gen_type, op->base_rate, op->max_rate, op->period,
  422. GNUNET_TIME_UNIT_FOREVER_REL);
  423. }
  424. static void
  425. enforce_stop_send(struct GNUNET_ATS_TEST_Operation *op)
  426. {
  427. struct BenchmarkPartner *p;
  428. p = GNUNET_ATS_TEST_get_partner(op->src_id, op->dest_id);
  429. if (NULL == p)
  430. {
  431. GNUNET_break(0);
  432. return;
  433. }
  434. fprintf(stderr, "Found master %llu slave %llu\n", op->src_id, op->dest_id);
  435. if (NULL != p->tg)
  436. {
  437. fprintf(stderr, "Stopping traffic between master %llu slave %llu\n",
  438. op->src_id, op->dest_id);
  439. GNUNET_ATS_TEST_generate_traffic_stop(p->tg);
  440. p->tg = NULL;
  441. }
  442. }
  443. static void
  444. enforce_start_preference(struct GNUNET_ATS_TEST_Operation *op)
  445. {
  446. struct BenchmarkPeer *peer;
  447. struct BenchmarkPartner *partner;
  448. peer = GNUNET_ATS_TEST_get_peer(op->src_id);
  449. if (NULL == peer)
  450. {
  451. GNUNET_break(0);
  452. return;
  453. }
  454. partner = GNUNET_ATS_TEST_get_partner(op->src_id, op->dest_id);
  455. if (NULL == partner)
  456. {
  457. GNUNET_break(0);
  458. return;
  459. }
  460. fprintf(stderr, "Found master %llu slave %llu\n", op->src_id, op->dest_id);
  461. if (NULL != partner->pg)
  462. {
  463. fprintf(stderr, "Stopping traffic between master %llu slave %llu\n",
  464. op->src_id, op->dest_id);
  465. GNUNET_ATS_TEST_generate_preferences_stop(partner->pg);
  466. partner->pg = NULL;
  467. }
  468. partner->pg = GNUNET_ATS_TEST_generate_preferences_start(peer, partner,
  469. op->gen_type, op->base_rate, op->max_rate, op->period, op->frequency,
  470. op->pref_type);
  471. }
  472. static void
  473. enforce_stop_preference(struct GNUNET_ATS_TEST_Operation *op)
  474. {
  475. struct BenchmarkPartner *p;
  476. p = GNUNET_ATS_TEST_get_partner(op->src_id, op->dest_id);
  477. if (NULL == p)
  478. {
  479. GNUNET_break(0);
  480. return;
  481. }
  482. fprintf(stderr, "Found master %llu slave %llu\n", op->src_id, op->dest_id);
  483. if (NULL != p->pg)
  484. {
  485. fprintf(stderr, "Stopping preference between master %llu slave %llu\n",
  486. op->src_id, op->dest_id);
  487. GNUNET_ATS_TEST_generate_preferences_stop(p->pg);
  488. p->pg = NULL;
  489. }
  490. }
  491. static void enforce_episode(struct Episode *ep)
  492. {
  493. struct GNUNET_ATS_TEST_Operation *cur;
  494. for (cur = ep->head; NULL != cur; cur = cur->next)
  495. {
  496. fprintf(stderr, "Enforcing operation: %s [%llu]->[%llu] == %llu\n",
  497. print_op(cur->type), cur->src_id, cur->dest_id, cur->base_rate);
  498. switch (cur->type)
  499. {
  500. case START_SEND:
  501. enforce_start_send(cur);
  502. break;
  503. case STOP_SEND:
  504. enforce_stop_send(cur);
  505. break;
  506. case START_PREFERENCE:
  507. enforce_start_preference(cur);
  508. break;
  509. case STOP_PREFERENCE:
  510. enforce_stop_preference(cur);
  511. break;
  512. default:
  513. break;
  514. }
  515. }
  516. }
  517. static void
  518. timeout_episode(void *cls)
  519. {
  520. struct Experiment *e = cls;
  521. e->episode_timeout_task = NULL;
  522. if (NULL != e->ep_done_cb)
  523. e->ep_done_cb(e->cur);
  524. /* Scheduling next */
  525. e->cur = e->cur->next;
  526. if (NULL == e->cur)
  527. {
  528. /* done */
  529. fprintf(stderr, "Last episode done!\n");
  530. if (NULL != e->experiment_timeout_task)
  531. {
  532. GNUNET_SCHEDULER_cancel(e->experiment_timeout_task);
  533. e->experiment_timeout_task = NULL;
  534. }
  535. e->e_done_cb(e, GNUNET_TIME_absolute_get_duration(e->start_time), GNUNET_OK);
  536. return;
  537. }
  538. fprintf(stderr, "Running episode %u with timeout %s\n",
  539. e->cur->id,
  540. GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
  541. enforce_episode(e->cur);
  542. e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed(e->cur->duration,
  543. &timeout_episode, e);
  544. }
  545. void
  546. GNUNET_ATS_TEST_experimentation_run(struct Experiment *e,
  547. GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb,
  548. GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb)
  549. {
  550. fprintf(stderr, "Running experiment `%s' with timeout %s\n", e->name,
  551. GNUNET_STRINGS_relative_time_to_string(e->max_duration, GNUNET_YES));
  552. e->e_done_cb = e_done_cb;
  553. e->ep_done_cb = ep_done_cb;
  554. e->start_time = GNUNET_TIME_absolute_get();
  555. /* Start total time out */
  556. e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed(e->max_duration,
  557. &timeout_experiment, e);
  558. /* Start */
  559. e->cur = e->start;
  560. fprintf(stderr, "Running episode %u with timeout %s\n",
  561. e->cur->id,
  562. GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES));
  563. enforce_episode(e->cur);
  564. e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed(e->cur->duration,
  565. &timeout_episode, e);
  566. }
  567. struct Experiment *
  568. GNUNET_ATS_TEST_experimentation_load(const char *filename)
  569. {
  570. struct Experiment *e;
  571. struct GNUNET_CONFIGURATION_Handle *cfg;
  572. e = NULL;
  573. cfg = GNUNET_CONFIGURATION_create();
  574. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load(cfg, filename))
  575. {
  576. fprintf(stderr, "Failed to load `%s'\n", filename);
  577. GNUNET_CONFIGURATION_destroy(cfg);
  578. return NULL;
  579. }
  580. e = create_experiment();
  581. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
  582. "name", &e->name))
  583. {
  584. fprintf(stderr, "Invalid %s", "name");
  585. free_experiment(e);
  586. return NULL;
  587. }
  588. else
  589. fprintf(stderr, "Experiment name: `%s'\n", e->name);
  590. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename(cfg, "experiment",
  591. "cfg_file", &e->cfg_file))
  592. {
  593. fprintf(stderr, "Invalid %s", "cfg_file");
  594. free_experiment(e);
  595. return NULL;
  596. }
  597. else
  598. fprintf(stderr, "Experiment name: `%s'\n", e->cfg_file);
  599. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg, "experiment",
  600. "masters", &e->num_masters))
  601. {
  602. fprintf(stderr, "Invalid %s", "masters");
  603. free_experiment(e);
  604. return NULL;
  605. }
  606. else
  607. fprintf(stderr, "Experiment masters: `%llu'\n",
  608. e->num_masters);
  609. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg, "experiment",
  610. "slaves", &e->num_slaves))
  611. {
  612. fprintf(stderr, "Invalid %s", "slaves");
  613. free_experiment(e);
  614. return NULL;
  615. }
  616. else
  617. fprintf(stderr, "Experiment slaves: `%llu'\n",
  618. e->num_slaves);
  619. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
  620. "log_freq", &e->log_freq))
  621. {
  622. fprintf(stderr, "Invalid %s", "log_freq");
  623. free_experiment(e);
  624. return NULL;
  625. }
  626. else
  627. fprintf(stderr, "Experiment logging frequency: `%s'\n",
  628. GNUNET_STRINGS_relative_time_to_string(e->log_freq, GNUNET_YES));
  629. if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
  630. "max_duration", &e->max_duration))
  631. {
  632. fprintf(stderr, "Invalid %s", "max_duration");
  633. free_experiment(e);
  634. return NULL;
  635. }
  636. else
  637. fprintf(stderr, "Experiment duration: `%s'\n",
  638. GNUNET_STRINGS_relative_time_to_string(e->max_duration, GNUNET_YES));
  639. load_episodes(e, cfg);
  640. fprintf(stderr, "Loaded %u episodes with total duration %s\n",
  641. e->num_episodes,
  642. GNUNET_STRINGS_relative_time_to_string(e->total_duration, GNUNET_YES));
  643. GNUNET_CONFIGURATION_destroy(cfg);
  644. return e;
  645. }
  646. void
  647. GNUNET_ATS_TEST_experimentation_stop(struct Experiment *e)
  648. {
  649. if (NULL != e->experiment_timeout_task)
  650. {
  651. GNUNET_SCHEDULER_cancel(e->experiment_timeout_task);
  652. e->experiment_timeout_task = NULL;
  653. }
  654. if (NULL != e->episode_timeout_task)
  655. {
  656. GNUNET_SCHEDULER_cancel(e->episode_timeout_task);
  657. e->episode_timeout_task = NULL;
  658. }
  659. free_experiment(e);
  660. }
  661. /* end of file ats-testing-experiment.c*/