aboutsummaryrefslogtreecommitdiff
path: root/src/testing
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2009-07-27 21:12:05 +0000
committerChristian Grothoff <christian@grothoff.org>2009-07-27 21:12:05 +0000
commiteafd8f1af4f3ebafb43bb83aca086f9a41b2c56a (patch)
treedb3c74099e4e4c04f3fd4eaeb1feb2d744b9427e /src/testing
parent216bd97054c16917135c626c1f4b1590f9452ba1 (diff)
downloadgnunet-eafd8f1af4f3ebafb43bb83aca086f9a41b2c56a.tar.gz
gnunet-eafd8f1af4f3ebafb43bb83aca086f9a41b2c56a.zip
more testing code
Diffstat (limited to 'src/testing')
-rw-r--r--src/testing/testing.c246
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 */
637void GNUNET_TESTING_daemon_reconfigure (struct GNUNET_TESTING_Daemon *d, 709void 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
781struct 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 */
796static size_t
797transmit_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 */
818static void
819process_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