aboutsummaryrefslogtreecommitdiff
path: root/src/testing/test_testing_topology_churn.c
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2010-05-12 15:48:52 +0000
committerNathan S. Evans <evans@in.tum.de>2010-05-12 15:48:52 +0000
commitdfe5fd29a357766ad681d7c95c47e06717367aa4 (patch)
treeef75959224a76f3e27aca614219267f4d14e96b0 /src/testing/test_testing_topology_churn.c
parent0bba5c2a473984a776f37ff064e926e4f0742f24 (diff)
downloadgnunet-dfe5fd29a357766ad681d7c95c47e06717367aa4.tar.gz
gnunet-dfe5fd29a357766ad681d7c95c47e06717367aa4.zip
churn fixes and testcase
Diffstat (limited to 'src/testing/test_testing_topology_churn.c')
-rw-r--r--src/testing/test_testing_topology_churn.c322
1 files changed, 322 insertions, 0 deletions
diff --git a/src/testing/test_testing_topology_churn.c b/src/testing/test_testing_topology_churn.c
new file mode 100644
index 000000000..0d894378f
--- /dev/null
+++ b/src/testing/test_testing_topology_churn.c
@@ -0,0 +1,322 @@
1/*
2 This file is part of GNUnet.
3 (C) 2009 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 2, 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 testing/test_testing_topology_churn.c
22 * @brief base testcase for testing simple churn functionality
23 */
24#include "platform.h"
25#include "gnunet_testing_lib.h"
26#include "gnunet_core_service.h"
27
28#define VERBOSE GNUNET_YES
29
30/**
31 * How long until we fail the whole testcase?
32 */
33#define TEST_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 600)
34
35/**
36 * How long until we give up on starting the peers? (Must be longer than the connect timeout!)
37 */
38#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300)
39
40#define DEFAULT_NUM_PEERS 4
41
42static int ok;
43
44static unsigned long long num_peers;
45
46static unsigned int expected_connections;
47
48static unsigned int expected_failed_connections;
49
50static unsigned long long peers_left;
51
52static struct GNUNET_TESTING_PeerGroup *pg;
53
54static struct GNUNET_SCHEDULER_Handle *sched;
55
56const struct GNUNET_CONFIGURATION_Handle *main_cfg;
57
58GNUNET_SCHEDULER_TaskIdentifier die_task;
59
60static char *test_directory;
61
62#define MTYPE 12345
63
64struct GNUNET_TestMessage
65{
66 /**
67 * Header of the message
68 */
69 struct GNUNET_MessageHeader header;
70
71 /**
72 * Unique identifier for this message.
73 */
74 uint32_t uid;
75};
76
77static void
78finish_testing ()
79{
80 GNUNET_assert (pg != NULL);
81
82 if (die_task != GNUNET_SCHEDULER_NO_TASK)
83 GNUNET_SCHEDULER_cancel(sched, die_task);
84
85#if VERBOSE
86 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
87 "Called finish testing, stopping daemons.\n");
88#endif
89
90#if VERBOSE
91 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
92 "Calling daemons_stop\n");
93#endif
94 GNUNET_TESTING_daemons_stop (pg, TIMEOUT);
95#if VERBOSE
96 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
97 "daemons_stop finished\n");
98#endif
99
100 ok = 0;
101}
102
103static void
104end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
105{
106 char *msg = cls;
107 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
108 "End badly was called (%s)... stopping daemons.\n", msg);
109
110 if (pg != NULL)
111 {
112 GNUNET_TESTING_daemons_stop (pg, TIMEOUT);
113 ok = 7331; /* Opposite of leet */
114 }
115 else
116 ok = 401; /* Never got peers started */
117
118}
119
120struct ChurnTestContext
121{
122 GNUNET_SCHEDULER_Task next_task;
123
124};
125
126static struct ChurnTestContext churn_ctx;
127
128/**
129 * Churn callback, report on success or failure of churn operation.
130 *
131 * @param cls closure
132 * @param emsg NULL on success
133 */
134void churn_callback(void *cls,
135 const char *emsg)
136{
137 if (emsg == NULL)
138 {
139 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Successfully churned peers!\n", emsg);
140 GNUNET_SCHEDULER_add_now(sched, churn_ctx.next_task, NULL);
141 }
142 else
143 {
144 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Failed to churn peers with error `%s'\n", emsg);
145 GNUNET_SCHEDULER_cancel(sched, die_task);
146 die_task = GNUNET_SCHEDULER_add_now(sched, &end_badly, NULL);
147 }
148}
149
150
151static void
152churn_peers_both()
153{
154 churn_ctx.next_task = &finish_testing;
155 GNUNET_TESTING_daemons_churn(pg, 1, 1, TIMEOUT, &churn_callback, NULL);
156}
157
158static void
159churn_peers_off_again()
160{
161 churn_ctx.next_task = &churn_peers_both;
162 GNUNET_TESTING_daemons_churn(pg, 2, 0, TIMEOUT, &churn_callback, NULL);
163}
164
165static void
166churn_peers_on()
167{
168 churn_ctx.next_task = &churn_peers_off_again;
169 GNUNET_TESTING_daemons_churn(pg, 0, 2, TIMEOUT, &churn_callback, NULL);
170}
171
172static void
173churn_peers_off()
174{
175 churn_ctx.next_task = &churn_peers_on;
176 GNUNET_TESTING_daemons_churn(pg, 2, 0, TIMEOUT, &churn_callback, NULL);
177}
178
179static void
180peers_started_callback (void *cls,
181 const struct GNUNET_PeerIdentity *id,
182 const struct GNUNET_CONFIGURATION_Handle *cfg,
183 struct GNUNET_TESTING_Daemon *d, const char *emsg)
184{
185 if (emsg != NULL)
186 {
187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to start daemon with error: `%s'\n",
188 emsg);
189 return;
190 }
191 GNUNET_assert (id != NULL);
192#if VERBOSE
193 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Started daemon %llu out of %llu\n",
194 (num_peers - peers_left) + 1, num_peers);
195#endif
196 peers_left--;
197 if (peers_left == 0)
198 {
199#if VERBOSE
200 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
201 "All %d daemons started, now testing churn!\n",
202 num_peers);
203#endif
204 GNUNET_SCHEDULER_cancel (sched, die_task);
205 /* Set up task in case topology creation doesn't finish
206 * within a reasonable amount of time */
207 die_task = GNUNET_SCHEDULER_add_delayed (sched,
208 GNUNET_TIME_relative_multiply
209 (GNUNET_TIME_UNIT_MINUTES, 5),
210 &end_badly, "from peers_started_callback");
211 churn_peers_off ();
212 ok = 0;
213 }
214}
215
216
217static void
218run (void *cls,
219 struct GNUNET_SCHEDULER_Handle *s,
220 char *const *args,
221 const char *cfgfile, const struct GNUNET_CONFIGURATION_Handle *cfg)
222{
223 sched = s;
224 ok = 1;
225
226#if VERBOSE
227 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
228 "Starting daemons based on config file %s\n", cfgfile);
229#endif
230
231 if (GNUNET_YES != GNUNET_CONFIGURATION_get_value_string(cfg, "paths", "servicehome", &test_directory))
232 {
233 ok = 404;
234 return;
235 }
236
237 if (GNUNET_SYSERR ==
238 GNUNET_CONFIGURATION_get_value_number (cfg, "testing", "num_peers",
239 &num_peers))
240 num_peers = DEFAULT_NUM_PEERS;
241
242 main_cfg = cfg;
243
244 peers_left = num_peers;
245
246 /* For this specific test we only really want a CLIQUE topology as the
247 * overlay allowed topology, and a RING topology as the underlying connection
248 * allowed topology. So we will expect only num_peers * 2 connections to
249 * work, and (num_peers * (num_peers - 1)) - (num_peers * 2) to fail.
250 */
251 expected_connections = num_peers * (num_peers - 1);
252 expected_failed_connections = expected_connections - (num_peers * 2);
253
254
255 /* Set up a task to end testing if peer start fails */
256 die_task = GNUNET_SCHEDULER_add_delayed (sched,
257 GNUNET_TIME_relative_multiply
258 (GNUNET_TIME_UNIT_MINUTES, 5),
259 &end_badly, "didn't start all daemons in reasonable amount of time!!!");
260
261 pg = GNUNET_TESTING_daemons_start (sched, cfg,
262 peers_left, TIMEOUT, NULL, NULL, &peers_started_callback, NULL,
263 NULL, NULL, NULL);
264
265}
266
267static int
268check ()
269{
270 int ret;
271 char *const argv[] = {"test-testing-topology-churn",
272 "-c",
273 "test_testing_data_topology_churn.conf",
274#if VERBOSE
275 "-L", "DEBUG",
276#endif
277 NULL
278 };
279 struct GNUNET_GETOPT_CommandLineOption options[] = {
280 GNUNET_GETOPT_OPTION_END
281 };
282 ret = GNUNET_PROGRAM_run ((sizeof (argv) / sizeof (char *)) - 1,
283 argv, "test-testing-topology-churn", "nohelp",
284 options, &run, &ok);
285 if (ret != GNUNET_OK)
286 {
287 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "`test-testing-topology-churn': Failed with error code %d\n", ret);
288 }
289
290 return ok;
291}
292
293int
294main (int argc, char *argv[])
295{
296 int ret;
297
298 GNUNET_log_setup ("test_testing_topology_churn",
299#if VERBOSE
300 "DEBUG",
301#else
302 "WARNING",
303#endif
304 NULL);
305 ret = check ();
306
307 /**
308 * Need to remove base directory, subdirectories taken care
309 * of by the testing framework.
310 */
311 if (test_directory != NULL)
312 {
313 if (GNUNET_DISK_directory_remove (test_directory) != GNUNET_OK)
314 {
315 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "Failed to remove testing directory %s\n", test_directory);
316 }
317 }
318
319 return ret;
320}
321
322/* end of test_testing_topology_churn.c */