2 This file is part of GNUnet
3 Copyright (C) 2009, 2010, 2011, 2012, 2016 GNUnet e.V.
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.
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.
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/>.
18 SPDX-License-Identifier: AGPL3.0-or-later
21 * @file hostlist/test_gnunet_daemon_hostlist_learning.c
22 * @brief test for gnunet_daemon_hostslist.c
23 * @author Christian Grothoff
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"
33 #define MAX_URL_LEN 1000
36 * How long until wait until testcases fails
38 #define TIMEOUT GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 180)
40 #define CHECK_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS, 1)
44 struct GNUNET_CONFIGURATION_Handle *cfg;
45 struct GNUNET_MessageHeader *hello;
46 struct GNUNET_CORE_Handle *core;
47 struct GNUNET_STATISTICS_Handle *stats;
48 struct GNUNET_OS_Process *arm_proc;
55 static int adv_arrived;
57 static int learned_hostlist_saved;
59 static int learned_hostlist_downloaded;
61 static char *current_adv_uri;
63 static const struct GNUNET_CONFIGURATION_Handle *cfg;
65 static struct GNUNET_SCHEDULER_Task *timeout_task;
67 static struct GNUNET_SCHEDULER_Task *check_task;
69 static struct PeerContext adv_peer;
71 static struct PeerContext learn_peer;
73 static struct GNUNET_STATISTICS_GetHandle *download_stats;
75 static struct GNUNET_STATISTICS_GetHandle *urisrecv_stat;
77 static struct GNUNET_STATISTICS_GetHandle *advsent_stat;
83 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
84 "Shutdown testcase....\n");
85 if (NULL != timeout_task)
87 GNUNET_SCHEDULER_cancel(timeout_task);
90 if (NULL != download_stats)
92 GNUNET_STATISTICS_get_cancel(download_stats);
93 download_stats = NULL;
95 if (NULL != urisrecv_stat)
97 GNUNET_STATISTICS_get_cancel(urisrecv_stat);
100 if (NULL != advsent_stat)
102 GNUNET_STATISTICS_get_cancel(advsent_stat);
105 if (NULL != adv_peer.stats)
107 GNUNET_STATISTICS_destroy(adv_peer.stats, GNUNET_NO);
108 adv_peer.stats = NULL;
110 if (NULL != learn_peer.stats)
112 GNUNET_STATISTICS_destroy(learn_peer.stats, GNUNET_NO);
113 learn_peer.stats = NULL;
115 if (NULL != check_task)
117 GNUNET_SCHEDULER_cancel(check_task);
120 if (NULL != current_adv_uri)
122 GNUNET_free(current_adv_uri);
123 current_adv_uri = NULL;
125 if (NULL != adv_peer.core)
127 GNUNET_CORE_disconnect(adv_peer.core);
128 adv_peer.core = NULL;
130 if (NULL != learn_peer.core)
132 GNUNET_CORE_disconnect(learn_peer.core);
133 learn_peer.core = NULL;
135 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
136 "Killing hostlist server ARM process.\n");
137 if (0 != GNUNET_OS_process_kill(adv_peer.arm_proc,
139 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING,
142 GNUNET_OS_process_wait(adv_peer.arm_proc))
143 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING,
145 GNUNET_OS_process_destroy(adv_peer.arm_proc);
146 adv_peer.arm_proc = NULL;
147 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
148 "Killing hostlist client ARM process.\n");
149 if (0 != GNUNET_OS_process_kill(learn_peer.arm_proc,
151 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING,
154 GNUNET_OS_process_wait(learn_peer.arm_proc))
155 GNUNET_log_strerror(GNUNET_ERROR_TYPE_WARNING,
157 GNUNET_OS_process_destroy(learn_peer.arm_proc);
158 learn_peer.arm_proc = NULL;
159 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
160 "Shutdown complete....\n");
168 timeout_error(void *cls)
171 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
172 "Timeout while executing testcase, test failed.\n");
173 timeout = GNUNET_YES;
179 process_downloads_done(void *cls, int success)
181 download_stats = NULL;
186 do_shutdown(void *cls)
193 process_downloads(void *cls,
194 const char *subsystem,
200 (GNUNET_NO == learned_hostlist_downloaded))
202 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
203 "Peer has successfully downloaded advertised URI\n");
204 learned_hostlist_downloaded = GNUNET_YES;
205 if ((learned_hostlist_saved == GNUNET_YES) && (adv_sent == GNUNET_YES))
207 GNUNET_SCHEDULER_add_now(&do_shutdown, NULL);
215 process_uris_recv_done(void *cls, int success)
217 urisrecv_stat = NULL;
222 process_uris_recv(void *cls,
223 const char *subsystem,
228 struct PeerContext *pc = cls;
230 if ((pc == &learn_peer) &&
232 (learned_hostlist_saved == GNUNET_NO))
234 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
235 "Peer has successfully saved advertised URI\n");
236 learned_hostlist_saved = GNUNET_YES;
237 if ((learned_hostlist_downloaded == GNUNET_YES) &&
238 (adv_sent == GNUNET_YES))
240 GNUNET_SCHEDULER_add_now(&do_shutdown,
249 process_adv_sent_done(void *cls, int success)
256 process_adv_sent(void *cls,
257 const char *subsystem,
262 if ((value >= 1) && (adv_sent == GNUNET_NO))
264 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
265 "Server has successfully sent advertisement\n");
266 adv_sent = GNUNET_YES;
267 if ((learned_hostlist_downloaded == GNUNET_YES) &&
268 (learned_hostlist_saved == GNUNET_YES))
270 GNUNET_SCHEDULER_add_now(&do_shutdown,
279 * Check the server statistics regularly
282 check_statistics(void *cls)
287 GNUNET_asprintf(&stat,
288 gettext_noop("# advertised URI `%s' downloaded"),
290 if (NULL != learn_peer.stats)
292 if (NULL != download_stats)
293 GNUNET_STATISTICS_get_cancel(download_stats);
295 GNUNET_STATISTICS_get(learn_peer.stats,
298 &process_downloads_done,
301 if (NULL != urisrecv_stat)
302 GNUNET_STATISTICS_get_cancel(urisrecv_stat);
304 GNUNET_STATISTICS_get(learn_peer.stats, "hostlist",
305 gettext_noop("# advertised hostlist URIs"),
306 &process_uris_recv_done, &process_uris_recv,
310 if (NULL != adv_peer.stats)
312 if (NULL != advsent_stat)
313 GNUNET_STATISTICS_get_cancel(advsent_stat);
315 GNUNET_STATISTICS_get(adv_peer.stats, "hostlist",
316 gettext_noop("# hostlist advertisements send"),
317 &process_adv_sent_done,
322 GNUNET_SCHEDULER_add_delayed(CHECK_INTERVAL,
329 check_ad_arrive(void *cls,
330 const struct GNUNET_MessageHeader *message)
332 const char *end = (const char *)&message[1];
334 if ('\0' != end[ntohs(message->size) - sizeof(struct GNUNET_MessageHeader) - 1])
337 return GNUNET_SYSERR;
344 handle_ad_arrive(void *cls,
345 const struct GNUNET_MessageHeader *message)
349 unsigned long long port;
353 GNUNET_CONFIGURATION_get_value_number(adv_peer.cfg,
358 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
359 "Could not read advertising server's configuration\n");
364 GNUNET_CONFIGURATION_get_value_string(adv_peer.cfg,
368 hostname = GNUNET_RESOLVER_local_fqdn_get();
369 GNUNET_asprintf(&expected_uri,
371 hostname != NULL ? hostname : "localhost",
373 end = (const char *)&message[1];
374 current_adv_uri = GNUNET_strdup(end);
375 if (0 == strcmp(expected_uri,
378 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
379 "Received hostlist advertisement with URI `%s' as expected\n",
381 adv_arrived = GNUNET_YES;
382 adv_sent = GNUNET_YES;
385 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
386 "Expected URI `%s' and received URI `%s' differ\n",
389 GNUNET_free(expected_uri);
390 GNUNET_free_non_null(hostname);
395 setup_learn_peer(struct PeerContext *p,
398 struct GNUNET_MQ_MessageHandler learn_handlers[] = {
399 GNUNET_MQ_hd_var_size(ad_arrive,
400 GNUNET_MESSAGE_TYPE_HOSTLIST_ADVERTISEMENT,
401 struct GNUNET_MessageHeader,
403 GNUNET_MQ_handler_end()
409 binary = GNUNET_OS_get_libexec_binary_path("gnunet-service-arm");
410 p->cfg = GNUNET_CONFIGURATION_create();
412 GNUNET_OS_start_process(GNUNET_YES, GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
415 "gnunet-service-arm",
416 "-c", cfgname, NULL);
417 GNUNET_assert(GNUNET_OK ==
418 GNUNET_CONFIGURATION_load(p->cfg,
421 GNUNET_CONFIGURATION_get_value_string(p->cfg,
426 if (GNUNET_YES == GNUNET_DISK_file_test(filename))
428 result = unlink(filename);
430 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
431 _("Hostlist file `%s' was removed\n"),
434 GNUNET_free(filename);
436 p->core = GNUNET_CORE_connect(p->cfg,
442 GNUNET_assert(NULL != p->core);
443 p->stats = GNUNET_STATISTICS_create("hostlist",
445 GNUNET_assert(NULL != p->stats);
451 setup_adv_peer(struct PeerContext *p,
456 binary = GNUNET_OS_get_libexec_binary_path("gnunet-service-arm");
457 p->cfg = GNUNET_CONFIGURATION_create();
459 GNUNET_OS_start_process(GNUNET_YES,
460 GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
463 "gnunet-service-arm",
464 "-c", cfgname, NULL);
465 GNUNET_assert(GNUNET_OK ==
466 GNUNET_CONFIGURATION_load(p->cfg,
468 p->stats = GNUNET_STATISTICS_create("hostlist", p->cfg);
469 GNUNET_assert(NULL != p->stats);
478 const struct GNUNET_CONFIGURATION_Handle *c)
481 adv_sent = GNUNET_NO;
484 learned_hostlist_saved = GNUNET_NO;
485 learned_hostlist_downloaded = GNUNET_NO;
489 setup_adv_peer(&adv_peer,
490 "test_learning_adv_peer.conf");
491 setup_learn_peer(&learn_peer,
492 "test_learning_learn_peer.conf");
493 timeout_task = GNUNET_SCHEDULER_add_delayed(TIMEOUT,
497 GNUNET_SCHEDULER_add_delayed(CHECK_INTERVAL,
508 char *const argv[] = {
509 "test-gnunet-daemon-hostlist-learning",
510 "-c", "learning_data.conf",
513 struct GNUNET_GETOPT_CommandLineOption options[] = {
514 GNUNET_GETOPT_OPTION_END
517 GNUNET_PROGRAM_run((sizeof(argv) / sizeof(char *)) - 1,
519 "test-gnunet-daemon-hostlist-learning",
525 if (timeout == GNUNET_YES)
527 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
528 "Testcase timeout\n");
531 if (adv_arrived != GNUNET_YES)
533 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
534 "Learning peer did not receive advertisement from server\n");
537 if (learned_hostlist_saved == GNUNET_NO)
539 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
540 "Advertised hostlist was not saved in datastore\n");
543 if (learned_hostlist_downloaded == GNUNET_NO)
545 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
546 "Advertised hostlist could not be downloaded from server\n");
549 if (adv_sent == GNUNET_NO)
551 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
552 "Advertised was not sent from server to client\n");
555 if (GNUNET_YES == failed)
562 main(int argc, char *argv[])
566 GNUNET_DISK_purge_cfg_dir("test_learning_learn_peer.conf",
568 GNUNET_DISK_purge_cfg_dir("test_learning_adv_peer.conf",
570 GNUNET_log_setup("test-gnunet-daemon-hostlist",
574 GNUNET_DISK_purge_cfg_dir("test_learning_learn_peer.conf",
576 GNUNET_DISK_purge_cfg_dir("test_learning_adv_peer.conf",
579 GNUNET_DISK_file_test("hostlists_learn_peer.file"))
581 if (0 == unlink("hostlists_learn_peer.file"))
582 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
583 "Hostlist file hostlists_learn_peer.file was removed\n");
588 /* end of test_gnunet_daemon_hostlist_learning.c */