GNUnet  0.10.x
Functions
ats-testing-experiment.c File Reference

ats benchmark: controlled experiment execution More...

#include "platform.h"
#include "gnunet_util_lib.h"
#include "ats-testing.h"
Include dependency graph for ats-testing-experiment.c:

Go to the source code of this file.

Functions

const char * print_op (enum OperationType op)
 
static struct Experimentcreate_experiment ()
 
static void free_experiment (struct Experiment *e)
 
static int load_episode (struct Experiment *e, struct Episode *cur, struct GNUNET_CONFIGURATION_Handle *cfg)
 
static int load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
 
static void timeout_experiment (void *cls)
 
static void enforce_start_send (struct GNUNET_ATS_TEST_Operation *op)
 
static void enforce_stop_send (struct GNUNET_ATS_TEST_Operation *op)
 
static void enforce_start_preference (struct GNUNET_ATS_TEST_Operation *op)
 
static void enforce_stop_preference (struct GNUNET_ATS_TEST_Operation *op)
 
static void enforce_episode (struct Episode *ep)
 
static void timeout_episode (void *cls)
 
void GNUNET_ATS_TEST_experimentation_run (struct Experiment *e, GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb, GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb)
 Execute the specified experiment. More...
 
struct ExperimentGNUNET_ATS_TEST_experimentation_load (const char *filename)
 Load an experiment from a file. More...
 
void GNUNET_ATS_TEST_experimentation_stop (struct Experiment *e)
 Stop an experiment. More...
 

Detailed Description

ats benchmark: controlled experiment execution

Author
Christian Grothoff
Matthias Wachs

Definition in file ats-testing-experiment.c.

Function Documentation

◆ print_op()

const char* print_op ( enum OperationType  op)

Definition at line 31 of file ats-testing-experiment.c.

References START_PREFERENCE, START_SEND, STOP_PREFERENCE, and STOP_SEND.

Referenced by enforce_episode(), and load_episode().

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 }
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
Here is the caller graph for this function:

◆ create_experiment()

static struct Experiment* create_experiment ( )
static

Definition at line 55 of file ats-testing-experiment.c.

References e, GNUNET_new, GNUNET_TIME_UNIT_ZERO, Experiment::name, Experiment::num_masters, Experiment::num_slaves, Experiment::start, and Experiment::total_duration.

Referenced by GNUNET_ATS_TEST_experimentation_load().

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;
65  return e;
66 }
struct Episode * start
unsigned long long int num_masters
Definition: ats-testing.h:513
struct GNUNET_TIME_Relative total_duration
static struct Experiment * e
#define GNUNET_new(type)
Allocate a struct or union of the given type.
unsigned long long int num_slaves
Definition: ats-testing.h:514
#define GNUNET_TIME_UNIT_ZERO
Relative time zero.
Here is the caller graph for this function:

◆ free_experiment()

static void free_experiment ( struct Experiment e)
static

Definition at line 69 of file ats-testing-experiment.c.

References Experiment::cfg_file, GNUNET_free, GNUNET_free_non_null, Episode::head, Experiment::name, GNUNET_ATS_TEST_Operation::next, Episode::next, and Experiment::start.

Referenced by GNUNET_ATS_TEST_experimentation_load(), and GNUNET_ATS_TEST_experimentation_stop().

70 {
71  struct Episode *cur;
72  struct Episode *next;
73  struct GNUNET_ATS_TEST_Operation *cur_o;
74  struct GNUNET_ATS_TEST_Operation *next_o;
75 
76  next = e->start;
77  for (cur = next; NULL != cur; cur = next)
78  {
79  next = cur->next;
80 
81  next_o = cur->head;
82  for (cur_o = next_o; NULL != cur_o; cur_o = next_o)
83  {
84  next_o = cur_o->next;
85  GNUNET_free(cur_o);
86  }
87  GNUNET_free(cur);
88  }
89 
92  GNUNET_free(e);
93 }
struct GNUNET_ATS_TEST_Operation * next
struct Episode * start
struct Episode * next
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
An operation in an experiment.
struct GNUNET_ATS_TEST_Operation * head
#define GNUNET_free(ptr)
Wrapper around free.
Here is the caller graph for this function:

◆ load_episode()

static int load_episode ( struct Experiment e,
struct Episode cur,
struct GNUNET_CONFIGURATION_Handle cfg 
)
static

Definition at line 97 of file ats-testing-experiment.c.

References GNUNET_ATS_TEST_Operation::base_rate, GNUNET_ATS_TEST_Operation::dest_id, Episode::duration, GNUNET_ATS_TEST_Operation::frequency, GNUNET_ATS_TEST_Operation::gen_type, GNUNET_asprintf(), GNUNET_ATS_PREFERENCE_BANDWIDTH, GNUNET_ATS_PREFERENCE_LATENCY, GNUNET_ATS_TEST_TG_CONSTANT, GNUNET_ATS_TEST_TG_LINEAR, GNUNET_ATS_TEST_TG_RANDOM, GNUNET_ATS_TEST_TG_SINUS, GNUNET_break, GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_time(), GNUNET_CONTAINER_DLL_insert, GNUNET_free, GNUNET_free_non_null, GNUNET_new, GNUNET_OK, GNUNET_STRINGS_relative_time_to_string(), GNUNET_SYSERR, GNUNET_YES, Episode::head, Episode::id, GNUNET_ATS_TEST_Operation::max_rate, Experiment::num_masters, Experiment::num_slaves, op, GNUNET_ATS_TEST_Operation::period, GNUNET_ATS_TEST_Operation::pref_type, print_op(), GNUNET_ATS_TEST_Operation::src_id, START_PREFERENCE, START_SEND, STOP_PREFERENCE, STOP_SEND, Episode::tail, type, and GNUNET_ATS_TEST_Operation::type.

