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
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 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 General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
22 * @file testbed/test_testbed_api_operations.c
23 * @brief tests cases for testbed_api_operations.c
24 * @author Sree Harsha Totakura
28 #include "gnunet_util_lib.h"
29 #include "testbed_api_operations.h"
32 * Generic logging shortcut
34 #define LOG(kind,...) \
35 GNUNET_log (kind, __VA_ARGS__)
38 * Delay to start step task
41 GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MILLISECONDS, 500)
44 * Queue A. Initially the max active is set to 2 and then reduced to 0 - this
45 * should block op2 even after op1 has finished. Later the max active is set to
46 * 2 and this should start op2
48 struct OperationQueue *q1;
51 * Queue B. Max active set to 2 is not changed throughout the test
53 struct OperationQueue *q2;
56 * This operation should go into both queues and block op2 until it is done
58 struct GNUNET_TESTBED_Operation *op1;
61 * This operation should go into q1 and q2
63 struct GNUNET_TESTBED_Operation *op2;
66 * This operation should go into both queues and should consume 2 units of
67 * resources on both queues. Since op2 needs a resource from both queues and is
68 * queues before this operation, it will be blocked until op2 is released even
69 * though q1 has enough free resources
71 struct GNUNET_TESTBED_Operation *op3;
74 * Just like op3, this operation also consumes 2 units of resources on both
75 * queues. Since this is queued after op3 and both queues are at max active
76 * 2. This will be blocked until op3 is done.
78 struct GNUNET_TESTBED_Operation *op4;
81 * This operation is started after op4 is released and should consume only 1
82 * resource on queue q1. It should be started along with op6 and op7
84 struct GNUNET_TESTBED_Operation *op5;
87 * This operation is started after op4 is released and should consume only 1
88 * resource on q2. It should be started along with op5 and op7
90 struct GNUNET_TESTBED_Operation *op6;
93 * This operation is started after op4 is released and should consume 1 resource
94 * on both queues q1 and q1. It should be started along with op5 and op6. It is
95 * then inactivated when op6 is released. op8's start should release this
96 * operation implicitly.
98 struct GNUNET_TESTBED_Operation *op7;
101 * This operation is started after op6 is finished in step task. It consumes 2
102 * resources on both queues q1 and q2. This operation should evict op7. After
103 * starting, it should be made inactive, active and inactive again in the step task.
105 struct GNUNET_TESTBED_Operation *op8;
108 * This opration is started after activating op8. It should consume a resource
109 * on queues q1 and q2. It should not be started until op8 is again made
110 * inactive at which point it should be released. It can be released as soon as
113 struct GNUNET_TESTBED_Operation *op9;
116 * The delay task identifier
118 struct GNUNET_SCHEDULER_Task * step_task;
122 * Enumeration of test stages
132 * op1 has been started
137 * op1 has been released
142 * Temporary pause where no operations should start as we set max active in q1
143 * to 0 in stage TEST_OP1_STARTED
178 * op5, op6, op7 started
180 TEST_OP5_6_7_STARTED,
193 * op8 has began waiting
218 * op8 has been released
228 * op9 has been released
240 * Function to call to start an operation once all
241 * queues the operation is part of declare that the
242 * operation can be activated.
245 start_cb (void *cls);
249 * Function to cancel an operation (release all associated resources). This can
250 * be because of a call to "GNUNET_TESTBED_operation_cancel" (before the
251 * operation generated an event) or AFTER the operation generated an event due
252 * to a call to "GNUNET_TESTBED_operation_done". Thus it is not guaranteed that
253 * a callback to the 'OperationStart' preceeds the call to 'OperationRelease'.
254 * Implementations of this function are expected to clean up whatever state is
255 * in 'cls' and release all resources associated with the operation.
258 release_cb (void *cls);
262 * Task to simulate artificial delay and change the test stage
269 GNUNET_assert (NULL != step_task);
273 case TEST_OP1_STARTED:
274 GNUNET_TESTBED_operation_release_ (op1);
275 GNUNET_TESTBED_operation_queue_reset_max_active_ (q1, 0);
276 op3 = GNUNET_TESTBED_operation_create_ (&op3, &start_cb, &release_cb);
277 GNUNET_TESTBED_operation_queue_insert2_ (q1, op3, 2);
278 GNUNET_TESTBED_operation_queue_insert2_ (q2, op3, 2);
279 GNUNET_TESTBED_operation_begin_wait_ (op3);
280 op4 = GNUNET_TESTBED_operation_create_ (&op4, &start_cb, &release_cb);
281 GNUNET_TESTBED_operation_queue_insert2_ (q1, op4, 2);
282 GNUNET_TESTBED_operation_queue_insert2_ (q2, op4, 2);
283 GNUNET_TESTBED_operation_begin_wait_ (op4);
285 case TEST_OP1_RELEASED:
287 GNUNET_TESTBED_operation_queue_reset_max_active_ (q1, 2);
289 case TEST_OP2_STARTED:
290 GNUNET_TESTBED_operation_release_ (op2);
292 case TEST_OP3_STARTED:
293 GNUNET_TESTBED_operation_release_ (op3);
295 case TEST_OP4_STARTED:
296 GNUNET_TESTBED_operation_release_ (op4);
298 case TEST_OP6_RELEASED:
299 op8 = GNUNET_TESTBED_operation_create_ (&op8, &start_cb, &release_cb);
300 GNUNET_TESTBED_operation_queue_insert2_ (q1, op8, 2);
301 GNUNET_TESTBED_operation_queue_insert2_ (q2, op8, 2);
302 result = TEST_OP8_WAITING;
303 GNUNET_TESTBED_operation_begin_wait_ (op8);
305 case TEST_OP8_STARTED:
306 GNUNET_TESTBED_operation_inactivate_ (op8);
307 result = TEST_OP8_INACTIVE_1;
308 step_task = GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
310 case TEST_OP8_INACTIVE_1:
311 GNUNET_TESTBED_operation_activate_ (op8);
312 result = TEST_OP8_ACTIVE;
313 op9 = GNUNET_TESTBED_operation_create_ (&op9, &start_cb, &release_cb);
314 GNUNET_TESTBED_operation_queue_insert2_ (q1, op9, 1);
315 GNUNET_TESTBED_operation_queue_insert2_ (q2, op9, 1);
316 GNUNET_TESTBED_operation_begin_wait_ (op9);
317 step_task = GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
319 case TEST_OP8_ACTIVE:
320 GNUNET_TESTBED_operation_inactivate_ (op8);
321 /* op8 should be released by now due to above call */
322 GNUNET_assert (TEST_OP8_RELEASED == result);
324 case TEST_OP9_STARTED:
325 GNUNET_TESTBED_operation_release_ (op9);
334 * Function to call to start an operation once all
335 * queues the operation is part of declare that the
336 * operation can be activated.
344 GNUNET_assert (&op1 == cls);
345 result = TEST_OP1_STARTED;
346 GNUNET_assert (NULL == step_task);
348 GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
351 GNUNET_assert (&op2 == cls);
352 result = TEST_OP2_STARTED;
353 GNUNET_assert (NULL == step_task);
355 GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
357 case TEST_OP2_RELEASED:
358 GNUNET_assert (&op3 == cls);
359 result = TEST_OP3_STARTED;
360 GNUNET_assert (NULL == step_task);
362 GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
364 case TEST_OP3_RELEASED:
365 GNUNET_assert (&op4 == cls);
366 result = TEST_OP4_STARTED;
367 GNUNET_assert (NULL == step_task);
369 GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
371 case TEST_OP4_RELEASED:
378 result = TEST_OP5_6_7_STARTED;
379 GNUNET_TESTBED_operation_release_ (op5);
384 case TEST_OP7_RELEASED:
385 GNUNET_assert (&op8 == cls);
386 result = TEST_OP8_STARTED;
387 step_task = GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
389 case TEST_OP8_RELEASED:
390 GNUNET_assert (&op9 == cls);
391 result = TEST_OP9_STARTED;
392 step_task = GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
401 * Function to cancel an operation (release all associated resources). This can
402 * be because of a call to "GNUNET_TESTBED_operation_cancel" (before the
403 * operation generated an event) or AFTER the operation generated an event due
404 * to a call to "GNUNET_TESTBED_operation_done". Thus it is not guaranteed that
405 * a callback to the 'OperationStart' preceeds the call to 'OperationRelease'.
406 * Implementations of this function are expected to clean up whatever state is
407 * in 'cls' and release all resources associated with the operation.
410 release_cb (void *cls)
414 case TEST_OP1_STARTED:
415 GNUNET_assert (&op1 == cls);
416 result = TEST_OP1_RELEASED;
419 GNUNET_SCHEDULER_add_delayed (STEP_DELAY, &step, NULL);
421 case TEST_OP2_STARTED:
422 GNUNET_assert (&op2 == cls);
423 result = TEST_OP2_RELEASED;
424 GNUNET_assert (NULL == step_task);
426 case TEST_OP3_STARTED:
427 GNUNET_assert (&op3 == cls);
428 result = TEST_OP3_RELEASED;
429 GNUNET_assert (NULL == step_task);
431 case TEST_OP4_STARTED:
432 GNUNET_assert (&op4 == cls);
433 result = TEST_OP4_RELEASED;
434 GNUNET_assert (NULL == step_task);
435 op5 = GNUNET_TESTBED_operation_create_ (&op5, &start_cb, &release_cb);
436 GNUNET_TESTBED_operation_queue_insert2_ (q1, op5, 1);
437 GNUNET_TESTBED_operation_begin_wait_ (op5);
438 op6 = GNUNET_TESTBED_operation_create_ (&op6, &start_cb, &release_cb);
439 GNUNET_TESTBED_operation_queue_insert2_ (q2, op6, 1);
440 GNUNET_TESTBED_operation_begin_wait_ (op6);
441 op7 = GNUNET_TESTBED_operation_create_ (&op7, &start_cb, &release_cb);
442 GNUNET_TESTBED_operation_queue_insert2_ (q1, op7, 1);
443 GNUNET_TESTBED_operation_queue_insert2_ (q2, op7, 1);
444 GNUNET_TESTBED_operation_begin_wait_ (op7);
446 case TEST_OP5_6_7_STARTED:
447 result = TEST_OP5_RELEASED;
449 GNUNET_TESTBED_operation_release_ (op6);
451 case TEST_OP5_RELEASED:
453 result = TEST_OP6_RELEASED;
454 GNUNET_TESTBED_operation_inactivate_ (op7);
455 step_task = GNUNET_SCHEDULER_add_now (&step, NULL);
457 case TEST_OP8_WAITING:
458 GNUNET_assert (&op7 == cls);
460 result = TEST_OP7_RELEASED;
462 case TEST_OP8_ACTIVE:
463 result = TEST_OP8_RELEASED;
466 case TEST_OP9_STARTED:
467 GNUNET_assert (&op9 == cls);
468 result = TEST_OP9_RELEASED;
469 GNUNET_TESTBED_operation_queue_destroy_ (q1);
470 GNUNET_TESTBED_operation_queue_destroy_ (q2);
484 * @param args arguments passed to GNUNET_PROGRAM_run
485 * @param cfgfile the path to configuration file
486 * @param cfg the configuration file handle
489 run (void *cls, char *const *args, const char *cfgfile,
490 const struct GNUNET_CONFIGURATION_Handle *config)
492 q1 = GNUNET_TESTBED_operation_queue_create_ (OPERATION_QUEUE_TYPE_FIXED, 1);
493 GNUNET_assert (NULL != q1);
494 q2 = GNUNET_TESTBED_operation_queue_create_ (OPERATION_QUEUE_TYPE_FIXED, 2);
495 GNUNET_assert (NULL != q2);
496 op1 = GNUNET_TESTBED_operation_create_ (&op1, start_cb, release_cb);
497 GNUNET_assert (NULL != op1);
498 op2 = GNUNET_TESTBED_operation_create_ (&op2, start_cb, release_cb);
499 GNUNET_TESTBED_operation_queue_insert_ (q1, op1);
500 GNUNET_TESTBED_operation_queue_insert_ (q2, op1);
501 GNUNET_TESTBED_operation_begin_wait_ (op1);
502 GNUNET_TESTBED_operation_queue_insert_ (q1, op2);
503 GNUNET_TESTBED_operation_queue_insert_ (q2, op2);
504 GNUNET_TESTBED_operation_begin_wait_ (op2);
513 main (int argc, char **argv)
516 char *const argv2[] =
517 { "test_testbed_api_operations", "-c", "test_testbed_api.conf", NULL };
518 struct GNUNET_GETOPT_CommandLineOption options[] =
519 { GNUNET_GETOPT_OPTION_END };
522 GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
523 "test_testbed_api_operations", "nohelp", options,
525 if ((GNUNET_OK != ret) || (TEST_OP9_RELEASED != result))
541 /* end of test_testbed_api_operations.c */