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.
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * @file testbed/test_testbed_api_operations.c
21 * @brief tests cases for testbed_api_operations.c
22 * @author Sree Harsha Totakura
26 #include "gnunet_util_lib.h"
27 #include "testbed_api_operations.h"
30 * Generic logging shortcut
32 #define LOG(kind,...) \
33 GNUNET_log (kind, __VA_ARGS__)
36 * Delay to start step task
39 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 500)
42 * Queue A. Initially the max active is set to 2 and then reduced to 0 - this
43 * should block op2 even after op1 has finished. Later the max active is set to
44 * 2 and this should start op2
46 struct OperationQueue *q1;
49 * Queue B. Max active set to 2 is not changed throughout the test
51 struct OperationQueue *q2;
54 * This operation should go into both queues and block op2 until it is done
56 struct GNUNET_TESTBED_Operation *op1;
59 * This operation should go into q1 and q2
61 struct GNUNET_TESTBED_Operation *op2;
64 * This operation should go into both queues and should consume 2 units of
65 * resources on both queues. Since op2 needs a resource from both queues and is
66 * queues before this operation, it will be blocked until op2 is released even
67 * though q1 has enough free resources
69 struct GNUNET_TESTBED_Operation *op3;
72 * Just like op3, this operation also consumes 2 units of resources on both
73 * queues. Since this is queued after op3 and both queues are at max active
74 * 2. This will be blocked until op3 is done.
76 struct GNUNET_TESTBED_Operation *op4;
79 * This operation is started after op4 is released and should consume only 1
80 * resource on queue q1. It should be started along with op6 and op7
82 struct GNUNET_TESTBED_Operation *op5;
85 * This operation is started after op4 is released and should consume only 1
86 * resource on q2. It should be started along with op5 and op7
88 struct GNUNET_TESTBED_Operation *op6;
91 * This operation is started after op4 is released and should consume 1 resource
92 * on both queues q1 and q1. It should be started along with op5 and op6. It is
93 * then inactivated when op6 is released. op8's start should release this
94 * operation implicitly.
96 struct GNUNET_TESTBED_Operation *op7;
99 * This operation is started after op6 is finished in step task. It consumes 2
100 * resources on both queues q1 and q2. This operation should evict op7. After
101 * starting, it should be made inactive, active and inactive again in the step task.
103 struct GNUNET_TESTBED_Operation *op8;
106 * This opration is started after activating op8. It should consume a resource
107 * on queues q1 and q2. It should not be started until op8 is again made
108 * inactive at which point it should be released. It can be released as soon as
111 struct GNUNET_TESTBED_Operation *op9;
114 * The delay task identifier
116 struct GNUNET_SCHEDULER_Task * step_task;
120 * Enumeration of test stages
130 * op1 has been started
135 * op1 has been released
140 * Temporary pause where no operations should start as we set max active in q1
141 * to 0 in stage TEST_OP1_STARTED
176 * op5, op6, op7 started
178 TEST_OP5_6_7_STARTED,
191 * op8 has began waiting
216 * op8 has been released
226 * op9 has been released
238 * Function to call to start an operation once all
239 * queues the operation is part of declare that the
240 * operation can be activated.
243 start_cb (void *cls);
247 * Function to cancel an operation (release all associated resources). This can
248 * be because of a call to "GNUNET_TESTBED_operation_cancel" (before the
249 * operation generated an event) or AFTER the operation generated an event due
250 * to a call to "GNUNET_TESTBED_operation_done". Thus it is not guaranteed that
251 * a callback to the 'OperationStart' preceeds the call to 'OperationRelease'.
252 * Implementations of this function are expected to clean up whatever state is
253 * in 'cls' and release all resources associated with the operation.
256 release_cb (void *cls);
260 * Task to simulate artificial delay and change the test stage
267 GNUNET_assert (NULL != step_task);
271 case TEST_OP1_STARTED:
272 GNUNET_TESTBED_operation_release_ (op1);
273 GNUNET_TESTBED_operation_queue_reset_max_active_ (q1, 0);
274 op3 = GNUNET_TESTBED_operation_create_ (&op3, &start_cb, &release_cb);
275 GNUNET_TESTBED_operation_queue_insert2_ (q1, op3, 2);
276 GNUNET_TESTBED_operation_queue_insert2_ (q2, op3, 2);
277 GNUNET_TESTBED_operation_begin_wait_ (op3);
278 op4 = GNUNET_TESTBED_operation_create_ (&op4, &start_cb, &release_cb);
279 GNUNET_TESTBED_operation_queue_insert2_ (q1, op4, 2);
280 GNUNET_TESTBED_operation_queue_insert2_ (q2, op4, 2);
281 GNUNET_TESTBED_operation_begin_wait_ (op4);
283 case TEST_OP1_RELEASED:
285 GNUNET_TESTBED_operation_queue_reset_max_active_ (q1, 2);
287 case TEST_OP2_STARTED:
288 GNUNET_TESTBED_operation_release_ (op2);
290 case TEST_OP3_STARTED:
291 GNUNET_TESTBED_operation_release_ (op3);
293 case TEST_OP4_STARTED:
294 GNUNET_TESTBED_operation_release_ (op4);
296 case TEST_OP6_RELEASED:
297 op8 = GNUNET_TESTBED_operation_create_ (&op8, &start_cb, &release_cb);
298 GNUNET_TESTBED_operation_queue_insert2_ (q1, op8, 2);
299 GNUNET_TESTBED_operation_queue_insert2_ (q2, op8, 2);
300 result = TEST_OP8_WAITING;
301 GNUNET_TESTBED_operation_begin_wait_ (op8);
303 case TEST_OP8_STARTED:
304 GNUNET_TESTBED_operation_inactivate_ (op8);
305 result = TEST_OP8_INACTIVE_1;
306 step_task = GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
308 case TEST_OP8_INACTIVE_1:
309 GNUNET_TESTBED_operation_activate_ (op8);
310 result = TEST_OP8_ACTIVE;
311 op9 = GNUNET_TESTBED_operation_create_ (&op9, &start_cb, &release_cb);
312 GNUNET_TESTBED_operation_queue_insert2_ (q1, op9, 1);
313 GNUNET_TESTBED_operation_queue_insert2_ (q2, op9, 1);
314 GNUNET_TESTBED_operation_begin_wait_ (op9);
315 step_task = GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
317 case TEST_OP8_ACTIVE:
318 GNUNET_TESTBED_operation_inactivate_ (op8);
319 /* op8 should be released by now due to above call */
320 GNUNET_assert (TEST_OP8_RELEASED == result);
322 case TEST_OP9_STARTED:
323 GNUNET_TESTBED_operation_release_ (op9);
332 * Function to call to start an operation once all
333 * queues the operation is part of declare that the
334 * operation can be activated.
342 GNUNET_assert (&op1 == cls);
343 result = TEST_OP1_STARTED;
344 GNUNET_assert (NULL == step_task);
346 GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
349 GNUNET_assert (&op2 == cls);
350 result = TEST_OP2_STARTED;
351 GNUNET_assert (NULL == step_task);
353 GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
355 case TEST_OP2_RELEASED:
356 GNUNET_assert (&op3 == cls);
357 result = TEST_OP3_STARTED;
358 GNUNET_assert (NULL == step_task);
360 GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
362 case TEST_OP3_RELEASED:
363 GNUNET_assert (&op4 == cls);
364 result = TEST_OP4_STARTED;
365 GNUNET_assert (NULL == step_task);
367 GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
369 case TEST_OP4_RELEASED:
376 result = TEST_OP5_6_7_STARTED;
377 GNUNET_TESTBED_operation_release_ (op5);
382 case TEST_OP7_RELEASED:
383 GNUNET_assert (&op8 == cls);
384 result = TEST_OP8_STARTED;
385 step_task = GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
387 case TEST_OP8_RELEASED:
388 GNUNET_assert (&op9 == cls);
389 result = TEST_OP9_STARTED;
390 step_task = GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
399 * Function to cancel an operation (release all associated resources). This can
400 * be because of a call to "GNUNET_TESTBED_operation_cancel" (before the
401 * operation generated an event) or AFTER the operation generated an event due
402 * to a call to "GNUNET_TESTBED_operation_done". Thus it is not guaranteed that
403 * a callback to the 'OperationStart' preceeds the call to 'OperationRelease'.
404 * Implementations of this function are expected to clean up whatever state is
405 * in 'cls' and release all resources associated with the operation.
408 release_cb (void *cls)
412 case TEST_OP1_STARTED:
413 GNUNET_assert (&op1 == cls);
414 result = TEST_OP1_RELEASED;
417 GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
419 case TEST_OP2_STARTED:
420 GNUNET_assert (&op2 == cls);
421 result = TEST_OP2_RELEASED;
422 GNUNET_assert (NULL == step_task);
424 case TEST_OP3_STARTED:
425 GNUNET_assert (&op3 == cls);
426 result = TEST_OP3_RELEASED;
427 GNUNET_assert (NULL == step_task);
429 case TEST_OP4_STARTED:
430 GNUNET_assert (&op4 == cls);
431 result = TEST_OP4_RELEASED;
432 GNUNET_assert (NULL == step_task);
433 op5 = GNUNET_TESTBED_operation_create_ (&op5, &start_cb, &release_cb);
434 GNUNET_TESTBED_operation_queue_insert2_ (q1, op5, 1);
435 GNUNET_TESTBED_operation_begin_wait_ (op5);
436 op6 = GNUNET_TESTBED_operation_create_ (&op6, &start_cb, &release_cb);
437 GNUNET_TESTBED_operation_queue_insert2_ (q2, op6, 1);
438 GNUNET_TESTBED_operation_begin_wait_ (op6);
439 op7 = GNUNET_TESTBED_operation_create_ (&op7, &start_cb, &release_cb);
440 GNUNET_TESTBED_operation_queue_insert2_ (q1, op7, 1);
441 GNUNET_TESTBED_operation_queue_insert2_ (q2, op7, 1);
442 GNUNET_TESTBED_operation_begin_wait_ (op7);
444 case TEST_OP5_6_7_STARTED:
445 result = TEST_OP5_RELEASED;
447 GNUNET_TESTBED_operation_release_ (op6);
449 case TEST_OP5_RELEASED:
451 result = TEST_OP6_RELEASED;
452 GNUNET_TESTBED_operation_inactivate_ (op7);
453 step_task = GNUNET_SCHEDULER_add_now (&step, NULL);
455 case TEST_OP8_WAITING:
456 GNUNET_assert (&op7 == cls);
458 result = TEST_OP7_RELEASED;
460 case TEST_OP8_ACTIVE:
461 result = TEST_OP8_RELEASED;
464 case TEST_OP9_STARTED:
465 GNUNET_assert (&op9 == cls);
466 result = TEST_OP9_RELEASED;
467 GNUNET_TESTBED_operation_queue_destroy_ (q1);
468 GNUNET_TESTBED_operation_queue_destroy_ (q2);
482 * @param args arguments passed to GNUNET_PROGRAM_run
483 * @param cfgfile the path to configuration file
484 * @param cfg the configuration file handle
487 run (void *cls, char *const *args, const char *cfgfile,
488 const struct GNUNET_CONFIGURATION_Handle *config)
490 q1 = GNUNET_TESTBED_operation_queue_create_ (OPERATION_QUEUE_TYPE_FIXED, 1);
491 GNUNET_assert (NULL != q1);
492 q2 = GNUNET_TESTBED_operation_queue_create_ (OPERATION_QUEUE_TYPE_FIXED, 2);
493 GNUNET_assert (NULL != q2);
494 op1 = GNUNET_TESTBED_operation_create_ (&op1, start_cb, release_cb);
495 GNUNET_assert (NULL != op1);
496 op2 = GNUNET_TESTBED_operation_create_ (&op2, start_cb, release_cb);
497 GNUNET_TESTBED_operation_queue_insert_ (q1, op1);
498 GNUNET_TESTBED_operation_queue_insert_ (q2, op1);
499 GNUNET_TESTBED_operation_begin_wait_ (op1);
500 GNUNET_TESTBED_operation_queue_insert_ (q1, op2);
501 GNUNET_TESTBED_operation_queue_insert_ (q2, op2);
502 GNUNET_TESTBED_operation_begin_wait_ (op2);
511 main (int argc, char **argv)
514 char *const argv2[] =
515 { "test_testbed_api_operations", "-c", "test_testbed_api.conf", NULL };
516 struct GNUNET_GETOPT_CommandLineOption options[] =
517 { GNUNET_GETOPT_OPTION_END };
520 GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
521 "test_testbed_api_operations", "nohelp", options,
523 if ((GNUNET_OK != ret) || (TEST_OP9_RELEASED != result))
539 /* end of test_testbed_api_operations.c */