Referenced by load_episodes().

100 {
101  struct GNUNET_ATS_TEST_Operation *o;
102  char *sec_name;
103  char *op_name;
104  char *op;
105  char *type;
106  char *pref;
107  int op_counter = 0;
108 
109  fprintf(stderr, "Parsing episode %u\n", cur->id);
110  GNUNET_asprintf(&sec_name, "episode-%u", cur->id);
111 
112  while (1)
113  {
114  /* Load operation */
115  GNUNET_asprintf(&op_name, "op-%u-operation", op_counter);
117  sec_name, op_name, &op))
118  {
119  GNUNET_free(op_name);
120  break;
121  }
123  /* operations = set_rate, start_send, stop_send, set_preference */
124  if (0 == strcmp(op, "start_send"))
125  {
126  o->type = START_SEND;
127  }
128  else if (0 == strcmp(op, "stop_send"))
129  {
130  o->type = STOP_SEND;
131  }
132  else if (0 == strcmp(op, "start_preference"))
133  {
134  o->type = START_PREFERENCE;
135  }
136  else if (0 == strcmp(op, "stop_preference"))
137  {
138  o->type = STOP_PREFERENCE;
139  }
140  else
141  {
142  fprintf(stderr, "Invalid operation %u `%s' in episode %u\n",
143  op_counter, op, cur->id);
144  GNUNET_free(op);
145  GNUNET_free(op_name);
146  GNUNET_free(o);
147  GNUNET_free(sec_name);
148  return GNUNET_SYSERR;
149  }
150  GNUNET_free(op_name);
151 
152  /* Get source */
153  GNUNET_asprintf(&op_name, "op-%u-src", op_counter);
155  sec_name, op_name, &o->src_id))
156  {
157  fprintf(stderr, "Missing src in operation %u `%s' in episode %u\n",
158  op_counter, op, cur->id);
159  GNUNET_free(op);
160  GNUNET_free(op_name);
161  GNUNET_free(o);
162  GNUNET_free(sec_name);
163  return GNUNET_SYSERR;
164  }
165  if (o->src_id > (e->num_masters - 1))
166  {
167  fprintf(stderr, "Invalid src %llu in operation %u `%s' in episode %u\n",
168  o->src_id, op_counter, op, cur->id);
169  GNUNET_free(op);
170  GNUNET_free(op_name);
171  GNUNET_free(o);
172  GNUNET_free(sec_name);
173  return GNUNET_SYSERR;
174  }
175  GNUNET_free(op_name);
176 
177  /* Get destination */
178  GNUNET_asprintf(&op_name, "op-%u-dest", op_counter);
180  sec_name, op_name, &o->dest_id))
181  {
182  fprintf(stderr, "Missing src in operation %u `%s' in episode %u\n",
183  op_counter, op, cur->id);
184  GNUNET_free(op);
185  GNUNET_free(op_name);
186  GNUNET_free(o);
187  GNUNET_free(sec_name);
188  return GNUNET_SYSERR;
189  }
190  if (o->dest_id > (e->num_slaves - 1))
191  {
192  fprintf(stderr, "Invalid destination %llu in operation %u `%s' in episode %u\n",
193  o->dest_id, op_counter, op, cur->id);
194  GNUNET_free(op);
195  GNUNET_free(op_name);
196  GNUNET_free(o);
197  GNUNET_free(sec_name);
198  return GNUNET_SYSERR;
199  }
200  GNUNET_free(op_name);
201 
202  GNUNET_asprintf(&op_name, "op-%u-type", op_counter);
204  sec_name, op_name, &type)) &&
205  (STOP_SEND != o->type) &&
206  (STOP_PREFERENCE != o->type))
207  {
208  /* Load arguments for set_rate, start_send, set_preference */
209  if (0 == strcmp(type, "constant"))
210  {
212  }
213  else if (0 == strcmp(type, "linear"))
214  {
216  }
217  else if (0 == strcmp(type, "sinus"))
218  {
220  }
221  else if (0 == strcmp(type, "random"))
222  {
224  }
225  else
226  {
227  fprintf(stderr, "Invalid type %u `%s' in episode %u\n",
228  op_counter, op, cur->id);
229  GNUNET_free(type);
230  GNUNET_free(op);
231  GNUNET_free(op_name);
232  GNUNET_free(sec_name);
233  GNUNET_free(o);
234  return GNUNET_SYSERR;
235  }
236  GNUNET_free(op_name);
237 
238  /* Get base rate */
239  GNUNET_asprintf(&op_name, "op-%u-base-rate", op_counter);
241  sec_name, op_name, &o->base_rate))
242  {
243  fprintf(stderr, "Missing base rate in operation %u `%s' in episode %u\n",
244  op_counter, op, cur->id);
245  GNUNET_free(type);
246  GNUNET_free(op);
247  GNUNET_free(op_name);
248  GNUNET_free(sec_name);
249  GNUNET_free(o);
250  return GNUNET_SYSERR;
251  }
252  GNUNET_free(op_name);
253 
254  /* Get max rate */
255  GNUNET_asprintf(&op_name, "op-%u-max-rate", op_counter);
257  sec_name, op_name, &o->max_rate))
258  {
259  if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
262  {
263  fprintf(stderr, "Missing max rate 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  }
273  GNUNET_free(op_name);
274 
275  /* Get period */
276  GNUNET_asprintf(&op_name, "op-%u-period", op_counter);
278  sec_name, op_name, &o->period))
279  {
280  o->period = cur->duration;
281  }
282  GNUNET_free(op_name);
283 
284  if (START_PREFERENCE == o->type)
285  {
286  /* Get frequency */
287  GNUNET_asprintf(&op_name, "op-%u-frequency", op_counter);
289  sec_name, op_name, &o->frequency))
290  {
291  fprintf(stderr, "Missing frequency in operation %u `%s' in episode %u\n",
292  op_counter, op, cur->id);
293  GNUNET_free(type);
294  GNUNET_free(op_name);
295  GNUNET_free(op);
296  GNUNET_free(o);
297  GNUNET_free(sec_name);
298  return GNUNET_SYSERR;
299  }
300  GNUNET_free(op_name);
301 
302  /* Get preference */
303  GNUNET_asprintf(&op_name, "op-%u-pref", op_counter);
305  sec_name, op_name, &pref))
306  {
307  fprintf(stderr, "Missing preference in operation %u `%s' in episode %u\n",
308  op_counter, op, cur->id);
309  GNUNET_free(type);
310  GNUNET_free(op_name);
311  GNUNET_free(op);
312  GNUNET_free_non_null(pref);
313  GNUNET_free(o);
314  GNUNET_free(sec_name);
315  return GNUNET_SYSERR;
316  }
317 
318  if (0 == strcmp(pref, "bandwidth"))
320  else if (0 == strcmp(pref, "latency"))
322  else
323  {
324  fprintf(stderr, "Invalid preference in operation %u `%s' in episode %u\n",
325  op_counter, op, cur->id);
326  GNUNET_free(type);
327  GNUNET_free(op_name);
328  GNUNET_free(op);
329  GNUNET_free_non_null(pref);
330  GNUNET_free(o);
331  GNUNET_free(sec_name);
332  return GNUNET_SYSERR;
333  }
334  GNUNET_free(pref);
335  GNUNET_free(op_name);
336  }
337  }
338 
339  /* Safety checks */
340  if ((GNUNET_ATS_TEST_TG_LINEAR == o->gen_type) ||
342  {
343  if ((o->max_rate - o->base_rate) > o->base_rate)
344  {
345  /* This will cause an underflow */
346  GNUNET_break(0);
347  }
348  fprintf(stderr, "Selected max rate and base rate cannot be used for desired traffic form!\n");
349  }
350 
351  if ((START_SEND == o->type) || (START_PREFERENCE == o->type))
352  fprintf(stderr, "Found operation %u in episode %u: %s [%llu]->[%llu] == %s, %llu -> %llu in %s\n",
353  op_counter, cur->id, print_op(o->type), o->src_id,
354  o->dest_id, (NULL != type) ? type : "",
355  o->base_rate, o->max_rate,
357  else
358  fprintf(stderr, "Found operation %u in episode %u: %s [%llu]->[%llu]\n",
359  op_counter, cur->id, print_op(o->type), o->src_id, o->dest_id);
360 
361  GNUNET_free_non_null(type);
362  GNUNET_free(op);
363 
364  GNUNET_CONTAINER_DLL_insert(cur->head, cur->tail, o);
365  op_counter++;
366  }
367  GNUNET_free(sec_name);
368 
369  return GNUNET_OK;
370 }
int GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
#define GNUNET_CONTAINER_DLL_insert(head, tail, element)
Insert an element at the head of a DLL.
unsigned long long int num_masters
Definition: ats-testing.h:513
long long unsigned int src_id
Definition: ats-testing.h:487
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_free_non_null(ptr)
Free the memory pointed to by ptr if ptr is not NULL.
#define GNUNET_new(type)
Allocate a struct or union of the given type.
struct GNUNET_TIME_Relative period
const char * print_op(enum OperationType op)
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
long long unsigned int dest_id
Definition: ats-testing.h:488
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:686
long long unsigned int base_rate
unsigned long long int num_slaves
Definition: ats-testing.h:514
enum GNUNET_ATS_PreferenceKind pref_type
struct GNUNET_TIME_Relative duration
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
An operation in an experiment.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
Change the peer's latency value to the given amount.
struct GNUNET_ATS_TEST_Operation * head
struct GNUNET_ATS_TEST_Operation * tail
Change the peer's bandwidth value (value per byte of bandwidth in the goal function) to the given amo...
struct GNUNET_TIME_Relative frequency
enum GNUNET_TESTBED_UnderlayLinkModelType type
the type of this model
#define GNUNET_YES
Definition: gnunet_common.h:77
static struct GNUNET_ARM_Operation * op
Current operation.
Definition: gnunet-arm.c:139
long long unsigned int max_rate
#define GNUNET_free(ptr)
Wrapper around free.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ load_episodes()

