diff options
Diffstat (limited to 'src/testing/testing_api_loop.c')
-rw-r--r-- | src/testing/testing_api_loop.c | 250 |
1 files changed, 249 insertions, 1 deletions
diff --git a/src/testing/testing_api_loop.c b/src/testing/testing_api_loop.c index 90713e45e..420e1cfcc 100644 --- a/src/testing/testing_api_loop.c +++ b/src/testing/testing_api_loop.c | |||
@@ -28,6 +28,7 @@ | |||
28 | #include "platform.h" | 28 | #include "platform.h" |
29 | #include "gnunet_util_lib.h" | 29 | #include "gnunet_util_lib.h" |
30 | #include "gnunet_testing_ng_lib.h" | 30 | #include "gnunet_testing_ng_lib.h" |
31 | #include "gnunet_testing_barrier.h" | ||
31 | #include "testing.h" | 32 | #include "testing.h" |
32 | 33 | ||
33 | /** | 34 | /** |
@@ -36,6 +37,21 @@ | |||
36 | */ | 37 | */ |
37 | struct GNUNET_TESTING_Interpreter | 38 | struct GNUNET_TESTING_Interpreter |
38 | { | 39 | { |
40 | /** | ||
41 | * Send handle for sending messages to netjail nodes. | ||
42 | */ | ||
43 | struct GNUNET_HELPER_SendHandle *sh; | ||
44 | |||
45 | /** | ||
46 | * Array with handles of helper processes for communication with netjails. | ||
47 | */ | ||
48 | const struct GNUNET_HELPER_Handle **helper; | ||
49 | |||
50 | /** | ||
51 | * Size of the array helper. | ||
52 | * | ||
53 | */ | ||
54 | unsigned int n_helper; | ||
39 | 55 | ||
40 | /** | 56 | /** |
41 | * Function to call with the test result. | 57 | * Function to call with the test result. |
@@ -53,6 +69,11 @@ struct GNUNET_TESTING_Interpreter | |||
53 | struct GNUNET_TESTING_Command *commands; | 69 | struct GNUNET_TESTING_Command *commands; |
54 | 70 | ||
55 | /** | 71 | /** |
72 | * Map with barriers for this loop. | ||
73 | */ | ||
74 | struct GNUNET_CONTAINER_MultiShortmap *barriers; | ||
75 | |||
76 | /** | ||
56 | * Number of GNUNET_TESTING_Command in commands. | 77 | * Number of GNUNET_TESTING_Command in commands. |
57 | */ | 78 | */ |
58 | unsigned int cmds_n; | 79 | unsigned int cmds_n; |
@@ -84,6 +105,24 @@ struct GNUNET_TESTING_Interpreter | |||
84 | */ | 105 | */ |
85 | enum GNUNET_GenericReturnValue result; | 106 | enum GNUNET_GenericReturnValue result; |
86 | 107 | ||
108 | /** | ||
109 | * Is the interpreter finishing? | ||
110 | */ | ||
111 | unsigned int finishing; | ||
112 | |||
113 | }; | ||
114 | |||
115 | struct FreeBarrierNodeCbCls | ||
116 | { | ||
117 | /** | ||
118 | * The interpreter. | ||
119 | */ | ||
120 | struct GNUNET_TESTING_Interpreter *is; | ||
121 | |||
122 | /** | ||
123 | * The barrier from which the nodes are freed.. | ||
124 | */ | ||
125 | struct GNUNET_TESTING_Barrier *barrier; | ||
87 | }; | 126 | }; |
88 | 127 | ||
89 | 128 | ||
@@ -215,6 +254,7 @@ finish_test (void *cls) | |||
215 | struct GNUNET_TESTING_Command *cmd; | 254 | struct GNUNET_TESTING_Command *cmd; |
216 | const char *label; | 255 | const char *label; |
217 | 256 | ||
257 | is->finishing = GNUNET_YES; | ||
218 | is->final_task = NULL; | 258 | is->final_task = NULL; |
219 | label = is->commands[is->ip].label; | 259 | label = is->commands[is->ip].label; |
220 | if (NULL == label) | 260 | if (NULL == label) |
@@ -448,7 +488,7 @@ GNUNET_TESTING_finished (struct GNUNET_TESTING_Command *command) | |||
448 | } | 488 | } |
449 | 489 | ||
450 | 490 | ||
451 | void | 491 | struct GNUNET_TESTING_Interpreter * |
452 | GNUNET_TESTING_run (struct GNUNET_TESTING_Command *commands, | 492 | GNUNET_TESTING_run (struct GNUNET_TESTING_Command *commands, |
453 | struct GNUNET_TIME_Relative timeout, | 493 | struct GNUNET_TIME_Relative timeout, |
454 | GNUNET_TESTING_ResultCallback rc, | 494 | GNUNET_TESTING_ResultCallback rc, |
@@ -460,6 +500,7 @@ GNUNET_TESTING_run (struct GNUNET_TESTING_Command *commands, | |||
460 | is = GNUNET_new (struct GNUNET_TESTING_Interpreter); | 500 | is = GNUNET_new (struct GNUNET_TESTING_Interpreter); |
461 | is->rc = rc; | 501 | is->rc = rc; |
462 | is->rc_cls = rc_cls; | 502 | is->rc_cls = rc_cls; |
503 | is->barriers = GNUNET_CONTAINER_multishortmap_create (1,GNUNET_NO); | ||
463 | /* get the number of commands */ | 504 | /* get the number of commands */ |
464 | for (i = 0; NULL != commands[i].label; i++) | 505 | for (i = 0; NULL != commands[i].label; i++) |
465 | ; | 506 | ; |
@@ -475,6 +516,8 @@ GNUNET_TESTING_run (struct GNUNET_TESTING_Command *commands, | |||
475 | is); | 516 | is); |
476 | is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, | 517 | is->task = GNUNET_SCHEDULER_add_now (&interpreter_run, |
477 | is); | 518 | is); |
519 | |||
520 | return is; | ||
478 | } | 521 | } |
479 | 522 | ||
480 | 523 | ||
@@ -538,6 +581,211 @@ loop_run (void *cls) | |||
538 | mp); | 581 | mp); |
539 | } | 582 | } |
540 | 583 | ||
584 | /** | ||
585 | * Continuation function from GNUNET_HELPER_send() | ||
586 | * | ||
587 | * @param cls closure | ||
588 | * @param result GNUNET_OK on success, | ||
589 | * GNUNET_NO if helper process died | ||
590 | * GNUNET_SYSERR during GNUNET_HELPER_stop | ||
591 | */ | ||
592 | static void | ||
593 | clear_msg (void *cls, int result) | ||
594 | { | ||
595 | struct GNUNET_TESTING_Interpreter *is = cls; | ||
596 | |||
597 | GNUNET_assert (NULL != is->sh); | ||
598 | GNUNET_free (is->sh); | ||
599 | is->sh = NULL; | ||
600 | } | ||
601 | |||
602 | /** | ||
603 | * Adding a helper handle to the interpreter. | ||
604 | * | ||
605 | * @param is The interpreter. | ||
606 | * @param helper The helper handle. | ||
607 | */ | ||
608 | void | ||
609 | GNUNET_TESTING_add_netjail_helper (struct GNUNET_TESTING_Interpreter *is, | ||
610 | const struct GNUNET_HELPER_Handle *helper) | ||
611 | { | ||
612 | GNUNET_array_append (is->helper, is->n_helper, helper); | ||
613 | } | ||
614 | |||
615 | |||
616 | /** | ||
617 | * Send Message to netjail nodes that a barrier can be advanced. | ||
618 | * | ||
619 | * @param is The interpreter. | ||
620 | * @param global_node_number The node to inform. | ||
621 | * @param header The message to send. | ||
622 | */ | ||
623 | void | ||
624 | GNUNET_TESTING_send_message_to_netjail (struct GNUNET_TESTING_Interpreter *is, | ||
625 | unsigned int global_node_number, | ||
626 | struct GNUNET_MessageHeader *header) | ||
627 | { | ||
628 | const struct GNUNET_HELPER_Handle *helper; | ||
629 | |||
630 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
631 | "send message of type %u to locals\n", | ||
632 | header->type); | ||
633 | helper = is->helper[global_node_number - 1]; | ||
634 | struct GNUNET_HELPER_SendHandle *sh = GNUNET_HELPER_send ( | ||
635 | (struct GNUNET_HELPER_Handle *) helper, | ||
636 | header, | ||
637 | GNUNET_NO, | ||
638 | &clear_msg, | ||
639 | is); | ||
640 | } | ||
641 | |||
642 | |||
643 | int | ||
644 | free_barrier_node_cb (void *cls, | ||
645 | const struct GNUNET_ShortHashCode *key, | ||
646 | void *value) | ||
647 | { | ||
648 | struct FreeBarrierNodeCbCls *free_barrier_node_cb_cls = cls; | ||
649 | struct GNUNET_TESTING_NetjailNode *node = value; | ||
650 | struct GNUNET_TESTING_Barrier *barrier = free_barrier_node_cb_cls->barrier; | ||
651 | struct GNUNET_TESTING_Interpreter *is = free_barrier_node_cb_cls->is; | ||
652 | |||
653 | if (GNUNET_NO == is->finishing) | ||
654 | { | ||
655 | GNUNET_TESTING_send_barrier_advance (is, | ||
656 | barrier->name, | ||
657 | node->node_number); | ||
658 | } | ||
659 | GNUNET_CONTAINER_multishortmap_remove (barrier->nodes, key, node); | ||
660 | } | ||
661 | |||
662 | |||
663 | /** | ||
664 | * Finish all "barrier reached" comands attached to this barrier. | ||
665 | * | ||
666 | * @param barrier The barrier in question. | ||
667 | */ | ||
668 | void | ||
669 | GNUNET_TESTING_finish_attached_cmds (struct GNUNET_TESTING_Interpreter *is, | ||
670 | struct GNUNET_TESTING_Barrier *barrier) | ||
671 | { | ||
672 | struct GNUNET_TESTING_Command *pos; | ||
673 | struct FreeBarrierNodeCbCls *free_barrier_node_cb_cls; | ||
674 | |||
675 | while (NULL != (pos = barrier->cmds_head)) | ||
676 | { | ||
677 | if (GNUNET_NO == pos->ac->finished && GNUNET_NO == pos->asynchronous_finish) | ||
678 | { | ||
679 | GNUNET_TESTING_async_finish (pos->ac); | ||
680 | } | ||
681 | else if (GNUNET_NO == pos->ac->finished) | ||
682 | { | ||
683 | pos->asynchronous_finish = GNUNET_YES; | ||
684 | } | ||
685 | GNUNET_CONTAINER_DLL_remove (barrier->cmds_head, | ||
686 | barrier->cmds_tail, | ||
687 | pos); | ||
688 | GNUNET_free (pos); | ||
689 | } | ||
690 | free_barrier_node_cb_cls = GNUNET_new (struct FreeBarrierNodeCbCls); | ||
691 | free_barrier_node_cb_cls->barrier = barrier; | ||
692 | free_barrier_node_cb_cls->is = is; | ||
693 | GNUNET_CONTAINER_multishortmap_iterate (barrier->nodes, free_barrier_node_cb, free_barrier_node_cb_cls); | ||
694 | GNUNET_CONTAINER_multishortmap_destroy (barrier->nodes); | ||
695 | GNUNET_free (free_barrier_node_cb_cls); | ||
696 | } | ||
697 | |||
698 | |||
699 | int | ||
700 | free_barriers_cb (void *cls, | ||
701 | const struct GNUNET_ShortHashCode *key, | ||
702 | void *value) | ||
703 | { | ||
704 | struct GNUNET_TESTING_Interpreter *is = cls; | ||
705 | struct GNUNET_TESTING_Barrier *barrier = value; | ||
706 | struct GNUNET_TESTING_Command *pos; | ||
707 | struct GNUNET_TESTING_NetjailNode *node; | ||
708 | struct FreeBarrierNodeCbCls *free_barrier_node_cb_cls; | ||
709 | |||
710 | free_barrier_node_cb_cls = GNUNET_new (struct FreeBarrierNodeCbCls); | ||
711 | free_barrier_node_cb_cls->barrier = barrier; | ||
712 | free_barrier_node_cb_cls->is = is; | ||
713 | GNUNET_CONTAINER_multishortmap_iterate (barrier->nodes, free_barrier_node_cb, free_barrier_node_cb_cls); | ||
714 | GNUNET_CONTAINER_multishortmap_destroy (barrier->nodes); | ||
715 | |||
716 | while (NULL != (pos = barrier->cmds_head)) | ||
717 | { | ||
718 | GNUNET_CONTAINER_DLL_remove (barrier->cmds_head, | ||
719 | barrier->cmds_tail, | ||
720 | pos); | ||
721 | GNUNET_free (pos); | ||
722 | } | ||
723 | GNUNET_free (barrier); | ||
724 | } | ||
725 | |||
726 | |||
727 | /** | ||
728 | * Deleting all barriers create in the context of this interpreter. | ||
729 | * | ||
730 | * @param is The interpreter. | ||
731 | */ | ||
732 | void | ||
733 | GNUNET_TESTING_delete_barriers (struct GNUNET_TESTING_Interpreter *is) | ||
734 | { | ||
735 | GNUNET_CONTAINER_multishortmap_iterate (is->barriers, | ||
736 | free_barriers_cb, | ||
737 | is); | ||
738 | GNUNET_CONTAINER_multishortmap_destroy (is->barriers); | ||
739 | } | ||
740 | |||
741 | /** | ||
742 | * Getting a barrier from the interpreter. | ||
743 | * | ||
744 | * @param is The interpreter. | ||
745 | * @param barrier_name The name of the barrier. | ||
746 | * @return The barrier. | ||
747 | */ | ||
748 | struct GNUNET_TESTING_Barrier * | ||
749 | GNUNET_TESTING_get_barrier (struct GNUNET_TESTING_Interpreter *is, | ||
750 | const char *barrier_name) | ||
751 | { | ||
752 | struct GNUNET_HashCode hc; | ||
753 | struct GNUNET_ShortHashCode create_key; | ||
754 | struct GNUNET_TESTING_Barrier *barrier; | ||
755 | unsigned int kx; | ||
756 | |||
757 | GNUNET_CRYPTO_hash (barrier_name, strlen(barrier_name), &hc); | ||
758 | memcpy (&create_key, | ||
759 | &hc, | ||
760 | sizeof (create_key)); | ||
761 | barrier = GNUNET_CONTAINER_multishortmap_get (is->barriers, &create_key); | ||
762 | //GNUNET_free (create_key); | ||
763 | return barrier; | ||
764 | } | ||
765 | |||
766 | /** | ||
767 | * Add a barrier to the loop. | ||
768 | * | ||
769 | * @param is The interpreter. | ||
770 | * @param barrier The barrier to add. | ||
771 | */ | ||
772 | void | ||
773 | GNUNET_TESTING_barrier_add (struct GNUNET_TESTING_Interpreter *is, | ||
774 | struct GNUNET_TESTING_Barrier *barrier) | ||
775 | { | ||
776 | struct GNUNET_HashCode hc; | ||
777 | struct GNUNET_ShortHashCode create_key; | ||
778 | |||
779 | GNUNET_CRYPTO_hash (barrier->name, strlen(barrier->name), &hc); | ||
780 | memcpy (&create_key, | ||
781 | &hc, | ||
782 | sizeof (create_key)); | ||
783 | GNUNET_CONTAINER_multishortmap_put (is->barriers, | ||
784 | &create_key, | ||
785 | barrier, | ||
786 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY); | ||
787 | } | ||
788 | |||
541 | 789 | ||
542 | int | 790 | int |
543 | GNUNET_TESTING_main (struct GNUNET_TESTING_Command *commands, | 791 | GNUNET_TESTING_main (struct GNUNET_TESTING_Command *commands, |