aboutsummaryrefslogtreecommitdiff
path: root/src/testing/testing.c
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2010-02-11 13:37:09 +0000
committerNathan S. Evans <evans@in.tum.de>2010-02-11 13:37:09 +0000
commit0bcffe690a5345324d7be4099a4bec157ec1282b (patch)
tree1f7d0e8e3295a4bd204ccc611f349d90c6227aea /src/testing/testing.c
parentdc252383026ab4641549b826a16548e0c1f2cb6d (diff)
downloadgnunet-0bcffe690a5345324d7be4099a4bec157ec1282b.tar.gz
gnunet-0bcffe690a5345324d7be4099a4bec157ec1282b.zip
testing changes, including real topology test (only for clique, and not that great of a test). Need to verify it will run on other machines... also need to commit it since it currently works for me
Diffstat (limited to 'src/testing/testing.c')
-rw-r--r--src/testing/testing.c380
1 files changed, 165 insertions, 215 deletions
diff --git a/src/testing/testing.c b/src/testing/testing.c
index 8ceaace75..bddd0f30c 100644
--- a/src/testing/testing.c
+++ b/src/testing/testing.c
@@ -54,160 +54,6 @@
54 */ 54 */
55#define MAX_EXEC_WAIT_RUNS 50 55#define MAX_EXEC_WAIT_RUNS 50
56 56
57/**
58 * Phases of starting GNUnet on a system.
59 */
60enum StartPhase
61{
62 /**
63 * Copy the configuration file to the target system.
64 */
65 SP_COPYING,
66
67 /**
68 * Configuration file has been copied, start ARM on target system.
69 */
70 SP_COPIED,
71
72 /**
73 * ARM has been started, check that it has properly daemonized and
74 * then try to connect to the CORE service (which should be
75 * auto-started by ARM).
76 */
77 SP_START_ARMING,
78
79 /**
80 * We're waiting for CORE to start.
81 */
82 SP_START_CORE,
83
84 /**
85 * Core has notified us that we've established a connection to the service.
86 * The main FSM halts here and waits to be moved to UPDATE or CLEANUP.
87 */
88 SP_START_DONE,
89
90 /**
91 * We've been asked to terminate the instance and are now waiting for
92 * the remote command to delete the configuration file to complete.
93 */
94 SP_CLEANUP,
95
96 /**
97 * We've received a configuration update and are currently waiting for
98 * the copy process for the update to complete. Once it is, we will
99 * return to "SP_START_DONE" (and rely on ARM to restart all affected
100 * services).
101 */
102 SP_CONFIG_UPDATE
103};
104
105
106/**
107 * Handle for a GNUnet daemon (technically a set of
108 * daemons; the handle is really for the master ARM
109 * daemon) started by the testing library.
110 */
111struct GNUNET_TESTING_Daemon
112{
113 /**
114 * Our scheduler.
115 */
116 struct GNUNET_SCHEDULER_Handle *sched;
117
118 /**
119 * Our configuration.
120 */
121 struct GNUNET_CONFIGURATION_Handle *cfg;
122
123 /**
124 * Host to run GNUnet on.
125 */
126 char *hostname;
127
128 /* Result of GNUNET_i2s of this peer, for printing */
129 char *shortname;
130
131 /**
132 * Username we are using.
133 */
134 char *username;
135
136 /**
137 * Name of the configuration file
138 */
139 char *cfgfile;
140
141 /**
142 * Function to call when the peer is running.
143 */
144 GNUNET_TESTING_NotifyDaemonRunning cb;
145
146 /**
147 * Closure for cb.
148 */
149 void *cb_cls;
150
151 /**
152 * Arguments from "daemon_stop" call.
153 */
154 GNUNET_TESTING_NotifyCompletion dead_cb;
155
156 /**
157 * Closure for 'dead_cb'.
158 */
159 void *dead_cb_cls;
160
161 /**
162 * Arguments from "daemon_stop" call.
163 */
164 GNUNET_TESTING_NotifyCompletion update_cb;
165
166 /**
167 * Closure for 'update_cb'.
168 */
169 void *update_cb_cls;
170
171 /**
172 * Identity of this peer (once started).
173 */
174 struct GNUNET_PeerIdentity id;
175
176 /**
177 * Flag to indicate that we've already been asked
178 * to terminate (but could not because some action
179 * was still pending).
180 */
181 int dead;
182
183 /**
184 * PID of the process that we started last.
185 */
186 pid_t pid;
187
188 /**
189 * How many iterations have we been waiting for
190 * the started process to complete?
191 */
192 unsigned int wait_runs;
193
194 /**
195 * In which phase are we during the start of
196 * this process?
197 */
198 enum StartPhase phase;
199
200 /**
201 * ID of the current task.
202 */
203 GNUNET_SCHEDULER_TaskIdentifier task;
204
205 /**
206 * Handle to the server.
207 */
208 struct GNUNET_CORE_Handle *server;
209};
210
211 57
212/** 58/**
213 * Function called after GNUNET_CORE_connect has succeeded 59 * Function called after GNUNET_CORE_connect has succeeded
@@ -793,11 +639,21 @@ struct ConnectContext
793 */ 639 */
794 struct GNUNET_TESTING_Daemon *d1; 640 struct GNUNET_TESTING_Daemon *d1;
795 641
642 /*
643 * Handle to core of first daemon (to check connect)
644 */
645 struct GNUNET_CORE_Handle * d1core;
646
796 /** 647 /**
797 * Testing handle to the second daemon. 648 * Testing handle to the second daemon.
798 */ 649 */
799 struct GNUNET_TESTING_Daemon *d2; 650 struct GNUNET_TESTING_Daemon *d2;
800 651
652 /*
653 * Handle to core of second daemon (to check connect)
654 */
655 struct GNUNET_CORE_Handle * d2core;
656
801 /** 657 /**
802 * Transport handle to the first daemon. 658 * Transport handle to the first daemon.
803 */ 659 */
@@ -830,10 +686,61 @@ struct ConnectContext
830 */ 686 */
831 struct GNUNET_TIME_Absolute timeout; 687 struct GNUNET_TIME_Absolute timeout;
832 688
689 /*
690 * Hello timeout task
691 */
692 GNUNET_SCHEDULER_TaskIdentifier hello_send_task;
693
694 /*
695 * Connect timeout task
696 */
697 GNUNET_SCHEDULER_TaskIdentifier timeout_task;
698
699 /**
700 * When should this operation be complete (or we must trigger
701 * a timeout).
702 */
703 struct GNUNET_TIME_Relative timeout_hello;
704
705 /*
706 * The current hello message we have (for d1)
707 */
708 struct GNUNET_MessageHeader *hello;
709
710 /*
711 * Was the connection successful?
712 */
713 int connected;
833}; 714};
834 715
835 716
836/** 717/**
718 * Receive the HELLO from one peer, give it to the other
719 * and ask them to connect.
720 *
721 * @param cls "struct ConnectContext"
722 * @param message HELLO message of peer
723 */
724static void
725process_hello (void *cls, const struct GNUNET_MessageHeader *message)
726{
727 struct ConnectContext *ctx = cls;
728
729#if DEBUG_TESTING
730 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
731 "Received `%s' from transport service of `%4s'\n",
732 "HELLO", GNUNET_i2s (&ctx->d1->id));
733#endif
734
735 GNUNET_assert (message != NULL);
736 GNUNET_free_non_null(ctx->hello);
737 ctx->hello = GNUNET_malloc(ntohs(message->size));
738 memcpy(ctx->hello, message, ntohs(message->size));
739
740}
741
742
743/**
837 * Notify callback about success or failure of the attempt 744 * Notify callback about success or failure of the attempt
838 * to connect the two peers 745 * to connect the two peers
839 * 746 *
@@ -846,16 +753,33 @@ notify_connect_result (void *cls,
846{ 753{
847 struct ConnectContext *ctx = cls; 754 struct ConnectContext *ctx = cls;
848 755
756 GNUNET_TRANSPORT_get_hello_cancel (ctx->d1th, &process_hello, ctx);
757 GNUNET_SCHEDULER_cancel(ctx->d1->sched, ctx->hello_send_task);
758
849 if (ctx->cb != NULL) 759 if (ctx->cb != NULL)
850 { 760 {
851 if ((tc->reason & GNUNET_SCHEDULER_REASON_TIMEOUT) != 0) 761 if (ctx->connected == GNUNET_NO)
852 ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, ctx->d1->cfg, 762 {
853 ctx->d2->cfg, ctx->d1, ctx->d2, 763 ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, ctx->d1->cfg,
854 _("Peers failed to connect")); 764 ctx->d2->cfg, ctx->d1, ctx->d2,
765 _("Peers failed to connect"));
766 }
855 else 767 else
856 ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, ctx->d1->cfg, 768 {
857 ctx->d2->cfg, ctx->d1, ctx->d2, NULL); 769 ctx->cb (ctx->cb_cls, &ctx->d1->id, &ctx->d2->id, ctx->d1->cfg,
770 ctx->d2->cfg, ctx->d1, ctx->d2, NULL);
771 GNUNET_SCHEDULER_cancel(ctx->d1->sched, ctx->timeout_task);
772 }
858 } 773 }
774
775 ctx->ntr = NULL;
776 GNUNET_TRANSPORT_disconnect (ctx->d1th);
777 ctx->d1th = NULL;
778 GNUNET_TRANSPORT_disconnect (ctx->d2th);
779 ctx->d2th = NULL;
780 GNUNET_CORE_disconnect (ctx->d1core);
781 ctx->d1core = NULL;
782
859 GNUNET_free (ctx); 783 GNUNET_free (ctx);
860} 784}
861 785
@@ -868,74 +792,48 @@ notify_connect_result (void *cls,
868 * @param buf where to copy the message, NULL on error 792 * @param buf where to copy the message, NULL on error
869 * @return number of bytes copied to buf 793 * @return number of bytes copied to buf
870 */ 794 */
871static size_t 795static void
872transmit_ready (void *cls, size_t size, void *buf) 796connect_notify (void *cls, const struct GNUNET_PeerIdentity * peer, struct GNUNET_TIME_Relative latency,
797 uint32_t distance)
873{ 798{
874 struct ConnectContext *ctx = cls; 799 struct ConnectContext *ctx = cls;
875 800
876#if DEBUG_TESTING 801#if DEBUG_TESTING
877 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 802 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
878 "Core notified us about readiness to transmit message, connection must be up!\n"); 803 "Core notified us about connection to a peer\n\n\n");
879#endif 804#endif
880 ctx->ntr = NULL; 805 if (memcmp(&ctx->d2->id, peer, sizeof(struct GNUNET_PeerIdentity)) == 0)
881 GNUNET_TRANSPORT_disconnect (ctx->d1th); 806 {
882 ctx->d1th = NULL; 807#if DEBUG_TESTING
883 GNUNET_TRANSPORT_disconnect (ctx->d2th); 808 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
884 ctx->d2th = NULL; 809 "Core notified us about connection to peer %s\n\n\n", GNUNET_i2s(peer));
885 GNUNET_SCHEDULER_add_continuation (ctx->d1->sched,
886 &notify_connect_result,
887 ctx,
888 (buf == NULL) ?
889 GNUNET_SCHEDULER_REASON_TIMEOUT :
890 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
891 return 0;
892}
893
894
895#if 0
896static void
897timeout_hello_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
898{
899 GNUNET_TRANSPORT_get_hello_cancel (ctx->d1th, &process_hello, ctx);
900 GNUNET_TRANSPORT_disconnect (ctx->d1th);
901 GNUNET_TRANSPORT_disconnect (ctx->d2th);
902 if (NULL != ctx->cb)
903 ctx->cb (ctx->cb_cls, _("Failed to receive `HELLO' from peer\n"));
904 GNUNET_free (ctx);
905}
906#endif 810#endif
811 /*
812 * If we disconnect here, then the hello may never get sent (if it was delayed!)
813 * However I'm sure there was a reason it was here... so I'm just commenting.
814 */
815 ctx->connected = GNUNET_YES;
816 GNUNET_SCHEDULER_add_now (ctx->d1->sched,
817 &notify_connect_result,
818 ctx);
819 }
907 820
821}
908 822
909/**
910 * Receive the HELLO from one peer, give it to the other
911 * and ask them to connect.
912 *
913 * @param cls "struct ConnectContext"
914 * @param message HELLO message of peer
915 */
916static void 823static void
917process_hello (void *cls, const struct GNUNET_MessageHeader *message) 824send_hello(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
918{ 825{
919 struct ConnectContext *ctx = cls; 826 struct ConnectContext *ctx = cls;
920 827
921 /* first of all, stop the notification stuff */ 828 GNUNET_assert (ctx->hello != NULL);
922 GNUNET_TRANSPORT_get_hello_cancel (ctx->d1th, &process_hello, ctx); 829 GNUNET_TRANSPORT_offer_hello (ctx->d2th, ctx->hello);
923#if DEBUG_TESTING 830
924 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 831 ctx->timeout_hello = GNUNET_TIME_relative_multiply(ctx->timeout_hello, 2);
925 "Received `%s' from transport service of `%4s'\n", 832 ctx->hello_send_task = GNUNET_SCHEDULER_add_delayed(ctx->d1->sched, ctx->timeout_hello, &send_hello, ctx);
926 "HELLO", GNUNET_i2s (&ctx->d1->id));
927#endif
928 GNUNET_assert (message != NULL);
929 GNUNET_TRANSPORT_offer_hello (ctx->d2th, message);
930 ctx->ntr
931 = GNUNET_CORE_notify_transmit_ready (ctx->d2->server,
932 0,
933 GNUNET_TIME_absolute_get_remaining
934 (ctx->timeout), &ctx->d1->id,
935 sizeof (struct GNUNET_MessageHeader),
936 &transmit_ready, ctx);
937} 833}
938 834
835
836#if HIDDEN
939/* 837/*
940 * Accessor function since we have hidden what GNUNET_TESTING_Daemon is 838 * Accessor function since we have hidden what GNUNET_TESTING_Daemon is
941 * 839 *
@@ -947,6 +845,32 @@ GNUNET_TESTING_daemon_get_shortname (struct GNUNET_TESTING_Daemon *d)
947 return d->shortname; 845 return d->shortname;
948} 846}
949 847
848char *
849GNUNET_TESTING_daemon_get_hostname (struct GNUNET_TESTING_Daemon *d)
850{
851 return d->hostname;
852}
853
854char *
855GNUNET_TESTING_daemon_get_username (struct GNUNET_TESTING_Daemon *d)
856{
857 return d->username;
858}
859
860struct GNUNET_PeerIdentity *
861GNUNET_TESTING_daemon_get_peer (struct GNUNET_TESTING_Daemon *d)
862{
863 return &d->id;
864}
865
866struct GNUNET_CONFIGURATION_Handle *
867GNUNET_TESTING_daemon_get_config (struct GNUNET_TESTING_Daemon *d)
868{
869 return d->cfg;
870}
871#endif
872
873
950/** 874/**
951 * Establish a connection between two GNUnet daemons. 875 * Establish a connection between two GNUnet daemons.
952 * 876 *
@@ -965,6 +889,7 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
965 void *cb_cls) 889 void *cb_cls)
966{ 890{
967 struct ConnectContext *ctx; 891 struct ConnectContext *ctx;
892 static struct GNUNET_CORE_MessageHandler no_handlers[] = { {NULL, 0, 0} };
968 893
969 if ((d1->server == NULL) || (d2->server == NULL)) 894 if ((d1->server == NULL) || (d2->server == NULL))
970 { 895 {
@@ -979,6 +904,8 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
979 ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout); 904 ctx->timeout = GNUNET_TIME_relative_to_absolute (timeout);
980 ctx->cb = cb; 905 ctx->cb = cb;
981 ctx->cb_cls = cb_cls; 906 ctx->cb_cls = cb_cls;
907 ctx->timeout_hello = GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 800);
908 ctx->connected = GNUNET_NO;
982#if DEBUG_TESTING 909#if DEBUG_TESTING
983 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 910 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
984 "Asked to connect peer %s to peer %s\n", 911 "Asked to connect peer %s to peer %s\n",
@@ -986,6 +913,24 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
986 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 913 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
987 "Connecting to transport service of peer %s\n", d1->shortname); 914 "Connecting to transport service of peer %s\n", d1->shortname);
988#endif 915#endif
916
917 ctx->d1core = GNUNET_CORE_connect (d1->sched,
918 d1->cfg,
919 timeout,
920 ctx,
921 NULL,
922 NULL, &connect_notify, NULL,
923 NULL, GNUNET_NO,
924 NULL, GNUNET_NO, no_handlers);
925 if (ctx->d1core == NULL)
926 {
927 GNUNET_free (ctx);
928 if (NULL != cb)
929 cb (cb_cls, &d1->id, &d2->id, d1->cfg, d2->cfg, d1, d2,
930 _("Failed to connect to core service of first peer!\n"));
931 return;
932 }
933
989 ctx->d1th = GNUNET_TRANSPORT_connect (d1->sched, 934 ctx->d1th = GNUNET_TRANSPORT_connect (d1->sched,
990 d1->cfg, d1, NULL, NULL, NULL); 935 d1->cfg, d1, NULL, NULL, NULL);
991 if (ctx->d1th == NULL) 936 if (ctx->d1th == NULL)
@@ -1004,6 +949,7 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
1004 "Connecting to transport service of peer %s\n", d2->shortname); 949 "Connecting to transport service of peer %s\n", d2->shortname);
1005 950
1006#endif 951#endif
952
1007 ctx->d2th = GNUNET_TRANSPORT_connect (d2->sched, 953 ctx->d2th = GNUNET_TRANSPORT_connect (d2->sched,
1008 d2->cfg, d2, NULL, NULL, NULL); 954 d2->cfg, d2, NULL, NULL, NULL);
1009 if (ctx->d2th == NULL) 955 if (ctx->d2th == NULL)
@@ -1020,9 +966,13 @@ GNUNET_TESTING_daemons_connect (struct GNUNET_TESTING_Daemon *d1,
1020 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 966 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1021 "Asking for hello from peer %s\n", GNUNET_i2s (&d1->id)); 967 "Asking for hello from peer %s\n", GNUNET_i2s (&d1->id));
1022#endif 968#endif
1023 /* FIXME: need to handle timeout: start timeout task 969
1024 as well here! (use 'timeout_hello_task') */ 970 ctx->timeout_task = GNUNET_SCHEDULER_add_delayed (d1->sched,
971 timeout,
972 &notify_connect_result, ctx);
973
1025 GNUNET_TRANSPORT_get_hello (ctx->d1th, &process_hello, ctx); 974 GNUNET_TRANSPORT_get_hello (ctx->d1th, &process_hello, ctx);
975 ctx->hello_send_task = GNUNET_SCHEDULER_add_delayed(ctx->d1->sched, ctx->timeout_hello, &send_hello, ctx);
1026} 976}
1027 977
1028 978