diff options
author | Christian Grothoff <christian@grothoff.org> | 2012-10-31 21:30:55 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2012-10-31 21:30:55 +0000 |
commit | 8df95b854d763559f2b06e3a6c3cb143723facc6 (patch) | |
tree | 68de6417f9a09ddeccd5071da96174f1024af9d6 | |
parent | 48c3f008109fe5c1925eee5fc946e5e606d410c7 (diff) | |
download | gnunet-8df95b854d763559f2b06e3a6c3cb143723facc6.tar.gz gnunet-8df95b854d763559f2b06e3a6c3cb143723facc6.zip |
-moving DHT test to testbed API
-rw-r--r-- | src/dht/Makefile.am | 35 | ||||
-rw-r--r-- | src/dht/dht_api.c | 2 | ||||
-rw-r--r-- | src/dht/dht_test_lib.c | 214 | ||||
-rw-r--r-- | src/dht/dht_test_lib.h | 80 | ||||
-rw-r--r-- | src/dht/test_dht_topo.c | 674 | ||||
-rw-r--r-- | src/include/gnunet_dht_service.h | 6 | ||||
-rw-r--r-- | src/testbed/testbed_api_testbed.c | 2 |
7 files changed, 514 insertions, 499 deletions
diff --git a/src/dht/Makefile.am b/src/dht/Makefile.am index a365c5e82..982c33815 100644 --- a/src/dht/Makefile.am +++ b/src/dht/Makefile.am | |||
@@ -109,6 +109,17 @@ gnunet_dht_monitor_DEPENDENCIES = \ | |||
109 | libgnunetdht.la | 109 | libgnunetdht.la |
110 | 110 | ||
111 | 111 | ||
112 | noinst_LIBRARIES = libgnunetdhttest.a | ||
113 | |||
114 | libgnunetdhttest_a_SOURCES = \ | ||
115 | dht_test_lib.c dht_test_lib.h | ||
116 | libgnunetdhttest_a_LIBADD = \ | ||
117 | $(top_builddir)/src/util/libgnunetutil.la \ | ||
118 | $(top_builddir)/src/testbed/libgnunettestbed.la \ | ||
119 | $(top_builddir)/src/dht/libgnunetdht.la | ||
120 | libgnunetdhttest_a_DEPENDENCIES = \ | ||
121 | libgnunetdht.la | ||
122 | |||
112 | check_PROGRAMS = \ | 123 | check_PROGRAMS = \ |
113 | test_dht_api \ | 124 | test_dht_api \ |
114 | test_dht_twopeer \ | 125 | test_dht_twopeer \ |
@@ -120,15 +131,18 @@ check_PROGRAMS = \ | |||
120 | test_dht_2dtorus \ | 131 | test_dht_2dtorus \ |
121 | test_dht_monitor | 132 | test_dht_monitor |
122 | 133 | ||
134 | if HAVE_EXPERIMENTAL | ||
135 | NEW_TESTS = test_dht_line test_dht_2dtorus | ||
136 | endif | ||
137 | |||
123 | if ENABLE_TEST_RUN | 138 | if ENABLE_TEST_RUN |
124 | TESTS = test_dht_api $(check_SCRIPTS) \ | 139 | TESTS = test_dht_api $(check_SCRIPTS) \ |
125 | test_dht_twopeer \ | 140 | test_dht_twopeer \ |
126 | test_dht_twopeer_put_get \ | 141 | test_dht_twopeer_put_get \ |
127 | test_dht_twopeer_get_put \ | 142 | test_dht_twopeer_get_put \ |
128 | test_dht_twopeer_path_tracking \ | 143 | test_dht_twopeer_path_tracking \ |
129 | test_dht_multipeer \ | 144 | test_dht_multipeer \ |
130 | test_dht_line \ | 145 | $(NEW_TESTS) \ |
131 | test_dht_2dtorus \ | ||
132 | test_dht_monitor | 146 | test_dht_monitor |
133 | endif | 147 | endif |
134 | 148 | ||
@@ -142,6 +156,7 @@ test_dht_api_LDADD = \ | |||
142 | test_dht_api_DEPENDENCIES = \ | 156 | test_dht_api_DEPENDENCIES = \ |
143 | libgnunetdht.la | 157 | libgnunetdht.la |
144 | 158 | ||
159 | # twopeer is obsolete once new test_dht_topo works... | ||
145 | test_dht_twopeer_SOURCES = \ | 160 | test_dht_twopeer_SOURCES = \ |
146 | test_dht_twopeer.c | 161 | test_dht_twopeer.c |
147 | test_dht_twopeer_LDADD = \ | 162 | test_dht_twopeer_LDADD = \ |
@@ -151,6 +166,7 @@ test_dht_twopeer_LDADD = \ | |||
151 | test_dht_twopeer_DEPENDENCIES = \ | 166 | test_dht_twopeer_DEPENDENCIES = \ |
152 | libgnunetdht.la | 167 | libgnunetdht.la |
153 | 168 | ||
169 | # twopeer_put_get is obsolete once new test_dht_topo works... | ||
154 | test_dht_twopeer_put_get_SOURCES = \ | 170 | test_dht_twopeer_put_get_SOURCES = \ |
155 | test_dht_twopeer_put_get.c | 171 | test_dht_twopeer_put_get.c |
156 | test_dht_twopeer_put_get_LDADD = \ | 172 | test_dht_twopeer_put_get_LDADD = \ |
@@ -158,6 +174,7 @@ test_dht_twopeer_put_get_LDADD = \ | |||
158 | $(top_builddir)/src/testing_old/libgnunettesting_old.la \ | 174 | $(top_builddir)/src/testing_old/libgnunettesting_old.la \ |
159 | $(top_builddir)/src/dht/libgnunetdht.la | 175 | $(top_builddir)/src/dht/libgnunetdht.la |
160 | 176 | ||
177 | # twopeer_get_put is obsolete once new test_dht_topo works... | ||
161 | test_dht_twopeer_get_put_SOURCES = \ | 178 | test_dht_twopeer_get_put_SOURCES = \ |
162 | test_dht_twopeer_get_put.c | 179 | test_dht_twopeer_get_put.c |
163 | test_dht_twopeer_get_put_LDADD = \ | 180 | test_dht_twopeer_get_put_LDADD = \ |
@@ -165,6 +182,7 @@ test_dht_twopeer_get_put_LDADD = \ | |||
165 | $(top_builddir)/src/testing_old/libgnunettesting_old.la \ | 182 | $(top_builddir)/src/testing_old/libgnunettesting_old.la \ |
166 | $(top_builddir)/src/dht/libgnunetdht.la | 183 | $(top_builddir)/src/dht/libgnunetdht.la |
167 | 184 | ||
185 | # twopeer_path_tracking is obsolete once new test_dht_topo works... | ||
168 | test_dht_twopeer_path_tracking_SOURCES = \ | 186 | test_dht_twopeer_path_tracking_SOURCES = \ |
169 | test_dht_twopeer_path_tracking.c | 187 | test_dht_twopeer_path_tracking.c |
170 | test_dht_twopeer_path_tracking_LDADD = \ | 188 | test_dht_twopeer_path_tracking_LDADD = \ |
@@ -172,6 +190,8 @@ test_dht_twopeer_path_tracking_LDADD = \ | |||
172 | $(top_builddir)/src/testing_old/libgnunettesting_old.la \ | 190 | $(top_builddir)/src/testing_old/libgnunettesting_old.la \ |
173 | $(top_builddir)/src/dht/libgnunetdht.la | 191 | $(top_builddir)/src/dht/libgnunetdht.la |
174 | 192 | ||
193 | # statistics functions should be integrated with test_dht_topo, | ||
194 | # then this one also becomes obsolete... | ||
175 | test_dht_multipeer_SOURCES = \ | 195 | test_dht_multipeer_SOURCES = \ |
176 | test_dht_multipeer.c | 196 | test_dht_multipeer.c |
177 | test_dht_multipeer_LDADD = \ | 197 | test_dht_multipeer_LDADD = \ |
@@ -185,8 +205,9 @@ test_dht_multipeer_DEPENDENCIES = \ | |||
185 | test_dht_2dtorus_SOURCES = \ | 205 | test_dht_2dtorus_SOURCES = \ |
186 | test_dht_topo.c | 206 | test_dht_topo.c |
187 | test_dht_2dtorus_LDADD = \ | 207 | test_dht_2dtorus_LDADD = \ |
208 | $(top_builddir)/src/dht/libgnunetdhttest.a \ | ||
188 | $(top_builddir)/src/util/libgnunetutil.la \ | 209 | $(top_builddir)/src/util/libgnunetutil.la \ |
189 | $(top_builddir)/src/testing_old/libgnunettesting_old.la \ | 210 | $(top_builddir)/src/testbed/libgnunettestbed.la \ |
190 | $(top_builddir)/src/dht/libgnunetdht.la | 211 | $(top_builddir)/src/dht/libgnunetdht.la |
191 | test_dht_2dtorus_DEPENDENCIES = \ | 212 | test_dht_2dtorus_DEPENDENCIES = \ |
192 | libgnunetdht.la | 213 | libgnunetdht.la |
@@ -194,12 +215,14 @@ test_dht_2dtorus_DEPENDENCIES = \ | |||
194 | test_dht_line_SOURCES = \ | 215 | test_dht_line_SOURCES = \ |
195 | test_dht_topo.c | 216 | test_dht_topo.c |
196 | test_dht_line_LDADD = \ | 217 | test_dht_line_LDADD = \ |
218 | $(top_builddir)/src/dht/libgnunetdhttest.a \ | ||
197 | $(top_builddir)/src/util/libgnunetutil.la \ | 219 | $(top_builddir)/src/util/libgnunetutil.la \ |
198 | $(top_builddir)/src/testing_old/libgnunettesting_old.la \ | 220 | $(top_builddir)/src/testbed/libgnunettestbed.la \ |
199 | $(top_builddir)/src/dht/libgnunetdht.la | 221 | $(top_builddir)/src/dht/libgnunetdht.la |
200 | test_dht_line_DEPENDENCIES = \ | 222 | test_dht_line_DEPENDENCIES = \ |
201 | libgnunetdht.la | 223 | libgnunetdht.la |
202 | 224 | ||
225 | # fixme, rewrite based on test_dht_topo.c! | ||
203 | test_dht_monitor_SOURCES = test_dht_monitor.c | 226 | test_dht_monitor_SOURCES = test_dht_monitor.c |
204 | test_dht_monitor_LDADD = \ | 227 | test_dht_monitor_LDADD = \ |
205 | $(top_builddir)/src/util/libgnunetutil.la \ | 228 | $(top_builddir)/src/util/libgnunetutil.la \ |
diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c index 0905486d1..7964ba98f 100644 --- a/src/dht/dht_api.c +++ b/src/dht/dht_api.c | |||
@@ -1041,7 +1041,7 @@ struct GNUNET_DHT_PutHandle * | |||
1041 | GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, const struct GNUNET_HashCode * key, | 1041 | GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, const struct GNUNET_HashCode * key, |
1042 | uint32_t desired_replication_level, | 1042 | uint32_t desired_replication_level, |
1043 | enum GNUNET_DHT_RouteOption options, | 1043 | enum GNUNET_DHT_RouteOption options, |
1044 | enum GNUNET_BLOCK_Type type, size_t size, const char *data, | 1044 | enum GNUNET_BLOCK_Type type, size_t size, const void *data, |
1045 | struct GNUNET_TIME_Absolute exp, | 1045 | struct GNUNET_TIME_Absolute exp, |
1046 | struct GNUNET_TIME_Relative timeout, GNUNET_DHT_PutContinuation cont, | 1046 | struct GNUNET_TIME_Relative timeout, GNUNET_DHT_PutContinuation cont, |
1047 | void *cont_cls) | 1047 | void *cont_cls) |
diff --git a/src/dht/dht_test_lib.c b/src/dht/dht_test_lib.c new file mode 100644 index 000000000..5fe34addf --- /dev/null +++ b/src/dht/dht_test_lib.c | |||
@@ -0,0 +1,214 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2012 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file dht/dht_test_lib.c | ||
22 | * @author Christian Grothoff | ||
23 | * @brief library for writing DHT tests | ||
24 | */ | ||
25 | #include "platform.h" | ||
26 | #include "dht_test_lib.h" | ||
27 | |||
28 | /** | ||
29 | * Test context for a DHT Test. | ||
30 | */ | ||
31 | struct GNUNET_DHT_TEST_Context | ||
32 | { | ||
33 | /** | ||
34 | * Array of running peers. | ||
35 | */ | ||
36 | struct GNUNET_TESTBED_Peer **peers; | ||
37 | |||
38 | /** | ||
39 | * Array of handles to the DHT for each peer. | ||
40 | */ | ||
41 | struct GNUNET_DHT_Handle **dhts; | ||
42 | |||
43 | /** | ||
44 | * Operation associated with the connection to the DHT. | ||
45 | */ | ||
46 | struct GNUNET_TESTBED_Operation **ops; | ||
47 | |||
48 | /** | ||
49 | * Main function of the test to run once all DHTs are available. | ||
50 | */ | ||
51 | GNUNET_DHT_TEST_AppMain app_main; | ||
52 | |||
53 | /** | ||
54 | * Closure for 'app_main'. | ||
55 | */ | ||
56 | void *app_main_cls; | ||
57 | |||
58 | /** | ||
59 | * Number of peers running, size of the arrays above. | ||
60 | */ | ||
61 | unsigned int num_peers; | ||
62 | |||
63 | }; | ||
64 | |||
65 | |||
66 | /** | ||
67 | * Adapter function called to establish a connection to | ||
68 | * the DHT service. | ||
69 | * | ||
70 | * @param cls closure | ||
71 | * @param cfg configuration of the peer to connect to; will be available until | ||
72 | * GNUNET_TESTBED_operation_done() is called on the operation returned | ||
73 | * from GNUNET_TESTBED_service_connect() | ||
74 | * @return service handle to return in 'op_result', NULL on error | ||
75 | */ | ||
76 | static void * | ||
77 | dht_connect_adapter (void *cls, | ||
78 | const struct GNUNET_CONFIGURATION_Handle *cfg) | ||
79 | { | ||
80 | return GNUNET_DHT_connect (cfg, 16); | ||
81 | } | ||
82 | |||
83 | |||
84 | /** | ||
85 | * Adapter function called to destroy a connection to | ||
86 | * the DHT service. | ||
87 | * | ||
88 | * @param cls closure | ||
89 | * @param op_result service handle returned from the connect adapter | ||
90 | */ | ||
91 | static void | ||
92 | dht_disconnect_adapter (void *cls, | ||
93 | void *op_result) | ||
94 | { | ||
95 | struct GNUNET_DHT_Handle *dht = op_result; | ||
96 | |||
97 | GNUNET_DHT_disconnect (dht); | ||
98 | } | ||
99 | |||
100 | |||
101 | /** | ||
102 | * Callback to be called when a service connect operation is completed | ||
103 | * | ||
104 | * @param cls the callback closure from functions generating an operation | ||
105 | * @param op the operation that has been finished | ||
106 | * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter() | ||
107 | * @param emsg error message in case the operation has failed; will be NULL if | ||
108 | * operation has executed successfully. | ||
109 | */ | ||
110 | static void | ||
111 | dht_connect_cb (void *cls, | ||
112 | struct GNUNET_TESTBED_Operation *op, | ||
113 | void *ca_result, | ||
114 | const char *emsg) | ||
115 | { | ||
116 | struct GNUNET_DHT_TEST_Context *ctx = cls; | ||
117 | unsigned int i; | ||
118 | |||
119 | if (NULL != emsg) | ||
120 | { | ||
121 | fprintf (stderr, "Failed to connect to DHT service: %s\n", | ||
122 | emsg); | ||
123 | GNUNET_SCHEDULER_shutdown (); | ||
124 | return; | ||
125 | } | ||
126 | for (i=0;i<ctx->num_peers;i++) | ||
127 | if (op == ctx->ops[i]) | ||
128 | ctx->dhts[i] = ca_result; | ||
129 | for (i=0;i<ctx->num_peers;i++) | ||
130 | if (NULL == ctx->dhts[i]) | ||
131 | return; /* still some DHT connections missing */ | ||
132 | /* all DHT connections ready! */ | ||
133 | ctx->app_main (ctx->app_main_cls, | ||
134 | ctx, | ||
135 | ctx->num_peers, | ||
136 | ctx->peers, | ||
137 | ctx->dhts); | ||
138 | } | ||
139 | |||
140 | |||
141 | /** | ||
142 | * Clean up the testbed. | ||
143 | * | ||
144 | * @param ctx handle for the testbed | ||
145 | */ | ||
146 | void | ||
147 | GNUNET_DHT_TEST_cleanup (struct GNUNET_DHT_TEST_Context *ctx) | ||
148 | { | ||
149 | unsigned int i; | ||
150 | |||
151 | for (i=0;i<ctx->num_peers;i++) | ||
152 | GNUNET_TESTBED_operation_done (ctx->ops[i]); | ||
153 | GNUNET_free (ctx->ops); | ||
154 | GNUNET_free (ctx->dhts); | ||
155 | GNUNET_free (ctx); | ||
156 | GNUNET_SCHEDULER_shutdown (); | ||
157 | } | ||
158 | |||
159 | |||
160 | static void | ||
161 | dht_test_run (void *cls, | ||
162 | unsigned int num_peers, | ||
163 | struct GNUNET_TESTBED_Peer **peers) | ||
164 | { | ||
165 | struct GNUNET_DHT_TEST_Context *ctx = cls; | ||
166 | unsigned int i; | ||
167 | |||
168 | GNUNET_assert (num_peers == ctx->num_peers); | ||
169 | ctx->peers = peers; | ||
170 | for (i=0;i<num_peers;i++) | ||
171 | ctx->ops[i] = GNUNET_TESTBED_service_connect (ctx, | ||
172 | peers[i], | ||
173 | "dht", | ||
174 | &dht_connect_cb, | ||
175 | ctx, | ||
176 | &dht_connect_adapter, | ||
177 | &dht_disconnect_adapter, | ||
178 | ctx); | ||
179 | } | ||
180 | |||
181 | |||
182 | /** | ||
183 | * Run a test using the given name, configuration file and number of | ||
184 | * peers. | ||
185 | * | ||
186 | * @param testname name of the test (for logging) | ||
187 | * @param cfgname name of the configuration file | ||
188 | * @param num_peers number of peers to start | ||
189 | * @param tmain main function to run once the testbed is ready | ||
190 | * @param tmain_cls closure for 'tmain' | ||
191 | */ | ||
192 | void | ||
193 | GNUNET_DHT_TEST_run (const char *testname, | ||
194 | const char *cfgname, | ||
195 | unsigned int num_peers, | ||
196 | GNUNET_DHT_TEST_AppMain tmain, | ||
197 | void *tmain_cls) | ||
198 | { | ||
199 | struct GNUNET_DHT_TEST_Context *ctx; | ||
200 | |||
201 | ctx = GNUNET_malloc (sizeof (struct GNUNET_DHT_TEST_Context)); | ||
202 | ctx->num_peers = num_peers; | ||
203 | ctx->ops = GNUNET_malloc (num_peers * sizeof (struct GNUNET_TESTBED_Operation *)); | ||
204 | ctx->dhts = GNUNET_malloc (num_peers * sizeof (struct GNUNET_DHT_Handle *)); | ||
205 | ctx->app_main = tmain; | ||
206 | ctx->app_main_cls = tmain_cls; | ||
207 | GNUNET_TESTBED_test_run (testname, | ||
208 | cfgname, | ||
209 | num_peers, | ||
210 | 0LL, NULL, NULL, | ||
211 | &dht_test_run, ctx); | ||
212 | } | ||
213 | |||
214 | /* end of dht_test_lib.c */ | ||
diff --git a/src/dht/dht_test_lib.h b/src/dht/dht_test_lib.h new file mode 100644 index 000000000..0cf6dfac9 --- /dev/null +++ b/src/dht/dht_test_lib.h | |||
@@ -0,0 +1,80 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet. | ||
3 | (C) 2012 Christian Grothoff (and other contributing authors) | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as published | ||
7 | by the Free Software Foundation; either version 3, or (at your | ||
8 | option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public License | ||
16 | along with GNUnet; see the file COPYING. If not, write to the | ||
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | /** | ||
21 | * @file dht/dht_test_lib.h | ||
22 | * @author Christian Grothoff | ||
23 | * @brief library for writing DHT tests | ||
24 | */ | ||
25 | #ifndef DHT_TEST_LIB_H | ||
26 | #define DHT_TEST_LIB_H | ||
27 | |||
28 | #include "gnunet_testbed_service.h" | ||
29 | #include "gnunet_dht_service.h" | ||
30 | |||
31 | /** | ||
32 | * Test context for a DHT Test. | ||
33 | */ | ||
34 | struct GNUNET_DHT_TEST_Context; | ||
35 | |||
36 | |||
37 | /** | ||
38 | * Main function of a DHT test. | ||
39 | * | ||
40 | * @param cls closure | ||
41 | * @param ctx argument to give to GNUNET_DHT_TEST_cleanup on test end | ||
42 | * @param num_peers number of peers that are running | ||
43 | * @param peers array of peers | ||
44 | * @param dhts handle to each of the DHTs of the peers | ||
45 | */ | ||
46 | typedef void (*GNUNET_DHT_TEST_AppMain) (void *cls, | ||
47 | struct GNUNET_DHT_TEST_Context *ctx, | ||
48 | unsigned int num_peers, | ||
49 | struct GNUNET_TESTBED_Peer **peers, | ||
50 | struct GNUNET_DHT_Handle **dhts); | ||
51 | |||
52 | |||
53 | /** | ||
54 | * Run a test using the given name, configuration file and number of | ||
55 | * peers. | ||
56 | * | ||
57 | * @param testname name of the test (for logging) | ||
58 | * @param cfgname name of the configuration file | ||
59 | * @param num_peers number of peers to start | ||
60 | * @param tmain main function to run once the testbed is ready | ||
61 | * @param tmain_cls closure for 'tmain' | ||
62 | */ | ||
63 | void | ||
64 | GNUNET_DHT_TEST_run (const char *testname, | ||
65 | const char *cfgname, | ||
66 | unsigned int num_peers, | ||
67 | GNUNET_DHT_TEST_AppMain tmain, | ||
68 | void *tmain_cls); | ||
69 | |||
70 | |||
71 | /** | ||
72 | * Clean up the testbed. | ||
73 | * | ||
74 | * @param ctx handle for the testbed | ||
75 | */ | ||
76 | void | ||
77 | GNUNET_DHT_TEST_cleanup (struct GNUNET_DHT_TEST_Context *ctx); | ||
78 | |||
79 | |||
80 | #endif | ||
diff --git a/src/dht/test_dht_topo.c b/src/dht/test_dht_topo.c index a4765ee89..0934d7abd 100644 --- a/src/dht/test_dht_topo.c +++ b/src/dht/test_dht_topo.c | |||
@@ -19,83 +19,59 @@ | |||
19 | */ | 19 | */ |
20 | /** | 20 | /** |
21 | * @file dht/test_dht_topo.c | 21 | * @file dht/test_dht_topo.c |
22 | * | 22 | * @author Christian Grothoff |
23 | * @brief Test for the dht service: store and retrieve in various topologies. | 23 | * @brief Test for the dht service: store and retrieve in various topologies. |
24 | * Each peer stores it own ID in the DHT and then a different peer tries to | 24 | * Each peer stores a value from the DHT and then each peer tries to get each |
25 | * retrieve that key from it. The GET starts after a first round of PUTS has | 25 | * value from each other peer. |
26 | * been made. Periodically, each peer stores its ID into the DHT. If after | ||
27 | * a timeout no result has been returned, the test fails. | ||
28 | */ | 26 | */ |
29 | #include "platform.h" | 27 | #include "platform.h" |
30 | #include "gnunet_testing_lib.h" | 28 | #include "gnunet_util_lib.h" |
31 | #include "gnunet_dht_service.h" | 29 | #include "gnunet_dht_service.h" |
32 | 30 | #include "dht_test_lib.h" | |
33 | #define REMOVE_DIR GNUNET_YES | ||
34 | 31 | ||
35 | /** | 32 | /** |
36 | * DIFFERENT TESTS TO RUN | 33 | * Number of peers to run. |
37 | */ | 34 | */ |
38 | #define LINE 0 | 35 | #define NUM_PEERS 5 |
39 | #define TORUS 1 | ||
40 | 36 | ||
41 | /** | 37 | /** |
42 | * How long until we give up on connecting the peers? | 38 | * How long until we give up on fetching the data? |
43 | */ | 39 | */ |
44 | #define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1500) | ||
45 | |||
46 | #define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120) | 40 | #define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120) |
47 | 41 | ||
48 | #define PUT_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) | ||
49 | |||
50 | /** | 42 | /** |
51 | * Result of the test. | 43 | * How frequently do we execute the PUTs? |
52 | */ | 44 | */ |
53 | static int ok; | 45 | #define PUT_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) |
54 | 46 | ||
55 | /** | ||
56 | * Total number of peers in the test. | ||
57 | */ | ||
58 | static unsigned long long num_peers; | ||
59 | 47 | ||
60 | /** | 48 | /** |
61 | * Global configuration file | 49 | * Information we keep for each GET operation. |
62 | */ | 50 | */ |
63 | static struct GNUNET_CONFIGURATION_Handle *testing_cfg; | 51 | struct GetOperation |
52 | { | ||
53 | /** | ||
54 | * DLL. | ||
55 | */ | ||
56 | struct GetOperation *next; | ||
64 | 57 | ||
65 | /** | 58 | /** |
66 | * Total number of currently running peers. | 59 | * DLL. |
67 | */ | 60 | */ |
68 | static unsigned long long peers_running; | 61 | struct GetOperation *prev; |
69 | 62 | ||
70 | /** | 63 | /** |
71 | * Total number of connections in the whole network. | 64 | * Handle for the operation. |
72 | */ | 65 | */ |
73 | static unsigned int total_connections; | 66 | struct GNUNET_DHT_GetHandle *get; |
74 | 67 | ||
75 | /** | 68 | }; |
76 | * The currently running peer group. | ||
77 | */ | ||
78 | static struct GNUNET_TESTING_PeerGroup *pg; | ||
79 | 69 | ||
80 | /** | ||
81 | * File to report results to. | ||
82 | */ | ||
83 | static struct GNUNET_DISK_FileHandle *output_file; | ||
84 | 70 | ||
85 | /** | 71 | /** |
86 | * File to log connection info, statistics to. | 72 | * Result of the test. |
87 | */ | ||
88 | static struct GNUNET_DISK_FileHandle *data_file; | ||
89 | |||
90 | /** | ||
91 | * Task called to disconnect peers. | ||
92 | */ | ||
93 | static GNUNET_SCHEDULER_TaskIdentifier disconnect_task; | ||
94 | |||
95 | /** | ||
96 | * Task To perform tests | ||
97 | */ | 73 | */ |
98 | static GNUNET_SCHEDULER_TaskIdentifier test_task; | 74 | static int ok = 1; |
99 | 75 | ||
100 | /** | 76 | /** |
101 | * Task to do DHT_puts | 77 | * Task to do DHT_puts |
@@ -103,454 +79,208 @@ static GNUNET_SCHEDULER_TaskIdentifier test_task; | |||
103 | static GNUNET_SCHEDULER_TaskIdentifier put_task; | 79 | static GNUNET_SCHEDULER_TaskIdentifier put_task; |
104 | 80 | ||
105 | /** | 81 | /** |
106 | * Task called to shutdown test. | 82 | * Task to time out / regular shutdown. |
107 | */ | 83 | */ |
108 | static GNUNET_SCHEDULER_TaskIdentifier shutdown_handle; | 84 | static GNUNET_SCHEDULER_TaskIdentifier timeout_task; |
109 | |||
110 | static char *topology_file; | ||
111 | |||
112 | static struct GNUNET_DHT_Handle **hs; | ||
113 | |||
114 | static struct GNUNET_DHT_GetHandle *get_h; | ||
115 | |||
116 | static struct GNUNET_DHT_GetHandle *get_h_2; | ||
117 | |||
118 | static struct GNUNET_DHT_GetHandle *get_h_far; | ||
119 | |||
120 | static int found_1; | ||
121 | |||
122 | static int found_2; | ||
123 | |||
124 | static int found_far; | ||
125 | 85 | ||
126 | /** | 86 | /** |
127 | * Which topology are we to run | 87 | * Head of list of active GET operations. |
128 | */ | 88 | */ |
129 | static int test_topology; | 89 | static struct GetOperation *get_head; |
130 | |||
131 | 90 | ||
132 | /** | 91 | /** |
133 | * Check whether peers successfully shut down. | 92 | * Tail of list of active GET operations. |
134 | */ | 93 | */ |
135 | static void | 94 | static struct GetOperation *get_tail; |
136 | shutdown_callback (void *cls, const char *emsg) | ||
137 | { | ||
138 | if (emsg != NULL) | ||
139 | { | ||
140 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Shutdown of peers failed!\n"); | ||
141 | ok++; | ||
142 | } | ||
143 | else | ||
144 | { | ||
145 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "All peers successfully shut down!\n"); | ||
146 | } | ||
147 | GNUNET_CONFIGURATION_destroy (testing_cfg); | ||
148 | } | ||
149 | 95 | ||
150 | 96 | ||
97 | /** | ||
98 | * Task run on success or timeout to clean up. | ||
99 | * Terminates active get operations and shuts down | ||
100 | * the testbed. | ||
101 | * | ||
102 | * @param cls the 'struct GNUNET_DHT_TestContext' | ||
103 | * @param tc scheduler context | ||
104 | */ | ||
151 | static void | 105 | static void |
152 | shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 106 | shutdown_task (void *cls, |
107 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
153 | { | 108 | { |
154 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Ending test.\n"); | 109 | struct GNUNET_DHT_TEST_Context *ctx = cls; |
110 | struct GetOperation *get_op; | ||
155 | 111 | ||
156 | if (disconnect_task != GNUNET_SCHEDULER_NO_TASK) | 112 | while (NULL != (get_op = get_tail)) |
157 | { | 113 | { |
158 | GNUNET_SCHEDULER_cancel (disconnect_task); | 114 | GNUNET_DHT_get_stop (get_op->get); |
159 | disconnect_task = GNUNET_SCHEDULER_NO_TASK; | 115 | GNUNET_CONTAINER_DLL_remove (get_head, |
116 | get_tail, | ||
117 | get_op); | ||
118 | GNUNET_free (get_op); | ||
160 | } | 119 | } |
161 | |||
162 | if (data_file != NULL) | ||
163 | GNUNET_DISK_file_close (data_file); | ||
164 | GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); | ||
165 | } | ||
166 | |||
167 | |||
168 | static void | ||
169 | disconnect_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
170 | { | ||
171 | unsigned int i; | ||
172 | |||
173 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "disconnecting peers\n"); | ||
174 | disconnect_task = GNUNET_SCHEDULER_NO_TASK; | ||
175 | GNUNET_SCHEDULER_cancel (put_task); | 120 | GNUNET_SCHEDULER_cancel (put_task); |
176 | if (NULL != get_h) | 121 | GNUNET_DHT_TEST_cleanup (ctx); |
177 | GNUNET_DHT_get_stop (get_h); | ||
178 | if (NULL != get_h_2) | ||
179 | GNUNET_DHT_get_stop (get_h_2); | ||
180 | if (NULL != get_h_far) | ||
181 | GNUNET_DHT_get_stop (get_h_far); | ||
182 | for (i = 0; i < num_peers; i++) | ||
183 | { | ||
184 | GNUNET_DHT_disconnect (hs[i]); | ||
185 | } | ||
186 | GNUNET_SCHEDULER_cancel (shutdown_handle); | ||
187 | shutdown_handle = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); | ||
188 | } | 122 | } |
189 | 123 | ||
190 | 124 | ||
125 | /** | ||
126 | * Iterator called on each result obtained for a DHT | ||
127 | * operation that expects a reply | ||
128 | * | ||
129 | * @param cls closure with our 'struct GetOperation' | ||
130 | * @param exp when will this value expire | ||
131 | * @param key key of the result | ||
132 | * @param get_path peers on reply path (or NULL if not recorded) | ||
133 | * @param get_path_length number of entries in get_path | ||
134 | * @param put_path peers on the PUT path (or NULL if not recorded) | ||
135 | * @param put_path_length number of entries in get_path | ||
136 | * @param type type of the result | ||
137 | * @param size number of bytes in data | ||
138 | * @param data pointer to the result data | ||
139 | */ | ||
191 | static void | 140 | static void |
192 | dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, | 141 | dht_get_handler (void *cls, struct GNUNET_TIME_Absolute exp, |
193 | const struct GNUNET_HashCode * key, | 142 | const struct GNUNET_HashCode * key, |
194 | const struct GNUNET_PeerIdentity *get_path, | 143 | const struct GNUNET_PeerIdentity *get_path, |
195 | unsigned int get_path_length, | 144 | unsigned int get_path_length, |
196 | const struct GNUNET_PeerIdentity *put_path, | 145 | const struct GNUNET_PeerIdentity *put_path, |
197 | unsigned int put_path_length, enum GNUNET_BLOCK_Type type, | 146 | unsigned int put_path_length, enum GNUNET_BLOCK_Type type, |
198 | size_t size, const void *data) | 147 | size_t size, const void *data) |
199 | { | 148 | { |
200 | int i; | 149 | struct GetOperation *get_op = cls; |
201 | 150 | struct GNUNET_HashCode want; | |
202 | if (sizeof (struct GNUNET_HashCode) == size) | 151 | struct GNUNET_DHT_TestContext *ctx; |
203 | { | ||
204 | const struct GNUNET_HashCode *h = data; | ||
205 | |||
206 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Contents: %s\n", | ||
207 | GNUNET_h2s_full (h)); | ||
208 | 152 | ||
209 | } | 153 | if (sizeof (struct GNUNET_HashCode) != size) |
210 | else | ||
211 | { | ||
212 | GNUNET_break(0); | ||
213 | } | ||
214 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH: (get %u, put %u)\n", | ||
215 | get_path_length, put_path_length); | ||
216 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " LOCAL\n"); | ||
217 | for (i = get_path_length - 1; i >= 0; i--) | ||
218 | { | 154 | { |
219 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", | 155 | GNUNET_break (0); |
220 | GNUNET_i2s (&get_path[i])); | 156 | return; |
221 | } | 157 | } |
222 | for (i = put_path_length - 1; i >= 0; i--) | 158 | GNUNET_CRYPTO_hash (key, sizeof (*key), &want); |
159 | if (0 != memcmp (&want, data, sizeof (want))) | ||
223 | { | 160 | { |
224 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", | 161 | GNUNET_break (0); |
225 | GNUNET_i2s (&put_path[i])); | 162 | return; |
226 | } | 163 | } |
227 | switch ((long)cls) | 164 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
165 | "Get successful\n"); | ||
166 | #if 0 | ||
228 | { | 167 | { |
229 | case 1: | 168 | int i; |
230 | found_1++; | 169 | |
231 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "FOUND 1!\n"); | 170 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH: (get %u, put %u)\n", |
232 | break; | 171 | get_path_length, put_path_length); |
233 | case 2: | 172 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " LOCAL\n"); |
234 | found_2++; | 173 | for (i = get_path_length - 1; i >= 0; i--) |
235 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "FOUND 2!\n"); | 174 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", |
236 | break; | 175 | GNUNET_i2s (&get_path[i])); |
237 | case 3: | 176 | for (i = put_path_length - 1; i >= 0; i--) |
238 | found_far++; | 177 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", |
239 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, "FOUND FAR!\n"); | 178 | GNUNET_i2s (&put_path[i])); |
240 | break; | ||
241 | default: | ||
242 | GNUNET_break(0); | ||
243 | } | 179 | } |
244 | if ( (TORUS == test_topology) && | 180 | #endif |
245 | ( (found_1 == 0) || (found_2 == 0) || (found_far == 0)) ) | 181 | GNUNET_DHT_get_stop (get_op->get); |
182 | GNUNET_CONTAINER_DLL_remove (get_head, | ||
183 | get_tail, | ||
184 | get_op); | ||
185 | GNUNET_free (get_op); | ||
186 | if (NULL != get_head) | ||
246 | return; | 187 | return; |
188 | /* all DHT GET operations successful; terminate! */ | ||
247 | ok = 0; | 189 | ok = 0; |
248 | GNUNET_SCHEDULER_cancel (disconnect_task); | 190 | ctx = GNUNET_SCHEDULER_cancel (timeout_task); |
249 | disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_peers, NULL); | 191 | timeout_task = GNUNET_SCHEDULER_add_now (&shutdown_task, ctx); |
250 | } | 192 | } |
251 | 193 | ||
252 | 194 | ||
253 | static void | ||
254 | do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
255 | { | ||
256 | struct GNUNET_TESTING_Daemon *d; | ||
257 | struct GNUNET_TESTING_Daemon *d2; | ||
258 | struct GNUNET_TESTING_Daemon *d_far; | ||
259 | struct GNUNET_TESTING_Daemon *o; | ||
260 | struct GNUNET_TESTING_Daemon *aux; | ||
261 | const char *id_aux; | ||
262 | const char *id_origin = "FC74"; | ||
263 | const char *id_near = "9P6V"; | ||
264 | const char *id_near2 = "2GDS"; | ||
265 | const char *id_far = "KPST"; | ||
266 | unsigned int i; | ||
267 | |||
268 | d = d2 = d_far = o = NULL; | ||
269 | found_1 = found_2 = found_far = 0; | ||
270 | if (LINE == test_topology) | ||
271 | { | ||
272 | o = GNUNET_TESTING_daemon_get (pg, 0); | ||
273 | d = GNUNET_TESTING_daemon_get (pg, num_peers - 1); | ||
274 | } | ||
275 | else if (TORUS == test_topology) | ||
276 | { | ||
277 | for (i = 0; i < num_peers; i++) | ||
278 | { | ||
279 | aux = GNUNET_TESTING_daemon_get (pg, i); | ||
280 | id_aux = GNUNET_i2s (&aux->id); | ||
281 | if (strcmp (id_aux, id_origin) == 0) | ||
282 | o = aux; | ||
283 | if (strcmp (id_aux, id_far) == 0) | ||
284 | d_far = aux; | ||
285 | if (strcmp (id_aux, id_near) == 0) | ||
286 | d = aux; | ||
287 | if (strcmp (id_aux, id_near2) == 0) | ||
288 | d2 = aux; | ||
289 | } | ||
290 | if ((NULL == o) || (NULL == d) || (NULL == d2) || (NULL == d_far)) | ||
291 | { | ||
292 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
293 | "Peers not found (hostkey file changed?)\n"); | ||
294 | GNUNET_SCHEDULER_cancel (disconnect_task); | ||
295 | disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_peers, NULL); | ||
296 | return; | ||
297 | } | ||
298 | } | ||
299 | else | ||
300 | { | ||
301 | GNUNET_assert (0); | ||
302 | } | ||
303 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test_task\nfrom %s\n", | ||
304 | GNUNET_h2s_full (&o->id.hashPubKey)); | ||
305 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " looking for %s\n", | ||
306 | GNUNET_h2s_full (&d->id.hashPubKey)); | ||
307 | get_h = GNUNET_DHT_get_start (hs[0], | ||
308 | GNUNET_BLOCK_TYPE_TEST, /* type */ | ||
309 | &d->id.hashPubKey, /*key to search */ | ||
310 | 4U, /* replication level */ | ||
311 | GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, | ||
312 | NULL, /* xquery */ | ||
313 | 0, /* xquery bits */ | ||
314 | &dht_get_id_handler, (void *)1); | ||
315 | if (TORUS == test_topology) | ||
316 | { | ||
317 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " looking for %s\n", | ||
318 | GNUNET_h2s_full (&d2->id.hashPubKey)); | ||
319 | get_h_2 = GNUNET_DHT_get_start (hs[0], | ||
320 | GNUNET_BLOCK_TYPE_TEST, /* type */ | ||
321 | &d2->id.hashPubKey, /*key to search */ | ||
322 | 4U, /* replication level */ | ||
323 | GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, | ||
324 | NULL, /* xquery */ | ||
325 | 0, /* xquery bits */ | ||
326 | &dht_get_id_handler, (void *)2); | ||
327 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " looking for %s\n", | ||
328 | GNUNET_h2s_full (&d_far->id.hashPubKey)); | ||
329 | get_h_far = GNUNET_DHT_get_start (hs[0], | ||
330 | GNUNET_BLOCK_TYPE_TEST, /* type */ | ||
331 | &d_far->id.hashPubKey, /*key to search */ | ||
332 | 4U, /* replication level */ | ||
333 | GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, | ||
334 | NULL, /* xquery */ | ||
335 | 0, /* xquery bits */ | ||
336 | &dht_get_id_handler, (void *)3); | ||
337 | } | ||
338 | GNUNET_SCHEDULER_cancel (disconnect_task); | ||
339 | disconnect_task = | ||
340 | GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, &disconnect_peers, NULL); | ||
341 | } | ||
342 | |||
343 | /** | 195 | /** |
344 | * Task to put the id of each peer into the DHT. | 196 | * Task to put the id of each peer into the DHT. |
345 | * | 197 | * |
346 | * @param cls Closure (unused) | 198 | * @param cls array with NUM_PEERS DHT handles |
347 | * @param tc Task context | 199 | * @param tc Task context |
348 | * | ||
349 | */ | 200 | */ |
350 | static void | 201 | static void |
351 | put_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 202 | do_puts (void *cls, |
203 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
352 | { | 204 | { |
353 | struct GNUNET_TESTING_Daemon *d; | 205 | struct GNUNET_DHT_Handle **hs = cls; |
206 | struct GNUNET_HashCode key; | ||
207 | struct GNUNET_HashCode value; | ||
354 | unsigned int i; | 208 | unsigned int i; |
355 | 209 | ||
356 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "putting id's in DHT\n"); | 210 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
357 | for (i = 0; i < num_peers; i++) | 211 | "Putting values into DHT\n"); |
212 | for (i = 0; i < NUM_PEERS; i++) | ||
358 | { | 213 | { |
359 | d = GNUNET_TESTING_daemon_get (pg, i); | 214 | GNUNET_CRYPTO_hash (&i, sizeof (i), &key); |
360 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " putting into DHT: %s\n", | 215 | GNUNET_CRYPTO_hash (&key, sizeof (key), &value); |
361 | GNUNET_h2s_full (&d->id.hashPubKey)); | 216 | GNUNET_DHT_put (hs[i], &key, 10U, |
362 | GNUNET_DHT_put (hs[i], &d->id.hashPubKey, 10U, | ||
363 | GNUNET_DHT_RO_RECORD_ROUTE | | 217 | GNUNET_DHT_RO_RECORD_ROUTE | |
364 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, | 218 | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, |
365 | GNUNET_BLOCK_TYPE_TEST, sizeof (struct GNUNET_PeerIdentity), | 219 | GNUNET_BLOCK_TYPE_TEST, |
366 | (const char *) &d->id, GNUNET_TIME_UNIT_FOREVER_ABS, | 220 | sizeof (value), &value, |
367 | GNUNET_TIME_UNIT_FOREVER_REL, NULL, NULL); | 221 | GNUNET_TIME_UNIT_FOREVER_ABS, |
368 | 222 | GNUNET_TIME_UNIT_FOREVER_REL, | |
223 | NULL, NULL); | ||
369 | } | 224 | } |
370 | put_task = GNUNET_SCHEDULER_add_delayed (PUT_FREQUENCY, &put_id, NULL); | 225 | put_task = GNUNET_SCHEDULER_add_delayed (PUT_FREQUENCY, |
371 | if (GNUNET_SCHEDULER_NO_TASK == test_task) | 226 | &do_puts, hs); |
372 | test_task = GNUNET_SCHEDULER_add_now (&do_test, NULL); | ||
373 | } | 227 | } |
374 | 228 | ||
375 | 229 | ||
376 | /** | 230 | /** |
377 | * peergroup_ready: start test when all peers are connected | 231 | * Main function of the test. |
378 | * | ||
379 | * @param cls closure | ||
380 | * @param emsg error message | ||
381 | * | ||
382 | */ | ||
383 | static void | ||
384 | peergroup_ready (void *cls, const char *emsg) | ||
385 | { | ||
386 | struct GNUNET_TESTING_Daemon *d; | ||
387 | char *buf; | ||
388 | int buf_len; | ||
389 | unsigned int i; | ||
390 | |||
391 | if (emsg != NULL) | ||
392 | { | ||
393 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
394 | "Peergroup callback called with error, aborting test!\n"); | ||
395 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
396 | "Error from testing: `%s'\n", | ||
397 | emsg); | ||
398 | ok++; | ||
399 | GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); | ||
400 | return; | ||
401 | } | ||
402 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
403 | "Peer Group started successfully with %u connections\n", | ||
404 | total_connections); | ||
405 | if (data_file != NULL) | ||
406 | { | ||
407 | buf = NULL; | ||
408 | buf_len = GNUNET_asprintf (&buf, "CONNECTIONS_0: %u\n", total_connections); | ||
409 | if (buf_len > 0) | ||
410 | GNUNET_DISK_file_write (data_file, buf, buf_len); | ||
411 | GNUNET_free (buf); | ||
412 | } | ||
413 | peers_running = GNUNET_TESTING_daemons_running (pg); | ||
414 | |||
415 | GNUNET_assert (peers_running == num_peers); | ||
416 | hs = GNUNET_malloc (num_peers * sizeof (struct GNUNET_DHT_Handle *)); | ||
417 | for (i = 0; i < num_peers; i++) | ||
418 | { | ||
419 | d = GNUNET_TESTING_daemon_get (pg, i); | ||
420 | hs[i] = GNUNET_DHT_connect (d->cfg, 32); | ||
421 | } | ||
422 | |||
423 | test_task = GNUNET_SCHEDULER_NO_TASK; | ||
424 | put_task = GNUNET_SCHEDULER_add_now (&put_id, NULL); | ||
425 | disconnect_task = | ||
426 | GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, &disconnect_peers, NULL); | ||
427 | |||
428 | } | ||
429 | |||
430 | |||
431 | /** | ||
432 | * Function that will be called whenever two daemons are connected by | ||
433 | * the testing library. | ||
434 | * | 232 | * |
435 | * @param cls closure | 233 | * @param cls closure (NULL) |
436 | * @param first peer id for first daemon | 234 | * @param ctx argument to give to GNUNET_DHT_TEST_cleanup on test end |
437 | * @param second peer id for the second daemon | 235 | * @param num_peers number of peers that are running |
438 | * @param distance distance between the connected peers | 236 | * @param peers array of peers |
439 | * @param first_cfg config for the first daemon | 237 | * @param dhts handle to each of the DHTs of the peers |
440 | * @param second_cfg config for the second daemon | ||
441 | * @param first_daemon handle for the first daemon | ||
442 | * @param second_daemon handle for the second daemon | ||
443 | * @param emsg error message (NULL on success) | ||
444 | */ | ||
445 | static void | ||
446 | connect_cb (void *cls, const struct GNUNET_PeerIdentity *first, | ||
447 | const struct GNUNET_PeerIdentity *second, uint32_t distance, | ||
448 | const struct GNUNET_CONFIGURATION_Handle *first_cfg, | ||
449 | const struct GNUNET_CONFIGURATION_Handle *second_cfg, | ||
450 | struct GNUNET_TESTING_Daemon *first_daemon, | ||
451 | struct GNUNET_TESTING_Daemon *second_daemon, const char *emsg) | ||
452 | { | ||
453 | if (emsg == NULL) | ||
454 | { | ||
455 | total_connections++; | ||
456 | GNUNET_PEER_intern (first); | ||
457 | GNUNET_PEER_intern (second); | ||
458 | } | ||
459 | else | ||
460 | { | ||
461 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | ||
462 | "Problem with new connection (%s)\n", emsg); | ||
463 | } | ||
464 | } | ||
465 | |||
466 | |||
467 | /** | ||
468 | * run: load configuration options and schedule test to run (start peergroup) | ||
469 | * @param cls closure | ||
470 | * @param args argv | ||
471 | * @param cfgfile configuration file name (can be NULL) | ||
472 | * @param cfg configuration handle | ||
473 | */ | 238 | */ |
474 | static void | 239 | static void |
475 | run (void *cls, char *const *args, const char *cfgfile, | 240 | run (void *cls, |
476 | const struct GNUNET_CONFIGURATION_Handle *cfg) | 241 | struct GNUNET_DHT_TEST_Context *ctx, |
242 | unsigned int num_peers, | ||
243 | struct GNUNET_TESTBED_Peer **peers, | ||
244 | struct GNUNET_DHT_Handle **dhts) | ||
477 | { | 245 | { |
478 | char *temp_str; | 246 | unsigned int i; |
479 | struct GNUNET_TESTING_Host *hosts; | 247 | unsigned int j; |
480 | char *data_filename; | 248 | struct GNUNET_HashCode key; |
481 | 249 | struct GetOperation *get_op; | |
482 | ok = 1; | 250 | |
483 | testing_cfg = GNUNET_CONFIGURATION_dup (cfg); | 251 | GNUNET_assert (NUM_PEERS == num_peers); |
484 | 252 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | |
485 | GNUNET_log_setup ("test_dht_topo", | 253 | "Peers setup, starting test\n"); |
486 | "WARNING", | 254 | /* FIXME: once testbed is finished, this call should |
487 | NULL); | 255 | no longer be needed */ |
488 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemons.\n"); | 256 | GNUNET_TESTBED_overlay_configure_topology (NULL, |
489 | GNUNET_CONFIGURATION_set_value_string (testing_cfg, "testing_old", | 257 | num_peers, |
490 | "use_progressbars", "YES"); | 258 | peers, |
491 | if (GNUNET_OK != | 259 | GNUNET_TESTBED_TOPOLOGY_LINE, |
492 | GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing_old", | 260 | GNUNET_TESTBED_TOPOLOGY_OPTION_END); |
493 | "num_peers", &num_peers)) | 261 | |
494 | { | 262 | put_task = GNUNET_SCHEDULER_add_now (&do_puts, dhts); |
495 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 263 | for (i=0;i<num_peers;i++) |
496 | "Option TESTING:NUM_PEERS is required!\n"); | ||
497 | return; | ||
498 | } | ||
499 | |||
500 | if (GNUNET_OK != | ||
501 | GNUNET_CONFIGURATION_get_value_string (testing_cfg, "testing_old", | ||
502 | "topology_output_file", | ||
503 | &topology_file)) | ||
504 | { | ||
505 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
506 | "Option test_dht_topo:topology_output_file is required!\n"); | ||
507 | return; | ||
508 | } | ||
509 | |||
510 | if (GNUNET_OK == | ||
511 | GNUNET_CONFIGURATION_get_value_string (testing_cfg, "test_dht_topo", | ||
512 | "data_output_file", | ||
513 | &data_filename)) | ||
514 | { | 264 | { |
515 | data_file = | 265 | GNUNET_CRYPTO_hash (&i, sizeof (i), &key); |
516 | GNUNET_DISK_file_open (data_filename, | 266 | for (j=0;j<num_peers;j++) |
517 | GNUNET_DISK_OPEN_READWRITE | | ||
518 | GNUNET_DISK_OPEN_CREATE, | ||
519 | GNUNET_DISK_PERM_USER_READ | | ||
520 | GNUNET_DISK_PERM_USER_WRITE); | ||
521 | if (data_file == NULL) | ||
522 | { | 267 | { |
523 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to open %s for output!\n", | 268 | get_op = GNUNET_malloc (sizeof (struct GetOperation)); |
524 | data_filename); | 269 | GNUNET_CONTAINER_DLL_insert (get_head, |
525 | GNUNET_free (data_filename); | 270 | get_tail, |
271 | get_op); | ||
272 | get_op->get = GNUNET_DHT_get_start (dhts[j], | ||
273 | GNUNET_BLOCK_TYPE_TEST, /* type */ | ||
274 | &key, /*key to search */ | ||
275 | 4U, /* replication level */ | ||
276 | GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, | ||
277 | NULL, /* xquery */ | ||
278 | 0, /* xquery bits */ | ||
279 | &dht_get_handler, get_op); | ||
526 | } | 280 | } |
527 | } | 281 | } |
528 | 282 | timeout_task = GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, | |
529 | if (GNUNET_YES == | 283 | &shutdown_task, ctx); |
530 | GNUNET_CONFIGURATION_get_value_string (cfg, "test_dht_topo", | ||
531 | "output_file", &temp_str)) | ||
532 | { | ||
533 | output_file = | ||
534 | GNUNET_DISK_file_open (temp_str, | ||
535 | GNUNET_DISK_OPEN_READWRITE | | ||
536 | GNUNET_DISK_OPEN_CREATE, | ||
537 | GNUNET_DISK_PERM_USER_READ | | ||
538 | GNUNET_DISK_PERM_USER_WRITE); | ||
539 | if (output_file == NULL) | ||
540 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to open %s for output!\n", | ||
541 | temp_str); | ||
542 | } | ||
543 | GNUNET_free_non_null (temp_str); | ||
544 | |||
545 | hosts = GNUNET_TESTING_hosts_load (testing_cfg); | ||
546 | |||
547 | pg = GNUNET_TESTING_peergroup_start (testing_cfg, num_peers, TIMEOUT, | ||
548 | &connect_cb, &peergroup_ready, NULL, | ||
549 | hosts); | ||
550 | GNUNET_assert (pg != NULL); | ||
551 | shutdown_handle = | ||
552 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, | ||
553 | &shutdown_task, NULL); | ||
554 | } | 284 | } |
555 | 285 | ||
556 | 286 | ||
@@ -560,62 +290,28 @@ run (void *cls, char *const *args, const char *cfgfile, | |||
560 | int | 290 | int |
561 | main (int xargc, char *xargv[]) | 291 | main (int xargc, char *xargv[]) |
562 | { | 292 | { |
563 | static struct GNUNET_GETOPT_CommandLineOption options[] = { | 293 | const char *cfg_filename; |
564 | GNUNET_GETOPT_OPTION_END | 294 | const char *test_name; |
565 | }; | ||
566 | static char *const argv_torus[] = { "test-dht-2dtorus", | ||
567 | "-c", | ||
568 | "test_dht_2dtorus.conf", | ||
569 | NULL | ||
570 | }; | ||
571 | static char *const argv_line[] = { "test-dht-line", | ||
572 | "-c", | ||
573 | "test_dht_line.conf", | ||
574 | NULL | ||
575 | }; | ||
576 | char *const *argv; | ||
577 | int argc; | ||
578 | 295 | ||
579 | if (strstr (xargv[0], "test_dht_2dtorus") != NULL) | 296 | if (NULL != strstr (xargv[0], "test_dht_2dtorus")) |
580 | { | 297 | { |
581 | argv = argv_torus; | 298 | cfg_filename = "test_dht_2dtorus.conf"; |
582 | argc = sizeof (argv_torus) / sizeof (char *); | 299 | test_name = "test-dht-2dtorus"; |
583 | test_topology = TORUS; | ||
584 | } | 300 | } |
585 | else if (strstr (xargv[0], "test_dht_line") != NULL) | 301 | else if (NULL != strstr (xargv[0], "test_dht_line")) |
586 | { | 302 | { |
587 | argv = argv_line; | 303 | cfg_filename = "test_dht_line.conf"; |
588 | argc = sizeof (argv_line) / sizeof (char *); | 304 | test_name = "test-dht-line"; |
589 | test_topology = LINE; | ||
590 | } | 305 | } |
591 | else | 306 | else |
592 | { | 307 | { |
593 | GNUNET_break (0); | 308 | GNUNET_break (0); |
594 | return 1; | 309 | return 1; |
595 | } | 310 | } |
596 | GNUNET_PROGRAM_run (argc - 1, argv, | 311 | GNUNET_DHT_TEST_run (test_name, |
597 | xargv[0], | 312 | cfg_filename, |
598 | gettext_noop ("Test dht in different topologies."), | 313 | NUM_PEERS, |
599 | options, | 314 | &run, NULL); |
600 | &run, NULL); | ||
601 | #if REMOVE_DIR | ||
602 | GNUNET_DISK_directory_remove ("/tmp/test_dht_topo"); | ||
603 | #endif | ||
604 | if (0 == found_1) | ||
605 | { | ||
606 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "ID 1 not found!\n"); | ||
607 | } | ||
608 | if (TORUS == test_topology) | ||
609 | { | ||
610 | if (0 == found_2) | ||
611 | { | ||
612 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "ID 2 not found!\n"); | ||
613 | } | ||
614 | if (0 == found_far) | ||
615 | { | ||
616 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "ID far not found!\n"); | ||
617 | } | ||
618 | } | ||
619 | return ok; | 315 | return ok; |
620 | } | 316 | } |
621 | 317 | ||
diff --git a/src/include/gnunet_dht_service.h b/src/include/gnunet_dht_service.h index 83774826e..89f42acb4 100644 --- a/src/include/gnunet_dht_service.h +++ b/src/include/gnunet_dht_service.h | |||
@@ -163,10 +163,12 @@ typedef void (*GNUNET_DHT_PutContinuation)(void *cls, | |||
163 | * (size too big) | 163 | * (size too big) |
164 | */ | 164 | */ |
165 | struct GNUNET_DHT_PutHandle * | 165 | struct GNUNET_DHT_PutHandle * |
166 | GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, const struct GNUNET_HashCode * key, | 166 | GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, |
167 | const struct GNUNET_HashCode * key, | ||
167 | uint32_t desired_replication_level, | 168 | uint32_t desired_replication_level, |
168 | enum GNUNET_DHT_RouteOption options, | 169 | enum GNUNET_DHT_RouteOption options, |
169 | enum GNUNET_BLOCK_Type type, size_t size, const char *data, | 170 | enum GNUNET_BLOCK_Type type, |
171 | size_t size, const void *data, | ||
170 | struct GNUNET_TIME_Absolute exp, | 172 | struct GNUNET_TIME_Absolute exp, |
171 | struct GNUNET_TIME_Relative timeout, | 173 | struct GNUNET_TIME_Relative timeout, |
172 | GNUNET_DHT_PutContinuation cont, | 174 | GNUNET_DHT_PutContinuation cont, |
diff --git a/src/testbed/testbed_api_testbed.c b/src/testbed/testbed_api_testbed.c index 96ac22c2b..a8f12f361 100644 --- a/src/testbed/testbed_api_testbed.c +++ b/src/testbed/testbed_api_testbed.c | |||
@@ -416,7 +416,7 @@ controller_status_cb (void *cls, const struct GNUNET_CONFIGURATION_Handle *cfg, | |||
416 | * @param cls the tesbed run handle | 416 | * @param cls the tesbed run handle |
417 | * @param tc the task context from scheduler | 417 | * @param tc the task context from scheduler |
418 | */ | 418 | */ |
419 | void | 419 | static void |
420 | shutdown_run_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 420 | shutdown_run_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
421 | { | 421 | { |
422 | struct RunContext *rc = cls; | 422 | struct RunContext *rc = cls; |