static int load_episodes ( struct Experiment e,
struct GNUNET_CONFIGURATION_Handle cfg 
)
static

Definition at line 374 of file ats-testing-experiment.c.

References Episode::duration, GNUNET_asprintf(), GNUNET_CONFIGURATION_get_value_time(), GNUNET_free, GNUNET_new, GNUNET_OK, GNUNET_STRINGS_relative_time_to_string(), GNUNET_SYSERR, GNUNET_TIME_relative_add(), GNUNET_YES, Episode::id, load_episode(), Episode::next, Experiment::num_episodes, Experiment::start, and Experiment::total_duration.

Referenced by GNUNET_ATS_TEST_experimentation_load().

375 {
376  int e_counter = 0;
377  char *sec_name;
378  struct GNUNET_TIME_Relative e_duration;
379  struct Episode *cur;
380  struct Episode *last;
381 
382  e_counter = 0;
383  last = NULL;
384  while (1)
385  {
386  GNUNET_asprintf(&sec_name, "episode-%u", e_counter);
388  sec_name, "duration", &e_duration))
389  {
390  GNUNET_free(sec_name);
391  break;
392  }
393 
394  cur = GNUNET_new(struct Episode);
395  cur->duration = e_duration;
396  cur->id = e_counter;
397 
398  if (GNUNET_OK != load_episode(e, cur, cfg))
399  {
400  GNUNET_free(sec_name);
401  GNUNET_free(cur);
402  return GNUNET_SYSERR;
403  }
404 
405  fprintf(stderr, "Found episode %u with duration %s \n",
406  e_counter,
408 
409  /* Update experiment */
410  e->num_episodes++;
412  /* Put in linked list */
413  if (NULL == last)
414  e->start = cur;
415  else
416  last->next = cur;
417 
418  GNUNET_free(sec_name);
419  e_counter++;
420  last = cur;
421  }
422  return e_counter;
423 }
struct Episode * start
int GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
struct Episode * next
struct GNUNET_TIME_Relative total_duration
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define GNUNET_new(type)
Allocate a struct or union of the given type.
unsigned int num_episodes
static int load_episode(struct Experiment *e, struct Episode *cur, struct GNUNET_CONFIGURATION_Handle *cfg)
int GNUNET_asprintf(char **buf, const char *format,...)
Like asprintf, just portable.
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:686
struct GNUNET_TIME_Relative duration
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
struct GNUNET_TIME_Relative GNUNET_TIME_relative_add(struct GNUNET_TIME_Relative a1, struct GNUNET_TIME_Relative a2)
Add relative times together.
Definition: time.c:577
#define GNUNET_YES
Definition: gnunet_common.h:77
#define GNUNET_free(ptr)
Wrapper around free.
Time for relative time used by GNUnet, in microseconds.
Here is the call graph for this function:
Here is the caller graph for this function:

