ats-testing-experiment.c 20 KB

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