aboutsummaryrefslogtreecommitdiff
path: root/src/service/hostlist/test_gnunet_daemon_hostlist_learning.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/service/hostlist/test_gnunet_daemon_hostlist_learning.c')
-rw-r--r--src/service/hostlist/test_gnunet_daemon_hostlist_learning.c593
1 files changed, 593 insertions, 0 deletions
diff --git a/src/service/hostlist/test_gnunet_daemon_hostlist_learning.c b/src/service/hostlist/test_gnunet_daemon_hostlist_learning.c
new file mode 100644
index 000000000..a0656f770
--- /dev/null
+++ b/src/service/hostlist/test_gnunet_daemon_hostlist_learning.c
@@ -0,0 +1,593 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2009, 2010, 2011, 2012, 2016 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your 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 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file hostlist/test_gnunet_daemon_hostlist_learning.c
22 * @brief test for gnunet_daemon_hostslist.c
23 * @author Christian Grothoff
24 */
25#include "platform.h"
26#include "gnunet_util_lib.h"
27#include "gnunet_arm_service.h"
28#include "gnunet_core_service.h"
29#include "gnunet_transport_service.h"
30#include "gnunet_resolver_service.h"
31#include "gnunet_statistics_service.h"
32
33#define MAX_URL_LEN 1000
34
35/**
36 * How long until wait until testcases fails
37 */
38#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 180)
39
40#define CHECK_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, \
41 1)
42
43
44struct PeerContext
45{
46 struct GNUNET_CONFIGURATION_Handle *cfg;
47 struct GNUNET_MessageHeader *hello;
48 struct GNUNET_CORE_Handle *core;
49 struct GNUNET_STATISTICS_Handle *stats;
50 struct GNUNET_OS_Process *arm_proc;
51};
52
53static int timeout;
54
55static int adv_sent;
56
57static int adv_arrived;
58
59static int learned_hostlist_saved;
60
61static int learned_hostlist_downloaded;
62
63static char *current_adv_uri;
64
65static const struct GNUNET_CONFIGURATION_Handle *cfg;
66
67static struct GNUNET_SCHEDULER_Task *timeout_task;
68
69static struct GNUNET_SCHEDULER_Task *check_task;
70
71static struct PeerContext adv_peer;
72
73static struct PeerContext learn_peer;
74
75static struct GNUNET_STATISTICS_GetHandle *download_stats;
76
77static struct GNUNET_STATISTICS_GetHandle *urisrecv_stat;
78
79static struct GNUNET_STATISTICS_GetHandle *advsent_stat;
80
81
82static void
83shutdown_testcase ()
84{
85 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
86 "Shutdown testcase....\n");
87 if (NULL != timeout_task)
88 {
89 GNUNET_SCHEDULER_cancel (timeout_task);
90 timeout_task = NULL;
91 }
92 if (NULL != download_stats)
93 {
94 GNUNET_STATISTICS_get_cancel (download_stats);
95 download_stats = NULL;
96 }
97 if (NULL != urisrecv_stat)
98 {
99 GNUNET_STATISTICS_get_cancel (urisrecv_stat);
100 urisrecv_stat = NULL;
101 }
102 if (NULL != advsent_stat)
103 {
104 GNUNET_STATISTICS_get_cancel (advsent_stat);
105 advsent_stat = NULL;
106 }
107 if (NULL != adv_peer.stats)
108 {
109 GNUNET_STATISTICS_destroy (adv_peer.stats, GNUNET_NO);
110 adv_peer.stats = NULL;
111 }
112 if (NULL != learn_peer.stats)
113 {
114 GNUNET_STATISTICS_destroy (learn_peer.stats, GNUNET_NO);
115 learn_peer.stats = NULL;
116 }
117 if (NULL != check_task)
118 {
119 GNUNET_SCHEDULER_cancel (check_task);
120 check_task = NULL;
121 }
122 if (NULL != current_adv_uri)
123 {
124 GNUNET_free (current_adv_uri);
125 current_adv_uri = NULL;
126 }
127 if (NULL != adv_peer.core)
128 {
129 GNUNET_CORE_disconnect (adv_peer.core);
130 adv_peer.core = NULL;
131 }
132 if (NULL != learn_peer.core)
133 {
134 GNUNET_CORE_disconnect (learn_peer.core);
135 learn_peer.core = NULL;
136 }
137 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
138 "Killing hostlist server ARM process.\n");
139 if (0 != GNUNET_OS_process_kill (adv_peer.arm_proc,
140 GNUNET_TERM_SIG))
141 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
142 "kill");
143 if (GNUNET_OK !=
144 GNUNET_OS_process_wait (adv_peer.arm_proc))
145 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
146 "waitpid");
147 GNUNET_OS_process_destroy (adv_peer.arm_proc);
148 adv_peer.arm_proc = NULL;
149 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
150 "Killing hostlist client ARM process.\n");
151 if (0 != GNUNET_OS_process_kill (learn_peer.arm_proc,
152 GNUNET_TERM_SIG))
153 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
154 "kill");
155 if (GNUNET_OK !=
156 GNUNET_OS_process_wait (learn_peer.arm_proc))
157 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING,
158 "waitpid");
159 GNUNET_OS_process_destroy (learn_peer.arm_proc);
160 learn_peer.arm_proc = NULL;
161 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
162 "Shutdown complete....\n");
163}
164
165
166/**
167 * Timeout, give up.
168 */
169static void
170timeout_error (void *cls)
171{
172 timeout_task = NULL;
173 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
174 "Timeout while executing testcase, test failed.\n");
175 timeout = GNUNET_YES;
176 shutdown_testcase ();
177}
178
179
180static void
181process_downloads_done (void *cls, int success)
182{
183 download_stats = NULL;
184}
185
186
187static void
188do_shutdown (void *cls)
189{
190 shutdown_testcase ();
191}
192
193
194static int
195process_downloads (void *cls,
196 const char *subsystem,
197 const char *name,
198 uint64_t value,
199 int is_persistent)
200{
201 if ((value >= 2) &&
202 (GNUNET_NO == learned_hostlist_downloaded))
203 {
204 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
205 "Peer has successfully downloaded advertised URI\n");
206 learned_hostlist_downloaded = GNUNET_YES;
207 if ((learned_hostlist_saved == GNUNET_YES) && (adv_sent == GNUNET_YES))
208 {
209 GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
210 }
211 }
212 return GNUNET_OK;
213}
214
215
216static void
217process_uris_recv_done (void *cls, int success)
218{
219 urisrecv_stat = NULL;
220}
221
222
223static int
224process_uris_recv (void *cls,
225 const char *subsystem,
226 const char *name,
227 uint64_t value,
228 int is_persistent)
229{
230 struct PeerContext *pc = cls;
231
232 if ((pc == &learn_peer) &&
233 (value == 1) &&
234 (learned_hostlist_saved == GNUNET_NO))
235 {
236 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
237 "Peer has successfully saved advertised URI\n");
238 learned_hostlist_saved = GNUNET_YES;
239 if ((learned_hostlist_downloaded == GNUNET_YES) &&
240 (adv_sent == GNUNET_YES))
241 {
242 GNUNET_SCHEDULER_add_now (&do_shutdown,
243 NULL);
244 }
245 }
246 return GNUNET_OK;
247}
248
249
250static void
251process_adv_sent_done (void *cls, int success)
252{
253 advsent_stat = NULL;
254}
255
256
257static int
258process_adv_sent (void *cls,
259 const char *subsystem,
260 const char *name,
261 uint64_t value,
262 int is_persistent)
263{
264 if ((value >= 1) && (adv_sent == GNUNET_NO))
265 {
266 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
267 "Server has successfully sent advertisement\n");
268 adv_sent = GNUNET_YES;
269 if ((learned_hostlist_downloaded == GNUNET_YES) &&
270 (learned_hostlist_saved == GNUNET_YES))
271 {
272 GNUNET_SCHEDULER_add_now (&do_shutdown,
273 NULL);
274 }
275 }
276 return GNUNET_OK;
277}
278
279
280/**
281 * Check the server statistics regularly
282 */
283static void
284check_statistics (void *cls)
285{
286 char *stat;
287
288 check_task = NULL;
289 GNUNET_asprintf (&stat,
290 gettext_noop ("# advertised URI `%s' downloaded"),
291 current_adv_uri);
292 if (NULL != learn_peer.stats)
293 {
294 if (NULL != download_stats)
295 GNUNET_STATISTICS_get_cancel (download_stats);
296 download_stats =
297 GNUNET_STATISTICS_get (learn_peer.stats,
298 "hostlist",
299 stat,
300 &process_downloads_done,
301 &process_downloads,
302 &learn_peer);
303 if (NULL != urisrecv_stat)
304 GNUNET_STATISTICS_get_cancel (urisrecv_stat);
305 urisrecv_stat =
306 GNUNET_STATISTICS_get (learn_peer.stats, "hostlist",
307 gettext_noop ("# advertised hostlist URIs"),
308 &process_uris_recv_done, &process_uris_recv,
309 &learn_peer);
310 }
311 GNUNET_free (stat);
312 if (NULL != adv_peer.stats)
313 {
314 if (NULL != advsent_stat)
315 GNUNET_STATISTICS_get_cancel (advsent_stat);
316 advsent_stat =
317 GNUNET_STATISTICS_get (adv_peer.stats, "hostlist",
318 gettext_noop ("# hostlist advertisements send"),
319 &process_adv_sent_done,
320 &process_adv_sent,
321 NULL);
322 }
323 check_task =
324 GNUNET_SCHEDULER_add_delayed (CHECK_INTERVAL,
325 &check_statistics,
326 NULL);
327}
328
329
330static int
331check_ad_arrive (void *cls,
332 const struct GNUNET_MessageHeader *message)
333{
334 const char *end = (const char *) &message[1];
335
336 if ('\0' != end[ntohs (message->size) - sizeof(struct GNUNET_MessageHeader)
337 - 1])
338 {
339 GNUNET_break (0);
340 return GNUNET_SYSERR;
341 }
342 return GNUNET_OK;
343}
344
345
346static void
347handle_ad_arrive (void *cls,
348 const struct GNUNET_MessageHeader *message)
349{
350 char *hostname;
351 char *expected_uri;
352 unsigned long long port;
353 const char *end;
354
355 if (GNUNET_SYSERR ==
356 GNUNET_CONFIGURATION_get_value_number (adv_peer.cfg,
357 "HOSTLIST",
358 "HTTPPORT",
359 &port))
360 {
361 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
362 "Could not read advertising server's configuration\n");
363 return;
364 }
365
366 if (GNUNET_SYSERR ==
367 GNUNET_CONFIGURATION_get_value_string (adv_peer.cfg,
368 "HOSTLIST",
369 "EXTERNAL_DNS_NAME",
370 &hostname))
371 hostname = GNUNET_RESOLVER_local_fqdn_get ();
372 GNUNET_asprintf (&expected_uri,
373 "http://%s:%u/",
374 hostname != NULL ? hostname : "localhost",
375 (unsigned int) port);
376 end = (const char *) &message[1];
377 current_adv_uri = GNUNET_strdup (end);
378 if (0 == strcmp (expected_uri,
379 current_adv_uri))
380 {
381 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
382 "Received hostlist advertisement with URI `%s' as expected\n",
383 current_adv_uri);
384 adv_arrived = GNUNET_YES;
385 adv_sent = GNUNET_YES;
386 }
387 else
388 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
389 "Expected URI `%s' and received URI `%s' differ\n",
390 expected_uri,
391 current_adv_uri);
392 GNUNET_free (expected_uri);
393 GNUNET_free (hostname);
394}
395
396
397static void
398setup_learn_peer (struct PeerContext *p,
399 const char *cfgname)
400{
401 struct GNUNET_MQ_MessageHandler learn_handlers[] = {
402 GNUNET_MQ_hd_var_size (ad_arrive,
403 GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT,
404 struct GNUNET_MessageHeader,
405 NULL),
406 GNUNET_MQ_handler_end ()
407 };
408 char *filename;
409 unsigned int result;
410 char *binary;
411
412 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-arm");
413 p->cfg = GNUNET_CONFIGURATION_create ();
414 p->arm_proc =
415 GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_OUT_AND_ERR
416 | GNUNET_OS_USE_PIPE_CONTROL,
417 NULL, NULL, NULL,
418 binary,
419 "gnunet-service-arm",
420 "-c", cfgname, NULL);
421 GNUNET_assert (GNUNET_OK ==
422 GNUNET_CONFIGURATION_load (p->cfg,
423 cfgname));
424 if (GNUNET_OK ==
425 GNUNET_CONFIGURATION_get_value_string (p->cfg,
426 "HOSTLIST",
427 "HOSTLISTFILE",
428 &filename))
429 {
430 if (GNUNET_YES == GNUNET_DISK_file_test (filename))
431 {
432 result = unlink (filename);
433 if (result == 0)
434 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
435 _ ("Hostlist file `%s' was removed\n"),
436 filename);
437 }
438 GNUNET_free (filename);
439 }
440 p->core = GNUNET_CORE_connect (p->cfg,
441 NULL,
442 NULL,
443 NULL,
444 NULL,
445 learn_handlers);
446 GNUNET_assert (NULL != p->core);
447 p->stats = GNUNET_STATISTICS_create ("hostlist",
448 p->cfg);
449 GNUNET_assert (NULL != p->stats);
450 GNUNET_free (binary);
451}
452
453
454static void
455setup_adv_peer (struct PeerContext *p,
456 const char *cfgname)
457{
458 char *binary;
459
460 binary = GNUNET_OS_get_libexec_binary_path ("gnunet-service-arm");
461 p->cfg = GNUNET_CONFIGURATION_create ();
462 p->arm_proc =
463 GNUNET_OS_start_process (GNUNET_OS_INHERIT_STD_OUT_AND_ERR
464 | GNUNET_OS_USE_PIPE_CONTROL,
465 NULL, NULL, NULL,
466 binary,
467 "gnunet-service-arm",
468 "-c", cfgname, NULL);
469 GNUNET_assert (GNUNET_OK ==
470 GNUNET_CONFIGURATION_load (p->cfg,
471 cfgname));
472 p->stats = GNUNET_STATISTICS_create ("hostlist", p->cfg);
473 GNUNET_assert (NULL != p->stats);
474 GNUNET_free (binary);
475}
476
477
478static void
479run (void *cls,
480 char *const *args,
481 const char *cfgfile,
482 const struct GNUNET_CONFIGURATION_Handle *c)
483{
484 timeout = GNUNET_NO;
485 adv_sent = GNUNET_NO;
486
487 adv_arrived = 0;
488 learned_hostlist_saved = GNUNET_NO;
489 learned_hostlist_downloaded = GNUNET_NO;
490
491 cfg = c;
492
493 setup_adv_peer (&adv_peer,
494 "test_learning_adv_peer.conf");
495 setup_learn_peer (&learn_peer,
496 "test_learning_learn_peer.conf");
497 timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
498 &timeout_error,
499 NULL);
500 check_task =
501 GNUNET_SCHEDULER_add_delayed (CHECK_INTERVAL,
502 &check_statistics,
503 NULL);
504}
505
506
507static int
508check ()
509{
510 unsigned int failed;
511
512 char *const argv[] = {
513 "test-gnunet-daemon-hostlist-learning",
514 "-c", "learning_data.conf",
515 NULL
516 };
517 struct GNUNET_GETOPT_CommandLineOption options[] = {
518 GNUNET_GETOPT_OPTION_END
519 };
520
521 GNUNET_PROGRAM_run ((sizeof(argv) / sizeof(char *)) - 1,
522 argv,
523 "test-gnunet-daemon-hostlist-learning",
524 "nohelp",
525 options,
526 &run,
527 NULL);
528 failed = GNUNET_NO;
529 if (timeout == GNUNET_YES)
530 {
531 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
532 "Testcase timeout\n");
533 failed = GNUNET_YES;
534 }
535 if (adv_arrived != GNUNET_YES)
536 {
537 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
538 "Learning peer did not receive advertisement from server\n");
539 failed = GNUNET_YES;
540 }
541 if (learned_hostlist_saved == GNUNET_NO)
542 {
543 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
544 "Advertised hostlist was not saved in datastore\n");
545 failed = GNUNET_YES;
546 }
547 if (learned_hostlist_downloaded == GNUNET_NO)
548 {
549 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
550 "Advertised hostlist could not be downloaded from server\n");
551 failed = GNUNET_YES;
552 }
553 if (adv_sent == GNUNET_NO)
554 {
555 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
556 "Advertised was not sent from server to client\n");
557 failed = GNUNET_YES;
558 }
559 if (GNUNET_YES == failed)
560 return GNUNET_YES;
561 return GNUNET_NO;
562}
563
564
565int
566main (int argc, char *argv[])
567{
568 int ret;
569
570 GNUNET_DISK_purge_cfg_dir ("test_learning_learn_peer.conf",
571 "GNUNET_TEST_HOME");
572 GNUNET_DISK_purge_cfg_dir ("test_learning_adv_peer.conf",
573 "GNUNET_TEST_HOME");
574 GNUNET_log_setup ("test-gnunet-daemon-hostlist",
575 "WARNING",
576 NULL);
577 ret = check ();
578 GNUNET_DISK_purge_cfg_dir ("test_learning_learn_peer.conf",
579 "GNUNET_TEST_HOME");
580 GNUNET_DISK_purge_cfg_dir ("test_learning_adv_peer.conf",
581 "GNUNET_TEST_HOME");
582 if (GNUNET_YES ==
583 GNUNET_DISK_file_test ("hostlists_learn_peer.file"))
584 {
585 if (0 == unlink ("hostlists_learn_peer.file"))
586 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
587 "Hostlist file hostlists_learn_peer.file was removed\n");
588 }
589 return ret;
590}
591
592
593/* end of test_gnunet_daemon_hostlist_learning.c */