◆ timeout_experiment()

static void timeout_experiment ( void *  cls)
static

Definition at line 427 of file ats-testing-experiment.c.

References e, Experiment::e_done_cb, Experiment::episode_timeout_task, Experiment::experiment_timeout_task, GNUNET_SCHEDULER_cancel(), GNUNET_SYSERR, GNUNET_TIME_absolute_get_duration(), and Experiment::start_time.

Referenced by GNUNET_ATS_TEST_experimentation_run().

428 {
429  struct Experiment *e = cls;
430 
431  e->experiment_timeout_task = NULL;
432  fprintf(stderr, "Experiment timeout!\n");
433 
434  if (NULL != e->episode_timeout_task)
435  {
437  e->episode_timeout_task = NULL;
438  }
439 
441  GNUNET_SYSERR);
442 }
GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb
static struct Experiment * e
struct GNUNET_SCHEDULER_Task * experiment_timeout_task
struct GNUNET_SCHEDULER_Task * episode_timeout_task
struct GNUNET_TIME_Absolute start_time
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:373
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
Here is the call graph for this function:
Here is the caller graph for this function:

◆ enforce_start_send()

static void enforce_start_send ( struct GNUNET_ATS_TEST_Operation op)
static

Definition at line 446 of file ats-testing-experiment.c.

References GNUNET_ATS_TEST_Operation::base_rate, GNUNET_ATS_TEST_Operation::dest_id, GNUNET_ATS_TEST_Operation::gen_type, GNUNET_ATS_TEST_generate_traffic_start(), GNUNET_ATS_TEST_generate_traffic_stop(), GNUNET_ATS_TEST_get_partner(), GNUNET_ATS_TEST_get_peer(), GNUNET_break, GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_ATS_TEST_Operation::max_rate, peer, GNUNET_ATS_TEST_Operation::period, GNUNET_ATS_TEST_Operation::src_id, and BenchmarkPartner::tg.

Referenced by enforce_episode().

