diff options
author | Christian Grothoff <christian@grothoff.org> | 2009-07-27 21:12:05 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2009-07-27 21:12:05 +0000 |
commit | eafd8f1af4f3ebafb43bb83aca086f9a41b2c56a (patch) | |
tree | db3c74099e4e4c04f3fd4eaeb1feb2d744b9427e /src/testing | |
parent | 216bd97054c16917135c626c1f4b1590f9452ba1 (diff) | |
download | gnunet-eafd8f1af4f3ebafb43bb83aca086f9a41b2c56a.tar.gz gnunet-eafd8f1af4f3ebafb43bb83aca086f9a41b2c56a.zip |
more testing code
Diffstat (limited to 'src/testing')
-rw-r--r-- | src/testing/testing.c | 246 |
1 files changed, 241 insertions, 5 deletions
diff --git a/src/testing/testing.c b/src/testing/testing.c index 1f6d60229..43553e5c1 100644 --- a/src/testing/testing.c +++ b/src/testing/testing.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include "gnunet_core_service.h" | 33 | #include "gnunet_core_service.h" |
34 | #include "gnunet_constants.h" | 34 | #include "gnunet_constants.h" |
35 | #include "gnunet_testing_lib.h" | 35 | #include "gnunet_testing_lib.h" |
36 | #include "gnunet_transport_service.h" | ||
36 | 37 | ||
37 | #define DEBUG_TESTING GNUNET_YES | 38 | #define DEBUG_TESTING GNUNET_YES |
38 | 39 | ||
@@ -59,7 +60,8 @@ enum StartPhase | |||
59 | SP_START_ARMING, | 60 | SP_START_ARMING, |
60 | SP_START_CORE, | 61 | SP_START_CORE, |
61 | SP_START_DONE, | 62 | SP_START_DONE, |
62 | SP_CLEANUP | 63 | SP_CLEANUP, |
64 | SP_CONFIG_UPDATE | ||
63 | }; | 65 | }; |
64 | 66 | ||
65 | 67 | ||
@@ -116,6 +118,16 @@ struct GNUNET_TESTING_Daemon | |||
116 | void *dead_cb_cls; | 118 | void *dead_cb_cls; |
117 | 119 | ||
118 | /** | 120 | /** |
121 | * Arguments from "daemon_stop" call. | ||
122 | */ | ||
123 | GNUNET_TESTING_NotifyCompletion update_cb; | ||
124 | |||
125 | /** | ||
126 | * Closure for 'update_cb'. | ||
127 | */ | ||
128 | void *update_cb_cls; | ||
129 | |||
130 | /** | ||
119 | * Identity of this peer (once started). | 131 | * Identity of this peer (once started). |
120 | */ | 132 | */ |
121 | struct GNUNET_PeerIdentity id; | 133 | struct GNUNET_PeerIdentity id; |
@@ -149,6 +161,10 @@ struct GNUNET_TESTING_Daemon | |||
149 | */ | 161 | */ |
150 | GNUNET_SCHEDULER_TaskIdentifier task; | 162 | GNUNET_SCHEDULER_TaskIdentifier task; |
151 | 163 | ||
164 | /** | ||
165 | * Handle to the server. | ||
166 | */ | ||
167 | struct GNUNET_CORE_Handle * server; | ||
152 | }; | 168 | }; |
153 | 169 | ||
154 | 170 | ||
@@ -197,6 +213,7 @@ testing_init (void *cls, | |||
197 | GNUNET_TESTING_daemon_stop (d, d->dead_cb, d->dead_cb_cls); | 213 | GNUNET_TESTING_daemon_stop (d, d->dead_cb, d->dead_cb_cls); |
198 | else | 214 | else |
199 | cb (d->cb_cls, my_identity, d->cfg, d, NULL); | 215 | cb (d->cb_cls, my_identity, d->cfg, d, NULL); |
216 | d->server = server; | ||
200 | } | 217 | } |
201 | 218 | ||
202 | 219 | ||
@@ -416,6 +433,50 @@ start_fsm (void *cls, | |||
416 | d->dead_cb (d->dead_cb_cls, NULL); | 433 | d->dead_cb (d->dead_cb_cls, NULL); |
417 | GNUNET_free (d); | 434 | GNUNET_free (d); |
418 | break; | 435 | break; |
436 | case SP_CONFIG_UPDATE: | ||
437 | /* confirm copying complete */ | ||
438 | if (GNUNET_OK != | ||
439 | GNUNET_OS_process_status (d->pid, | ||
440 | &type, | ||
441 | &code)) | ||
442 | { | ||
443 | d->wait_runs++; | ||
444 | if (d->wait_runs > MAX_EXEC_WAIT_RUNS) | ||
445 | { | ||
446 | cb = d->cb; | ||
447 | d->cb = NULL; | ||
448 | cb (d->cb_cls, | ||
449 | NULL, | ||
450 | d->cfg, | ||
451 | d, | ||
452 | _("`scp' does not seem to terminate.\n")); | ||
453 | return; | ||
454 | } | ||
455 | /* wait some more */ | ||
456 | d->task | ||
457 | = GNUNET_SCHEDULER_add_delayed (d->sched, | ||
458 | GNUNET_NO, | ||
459 | GNUNET_SCHEDULER_PRIORITY_KEEP, | ||
460 | GNUNET_SCHEDULER_NO_TASK, | ||
461 | GNUNET_CONSTANTS_EXEC_WAIT, | ||
462 | &start_fsm, | ||
463 | d); | ||
464 | return; | ||
465 | } | ||
466 | if ( (type != GNUNET_OS_PROCESS_EXITED) || | ||
467 | (code != 0) ) | ||
468 | { | ||
469 | d->update_cb (d->update_cb_cls, | ||
470 | _("`scp' did not complete cleanly.\n")); | ||
471 | return; | ||
472 | } | ||
473 | #if DEBUG_TESTING | ||
474 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
475 | "Successfully copied configuration file.\n"); | ||
476 | #endif | ||
477 | d->update_cb (d->update_cb_cls, NULL); | ||
478 | d->phase = SP_START_DONE; | ||
479 | break; | ||
419 | } | 480 | } |
420 | } | 481 | } |
421 | 482 | ||
@@ -505,6 +566,7 @@ GNUNET_TESTING_daemon_start (struct GNUNET_SCHEDULER_Handle *sched, | |||
505 | ret->cfgfile, | 566 | ret->cfgfile, |
506 | arg, | 567 | arg, |
507 | NULL); | 568 | NULL); |
569 | GNUNET_free (arg); | ||
508 | if (-1 == ret->pid) | 570 | if (-1 == ret->pid) |
509 | { | 571 | { |
510 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 572 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
@@ -528,7 +590,6 @@ GNUNET_TESTING_daemon_start (struct GNUNET_SCHEDULER_Handle *sched, | |||
528 | GNUNET_CONSTANTS_EXEC_WAIT, | 590 | GNUNET_CONSTANTS_EXEC_WAIT, |
529 | &start_fsm, | 591 | &start_fsm, |
530 | ret); | 592 | ret); |
531 | GNUNET_free (arg); | ||
532 | return ret; | 593 | return ret; |
533 | } | 594 | } |
534 | ret->phase = SP_COPIED; | 595 | ret->phase = SP_COPIED; |
@@ -562,6 +623,17 @@ void GNUNET_TESTING_daemon_stop (struct GNUNET_TESTING_Daemon *d, | |||
562 | d->dead_cb_cls = cb_cls; | 623 | d->dead_cb_cls = cb_cls; |
563 | return; | 624 | return; |
564 | } | 625 | } |
626 | if (d->phase == SP_CONFIG_UPDATE) | ||
627 | { | ||
628 | GNUNET_SCHEDULER_cancel (d->sched, | ||
629 | d->task); | ||
630 | d->phase = SP_START_DONE; | ||
631 | } | ||
632 | if (d->server != NULL) | ||
633 | { | ||
634 | GNUNET_CORE_disconnect (d->server); | ||
635 | d->server = NULL; | ||
636 | } | ||
565 | /* shutdown ARM process (will also terminate others) */ | 637 | /* shutdown ARM process (will also terminate others) */ |
566 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 638 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
567 | _("Terminating peer `%4s'\n"), | 639 | _("Terminating peer `%4s'\n"), |
@@ -635,11 +707,143 @@ void GNUNET_TESTING_daemon_stop (struct GNUNET_TESTING_Daemon *d, | |||
635 | * @param cb_cls closure for cb | 707 | * @param cb_cls closure for cb |
636 | */ | 708 | */ |
637 | void GNUNET_TESTING_daemon_reconfigure (struct GNUNET_TESTING_Daemon *d, | 709 | void GNUNET_TESTING_daemon_reconfigure (struct GNUNET_TESTING_Daemon *d, |
638 | const struct GNUNET_CONFIGURATION_Handle *cfg, | 710 | struct GNUNET_CONFIGURATION_Handle *cfg, |
639 | GNUNET_TESTING_NotifyCompletion cb, | 711 | GNUNET_TESTING_NotifyCompletion cb, |
640 | void * cb_cls) | 712 | void * cb_cls) |
641 | { | 713 | { |
642 | cb (cb_cls, "not implemented"); | 714 | char *arg; |
715 | |||
716 | if (d->phase != SP_START_DONE) | ||
717 | { | ||
718 | cb (cb_cls, | ||
719 | _("Peer not yet running, can not change configuration at this point.")); | ||
720 | return; | ||
721 | } | ||
722 | |||
723 | /* 1) write configuration to temporary file */ | ||
724 | if (GNUNET_OK != | ||
725 | GNUNET_CONFIGURATION_write (cfg, | ||
726 | d->cfgfile)) | ||
727 | { | ||
728 | cb (cb_cls, | ||
729 | _("Failed to write new configuration to disk.")); | ||
730 | return; | ||
731 | } | ||
732 | |||
733 | /* 2) copy file to remote host (if necessary) */ | ||
734 | if (NULL == d->hostname) | ||
735 | { | ||
736 | /* signal success */ | ||
737 | cb (cb_cls, NULL); | ||
738 | return; | ||
739 | } | ||
740 | d->phase = SP_CONFIG_UPDATE; | ||
741 | if (NULL != d->username) | ||
742 | GNUNET_asprintf (&arg, | ||
743 | "%s@%s:%s", | ||
744 | d->username, | ||
745 | d->hostname, | ||
746 | d->cfgfile); | ||
747 | else | ||
748 | GNUNET_asprintf (&arg, | ||
749 | "%s:%s", | ||
750 | d->hostname, | ||
751 | d->cfgfile); | ||
752 | d->pid = GNUNET_OS_start_process ("scp", | ||
753 | "scp", | ||
754 | d->cfgfile, | ||
755 | arg, | ||
756 | NULL); | ||
757 | GNUNET_free (arg); | ||
758 | if (-1 == d->pid) | ||
759 | { | ||
760 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
761 | _("Could not start `%s' process to copy configuration file.\n"), | ||
762 | "scp"); | ||
763 | cb (cb_cls, | ||
764 | _("Failed to copy new configuration to remote machine.")); | ||
765 | d->phase = SP_START_DONE; | ||
766 | return; | ||
767 | } | ||
768 | d->update_cb = cb; | ||
769 | d->update_cb_cls = cb_cls; | ||
770 | d->task | ||
771 | = GNUNET_SCHEDULER_add_delayed (d->sched, | ||
772 | GNUNET_NO, | ||
773 | GNUNET_SCHEDULER_PRIORITY_KEEP, | ||
774 | GNUNET_SCHEDULER_NO_TASK, | ||
775 | GNUNET_CONSTANTS_EXEC_WAIT, | ||
776 | &start_fsm, | ||
777 | d); | ||
778 | } | ||
779 | |||
780 | |||
781 | struct ConnectContext | ||
782 | { | ||
783 | struct GNUNET_TESTING_Daemon *d1; | ||
784 | struct GNUNET_TESTING_Daemon *d2; | ||
785 | struct GNUNET_TRANSPORT_Handle *d1th; | ||
786 | struct GNUNET_TRANSPORT_Handle *d2th; | ||
787 | struct GNUNET_TIME_Absolute timeout; | ||
788 | GNUNET_TESTING_NotifyCompletion cb; | ||
789 | void *cb_cls; | ||
790 | }; | ||
791 | |||
792 | |||
793 | /** | ||
794 | * Success, connection is up. Signal client our success. | ||
795 | */ | ||
796 | static size_t | ||
797 | transmit_ready (void *cls, size_t size, void *buf) | ||
798 | { | ||
799 | struct ConnectContext *ctx = cls; | ||
800 | if (buf == NULL) | ||
801 | ctx->cb (ctx->cb_cls, _("Peers failed to connect")); | ||
802 | else | ||
803 | ctx->cb (ctx->cb_cls, NULL); | ||
804 | GNUNET_free (ctx); | ||
805 | return 0; | ||
806 | } | ||
807 | |||
808 | |||
809 | /** | ||
810 | * Receive the HELLO from one peer, give it to the other | ||
811 | * and ask them to connect. | ||
812 | * | ||
813 | * @param cls "struct ConnectContext" | ||
814 | * @param latency how fast is the connection | ||
815 | * @param peer ID of peer giving us the HELLO | ||
816 | * @param message HELLO message of peer | ||
817 | */ | ||
818 | static void | ||
819 | process_hello (void *cls, | ||
820 | struct GNUNET_TIME_Relative latency, | ||
821 | const struct GNUNET_PeerIdentity *peer, | ||
822 | const struct GNUNET_MessageHeader *message) | ||
823 | { | ||
824 | struct ConnectContext *ctx = cls; | ||
825 | |||
826 | if (peer == NULL) | ||
827 | { | ||
828 | /* signal error */ | ||
829 | ctx->cb (ctx->cb_cls, | ||
830 | _("Failed to receive `HELLO' from peer\n")); | ||
831 | GNUNET_TRANSPORT_disconnect (ctx->d1th); | ||
832 | GNUNET_TRANSPORT_disconnect (ctx->d2th); | ||
833 | GNUNET_free (ctx); | ||
834 | return; | ||
835 | } | ||
836 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
837 | "Received `%s' from transport service of `%4s'\n", | ||
838 | "HELLO", GNUNET_i2s (peer)); | ||
839 | GNUNET_assert (message != NULL); | ||
840 | GNUNET_TRANSPORT_offer_hello (ctx->d2th, message); | ||
841 | GNUNET_CORE_notify_transmit_ready (ctx->d2->server, | ||
842 | 0, | ||
843 | GNUNET_TIME_absolute_get_remaining (ctx->timeout), | ||
844 | &ctx->d1->id, | ||
845 | sizeof (struct GNUNET_MessageHeader), | ||
846 | &transmit_ready, ctx); | ||
643 | } | 847 | } |
644 | 848 | ||
645 | 849 | ||
@@ -659,7 +863,39 @@ void GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1, | |||
659 | GNUNET_TESTING_NotifyCompletion cb, | 863 | GNUNET_TESTING_NotifyCompletion cb, |
660 | void *cb_cls) | 864 | void *cb_cls) |
661 | { | 865 | { |
662 | cb (cb_cls, "not implemented"); | 866 | struct ConnectContext *ctx; |
867 | |||
868 | if ( (d1->server == NULL) || | ||
869 | (d2->server == NULL) ) | ||
870 | { | ||
871 | cb (cb_cls, _("Peers are not fully running yet, can not connect!\n")); | ||
872 | return; | ||
873 | } | ||
874 | ctx = GNUNET_malloc (sizeof(struct ConnectContext)); | ||
875 | ctx->d1 = d1; | ||
876 | ctx->d2 = d2; | ||
877 | ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); | ||
878 | ctx->cb = cb; | ||
879 | ctx->cb_cls = cb_cls; | ||
880 | ctx->d1th = GNUNET_TRANSPORT_connect (d1->sched, d1->cfg, d1, NULL, NULL, NULL); | ||
881 | if (ctx->d1th == NULL) | ||
882 | { | ||
883 | GNUNET_free (ctx); | ||
884 | cb (cb_cls, _("Failed to connect to transport service!\n")); | ||
885 | return; | ||
886 | } | ||
887 | ctx->d2th = GNUNET_TRANSPORT_connect (d2->sched, d2->cfg, d2, NULL, NULL, NULL); | ||
888 | if (ctx->d2th == NULL) | ||
889 | { | ||
890 | GNUNET_TRANSPORT_disconnect (ctx->d1th); | ||
891 | GNUNET_free (ctx); | ||
892 | cb (cb_cls, _("Failed to connect to transport service!\n")); | ||
893 | return; | ||
894 | } | ||
895 | GNUNET_TRANSPORT_get_hello (ctx->d1th, | ||
896 | timeout, | ||
897 | &process_hello, | ||
898 | ctx); | ||
663 | } | 899 | } |
664 | 900 | ||
665 | 901 | ||