2 This file is part of GNUnet
3 (C) 2008--2012 Christian Grothoff (and other contributing authors)
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., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, 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 * Queue A. Initially the max active is set to 2 and then reduced to 0 - this
39 * should block op2 even after op1 has finished. Later the max active is set to
40 * 2 and this should start op2
42 struct OperationQueue *q1;
45 * Queue B. Max active set to 2 is not changed throughout the test
47 struct OperationQueue *q2;
50 * This operation should go into both queues and block op2 until it is done
52 struct GNUNET_TESTBED_Operation *op1;
55 * This operation should go into q1 and q2
57 struct GNUNET_TESTBED_Operation *op2;
60 * This operation should go into both queues and should consume 2 units of
61 * resources on both queues. Since op2 needs a resource from both queues and is
62 * queues before this operation, it will be blocked until op2 is released even
65 struct GNUNET_TESTBED_Operation *op3;
68 * Just like op3, this operation also consumes 2 units of resources on both
69 * queues. Since this is queued after op3 and both queues are at max active
70 * 2. This will be blocked until op3 is done.
72 struct GNUNET_TESTBED_Operation *op4;
75 * This operation is started after op4 is released and should consume only 1
76 * resource on queue q1. It should be started along with op6 and op7
78 struct GNUNET_TESTBED_Operation *op5;
81 * This operation is started after op4 is released and should consume only 1
82 * resource on q2. It should be started along with op5 and op7
84 struct GNUNET_TESTBED_Operation *op6;
87 * This operation is started after op4 is released and should consume 1 resource
88 * on both queues q1 and q1. It should be started along with op5 and op6
90 struct GNUNET_TESTBED_Operation *op7;
93 * The delay task identifier
95 GNUNET_SCHEDULER_TaskIdentifier step_task;
99 * Enumeration of test stages
109 * op1 has been started
114 * op1 has been released
119 * Temporary pause where no operations should start as we set max active in q1
120 * to 0 in stage TEST_OP1_STARTED
155 * op5, op6, op7 started
157 TEST_OP5_6_7_STARTED,
182 * Function to call to start an operation once all
183 * queues the operation is part of declare that the
184 * operation can be activated.
187 start_cb (void *cls);
191 * Function to cancel an operation (release all associated resources). This can
192 * be because of a call to "GNUNET_TESTBED_operation_cancel" (before the
193 * operation generated an event) or AFTER the operation generated an event due
194 * to a call to "GNUNET_TESTBED_operation_done". Thus it is not guaranteed that
195 * a callback to the 'OperationStart' preceeds the call to 'OperationRelease'.
196 * Implementations of this function are expected to clean up whatever state is
197 * in 'cls' and release all resources associated with the operation.
200 release_cb (void *cls);
204 * Task to simulate artificial delay and change the test stage
207 * @param tc the task context
210 step (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
212 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK != step_task);
213 step_task = GNUNET_SCHEDULER_NO_TASK;
216 case TEST_OP1_STARTED:
217 GNUNET_TESTBED_operation_release_ (op1);
218 GNUNET_TESTBED_operation_queue_reset_max_active_ (q1, 0);
219 op3 = GNUNET_TESTBED_operation_create_ (&op3, &start_cb, &release_cb);
220 GNUNET_TESTBED_operation_queue_insert2_ (q1, op3, 2);
221 GNUNET_TESTBED_operation_queue_insert2_ (q2, op3, 2);
222 GNUNET_TESTBED_operation_begin_wait_ (op3);
223 op4 = GNUNET_TESTBED_operation_create_ (&op4, &start_cb, &release_cb);
224 GNUNET_TESTBED_operation_queue_insert2_ (q1, op4, 2);
225 GNUNET_TESTBED_operation_queue_insert2_ (q2, op4, 2);
226 GNUNET_TESTBED_operation_begin_wait_ (op4);
228 case TEST_OP1_RELEASED:
230 GNUNET_TESTBED_operation_queue_reset_max_active_ (q1, 2);
232 case TEST_OP2_STARTED:
233 GNUNET_TESTBED_operation_release_ (op2);
235 case TEST_OP3_STARTED:
236 GNUNET_TESTBED_operation_release_ (op3);
238 case TEST_OP4_STARTED:
239 GNUNET_TESTBED_operation_release_ (op4);
248 * Function to call to start an operation once all
249 * queues the operation is part of declare that the
250 * operation can be activated.
258 GNUNET_assert (&op1 == cls);
259 result = TEST_OP1_STARTED;
260 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == step_task);
261 step_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &step, NULL);
264 GNUNET_assert (&op2 == cls);
265 result = TEST_OP2_STARTED;
266 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == step_task);
267 step_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &step, NULL);
269 case TEST_OP2_RELEASED:
270 GNUNET_assert (&op3 == cls);
271 result = TEST_OP3_STARTED;
272 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == step_task);
273 step_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &step, NULL);
275 case TEST_OP3_RELEASED:
276 GNUNET_assert (&op4 == cls);
277 result = TEST_OP4_STARTED;
278 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == step_task);
279 step_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &step,
282 case TEST_OP4_RELEASED:
289 result = TEST_OP5_6_7_STARTED;
290 GNUNET_TESTBED_operation_release_ (op5);
302 * Function to cancel an operation (release all associated resources). This can
303 * be because of a call to "GNUNET_TESTBED_operation_cancel" (before the
304 * operation generated an event) or AFTER the operation generated an event due
305 * to a call to "GNUNET_TESTBED_operation_done". Thus it is not guaranteed that
306 * a callback to the 'OperationStart' preceeds the call to 'OperationRelease'.
307 * Implementations of this function are expected to clean up whatever state is
308 * in 'cls' and release all resources associated with the operation.
311 release_cb (void *cls)
315 case TEST_OP1_STARTED:
316 GNUNET_assert (&op1 == cls);
317 result = TEST_OP1_RELEASED;
319 step_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &step,
322 case TEST_OP2_STARTED:
323 GNUNET_assert (&op2 == cls);
324 result = TEST_OP2_RELEASED;
325 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == step_task);
326 //step_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &step, NULL);
328 case TEST_OP3_STARTED:
329 GNUNET_assert (&op3 == cls);
330 result = TEST_OP3_RELEASED;
331 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == step_task);
333 case TEST_OP4_STARTED:
334 GNUNET_assert (&op4 == cls);
335 result = TEST_OP4_RELEASED;
336 GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == step_task);
337 op5 = GNUNET_TESTBED_operation_create_ (&op5, &start_cb, &release_cb);
338 GNUNET_TESTBED_operation_queue_insert2_ (q1, op5, 1);
339 GNUNET_TESTBED_operation_begin_wait_ (op5);
340 op6 = GNUNET_TESTBED_operation_create_ (&op6, &start_cb, &release_cb);
341 GNUNET_TESTBED_operation_queue_insert2_ (q2, op6, 1);
342 GNUNET_TESTBED_operation_begin_wait_ (op6);
343 op7 = GNUNET_TESTBED_operation_create_ (&op7, &start_cb, &release_cb);
344 GNUNET_TESTBED_operation_queue_insert2_ (q1, op7, 1);
345 GNUNET_TESTBED_operation_queue_insert2_ (q2, op7, 1);
346 GNUNET_TESTBED_operation_begin_wait_ (op7);
348 case TEST_OP5_6_7_STARTED:
349 result = TEST_OP5_RELEASED;
351 GNUNET_TESTBED_operation_release_ (op6);
353 case TEST_OP5_RELEASED:
355 result = TEST_OP6_RELEASED;
356 GNUNET_TESTBED_operation_release_ (op7);
358 case TEST_OP6_RELEASED:
359 result = TEST_OP7_RELEASED;
361 GNUNET_TESTBED_operation_queue_destroy_ (q1);
362 GNUNET_TESTBED_operation_queue_destroy_ (q2);
376 * @param args arguments passed to GNUNET_PROGRAM_run
377 * @param cfgfile the path to configuration file
378 * @param cfg the configuration file handle
381 run (void *cls, char *const *args, const char *cfgfile,
382 const struct GNUNET_CONFIGURATION_Handle *config)
384 q1 = GNUNET_TESTBED_operation_queue_create_ (1);
385 GNUNET_assert (NULL != q1);
386 q2 = GNUNET_TESTBED_operation_queue_create_ (2);
387 GNUNET_assert (NULL != q2);
388 op1 = GNUNET_TESTBED_operation_create_ (&op1, start_cb, release_cb);
389 GNUNET_assert (NULL != op1);
390 op2 = GNUNET_TESTBED_operation_create_ (&op2, start_cb, release_cb);
391 GNUNET_TESTBED_operation_queue_insert_ (q1, op1);
392 GNUNET_TESTBED_operation_queue_insert_ (q2, op1);
393 GNUNET_TESTBED_operation_begin_wait_ (op1);
394 GNUNET_TESTBED_operation_queue_insert_ (q1, op2);
395 GNUNET_TESTBED_operation_queue_insert_ (q2, op2);
396 GNUNET_TESTBED_operation_begin_wait_ (op2);
405 main (int argc, char **argv)
408 char *const argv2[] =
409 { "test_testbed_api_operations", "-c", "test_testbed_api.conf", NULL };
410 struct GNUNET_GETOPT_CommandLineOption options[] =
411 { GNUNET_GETOPT_OPTION_END };
414 GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
415 "test_testbed_api_operations", "nohelp", options,
417 if ((GNUNET_OK != ret) || (TEST_OP7_RELEASED != result))
427 /* end of test_testbed_api_operations.c */