447 {
448  struct BenchmarkPeer *peer;
449  struct BenchmarkPartner *partner;
450 
451  peer = GNUNET_ATS_TEST_get_peer(op->src_id);
452  if (NULL == peer)
453  {
454  GNUNET_break(0);
455  return;
456  }
457 
458  partner = GNUNET_ATS_TEST_get_partner(op->src_id, op->dest_id);
459  if (NULL == partner)
460  {
461  GNUNET_break(0);
462  return;
463  }
464 
465  fprintf(stderr, "Found master %llu slave %llu\n", op->src_id, op->dest_id);
466 
467  if (NULL != partner->tg)
468  {
469  fprintf(stderr, "Stopping traffic between master %llu slave %llu\n", op->src_id, op->dest_id);
471  partner->tg = NULL;
472  }
473 
474  partner->tg = GNUNET_ATS_TEST_generate_traffic_start(peer, partner,
475  op->gen_type, op->base_rate, op->max_rate, op->period,
477 }
long long unsigned int src_id
Definition: ats-testing.h:487
struct GNUNET_TIME_Relative period
struct TrafficGenerator * GNUNET_ATS_TEST_generate_traffic_start(struct BenchmarkPeer *src, struct BenchmarkPartner *dest, enum GeneratorType type, unsigned int base_rate, unsigned int max_rate, struct GNUNET_TIME_Relative period, struct GNUNET_TIME_Relative duration)
Generate between the source master and the partner and send traffic with a maximum rate...
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct TrafficGenerator * tg
Handle for traffic generator.
Definition: ats-testing.h:289
Information we track for a peer in the testbed.
Definition: ats-testing.h:109
long long unsigned int dest_id
Definition: ats-testing.h:488
long long unsigned int base_rate
Information about a benchmarking partner.
Definition: ats-testing.h:270
#define GNUNET_TIME_UNIT_FOREVER_REL
Constant used to specify "forever".
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
struct BenchmarkPartner * GNUNET_ATS_TEST_get_partner(int src, int dest)
Definition: ats-testing.c:902
struct BenchmarkPeer * GNUNET_ATS_TEST_get_peer(int src)
Topology related functions.
Definition: ats-testing.c:893
void GNUNET_ATS_TEST_generate_traffic_stop(struct TrafficGenerator *tg)
long long unsigned int max_rate
Here is the call graph for this function:
Here is the caller graph for this function:

◆ enforce_stop_send()

static void enforce_stop_send ( struct GNUNET_ATS_TEST_Operation op)
static

Definition at line 480 of file ats-testing-experiment.c.

References GNUNET_ATS_TEST_Operation::dest_id, GNUNET_ATS_TEST_generate_traffic_stop(), GNUNET_ATS_TEST_get_partner(), GNUNET_break, p, GNUNET_ATS_TEST_Operation::src_id, and BenchmarkPartner::tg.

Referenced by enforce_episode().

481 {
482  struct BenchmarkPartner *p;
483 
485  if (NULL == p)
486  {
487  GNUNET_break(0);
488  return;
489  }
490 
491  fprintf(stderr, "Found master %llu slave %llu\n", op->src_id, op->dest_id);
492 
493  if (NULL != p->tg)
494  {
495  fprintf(stderr, "Stopping traffic between master %llu slave %llu\n",
496  op->src_id, op->dest_id);
498  p->tg = NULL;
499  }
500 }
long long unsigned int src_id
Definition: ats-testing.h:487
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
struct TrafficGenerator * tg
Handle for traffic generator.
Definition: ats-testing.h:289
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
long long unsigned int dest_id
Definition: ats-testing.h:488
Information about a benchmarking partner.
Definition: ats-testing.h:270
struct BenchmarkPartner * GNUNET_ATS_TEST_get_partner(int src, int dest)
Definition: ats-testing.c:902
void GNUNET_ATS_TEST_generate_traffic_stop(struct TrafficGenerator *tg)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ enforce_start_preference()

static void enforce_start_preference ( struct GNUNET_ATS_TEST_Operation op)
static

Definition at line 504 of file ats-testing-experiment.c.

References GNUNET_ATS_TEST_Operation::base_rate, GNUNET_ATS_TEST_Operation::dest_id, GNUNET_ATS_TEST_Operation::frequency, GNUNET_ATS_TEST_Operation::gen_type, GNUNET_ATS_TEST_generate_preferences_start(), GNUNET_ATS_TEST_generate_preferences_stop(), GNUNET_ATS_TEST_get_partner(), GNUNET_ATS_TEST_get_peer(), GNUNET_break, GNUNET_ATS_TEST_Operation::max_rate, peer, GNUNET_ATS_TEST_Operation::period, BenchmarkPartner::pg, GNUNET_ATS_TEST_Operation::pref_type, and GNUNET_ATS_TEST_Operation::src_id.

Referenced by enforce_episode().

505 {
506  struct BenchmarkPeer *peer;
507  struct BenchmarkPartner *partner;
508 
509  peer = GNUNET_ATS_TEST_get_peer(op->src_id);
510  if (NULL == peer)
511  {
512  GNUNET_break(0);
513  return;
514  }
515 
516  partner = GNUNET_ATS_TEST_get_partner(op->src_id, op->dest_id);
517  if (NULL == partner)
518  {
519  GNUNET_break(0);
520  return;
521  }
522 
523  fprintf(stderr, "Found master %llu slave %llu\n", op->src_id, op->dest_id);
524 
525  if (NULL != partner->pg)
526  {
527  fprintf(stderr, "Stopping traffic between master %llu slave %llu\n",
528  op->src_id, op->dest_id);
530  partner->pg = NULL;
531  }
532 
533  partner->pg = GNUNET_ATS_TEST_generate_preferences_start(peer, partner,
534  op->gen_type, op->base_rate, op->max_rate, op->period, op->frequency,
535  op->pref_type);
536 }
struct PreferenceGenerator * pg
Handle for preference generator.
Definition: ats-testing.h:294
long long unsigned int src_id
Definition: ats-testing.h:487
struct GNUNET_TIME_Relative period
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
Information we track for a peer in the testbed.
Definition: ats-testing.h:109
long long unsigned int dest_id
Definition: ats-testing.h:488
long long unsigned int base_rate
Information about a benchmarking partner.
Definition: ats-testing.h:270
enum GNUNET_ATS_PreferenceKind pref_type
struct PreferenceGenerator * GNUNET_ATS_TEST_generate_preferences_start(struct BenchmarkPeer *src, struct BenchmarkPartner *dest, enum GeneratorType type, unsigned int base_value, unsigned int value_rate, struct GNUNET_TIME_Relative period, struct GNUNET_TIME_Relative frequency, enum GNUNET_ATS_PreferenceKind kind)
Generate between the source master and the partner and set preferences with a value depending on the ...
void GNUNET_ATS_TEST_generate_preferences_stop(struct PreferenceGenerator *pg)
struct GNUNET_TESTBED_Peer * peer
The peer associated with this model.
struct BenchmarkPartner * GNUNET_ATS_TEST_get_partner(int src, int dest)
Definition: ats-testing.c:902
struct BenchmarkPeer * GNUNET_ATS_TEST_get_peer(int src)
Topology related functions.
Definition: ats-testing.c:893
struct GNUNET_TIME_Relative frequency
long long unsigned int max_rate
Here is the call graph for this function:
Here is the caller graph for this function:

◆ enforce_stop_preference()

static void enforce_stop_preference ( struct GNUNET_ATS_TEST_Operation op)
static

Definition at line 539 of file ats-testing-experiment.c.

References GNUNET_ATS_TEST_Operation::dest_id, GNUNET_ATS_TEST_generate_preferences_stop(), GNUNET_ATS_TEST_get_partner(), GNUNET_break, p, BenchmarkPartner::pg, and GNUNET_ATS_TEST_Operation::src_id.

Referenced by enforce_episode().

540 {
541  struct BenchmarkPartner *p;
542 
544  if (NULL == p)
545  {
546  GNUNET_break(0);
547  return;
548  }
549 
550  fprintf(stderr, "Found master %llu slave %llu\n", op->src_id, op->dest_id);
551 
552  if (NULL != p->pg)
553  {
554  fprintf(stderr, "Stopping preference between master %llu slave %llu\n",
555  op->src_id, op->dest_id);
557  p->pg = NULL;
558  }
559 }
struct PreferenceGenerator * pg
Handle for preference generator.
Definition: ats-testing.h:294
long long unsigned int src_id
Definition: ats-testing.h:487
#define GNUNET_break(cond)
Use this for internal assertion violations that are not fatal (can be handled) but should not occur...
static struct GNUNET_OS_Process * p
Helper process we started.
Definition: gnunet-qr.c:59
long long unsigned int dest_id
Definition: ats-testing.h:488
Information about a benchmarking partner.
Definition: ats-testing.h:270
void GNUNET_ATS_TEST_generate_preferences_stop(struct PreferenceGenerator *pg)
struct BenchmarkPartner * GNUNET_ATS_TEST_get_partner(int src, int dest)
Definition: ats-testing.c:902
Here is the call graph for this function:
Here is the caller graph for this function:

◆ enforce_episode()

static void enforce_episode ( struct Episode ep)
static

Definition at line 561 of file ats-testing-experiment.c.

References GNUNET_ATS_TEST_Operation::base_rate, GNUNET_ATS_TEST_Operation::dest_id, enforce_start_preference(), enforce_start_send(), enforce_stop_preference(), enforce_stop_send(), Episode::head, GNUNET_ATS_TEST_Operation::next, print_op(), GNUNET_ATS_TEST_Operation::src_id, START_PREFERENCE, START_SEND, STOP_PREFERENCE, STOP_SEND, and GNUNET_ATS_TEST_Operation::type.

Referenced by GNUNET_ATS_TEST_experimentation_run(), and timeout_episode().

562 {
563  struct GNUNET_ATS_TEST_Operation *cur;
564 
565  for (cur = ep->head; NULL != cur; cur = cur->next)
566  {
567  fprintf(stderr, "Enforcing operation: %s [%llu]->[%llu] == %llu\n",
568  print_op(cur->type), cur->src_id, cur->dest_id, cur->base_rate);
569  switch (cur->type)
570  {
571  case START_SEND:
572  enforce_start_send(cur);
573  break;
574 
575  case STOP_SEND:
576  enforce_stop_send(cur);
577  break;
578 
579  case START_PREFERENCE:
581  break;
582 
583  case STOP_PREFERENCE:
585  break;
586 
587  default:
588  break;
589  }
590  }
591 }
struct GNUNET_ATS_TEST_Operation * next
long long unsigned int src_id
Definition: ats-testing.h:487
static void enforce_stop_send(struct GNUNET_ATS_TEST_Operation *op)
const char * print_op(enum OperationType op)
long long unsigned int dest_id
Definition: ats-testing.h:488
long long unsigned int base_rate
static void enforce_start_preference(struct GNUNET_ATS_TEST_Operation *op)
An operation in an experiment.
struct GNUNET_ATS_TEST_Operation * head
static void enforce_stop_preference(struct GNUNET_ATS_TEST_Operation *op)
static void enforce_start_send(struct GNUNET_ATS_TEST_Operation *op)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ timeout_episode()

static void timeout_episode ( void *  cls)
static

Definition at line 595 of file ats-testing-experiment.c.

References Experiment::cur, Episode::duration, e, Experiment::e_done_cb, enforce_episode(), Experiment::ep_done_cb, Experiment::episode_timeout_task, Experiment::experiment_timeout_task, GNUNET_OK, GNUNET_SCHEDULER_add_delayed(), GNUNET_SCHEDULER_cancel(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get_duration(), GNUNET_YES, Episode::id, Episode::next, and Experiment::start_time.

Referenced by GNUNET_ATS_TEST_experimentation_run().

596 {
597  struct Experiment *e = cls;
598 
599  e->episode_timeout_task = NULL;
600  if (NULL != e->ep_done_cb)
601  e->ep_done_cb(e->cur);
602 
603  /* Scheduling next */
604  e->cur = e->cur->next;
605  if (NULL == e->cur)
606  {
607  /* done */
608  fprintf(stderr, "Last episode done!\n");
609  if (NULL != e->experiment_timeout_task)
610  {
612  e->experiment_timeout_task = NULL;
613  }
615  return;
616  }
617 
618  fprintf(stderr, "Running episode %u with timeout %s\n",
619  e->cur->id,
621  enforce_episode(e->cur);
622 
624  &timeout_episode, e);
625 }
GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb
GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb
struct Episode * next
static struct Experiment * e
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
struct GNUNET_SCHEDULER_Task * experiment_timeout_task
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1237
struct Episode * cur
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:686
struct GNUNET_SCHEDULER_Task * episode_timeout_task
struct GNUNET_TIME_Relative duration
struct GNUNET_TIME_Absolute start_time
static void enforce_episode(struct Episode *ep)
struct GNUNET_TIME_Relative GNUNET_TIME_absolute_get_duration(struct GNUNET_TIME_Absolute whence)
Get the duration of an operation as the difference of the current time and the given start time "henc...
Definition: time.c:373
static void timeout_episode(void *cls)
#define GNUNET_YES
Definition: gnunet_common.h:77
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_ATS_TEST_experimentation_run()

void GNUNET_ATS_TEST_experimentation_run ( struct Experiment e,
GNUNET_ATS_TESTING_EpisodeDoneCallback  ep_done_cb,
GNUNET_ATS_TESTING_ExperimentDoneCallback  e_done_cb 
)

Execute the specified experiment.

Parameters
ethe Experiment
ep_done_cba episode is completed
e_done_cbthe experiment is completed

Definition at line 629 of file ats-testing-experiment.c.

References Experiment::cur, Episode::duration, Experiment::e_done_cb, enforce_episode(), Experiment::ep_done_cb, Experiment::episode_timeout_task, Experiment::experiment_timeout_task, GNUNET_SCHEDULER_add_delayed(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_TIME_absolute_get(), GNUNET_YES, Episode::id, Experiment::max_duration, Experiment::name, Experiment::start, Experiment::start_time, timeout_episode(), and timeout_experiment().

Referenced by topology_setup_done().

632 {
633  fprintf(stderr, "Running experiment `%s' with timeout %s\n", e->name,
635  e->e_done_cb = e_done_cb;
636  e->ep_done_cb = ep_done_cb;
638 
639  /* Start total time out */
641  &timeout_experiment, e);
642 
643  /* Start */
644  e->cur = e->start;
645  fprintf(stderr, "Running episode %u with timeout %s\n",
646  e->cur->id,
648  enforce_episode(e->cur);
650  &timeout_episode, e);
651 }
struct Episode * start
GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb
GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb
static void timeout_experiment(void *cls)
struct GNUNET_SCHEDULER_Task * experiment_timeout_task
struct GNUNET_SCHEDULER_Task * GNUNET_SCHEDULER_add_delayed(struct GNUNET_TIME_Relative delay, GNUNET_SCHEDULER_TaskCallback task, void *task_cls)
Schedule a new task to be run with a specified delay.
Definition: scheduler.c:1237
struct Episode * cur
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:686
struct GNUNET_SCHEDULER_Task * episode_timeout_task
struct GNUNET_TIME_Absolute GNUNET_TIME_absolute_get(void)
Get the current time.
Definition: time.c:118
struct GNUNET_TIME_Relative duration
struct GNUNET_TIME_Absolute start_time
static void enforce_episode(struct Episode *ep)
static void timeout_episode(void *cls)
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_TIME_Relative max_duration
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_ATS_TEST_experimentation_load()

struct Experiment* GNUNET_ATS_TEST_experimentation_load ( const char *  filename)

Load an experiment from a file.

Parameters
filenamethe file
Returns
the Experiment or NULL on failure

Definition at line 655 of file ats-testing-experiment.c.

References cfg, Experiment::cfg_file, create_experiment(), e, free_experiment(), GNUNET_CONFIGURATION_create(), GNUNET_CONFIGURATION_destroy(), GNUNET_CONFIGURATION_get_value_filename(), GNUNET_CONFIGURATION_get_value_number(), GNUNET_CONFIGURATION_get_value_string(), GNUNET_CONFIGURATION_get_value_time(), GNUNET_CONFIGURATION_load(), GNUNET_STRINGS_relative_time_to_string(), GNUNET_SYSERR, GNUNET_YES, load_episodes(), Experiment::log_freq, Experiment::max_duration, Experiment::name, Experiment::num_episodes, Experiment::num_masters, Experiment::num_slaves, and Experiment::total_duration.

Referenced by main().

656 {
657  struct Experiment *e;
659 
660  e = NULL;
661 
664  {
665  fprintf(stderr, "Failed to load `%s'\n", filename);
667  return NULL;
668  }
669 
670  e = create_experiment();
671 
672  if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_string(cfg, "experiment",
673  "name", &e->name))
674  {
675  fprintf(stderr, "Invalid %s", "name");
676  free_experiment(e);
677  return NULL;
678  }
679  else
680  fprintf(stderr, "Experiment name: `%s'\n", e->name);
681 
683  "cfg_file", &e->cfg_file))
684  {
685  fprintf(stderr, "Invalid %s", "cfg_file");
686  free_experiment(e);
687  return NULL;
688  }
689  else
690  fprintf(stderr, "Experiment name: `%s'\n", e->cfg_file);
691 
692  if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg, "experiment",
693  "masters", &e->num_masters))
694  {
695  fprintf(stderr, "Invalid %s", "masters");
696  free_experiment(e);
697  return NULL;
698  }
699  else
700  fprintf(stderr, "Experiment masters: `%llu'\n",
701  e->num_masters);
702 
703  if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg, "experiment",
704  "slaves", &e->num_slaves))
705  {
706  fprintf(stderr, "Invalid %s", "slaves");
707  free_experiment(e);
708  return NULL;
709  }
710  else
711  fprintf(stderr, "Experiment slaves: `%llu'\n",
712  e->num_slaves);
713 
714  if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
715  "log_freq", &e->log_freq))
716  {
717  fprintf(stderr, "Invalid %s", "log_freq");
718  free_experiment(e);
719  return NULL;
720  }
721  else
722  fprintf(stderr, "Experiment logging frequency: `%s'\n",
724 
725  if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment",
726  "max_duration", &e->max_duration))
727  {
728  fprintf(stderr, "Invalid %s", "max_duration");
729  free_experiment(e);
730  return NULL;
731  }
732  else
733  fprintf(stderr, "Experiment duration: `%s'\n",
735 
736  load_episodes(e, cfg);
737  fprintf(stderr, "Loaded %u episodes with total duration %s\n",
738  e->num_episodes,
740 
742  return e;
743 }
static struct Experiment * create_experiment()
int GNUNET_CONFIGURATION_get_value_time(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, struct GNUNET_TIME_Relative *time)
Get a configuration value that should be a relative time.
int GNUNET_CONFIGURATION_get_value_number(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, unsigned long long *number)
Get a configuration value that should be a number.
unsigned long long int num_masters
Definition: ats-testing.h:513
struct GNUNET_TIME_Relative total_duration
static struct Experiment * e
unsigned int num_episodes
struct GNUNET_CONFIGURATION_Handle * GNUNET_CONFIGURATION_create(void)
Create a new configuration object.
static int load_episodes(struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg)
static void free_experiment(struct Experiment *e)
int GNUNET_CONFIGURATION_load(struct GNUNET_CONFIGURATION_Handle *cfg, const char *filename)
Load configuration.
struct GNUNET_TIME_Relative log_freq
const char * GNUNET_STRINGS_relative_time_to_string(struct GNUNET_TIME_Relative delta, int do_round)
Give relative time in human-readable fancy format.
Definition: strings.c:686
void GNUNET_CONFIGURATION_destroy(struct GNUNET_CONFIGURATION_Handle *cfg)
Destroy configuration object.
unsigned long long int num_slaves
Definition: ats-testing.h:514
static char * filename
int GNUNET_CONFIGURATION_get_value_string(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be a string.
static struct GNUNET_CONFIGURATION_Handle * cfg
Our configuration.
Definition: gnunet-arm.c:104
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
configuration data
Definition: configuration.c:83
int GNUNET_CONFIGURATION_get_value_filename(const struct GNUNET_CONFIGURATION_Handle *cfg, const char *section, const char *option, char **value)
Get a configuration value that should be the name of a file or directory.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_TIME_Relative max_duration
Here is the call graph for this function:
Here is the caller graph for this function:

◆ GNUNET_ATS_TEST_experimentation_stop()

void GNUNET_ATS_TEST_experimentation_stop ( struct Experiment e)

Stop an experiment.

Parameters
ethe experiment

Definition at line 746 of file ats-testing-experiment.c.

References Experiment::episode_timeout_task, Experiment::experiment_timeout_task, free_experiment(), and GNUNET_SCHEDULER_cancel().

Referenced by do_shutdown().

747 {
748  if (NULL != e->experiment_timeout_task)
749  {
751  e->experiment_timeout_task = NULL;
752  }
753  if (NULL != e->episode_timeout_task)
754  {
756  e->episode_timeout_task = NULL;
757  }
758  free_experiment(e);
759 }
static void free_experiment(struct Experiment *e)
struct GNUNET_SCHEDULER_Task * experiment_timeout_task
struct GNUNET_SCHEDULER_Task * episode_timeout_task
void * GNUNET_SCHEDULER_cancel(struct GNUNET_SCHEDULER_Task *task)
Cancel the task with the specified identifier.
Definition: scheduler.c:956
Here is the call graph for this function:
Here is the caller graph for this function: