From 5aeb7f512e5946aec63567e81c72d64523b17530 Mon Sep 17 00:00:00 2001 From: Matthias Wachs Date: Tue, 19 Nov 2013 14:06:32 +0000 Subject: preference client management and test --- src/ats/Makefile.am | 33 ++++ src/ats/gnunet-service-ats_addresses.c | 15 +- src/ats/libgnunet_plugin_ats_mlp.c | 3 +- src/ats/test_ats_solver_preferences.c | 313 +++++++++++++++++++++++++++++++++ 4 files changed, 362 insertions(+), 2 deletions(-) create mode 100644 src/ats/test_ats_solver_preferences.c (limited to 'src/ats') diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am index 714f3640d..4851ff8a5 100644 --- a/src/ats/Makefile.am +++ b/src/ats/Makefile.am @@ -25,6 +25,7 @@ if HAVE_LIBGLPK GN_MLP_ADD_REQUEST_ADDRESS = test_ats_solver_add_address_and_request_mlp GN_MLP_REQUEST_ADD_ADDRESS = test_ats_solver_request_and_add_address_mlp GN_MLP_REQUEST_DELETE_ADDRESS = test_ats_solver_request_and_delete_address_mlp + GN_MLP_PREFERENCES_ADDRESS = test_ats_solver_preferences_mlp GN_MLP_ALTERNATIVE_DELETE_ADDRESS = test_ats_solver_alternative_after_delete_address_mlp GN_MLP_SOLVER_PERF = perf_ats_solver_mlp endif @@ -123,11 +124,14 @@ TESTING_TESTS = \ test_ats_solver_request_and_add_address_proportional \ test_ats_solver_request_and_delete_address_proportional \ test_ats_solver_alternative_after_delete_address_proportional \ + test_ats_solver_preferences_proportional \ + test_ats_solver_preferences_ril \ $(GN_MLP_ADD_ADDRESS) \ $(GN_MLP_ADD_REQUEST_ADDRESS) \ $(GN_MLP_REQUEST_ADD_ADDRESS) \ $(GN_MLP_REQUEST_DELETE_ADDRESS) \ $(GN_MLP_ALTERNATIVE_DELETE_ADDRESS) \ + $(GN_MLP_PREFERENCES_ADDRESS) \ test_ats_solver_add_address_ril \ test_ats_solver_add_address_and_request_ril \ test_ats_solver_request_and_add_address_ril \ @@ -405,6 +409,16 @@ test_ats_solver_alternative_after_delete_address_proportional_LDADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la + +test_ats_solver_preferences_proportional_SOURCES = \ + test_ats_solver_preferences.c \ + test_ats_api_common.c test_ats_api_common.h +test_ats_solver_preferences_proportional_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la if HAVE_LIBGLPK test_ats_solver_alternative_after_delete_address_mlp_SOURCES = \ @@ -416,6 +430,16 @@ test_ats_solver_alternative_after_delete_address_mlp_LDADD = \ $(top_builddir)/src/hello/libgnunethello.la \ $(top_builddir)/src/ats/libgnunetats.la \ $(top_builddir)/src/statistics/libgnunetstatistics.la + +test_ats_solver_preferences_mlp_SOURCES = \ + test_ats_solver_preferences.c \ + test_ats_api_common.c test_ats_api_common.h +test_ats_solver_preferences_mlp_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la endif test_ats_solver_alternative_after_delete_address_ril_SOURCES = \ @@ -460,6 +484,15 @@ perf_ats_solver_ril_LDADD = \ $(top_builddir)/src/statistics/libgnunetstatistics.la \ $(top_builddir)/src/ats/libgnunetats.la +test_ats_solver_preferences_ril_SOURCES = \ + test_ats_solver_preferences.c \ + test_ats_api_common.c test_ats_api_common.h +test_ats_solver_preferences_ril_LDADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testing/libgnunettesting.la \ + $(top_builddir)/src/hello/libgnunethello.la \ + $(top_builddir)/src/ats/libgnunetats.la \ + $(top_builddir)/src/statistics/libgnunetstatistics.la EXTRA_DIST = \ ats.h \ diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c index 746dbd7e3..7d0eb48ea 100644 --- a/src/ats/gnunet-service-ats_addresses.c +++ b/src/ats/gnunet-service-ats_addresses.c @@ -290,6 +290,11 @@ struct GAS_Addresses_Handle */ int running; + /** + * Preferences clients + */ + int pref_clients; + /** * Configured ATS solver */ @@ -1721,8 +1726,10 @@ GAS_addresses_preference_client_disconnect (struct GAS_Addresses_Handle *handle, GNUNET_CONTAINER_DLL_remove (handle->preference_clients_head, handle->preference_clients_tail, pc); GNUNET_free (pc); + GNUNET_assert (handle->pref_clients > 0); + handle->pref_clients --; + GNUNET_STATISTICS_set (handle->stat, "# active performance clients", handle->pref_clients, GNUNET_NO); } - GAS_normalization_preference_client_disconnect (client); } @@ -1764,6 +1771,8 @@ GAS_addresses_preference_change (struct GAS_Addresses_Handle *handle, pc->client = client; GNUNET_CONTAINER_DLL_insert (handle->preference_clients_head, handle->preference_clients_tail, pc); + handle->pref_clients ++; + GNUNET_STATISTICS_set (handle->stat, "# active performance clients", handle->pref_clients, GNUNET_NO); } handle->env.sf.s_bulk_start (handle->solver); @@ -2019,6 +2028,7 @@ GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg, ah->stat = (struct GNUNET_STATISTICS_Handle *) stats; /* Initialize the addresses database */ ah->addresses = GNUNET_CONTAINER_multipeermap_create (128, GNUNET_NO); + ah->pref_clients = 0; GNUNET_assert(NULL != ah->addresses); /* Figure out configured solution method */ @@ -2205,6 +2215,9 @@ GAS_addresses_done (struct GAS_Addresses_Handle *handle) { GNUNET_CONTAINER_DLL_remove (handle->preference_clients_head, handle->preference_clients_tail, pcur); + GNUNET_assert (handle->pref_clients > 0); + handle->pref_clients --; + GNUNET_STATISTICS_set (handle->stat, "# active performance clients", handle->pref_clients, GNUNET_NO); GNUNET_free (pcur); } diff --git a/src/ats/libgnunet_plugin_ats_mlp.c b/src/ats/libgnunet_plugin_ats_mlp.c index cdd9ac64f..07f77161f 100644 --- a/src/ats/libgnunet_plugin_ats_mlp.c +++ b/src/ats/libgnunet_plugin_ats_mlp.c @@ -1800,8 +1800,9 @@ GAS_mlp_address_change_preference (void *solver, return; } p->f = get_peer_pref_value (mlp, peer); + /* LOG (GNUNET_ERROR_TYPE_ERROR, "PEER PREF: %s %.2f\n", - GNUNET_i2s(peer), p->f); + GNUNET_i2s(peer), p->f);*/ mlp_create_problem_update_value (&mlp->p, p->r_c9, mlp->p.c_r, -p->f, __LINE__); /* Problem size changed: new address for peer with pending request */ diff --git a/src/ats/test_ats_solver_preferences.c b/src/ats/test_ats_solver_preferences.c new file mode 100644 index 000000000..0e96dc129 --- /dev/null +++ b/src/ats/test_ats_solver_preferences.c @@ -0,0 +1,313 @@ +/* + if (NULL == (perf_ats = GNUNET_ATS_performance_init (cfg, &ats_perf_cb, NULL))) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Failed to connect to performance API\n"); + GNUNET_SCHEDULER_add_now (end_badly, NULL); + } + This file is part of GNUnet. + (C) 2010-2013 Christian Grothoff (and other contributing authors) + + GNUnet is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published + by the Free Software Foundation; either version 3, or (at your + option) any later version. + + GNUnet is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with GNUnet; see the file COPYING. If not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + */ +/** + * @file ats/test_ats_solver_preferences.c + * @brief solver test: preference client handling + * @author Christian Grothoff + * @author Matthias Wachs + */ +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_testbed_service.h" +#include "gnunet_ats_service.h" +#include "test_ats_api_common.h" + +/** + * Timeout task + */ +static GNUNET_SCHEDULER_TaskIdentifier die_task; + +/** + * Statistics handle + */ +struct GNUNET_STATISTICS_Handle *stats; + +/** + * Scheduling handle + */ +static struct GNUNET_ATS_SchedulingHandle *sched_ats; + +/** + * Scheduling handle + */ +static struct GNUNET_ATS_PerformanceHandle *perf_ats; + +/** + * Return value + */ +static int ret; + +/** + * Test address + */ +static struct Test_Address test_addr; + +/** + * Test peer + */ +static struct PeerContext p; + +/** + * HELLO address + */ +struct GNUNET_HELLO_Address test_hello_address; + +/** + * Session + */ +static void *test_session; + +/** + * Test ats info + */ +struct GNUNET_ATS_Information test_ats_info[2]; + +/** + * Test ats count + */ +uint32_t test_ats_count; + +static int +stat_cb (void *cls, const char *subsystem, const char *name, uint64_t value, + int is_persistent); + +static void +end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Done!\n"); + + if (die_task != GNUNET_SCHEDULER_NO_TASK ) + { + GNUNET_SCHEDULER_cancel (die_task); + die_task = GNUNET_SCHEDULER_NO_TASK; + } + + if (NULL != sched_ats) + { + GNUNET_ATS_scheduling_done (sched_ats); + sched_ats = NULL; + } + + if (NULL != perf_ats) + { + GNUNET_ATS_performance_done (perf_ats); + perf_ats = NULL; + } + + GNUNET_STATISTICS_watch_cancel (stats, "ats", "# active performance clients", &stat_cb, NULL ); + if (NULL != stats) + { + GNUNET_STATISTICS_destroy (stats, GNUNET_NO); + stats = NULL; + } + + free_test_address (&test_addr); + + ret = 0; +} + +static void +end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +{ + die_task = GNUNET_SCHEDULER_NO_TASK; + end (NULL, NULL ); + ret = GNUNET_SYSERR; +} + + +static void +perf_info_cb (void *cls, + const struct GNUNET_HELLO_Address *address, int address_active, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, + const struct GNUNET_ATS_Information *ats, uint32_t ats_count) +{ + GNUNET_log(GNUNET_ERROR_TYPE_INFO, "ATS performance info: `%s'\n", + GNUNET_i2s (&address->peer)); +} + +static void +address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address, + struct Session *session, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, + struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, + const struct GNUNET_ATS_Information *atsi, uint32_t ats_count) +{ + int c; + double pref_val; + int prefs[GNUNET_ATS_PreferenceCount] = GNUNET_ATS_PreferenceType; + + if (NULL == perf_ats) + return; + for (c = 1; c < GNUNET_ATS_PreferenceCount; c++) + { + pref_val = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 10); + GNUNET_ATS_performance_change_preference (perf_ats, + &test_hello_address.peer, prefs[c], pref_val, + GNUNET_ATS_PREFERENCE_END); + } +} + +static int +stat_cb (void *cls, const char *subsystem, const char *name, uint64_t value, + int is_persistent) +{ + static int last_value = 0; + GNUNET_log(GNUNET_ERROR_TYPE_INFO, "ATS statistics: `%s' `%s' %llu\n", + subsystem, name, value); + + if ((0 == last_value) && (1 == value)) + { + if (perf_ats != NULL) + { + GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Disconnecting performance client\n"); + GNUNET_ATS_performance_done(perf_ats); + perf_ats = NULL; + } + } + if ((1 == last_value) && (0 == value)) + { + GNUNET_SCHEDULER_add_now (&end, NULL); + } + last_value = value; + + return GNUNET_OK; +} + +static void +run (void *cls, const struct GNUNET_CONFIGURATION_Handle *mycfg, + struct GNUNET_TESTING_Peer *peer) +{ + + die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL ); + stats = GNUNET_STATISTICS_create ("ats", mycfg); + GNUNET_STATISTICS_watch (stats, "ats", "# active performance clients", &stat_cb, NULL ); + + /* Connect to ATS scheduling */ + sched_ats = GNUNET_ATS_scheduling_init (mycfg, &address_suggest_cb, NULL ); + if (sched_ats == NULL ) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "Could not connect to ATS scheduling!\n"); + GNUNET_SCHEDULER_add_now (&end_badly, NULL ); + return; + } + + perf_ats = GNUNET_ATS_performance_init (mycfg, &perf_info_cb, NULL ); + if (perf_ats == NULL ) + { + GNUNET_log(GNUNET_ERROR_TYPE_ERROR, + "Could not connect to ATS performance!\n"); + GNUNET_SCHEDULER_add_now (&end_badly, NULL ); + return; + } + + /* Set up peer */ + memset (&p.id, '1', sizeof(p.id)); + + GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n", + GNUNET_i2s_full (&p.id)); + + /* Prepare ATS Information */ + test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE); + test_ats_info[0].value = htonl (GNUNET_ATS_NET_WAN); + test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE); + test_ats_info[1].value = htonl (1); + test_ats_count = 2; + + /* Adding address without session */ + test_session = NULL; + create_test_address (&test_addr, "test", test_session, "test", + strlen ("test") + 1); + test_hello_address.peer = p.id; + test_hello_address.transport_name = test_addr.plugin; + test_hello_address.address = test_addr.addr; + test_hello_address.address_length = test_addr.addr_len; + + /* Adding address */ + GNUNET_ATS_address_add (sched_ats, &test_hello_address, test_session, + test_ats_info, test_ats_count); + GNUNET_ATS_suggest_address(sched_ats, &test_hello_address.peer); +} + +int +main (int argc, char *argv[]) +{ + char *sep; + char *src_filename = GNUNET_strdup (__FILE__); + char *test_filename = GNUNET_strdup (argv[0]); + char *config_file; + char *solver; + + ret = 0; + + if (NULL == (sep = (strstr (src_filename, ".c")))) + { + GNUNET_break(0); + return -1; + } + sep[0] = '\0'; + + if (NULL != (sep = strstr (test_filename, ".exe"))) + sep[0] = '\0'; + + if (NULL == (solver = strstr (test_filename, src_filename))) + { + GNUNET_break(0); + return -1; + } + solver += strlen (src_filename) + 1; + + if (0 == strcmp (solver, "proportional")) + { + config_file = "test_ats_solver_proportional.conf"; + } + else if (0 == strcmp (solver, "mlp")) + { + config_file = "test_ats_solver_mlp.conf"; + } + else if ((0 == strcmp (solver, "ril"))) + { + config_file = "test_ats_solver_ril.conf"; + } + else + { + GNUNET_break(0); + GNUNET_free(src_filename); + GNUNET_free(test_filename); + return 1; + } + + GNUNET_free(src_filename); + GNUNET_free(test_filename); + + if (0 + != GNUNET_TESTING_peer_run ("test-ats-solver", config_file, &run, NULL )) + return GNUNET_SYSERR; + + return ret; +} + +/* end of file test_ats_solver_preferences.c */ -- cgit v1.2.3