diff options
author | t3sserakt <t3ss@posteo.de> | 2021-03-08 11:18:18 +0100 |
---|---|---|
committer | t3sserakt <t3ss@posteo.de> | 2021-03-08 11:18:18 +0100 |
commit | 3583e51e3c4a6fb4bac331996891a7f7cd42f9cf (patch) | |
tree | 9f41ce5bebd44fbb6747eda7525e9d7b91060399 /src/testing | |
parent | 79e9673137f1c94644bf9ef781e08c53c2e3901f (diff) | |
download | gnunet-3583e51e3c4a6fb4bac331996891a7f7cd42f9cf.tar.gz gnunet-3583e51e3c4a6fb4bac331996891a7f7cd42f9cf.zip |
- Just make it compile again.
Diffstat (limited to 'src/testing')
-rw-r--r-- | src/testing/testing_api_loop.c | 368 |
1 files changed, 11 insertions, 357 deletions
diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c index 724c09c7a..993777de6 100644 --- a/src/testing/testing_api_loop.c +++ b/src/testing/testing_api_loop.c | |||
@@ -30,12 +30,6 @@ | |||
30 | #include "gnunet_testing_ng_lib.h" | 30 | #include "gnunet_testing_ng_lib.h" |
31 | 31 | ||
32 | /** | 32 | /** |
33 | * Pipe used to communicate child death via signal. | ||
34 | * Must be global, as used in signal handler! | ||
35 | */ | ||
36 | static struct GNUNET_DISK_PipeHandle *sigpipe; | ||
37 | |||
38 | /** | ||
39 | * Lookup command by label. | 33 | * Lookup command by label. |
40 | * | 34 | * |
41 | * @param is interpreter state to search | 35 | * @param is interpreter state to search |
@@ -243,7 +237,7 @@ interpreter_run (void *cls) | |||
243 | * | 237 | * |
244 | * @param cls the interpreter state. | 238 | * @param cls the interpreter state. |
245 | */ | 239 | */ |
246 | static void | 240 | /*static void |
247 | do_shutdown (void *cls) | 241 | do_shutdown (void *cls) |
248 | { | 242 | { |
249 | struct GNUNET_TESTING_Interpreter *is = cls; | 243 | struct GNUNET_TESTING_Interpreter *is = cls; |
@@ -274,145 +268,8 @@ do_shutdown (void *cls) | |||
274 | GNUNET_SCHEDULER_cancel (is->timeout_task); | 268 | GNUNET_SCHEDULER_cancel (is->timeout_task); |
275 | is->timeout_task = NULL; | 269 | is->timeout_task = NULL; |
276 | } | 270 | } |
277 | if (NULL != is->child_death_task) | ||
278 | { | ||
279 | GNUNET_SCHEDULER_cancel (is->child_death_task); | ||
280 | is->child_death_task = NULL; | ||
281 | } | ||
282 | GNUNET_free (is->commands); | 271 | GNUNET_free (is->commands); |
283 | } | 272 | }*/ |
284 | |||
285 | |||
286 | /** | ||
287 | * Function run when the test terminates (good or bad) with timeout. | ||
288 | * | ||
289 | * @param cls NULL | ||
290 | */ | ||
291 | static void | ||
292 | do_timeout (void *cls) | ||
293 | { | ||
294 | struct GNUNET_TESTING_Interpreter *is = cls; | ||
295 | |||
296 | is->timeout_task = NULL; | ||
297 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
298 | "Terminating test due to timeout\n"); | ||
299 | GNUNET_SCHEDULER_shutdown (); | ||
300 | } | ||
301 | |||
302 | |||
303 | /** | ||
304 | * Task triggered whenever we receive a SIGCHLD (child | ||
305 | * process died). | ||
306 | * | ||
307 | * @param cls closure | ||
308 | */ | ||
309 | static void | ||
310 | maint_child_death (void *cls) | ||
311 | { | ||
312 | struct GNUNET_TESTING_Interpreter *is = cls; | ||
313 | struct GNUNET_TESTING_Command *cmd = &is->commands[is->ip]; | ||
314 | const struct GNUNET_DISK_FileHandle *pr; | ||
315 | struct GNUNET_OS_Process **processp; | ||
316 | char c[16]; | ||
317 | enum GNUNET_OS_ProcessStatusType type; | ||
318 | unsigned long code; | ||
319 | |||
320 | if (GNUNET_TESTING_cmd_is_batch (cmd)) | ||
321 | { | ||
322 | struct GNUNET_TESTING_Command *batch_cmd; | ||
323 | |||
324 | GNUNET_assert (GNUNET_OK == | ||
325 | GNUNET_TESTING_get_trait_cmd (cmd, | ||
326 | 0, | ||
327 | &batch_cmd)); | ||
328 | cmd = batch_cmd; | ||
329 | } | ||
330 | |||
331 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
332 | "Got SIGCHLD for `%s'.\n", | ||
333 | cmd->label); | ||
334 | is->child_death_task = NULL; | ||
335 | pr = GNUNET_DISK_pipe_handle (sigpipe, | ||
336 | GNUNET_DISK_PIPE_END_READ); | ||
337 | GNUNET_break (0 < | ||
338 | GNUNET_DISK_file_read (pr, | ||
339 | &c, | ||
340 | sizeof (c))); | ||
341 | if (GNUNET_OK != | ||
342 | GNUNET_TESTING_get_trait_process (cmd, | ||
343 | 0, | ||
344 | &processp)) | ||
345 | { | ||
346 | GNUNET_break (0); | ||
347 | GNUNET_TESTING_interpreter_fail (is); | ||
348 | return; | ||
349 | } | ||
350 | |||
351 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
352 | "Got the dead child process handle, waiting for termination ...\n"); | ||
353 | GNUNET_OS_process_wait_status (*processp, | ||
354 | &type, | ||
355 | &code); | ||
356 | GNUNET_OS_process_destroy (*processp); | ||
357 | *processp = NULL; | ||
358 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
359 | "... definitively terminated\n"); | ||
360 | switch (type) | ||
361 | { | ||
362 | case GNUNET_OS_PROCESS_UNKNOWN: | ||
363 | GNUNET_break (0); | ||
364 | GNUNET_TESTING_interpreter_fail (is); | ||
365 | return; | ||
366 | case GNUNET_OS_PROCESS_RUNNING: | ||
367 | GNUNET_break (0); | ||
368 | GNUNET_TESTING_interpreter_fail (is); | ||
369 | return; | ||
370 | case GNUNET_OS_PROCESS_STOPPED: | ||
371 | GNUNET_break (0); | ||
372 | GNUNET_TESTING_interpreter_fail (is); | ||
373 | return; | ||
374 | case GNUNET_OS_PROCESS_EXITED: | ||
375 | if (0 != code) | ||
376 | { | ||
377 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
378 | "Process exited with unexpected status %u\n", | ||
379 | (unsigned int) code); | ||
380 | GNUNET_TESTING_interpreter_fail (is); | ||
381 | return; | ||
382 | } | ||
383 | break; | ||
384 | case GNUNET_OS_PROCESS_SIGNALED: | ||
385 | GNUNET_break (0); | ||
386 | GNUNET_TESTING_interpreter_fail (is); | ||
387 | return; | ||
388 | } | ||
389 | |||
390 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
391 | "Dead child, go on with next command.\n"); | ||
392 | GNUNET_TESTING_interpreter_next (is); | ||
393 | } | ||
394 | |||
395 | |||
396 | /** | ||
397 | * Wait until we receive SIGCHLD signal. | ||
398 | * Then obtain the process trait of the current | ||
399 | * command, wait on the the zombie and continue | ||
400 | * with the next command. | ||
401 | */ | ||
402 | void | ||
403 | GNUNET_TESTING_wait_for_sigchld (struct GNUNET_TESTING_Interpreter *is) | ||
404 | { | ||
405 | const struct GNUNET_DISK_FileHandle *pr; | ||
406 | |||
407 | GNUNET_assert (NULL == is->child_death_task); | ||
408 | pr = GNUNET_DISK_pipe_handle (sigpipe, | ||
409 | GNUNET_DISK_PIPE_END_READ); | ||
410 | is->child_death_task | ||
411 | = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | ||
412 | pr, | ||
413 | &maint_child_death, | ||
414 | is); | ||
415 | } | ||
416 | 273 | ||
417 | 274 | ||
418 | /** | 275 | /** |
@@ -425,228 +282,25 @@ GNUNET_TESTING_wait_for_sigchld (struct GNUNET_TESTING_Interpreter *is) | |||
425 | * @param commands the list of command to execute | 282 | * @param commands the list of command to execute |
426 | * @param timeout how long to wait | 283 | * @param timeout how long to wait |
427 | */ | 284 | */ |
428 | void | 285 | int |
429 | GNUNET_TESTING_run2 (struct GNUNET_TESTING_Interpreter *is, | 286 | GNUNET_TESTING_run (const char *cfg_filename, |
430 | struct GNUNET_TESTING_Command *commands, | 287 | struct GNUNET_TESTING_Command *commands, |
431 | struct GNUNET_TIME_Relative timeout) | 288 | struct GNUNET_TIME_Relative timeout) |
432 | { | 289 | { |
433 | unsigned int i; | 290 | unsigned int i; |
434 | 291 | ||
435 | if (NULL != is->timeout_task) | ||
436 | { | ||
437 | GNUNET_SCHEDULER_cancel (is->timeout_task); | ||
438 | is->timeout_task = NULL; | ||
439 | } | ||
440 | /* get the number of commands */ | 292 | /* get the number of commands */ |
441 | for (i = 0; NULL != commands[i].label; i++) | 293 | for (i = 0; NULL != commands[i].label; i++) |
442 | ; | 294 | ; |
443 | is->commands = GNUNET_new_array (i + 1, | 295 | |
444 | struct GNUNET_TESTING_Command); | 296 | |
445 | memcpy (is->commands, | 297 | /*is->timeout_task = GNUNET_SCHEDULER_add_delayed |
446 | commands, | ||
447 | sizeof (struct GNUNET_TESTING_Command) * i); | ||
448 | is->timeout_task = GNUNET_SCHEDULER_add_delayed | ||
449 | (timeout, | 298 | (timeout, |
450 | &do_timeout, | 299 | &do_timeout, |
451 | is); | 300 | is); |
452 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, is); | 301 | GNUNET_SCHEDULER_add_shutdown (&do_shutdown, is); |
453 | is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, is); | 302 | is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, is);*/ |
454 | } | 303 | return GNUNET_OK; |
455 | |||
456 | |||
457 | /** | ||
458 | * Run the testsuite. Note, CMDs are copied into | ||
459 | * the interpreter state because they are _usually_ | ||
460 | * defined into the "run" method that returns after | ||
461 | * having scheduled the test interpreter. | ||
462 | * | ||
463 | * @param is the interpreter state | ||
464 | * @param commands the list of command to execute | ||
465 | */ | ||
466 | void | ||
467 | GNUNET_TESTING_run (struct GNUNET_TESTING_Interpreter *is, | ||
468 | struct GNUNET_TESTING_Command *commands) | ||
469 | { | ||
470 | GNUNET_TESTING_run2 (is, | ||
471 | commands, | ||
472 | GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, | ||
473 | 5)); | ||
474 | } | ||
475 | |||
476 | |||
477 | /** | ||
478 | * Information used by the wrapper around the main | ||
479 | * "run" method. | ||
480 | */ | ||
481 | struct MainContext | ||
482 | { | ||
483 | /** | ||
484 | * Main "run" method. | ||
485 | */ | ||
486 | GNUNET_TESTING_Main main_cb; | ||
487 | |||
488 | /** | ||
489 | * Closure for @e main_cb. | ||
490 | */ | ||
491 | void *main_cb_cls; | ||
492 | |||
493 | /** | ||
494 | * Interpreter state. | ||
495 | */ | ||
496 | struct GNUNET_TESTING_Interpreter *is; | ||
497 | }; | ||
498 | |||
499 | |||
500 | /** | ||
501 | * Signal handler called for SIGCHLD. Triggers the | ||
502 | * respective handler by writing to the trigger pipe. | ||
503 | */ | ||
504 | static void | ||
505 | sighandler_child_death (void) | ||
506 | { | ||
507 | static char c; | ||
508 | int old_errno = errno; /* back-up errno */ | ||
509 | |||
510 | GNUNET_break (1 == GNUNET_DISK_file_write | ||
511 | (GNUNET_DISK_pipe_handle (sigpipe, | ||
512 | GNUNET_DISK_PIPE_END_WRITE), | ||
513 | &c, sizeof (c))); | ||
514 | errno = old_errno; /* restore errno */ | ||
515 | } | ||
516 | |||
517 | |||
518 | /** | ||
519 | * Initialize scheduler loop and curl context for the testcase, | ||
520 | * and responsible to run the "run" method. | ||
521 | * | ||
522 | * @param cls closure, typically the "run" method, the | ||
523 | * interpreter state and a closure for "run". | ||
524 | */ | ||
525 | static void | ||
526 | main_wrapper_exchange_agnostic (void *cls) | ||
527 | { | ||
528 | struct MainContext *main_ctx = cls; | ||
529 | |||
530 | main_ctx->main_cb (main_ctx->main_cb_cls, | ||
531 | main_ctx->is); | ||
532 | } | ||
533 | |||
534 | |||
535 | /** | ||
536 | * Function run when the test is aborted before we launch the actual | ||
537 | * interpreter. Cleans up our state. | ||
538 | * | ||
539 | * @param cls the main context | ||
540 | */ | ||
541 | static void | ||
542 | do_abort (void *cls) | ||
543 | { | ||
544 | struct MainContext *main_ctx = cls; | ||
545 | struct GNUNET_TESTING_Interpreter *is = main_ctx->is; | ||
546 | |||
547 | is->timeout_task = NULL; | ||
548 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
549 | "Executing abort prior to interpreter launch\n"); | ||
550 | } | ||
551 | |||
552 | |||
553 | /** | ||
554 | * Initialize scheduler loop and curl context for the testcase, | ||
555 | * and responsible to run the "run" method. | ||
556 | * | ||
557 | * @param cls a `struct MainContext *` | ||
558 | */ | ||
559 | static void | ||
560 | main_wrapper_exchange_connect (void *cls) | ||
561 | { | ||
562 | struct MainContext *main_ctx = cls; | ||
563 | struct GNUNET_TESTING_Interpreter *is = main_ctx->is; | ||
564 | char *exchange_url; | ||
565 | |||
566 | if (GNUNET_OK != | ||
567 | GNUNET_CONFIGURATION_get_value_string (is->cfg, | ||
568 | "exchange", | ||
569 | "BASE_URL", | ||
570 | &exchange_url)) | ||
571 | { | ||
572 | GNUNET_log_config_missing (GNUNET_ERROR_TYPE_ERROR, | ||
573 | "exchange", | ||
574 | "BASE_URL"); | ||
575 | return; | ||
576 | } | ||
577 | is->timeout_task = GNUNET_SCHEDULER_add_shutdown (&do_abort, | ||
578 | main_ctx); | ||
579 | is->working = GNUNET_YES; | ||
580 | |||
581 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
582 | "Starting main test loop\n"); | ||
583 | main_ctx->main_cb (main_ctx->main_cb_cls, | ||
584 | is); | ||
585 | } | ||
586 | |||
587 | |||
588 | /** | ||
589 | * Install signal handlers plus schedules the main wrapper | ||
590 | * around the "run" method. | ||
591 | * | ||
592 | * @param main_cb the "run" method which contains all the | ||
593 | * commands. | ||
594 | * @param main_cb_cls a closure for "run", typically NULL. | ||
595 | * @param cfg configuration to use | ||
596 | * @param exchanged exchange process handle: will be put in the | ||
597 | * state as some commands - e.g. revoke - need to send | ||
598 | * signal to it, for example to let it know to reload the | ||
599 | * key state.. if NULL, the interpreter will run without | ||
600 | * trying to connect to the exchange first. | ||
601 | * @param exchange_connect #GNUNET_YES if the test should connect | ||
602 | * to the exchange, #GNUNET_NO otherwise | ||
603 | * @return #GNUNET_OK if all is okay, != #GNUNET_OK otherwise. | ||
604 | * non-GNUNET_OK codes are #GNUNET_SYSERR most of the | ||
605 | * times. | ||
606 | */ | ||
607 | int | ||
608 | GNUNET_TESTING_setup (GNUNET_TESTING_Main main_cb, | ||
609 | void *main_cb_cls, | ||
610 | const struct GNUNET_CONFIGURATION_Handle *cfg, | ||
611 | struct GNUNET_OS_Process *exchanged, | ||
612 | int exchange_connect) | ||
613 | { | ||
614 | struct GNUNET_TESTING_Interpreter is; | ||
615 | struct MainContext main_ctx = { | ||
616 | .main_cb = main_cb, | ||
617 | .main_cb_cls = main_cb_cls, | ||
618 | /* needed to init the curl ctx */ | ||
619 | .is = &is, | ||
620 | }; | ||
621 | struct GNUNET_SIGNAL_Context *shc_chld; | ||
622 | |||
623 | memset (&is, | ||
624 | 0, | ||
625 | sizeof (is)); | ||
626 | is.exchanged = exchanged; | ||
627 | is.cfg = cfg; | ||
628 | sigpipe = GNUNET_DISK_pipe (GNUNET_DISK_PF_NONE); | ||
629 | GNUNET_assert (NULL != sigpipe); | ||
630 | shc_chld = GNUNET_SIGNAL_handler_install | ||
631 | (GNUNET_SIGCHLD, | ||
632 | &sighandler_child_death); | ||
633 | |||
634 | |||
635 | /* Blocking */ | ||
636 | if (GNUNET_YES == exchange_connect) | ||
637 | GNUNET_SCHEDULER_run (&main_wrapper_exchange_connect, | ||
638 | &main_ctx); | ||
639 | else | ||
640 | GNUNET_SCHEDULER_run (&main_wrapper_exchange_agnostic, | ||
641 | &main_ctx); | ||
642 | if (NULL != is.final_cleanup_cb) | ||
643 | is.final_cleanup_cb (is.final_cleanup_cb_cls); | ||
644 | GNUNET_SIGNAL_handler_uninstall (shc_chld); | ||
645 | GNUNET_DISK_pipe_close (sigpipe); | ||
646 | sigpipe = NULL; | ||
647 | GNUNET_free (is.auditor_url); | ||
648 | GNUNET_free (is.exchange_url); | ||
649 | return is.result; | ||
650 | } | 304 | } |
651 | 305 | ||
652 | 306 | ||