2 This file is part of GNUnet
3 Copyright (C) 2008--2013 GNUnet e.V.
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.
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.
17 * @file testbed/test_testbed_api_operations.c
18 * @brief tests cases for testbed_api_operations.c
19 * @author Sree Harsha Totakura
23 #include "gnunet_util_lib.h"
24 #include "testbed_api_operations.h"
27 * Generic logging shortcut
29 #define LOG(kind,...) \
30 GNUNET_log (kind, __VA_ARGS__)
33 * Delay to start step task
36 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 500)
39 * Queue A. Initially the max active is set to 2 and then reduced to 0 - this
40 * should block op2 even after op1 has finished. Later the max active is set to
41 * 2 and this should start op2
43 struct OperationQueue *q1;
46 * Queue B. Max active set to 2 is not changed throughout the test
48 struct OperationQueue *q2;
51 * This operation should go into both queues and block op2 until it is done
53 struct GNUNET_TESTBED_Operation *op1;
56 * This operation should go into q1 and q2
58 struct GNUNET_TESTBED_Operation *op2;
61 * This operation should go into both queues and should consume 2 units of
62 * resources on both queues. Since op2 needs a resource from both queues and is
63 * queues before this operation, it will be blocked until op2 is released even
64 * though q1 has enough free resources
66 struct GNUNET_TESTBED_Operation *op3;
69 * Just like op3, this operation also consumes 2 units of resources on both
70 * queues. Since this is queued after op3 and both queues are at max active
71 * 2. This will be blocked until op3 is done.
73 struct GNUNET_TESTBED_Operation *op4;
76 * This operation is started after op4 is released and should consume only 1
77 * resource on queue q1. It should be started along with op6 and op7
79 struct GNUNET_TESTBED_Operation *op5;
82 * This operation is started after op4 is released and should consume only 1
83 * resource on q2. It should be started along with op5 and op7
85 struct GNUNET_TESTBED_Operation *op6;
88 * This operation is started after op4 is released and should consume 1 resource
89 * on both queues q1 and q1. It should be started along with op5 and op6. It is
90 * then inactivated when op6 is released. op8's start should release this
91 * operation implicitly.
93 struct GNUNET_TESTBED_Operation *op7;
96 * This operation is started after op6 is finished in step task. It consumes 2
97 * resources on both queues q1 and q2. This operation should evict op7. After
98 * starting, it should be made inactive, active and inactive again in the step task.
100 struct GNUNET_TESTBED_Operation *op8;
103 * This opration is started after activating op8. It should consume a resource
104 * on queues q1 and q2. It should not be started until op8 is again made
105 * inactive at which point it should be released. It can be released as soon as
108 struct GNUNET_TESTBED_Operation *op9;
111 * The delay task identifier
113 struct GNUNET_SCHEDULER_Task * step_task;
117 * Enumeration of test stages
127 * op1 has been started
132 * op1 has been released
137 * Temporary pause where no operations should start as we set max active in q1
138 * to 0 in stage TEST_OP1_STARTED
173 * op5, op6, op7 started
175 TEST_OP5_6_7_STARTED,
188 * op8 has began waiting
213 * op8 has been released
223 * op9 has been released
235 * Function to call to start an operation once all
236 * queues the operation is part of declare that the
237 * operation can be activated.
240 start_cb (void *cls);
244 * Function to cancel an operation (release all associated resources). This can
245 * be because of a call to "GNUNET_TESTBED_operation_cancel" (before the
246 * operation generated an event) or AFTER the operation generated an event due
247 * to a call to "GNUNET_TESTBED_operation_done". Thus it is not guaranteed that
248 * a callback to the 'OperationStart' preceeds the call to 'OperationRelease'.
249 * Implementations of this function are expected to clean up whatever state is
250 * in 'cls' and release all resources associated with the operation.
253 release_cb (void *cls);
257 * Task to simulate artificial delay and change the test stage
264 GNUNET_assert (NULL != step_task);
268 case TEST_OP1_STARTED:
269 GNUNET_TESTBED_operation_release_ (op1);
270 GNUNET_TESTBED_operation_queue_reset_max_active_ (q1, 0);
271 op3 = GNUNET_TESTBED_operation_create_ (&op3, &start_cb, &release_cb);
272 GNUNET_TESTBED_operation_queue_insert2_ (q1, op3, 2);
273 GNUNET_TESTBED_operation_queue_insert2_ (q2, op3, 2);
274 GNUNET_TESTBED_operation_begin_wait_ (op3);
275 op4 = GNUNET_TESTBED_operation_create_ (&op4, &start_cb, &release_cb);
276 GNUNET_TESTBED_operation_queue_insert2_ (q1, op4, 2);
277 GNUNET_TESTBED_operation_queue_insert2_ (q2, op4, 2);
278 GNUNET_TESTBED_operation_begin_wait_ (op4);
280 case TEST_OP1_RELEASED:
282 GNUNET_TESTBED_operation_queue_reset_max_active_ (q1, 2);
284 case TEST_OP2_STARTED:
285 GNUNET_TESTBED_operation_release_ (op2);
287 case TEST_OP3_STARTED:
288 GNUNET_TESTBED_operation_release_ (op3);
290 case TEST_OP4_STARTED:
291 GNUNET_TESTBED_operation_release_ (op4);
293 case TEST_OP6_RELEASED:
294 op8 = GNUNET_TESTBED_operation_create_ (&op8, &start_cb, &release_cb);
295 GNUNET_TESTBED_operation_queue_insert2_ (q1, op8, 2);
296 GNUNET_TESTBED_operation_queue_insert2_ (q2, op8, 2);
297 result = TEST_OP8_WAITING;
298 GNUNET_TESTBED_operation_begin_wait_ (op8);
300 case TEST_OP8_STARTED:
301 GNUNET_TESTBED_operation_inactivate_ (op8);
302 result = TEST_OP8_INACTIVE_1;
303 step_task = GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
305 case TEST_OP8_INACTIVE_1:
306 GNUNET_TESTBED_operation_activate_ (op8);
307 result = TEST_OP8_ACTIVE;
308 op9 = GNUNET_TESTBED_operation_create_ (&op9, &start_cb, &release_cb);
309 GNUNET_TESTBED_operation_queue_insert2_ (q1, op9, 1);
310 GNUNET_TESTBED_operation_queue_insert2_ (q2, op9, 1);
311 GNUNET_TESTBED_operation_begin_wait_ (op9);
312 step_task = GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
314 case TEST_OP8_ACTIVE:
315 GNUNET_TESTBED_operation_inactivate_ (op8);
316 /* op8 should be released by now due to above call */
317 GNUNET_assert (TEST_OP8_RELEASED == result);
319 case TEST_OP9_STARTED:
320 GNUNET_TESTBED_operation_release_ (op9);
329 * Function to call to start an operation once all
330 * queues the operation is part of declare that the
331 * operation can be activated.
339 GNUNET_assert (&op1 == cls);
340 result = TEST_OP1_STARTED;
341 GNUNET_assert (NULL == step_task);
343 GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
346 GNUNET_assert (&op2 == cls);
347 result = TEST_OP2_STARTED;
348 GNUNET_assert (NULL == step_task);
350 GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
352 case TEST_OP2_RELEASED:
353 GNUNET_assert (&op3 == cls);
354 result = TEST_OP3_STARTED;
355 GNUNET_assert (NULL == step_task);
357 GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
359 case TEST_OP3_RELEASED:
360 GNUNET_assert (&op4 == cls);
361 result = TEST_OP4_STARTED;
362 GNUNET_assert (NULL == step_task);
364 GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
366 case TEST_OP4_RELEASED:
373 result = TEST_OP5_6_7_STARTED;
374 GNUNET_TESTBED_operation_release_ (op5);
379 case TEST_OP7_RELEASED:
380 GNUNET_assert (&op8 == cls);
381 result = TEST_OP8_STARTED;
382 step_task = GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
384 case TEST_OP8_RELEASED:
385 GNUNET_assert (&op9 == cls);
386 result = TEST_OP9_STARTED;
387 step_task = GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
396 * Function to cancel an operation (release all associated resources). This can
397 * be because of a call to "GNUNET_TESTBED_operation_cancel" (before the
398 * operation generated an event) or AFTER the operation generated an event due
399 * to a call to "GNUNET_TESTBED_operation_done". Thus it is not guaranteed that
400 * a callback to the 'OperationStart' preceeds the call to 'OperationRelease'.
401 * Implementations of this function are expected to clean up whatever state is
402 * in 'cls' and release all resources associated with the operation.
405 release_cb (void *cls)
409 case TEST_OP1_STARTED:
410 GNUNET_assert (&op1 == cls);
411 result = TEST_OP1_RELEASED;
414 GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
416 case TEST_OP2_STARTED:
417 GNUNET_assert (&op2 == cls);
418 result = TEST_OP2_RELEASED;
419 GNUNET_assert (NULL == step_task);
421 case TEST_OP3_STARTED:
422 GNUNET_assert (&op3 == cls);
423 result = TEST_OP3_RELEASED;
424 GNUNET_assert (NULL == step_task);
426 case TEST_OP4_STARTED:
427 GNUNET_assert (&op4 == cls);
428 result = TEST_OP4_RELEASED;
429 GNUNET_assert (NULL == step_task);
430 op5 = GNUNET_TESTBED_operation_create_ (&op5, &start_cb, &release_cb);
431 GNUNET_TESTBED_operation_queue_insert2_ (q1, op5, 1);
432 GNUNET_TESTBED_operation_begin_wait_ (op5);
433 op6 = GNUNET_TESTBED_operation_create_ (&op6, &start_cb, &release_cb);
434 GNUNET_TESTBED_operation_queue_insert2_ (q2, op6, 1);
435 GNUNET_TESTBED_operation_begin_wait_ (op6);
436 op7 = GNUNET_TESTBED_operation_create_ (&op7, &start_cb, &release_cb);
437 GNUNET_TESTBED_operation_queue_insert2_ (q1, op7, 1);
438 GNUNET_TESTBED_operation_queue_insert2_ (q2, op7, 1);
439 GNUNET_TESTBED_operation_begin_wait_ (op7);
441 case TEST_OP5_6_7_STARTED:
442 result = TEST_OP5_RELEASED;
444 GNUNET_TESTBED_operation_release_ (op6);
446 case TEST_OP5_RELEASED:
448 result = TEST_OP6_RELEASED;
449 GNUNET_TESTBED_operation_inactivate_ (op7);
450 step_task = GNUNET_SCHEDULER_add_now (&step, NULL);
452 case TEST_OP8_WAITING:
453 GNUNET_assert (&op7 == cls);
455 result = TEST_OP7_RELEASED;
457 case TEST_OP8_ACTIVE:
458 result = TEST_OP8_RELEASED;
461 case TEST_OP9_STARTED:
462 GNUNET_assert (&op9 == cls);
463 result = TEST_OP9_RELEASED;
464 GNUNET_TESTBED_operation_queue_destroy_ (q1);
465 GNUNET_TESTBED_operation_queue_destroy_ (q2);
479 * @param args arguments passed to GNUNET_PROGRAM_run
480 * @param cfgfile the path to configuration file
481 * @param cfg the configuration file handle
484 run (void *cls, char *const *args, const char *cfgfile,
485 const struct GNUNET_CONFIGURATION_Handle *config)
487 q1 = GNUNET_TESTBED_operation_queue_create_ (OPERATION_QUEUE_TYPE_FIXED, 1);
488 GNUNET_assert (NULL != q1);
489 q2 = GNUNET_TESTBED_operation_queue_create_ (OPERATION_QUEUE_TYPE_FIXED, 2);
490 GNUNET_assert (NULL != q2);
491 op1 = GNUNET_TESTBED_operation_create_ (&op1, start_cb, release_cb);
492 GNUNET_assert (NULL != op1);
493 op2 = GNUNET_TESTBED_operation_create_ (&op2, start_cb, release_cb);
494 GNUNET_TESTBED_operation_queue_insert_ (q1, op1);
495 GNUNET_TESTBED_operation_queue_insert_ (q2, op1);
496 GNUNET_TESTBED_operation_begin_wait_ (op1);
497 GNUNET_TESTBED_operation_queue_insert_ (q1, op2);
498 GNUNET_TESTBED_operation_queue_insert_ (q2, op2);
499 GNUNET_TESTBED_operation_begin_wait_ (op2);
508 main (int argc, char **argv)
511 char *const argv2[] =
512 { "test_testbed_api_operations", "-c", "test_testbed_api.conf", NULL };
513 struct GNUNET_GETOPT_CommandLineOption options[] =
514 { GNUNET_GETOPT_OPTION_END };
517 GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
518 "test_testbed_api_operations", "nohelp", options,
520 if ((GNUNET_OK != ret) || (TEST_OP9_RELEASED != result))
536 /* end of test_testbed_api_operations.c */