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 /src | |
parent | 48c3f008109fe5c1925eee5fc946e5e606d410c7 (diff) |
-moving DHT test to testbed API
Diffstat (limited to 'src')
-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 a365c5e82a..982c33815b 100644 --- a/src/dht/Makefile.am +++ b/src/dht/Makefile.am @@ -109,6 +109,17 @@ gnunet_dht_monitor_DEPENDENCIES = \ libgnunetdht.la +noinst_LIBRARIES = libgnunetdhttest.a + +libgnunetdhttest_a_SOURCES = \ + dht_test_lib.c dht_test_lib.h +libgnunetdhttest_a_LIBADD = \ + $(top_builddir)/src/util/libgnunetutil.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ + $(top_builddir)/src/dht/libgnunetdht.la +libgnunetdhttest_a_DEPENDENCIES = \ + libgnunetdht.la + check_PROGRAMS = \ test_dht_api \ test_dht_twopeer \ @@ -120,15 +131,18 @@ check_PROGRAMS = \ test_dht_2dtorus \ test_dht_monitor +if HAVE_EXPERIMENTAL + NEW_TESTS = test_dht_line test_dht_2dtorus +endif + if ENABLE_TEST_RUN TESTS = test_dht_api $(check_SCRIPTS) \ test_dht_twopeer \ test_dht_twopeer_put_get \ test_dht_twopeer_get_put \ test_dht_twopeer_path_tracking \ - test_dht_multipeer \ - test_dht_line \ - test_dht_2dtorus \ + test_dht_multipeer \ + $(NEW_TESTS) \ test_dht_monitor endif @@ -142,6 +156,7 @@ test_dht_api_LDADD = \ test_dht_api_DEPENDENCIES = \ libgnunetdht.la +# twopeer is obsolete once new test_dht_topo works... test_dht_twopeer_SOURCES = \ test_dht_twopeer.c test_dht_twopeer_LDADD = \ @@ -151,6 +166,7 @@ test_dht_twopeer_LDADD = \ test_dht_twopeer_DEPENDENCIES = \ libgnunetdht.la +# twopeer_put_get is obsolete once new test_dht_topo works... test_dht_twopeer_put_get_SOURCES = \ test_dht_twopeer_put_get.c test_dht_twopeer_put_get_LDADD = \ @@ -158,6 +174,7 @@ test_dht_twopeer_put_get_LDADD = \ $(top_builddir)/src/testing_old/libgnunettesting_old.la \ $(top_builddir)/src/dht/libgnunetdht.la +# twopeer_get_put is obsolete once new test_dht_topo works... test_dht_twopeer_get_put_SOURCES = \ test_dht_twopeer_get_put.c test_dht_twopeer_get_put_LDADD = \ @@ -165,6 +182,7 @@ test_dht_twopeer_get_put_LDADD = \ $(top_builddir)/src/testing_old/libgnunettesting_old.la \ $(top_builddir)/src/dht/libgnunetdht.la +# twopeer_path_tracking is obsolete once new test_dht_topo works... test_dht_twopeer_path_tracking_SOURCES = \ test_dht_twopeer_path_tracking.c test_dht_twopeer_path_tracking_LDADD = \ @@ -172,6 +190,8 @@ test_dht_twopeer_path_tracking_LDADD = \ $(top_builddir)/src/testing_old/libgnunettesting_old.la \ $(top_builddir)/src/dht/libgnunetdht.la +# statistics functions should be integrated with test_dht_topo, +# then this one also becomes obsolete... test_dht_multipeer_SOURCES = \ test_dht_multipeer.c test_dht_multipeer_LDADD = \ @@ -185,8 +205,9 @@ test_dht_multipeer_DEPENDENCIES = \ test_dht_2dtorus_SOURCES = \ test_dht_topo.c test_dht_2dtorus_LDADD = \ + $(top_builddir)/src/dht/libgnunetdhttest.a \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing_old/libgnunettesting_old.la \ + $(top_builddir)/src/testbed/libgnunettestbed.la \ $(top_builddir)/src/dht/libgnunetdht.la test_dht_2dtorus_DEPENDENCIES = \ libgnunetdht.la @@ -194,12 +215,14 @@ test_dht_2dtorus_DEPENDENCIES = \ test_dht_line_SOURCES = \ test_dht_topo.c test_dht_line_LDADD = \ + $(top_builddir)/src/dht/libgnunetdhttest.a \ $(top_builddir)/src/util/libgnunetutil.la \ - $(top_builddir)/src/testing_old/libgnunettesting_old.la \ - $(top_builddir)/src/dht/libgnunetdht.la + $(top_builddir)/src/testbed/libgnunettestbed.la \ + $(top_builddir)/src/dht/libgnunetdht.la test_dht_line_DEPENDENCIES = \ libgnunetdht.la +# fixme, rewrite based on test_dht_topo.c! test_dht_monitor_SOURCES = test_dht_monitor.c test_dht_monitor_LDADD = \ $(top_builddir)/src/util/libgnunetutil.la \ diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c index 0905486d12..7964ba98f9 100644 --- a/src/dht/dht_api.c +++ b/src/dht/dht_api.c @@ -1041,7 +1041,7 @@ struct GNUNET_DHT_PutHandle * GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, const struct GNUNET_HashCode * key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, - enum GNUNET_BLOCK_Type type, size_t size, const char *data, + enum GNUNET_BLOCK_Type type, size_t size, const void *data, struct GNUNET_TIME_Absolute exp, struct GNUNET_TIME_Relative timeout, GNUNET_DHT_PutContinuation cont, void *cont_cls) diff --git a/src/dht/dht_test_lib.c b/src/dht/dht_test_lib.c new file mode 100644 index 0000000000..5fe34addf1 --- /dev/null +++ b/src/dht/dht_test_lib.c @@ -0,0 +1,214 @@ +/* + This file is part of GNUnet. + (C) 2012 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 dht/dht_test_lib.c + * @author Christian Grothoff + * @brief library for writing DHT tests + */ +#include "platform.h" +#include "dht_test_lib.h" + +/** + * Test context for a DHT Test. + */ +struct GNUNET_DHT_TEST_Context +{ + /** + * Array of running peers. + */ + struct GNUNET_TESTBED_Peer **peers; + + /** + * Array of handles to the DHT for each peer. + */ + struct GNUNET_DHT_Handle **dhts; + + /** + * Operation associated with the connection to the DHT. + */ + struct GNUNET_TESTBED_Operation **ops; + + /** + * Main function of the test to run once all DHTs are available. + */ + GNUNET_DHT_TEST_AppMain app_main; + + /** + * Closure for 'app_main'. + */ + void *app_main_cls; + + /** + * Number of peers running, size of the arrays above. + */ + unsigned int num_peers; + +}; + + +/** + * Adapter function called to establish a connection to + * the DHT service. + * + * @param cls closure + * @param cfg configuration of the peer to connect to; will be available until + * GNUNET_TESTBED_operation_done() is called on the operation returned + * from GNUNET_TESTBED_service_connect() + * @return service handle to return in 'op_result', NULL on error + */ +static void * +dht_connect_adapter (void *cls, + const struct GNUNET_CONFIGURATION_Handle *cfg) +{ + return GNUNET_DHT_connect (cfg, 16); +} + + +/** + * Adapter function called to destroy a connection to + * the DHT service. + * + * @param cls closure + * @param op_result service handle returned from the connect adapter + */ +static void +dht_disconnect_adapter (void *cls, + void *op_result) +{ + struct GNUNET_DHT_Handle *dht = op_result; + + GNUNET_DHT_disconnect (dht); +} + + +/** + * Callback to be called when a service connect operation is completed + * + * @param cls the callback closure from functions generating an operation + * @param op the operation that has been finished + * @param ca_result the service handle returned from GNUNET_TESTBED_ConnectAdapter() + * @param emsg error message in case the operation has failed; will be NULL if + * operation has executed successfully. + */ +static void +dht_connect_cb (void *cls, + struct GNUNET_TESTBED_Operation *op, + void *ca_result, + const char *emsg) +{ + struct GNUNET_DHT_TEST_Context *ctx = cls; + unsigned int i; + + if (NULL != emsg) + { + fprintf (stderr, "Failed to connect to DHT service: %s\n", + emsg); + GNUNET_SCHEDULER_shutdown (); + return; + } + for (i=0;i<ctx->num_peers;i++) + if (op == ctx->ops[i]) + ctx->dhts[i] = ca_result; + for (i=0;i<ctx->num_peers;i++) + if (NULL == ctx->dhts[i]) + return; /* still some DHT connections missing */ + /* all DHT connections ready! */ + ctx->app_main (ctx->app_main_cls, + ctx, + ctx->num_peers, + ctx->peers, + ctx->dhts); +} + + +/** + * Clean up the testbed. + * + * @param ctx handle for the testbed + */ +void +GNUNET_DHT_TEST_cleanup (struct GNUNET_DHT_TEST_Context *ctx) +{ + unsigned int i; + + for (i=0;i<ctx->num_peers;i++) + GNUNET_TESTBED_operation_done (ctx->ops[i]); + GNUNET_free (ctx->ops); + GNUNET_free (ctx->dhts); + GNUNET_free (ctx); + GNUNET_SCHEDULER_shutdown (); +} + + +static void +dht_test_run (void *cls, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers) +{ + struct GNUNET_DHT_TEST_Context *ctx = cls; + unsigned int i; + + GNUNET_assert (num_peers == ctx->num_peers); + ctx->peers = peers; + for (i=0;i<num_peers;i++) + ctx->ops[i] = GNUNET_TESTBED_service_connect (ctx, + peers[i], + "dht", + &dht_connect_cb, + ctx, + &dht_connect_adapter, + &dht_disconnect_adapter, + ctx); +} + + +/** + * Run a test using the given name, configuration file and number of + * peers. + * + * @param testname name of the test (for logging) + * @param cfgname name of the configuration file + * @param num_peers number of peers to start + * @param tmain main function to run once the testbed is ready + * @param tmain_cls closure for 'tmain' + */ +void +GNUNET_DHT_TEST_run (const char *testname, + const char *cfgname, + unsigned int num_peers, + GNUNET_DHT_TEST_AppMain tmain, + void *tmain_cls) +{ + struct GNUNET_DHT_TEST_Context *ctx; + + ctx = GNUNET_malloc (sizeof (struct GNUNET_DHT_TEST_Context)); + ctx->num_peers = num_peers; + ctx->ops = GNUNET_malloc (num_peers * sizeof (struct GNUNET_TESTBED_Operation *)); + ctx->dhts = GNUNET_malloc (num_peers * sizeof (struct GNUNET_DHT_Handle *)); + ctx->app_main = tmain; + ctx->app_main_cls = tmain_cls; + GNUNET_TESTBED_test_run (testname, + cfgname, + num_peers, + 0LL, NULL, NULL, + &dht_test_run, ctx); +} + +/* 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 0000000000..0cf6dfac9a --- /dev/null +++ b/src/dht/dht_test_lib.h @@ -0,0 +1,80 @@ +/* + This file is part of GNUnet. + (C) 2012 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 dht/dht_test_lib.h + * @author Christian Grothoff + * @brief library for writing DHT tests + */ +#ifndef DHT_TEST_LIB_H +#define DHT_TEST_LIB_H + +#include "gnunet_testbed_service.h" +#include "gnunet_dht_service.h" + +/** + * Test context for a DHT Test. + */ +struct GNUNET_DHT_TEST_Context; + + +/** + * Main function of a DHT test. + * + * @param cls closure + * @param ctx argument to give to GNUNET_DHT_TEST_cleanup on test end + * @param num_peers number of peers that are running + * @param peers array of peers + * @param dhts handle to each of the DHTs of the peers + */ +typedef void (*GNUNET_DHT_TEST_AppMain) (void *cls, + struct GNUNET_DHT_TEST_Context *ctx, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers, + struct GNUNET_DHT_Handle **dhts); + + +/** + * Run a test using the given name, configuration file and number of + * peers. + * + * @param testname name of the test (for logging) + * @param cfgname name of the configuration file + * @param num_peers number of peers to start + * @param tmain main function to run once the testbed is ready + * @param tmain_cls closure for 'tmain' + */ +void +GNUNET_DHT_TEST_run (const char *testname, + const char *cfgname, + unsigned int num_peers, + GNUNET_DHT_TEST_AppMain tmain, + void *tmain_cls); + + +/** + * Clean up the testbed. + * + * @param ctx handle for the testbed + */ +void +GNUNET_DHT_TEST_cleanup (struct GNUNET_DHT_TEST_Context *ctx); + + +#endif diff --git a/src/dht/test_dht_topo.c b/src/dht/test_dht_topo.c index a4765ee892..0934d7abd8 100644 --- a/src/dht/test_dht_topo.c +++ b/src/dht/test_dht_topo.c @@ -19,83 +19,59 @@ */ /** * @file dht/test_dht_topo.c - * + * @author Christian Grothoff * @brief Test for the dht service: store and retrieve in various topologies. - * Each peer stores it own ID in the DHT and then a different peer tries to - * retrieve that key from it. The GET starts after a first round of PUTS has - * been made. Periodically, each peer stores its ID into the DHT. If after - * a timeout no result has been returned, the test fails. + * Each peer stores a value from the DHT and then each peer tries to get each + * value from each other peer. */ #include "platform.h" -#include "gnunet_testing_lib.h" +#include "gnunet_util_lib.h" #include "gnunet_dht_service.h" - -#define REMOVE_DIR GNUNET_YES +#include "dht_test_lib.h" /** - * DIFFERENT TESTS TO RUN + * Number of peers to run. */ -#define LINE 0 -#define TORUS 1 +#define NUM_PEERS 5 /** - * How long until we give up on connecting the peers? + * How long until we give up on fetching the data? */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1500) - #define GET_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120) -#define PUT_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) - /** - * Result of the test. + * How frequently do we execute the PUTs? */ -static int ok; +#define PUT_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 5) -/** - * Total number of peers in the test. - */ -static unsigned long long num_peers; /** - * Global configuration file + * Information we keep for each GET operation. */ -static struct GNUNET_CONFIGURATION_Handle *testing_cfg; +struct GetOperation +{ + /** + * DLL. + */ + struct GetOperation *next; -/** - * Total number of currently running peers. - */ -static unsigned long long peers_running; + /** + * DLL. + */ + struct GetOperation *prev; -/** - * Total number of connections in the whole network. - */ -static unsigned int total_connections; + /** + * Handle for the operation. + */ + struct GNUNET_DHT_GetHandle *get; -/** - * The currently running peer group. - */ -static struct GNUNET_TESTING_PeerGroup *pg; +}; -/** - * File to report results to. - */ -static struct GNUNET_DISK_FileHandle *output_file; /** - * File to log connection info, statistics to. - */ -static struct GNUNET_DISK_FileHandle *data_file; - -/** - * Task called to disconnect peers. - */ -static GNUNET_SCHEDULER_TaskIdentifier disconnect_task; - -/** - * Task To perform tests + * Result of the test. */ -static GNUNET_SCHEDULER_TaskIdentifier test_task; +static int ok = 1; /** * Task to do DHT_puts @@ -103,454 +79,208 @@ static GNUNET_SCHEDULER_TaskIdentifier test_task; static GNUNET_SCHEDULER_TaskIdentifier put_task; /** - * Task called to shutdown test. + * Task to time out / regular shutdown. */ -static GNUNET_SCHEDULER_TaskIdentifier shutdown_handle; - -static char *topology_file; - -static struct GNUNET_DHT_Handle **hs; - -static struct GNUNET_DHT_GetHandle *get_h; - -static struct GNUNET_DHT_GetHandle *get_h_2; - -static struct GNUNET_DHT_GetHandle *get_h_far; - -static int found_1; - -static int found_2; - -static int found_far; +static GNUNET_SCHEDULER_TaskIdentifier timeout_task; /** - * Which topology are we to run + * Head of list of active GET operations. */ -static int test_topology; - +static struct GetOperation *get_head; /** - * Check whether peers successfully shut down. + * Tail of list of active GET operations. */ -static void -shutdown_callback (void *cls, const char *emsg) -{ - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Shutdown of peers failed!\n"); - ok++; - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "All peers successfully shut down!\n"); - } - GNUNET_CONFIGURATION_destroy (testing_cfg); -} +static struct GetOperation *get_tail; +/** + * Task run on success or timeout to clean up. + * Terminates active get operations and shuts down + * the testbed. + * + * @param cls the 'struct GNUNET_DHT_TestContext' + * @param tc scheduler context + */ static void -shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +shutdown_task (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Ending test.\n"); + struct GNUNET_DHT_TEST_Context *ctx = cls; + struct GetOperation *get_op; - if (disconnect_task != GNUNET_SCHEDULER_NO_TASK) + while (NULL != (get_op = get_tail)) { - GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = GNUNET_SCHEDULER_NO_TASK; + GNUNET_DHT_get_stop (get_op->get); + GNUNET_CONTAINER_DLL_remove (get_head, + get_tail, + get_op); + GNUNET_free (get_op); } - - if (data_file != NULL) - GNUNET_DISK_file_close (data_file); - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); -} - - -static void -disconnect_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - unsigned int i; - - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "disconnecting peers\n"); - disconnect_task = GNUNET_SCHEDULER_NO_TASK; GNUNET_SCHEDULER_cancel (put_task); - if (NULL != get_h) - GNUNET_DHT_get_stop (get_h); - if (NULL != get_h_2) - GNUNET_DHT_get_stop (get_h_2); - if (NULL != get_h_far) - GNUNET_DHT_get_stop (get_h_far); - for (i = 0; i < num_peers; i++) - { - GNUNET_DHT_disconnect (hs[i]); - } - GNUNET_SCHEDULER_cancel (shutdown_handle); - shutdown_handle = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); + GNUNET_DHT_TEST_cleanup (ctx); } +/** + * Iterator called on each result obtained for a DHT + * operation that expects a reply + * + * @param cls closure with our 'struct GetOperation' + * @param exp when will this value expire + * @param key key of the result + * @param get_path peers on reply path (or NULL if not recorded) + * @param get_path_length number of entries in get_path + * @param put_path peers on the PUT path (or NULL if not recorded) + * @param put_path_length number of entries in get_path + * @param type type of the result + * @param size number of bytes in data + * @param data pointer to the result data + */ static void -dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, - const struct GNUNET_HashCode * key, - const struct GNUNET_PeerIdentity *get_path, - unsigned int get_path_length, - const struct GNUNET_PeerIdentity *put_path, - unsigned int put_path_length, enum GNUNET_BLOCK_Type type, - size_t size, const void *data) +dht_get_handler (void *cls, struct GNUNET_TIME_Absolute exp, + const struct GNUNET_HashCode * key, + const struct GNUNET_PeerIdentity *get_path, + unsigned int get_path_length, + const struct GNUNET_PeerIdentity *put_path, + unsigned int put_path_length, enum GNUNET_BLOCK_Type type, + size_t size, const void *data) { - int i; - - if (sizeof (struct GNUNET_HashCode) == size) - { - const struct GNUNET_HashCode *h = data; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Contents: %s\n", - GNUNET_h2s_full (h)); + struct GetOperation *get_op = cls; + struct GNUNET_HashCode want; + struct GNUNET_DHT_TestContext *ctx; - } - else - { - GNUNET_break(0); - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH: (get %u, put %u)\n", - get_path_length, put_path_length); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " LOCAL\n"); - for (i = get_path_length - 1; i >= 0; i--) + if (sizeof (struct GNUNET_HashCode) != size) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", - GNUNET_i2s (&get_path[i])); + GNUNET_break (0); + return; } - for (i = put_path_length - 1; i >= 0; i--) + GNUNET_CRYPTO_hash (key, sizeof (*key), &want); + if (0 != memcmp (&want, data, sizeof (want))) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", - GNUNET_i2s (&put_path[i])); + GNUNET_break (0); + return; } - switch ((long)cls) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Get successful\n"); +#if 0 { - case 1: - found_1++; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "FOUND 1!\n"); - break; - case 2: - found_2++; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "FOUND 2!\n"); - break; - case 3: - found_far++; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "FOUND FAR!\n"); - break; - default: - GNUNET_break(0); + int i; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "PATH: (get %u, put %u)\n", + get_path_length, put_path_length); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " LOCAL\n"); + for (i = get_path_length - 1; i >= 0; i--) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", + GNUNET_i2s (&get_path[i])); + for (i = put_path_length - 1; i >= 0; i--) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %s\n", + GNUNET_i2s (&put_path[i])); } - if ( (TORUS == test_topology) && - ( (found_1 == 0) || (found_2 == 0) || (found_far == 0)) ) +#endif + GNUNET_DHT_get_stop (get_op->get); + GNUNET_CONTAINER_DLL_remove (get_head, + get_tail, + get_op); + GNUNET_free (get_op); + if (NULL != get_head) return; + /* all DHT GET operations successful; terminate! */ ok = 0; - GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_peers, NULL); + ctx = GNUNET_SCHEDULER_cancel (timeout_task); + timeout_task = GNUNET_SCHEDULER_add_now (&shutdown_task, ctx); } -static void -do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) -{ - struct GNUNET_TESTING_Daemon *d; - struct GNUNET_TESTING_Daemon *d2; - struct GNUNET_TESTING_Daemon *d_far; - struct GNUNET_TESTING_Daemon *o; - struct GNUNET_TESTING_Daemon *aux; - const char *id_aux; - const char *id_origin = "FC74"; - const char *id_near = "9P6V"; - const char *id_near2 = "2GDS"; - const char *id_far = "KPST"; - unsigned int i; - - d = d2 = d_far = o = NULL; - found_1 = found_2 = found_far = 0; - if (LINE == test_topology) - { - o = GNUNET_TESTING_daemon_get (pg, 0); - d = GNUNET_TESTING_daemon_get (pg, num_peers - 1); - } - else if (TORUS == test_topology) - { - for (i = 0; i < num_peers; i++) - { - aux = GNUNET_TESTING_daemon_get (pg, i); - id_aux = GNUNET_i2s (&aux->id); - if (strcmp (id_aux, id_origin) == 0) - o = aux; - if (strcmp (id_aux, id_far) == 0) - d_far = aux; - if (strcmp (id_aux, id_near) == 0) - d = aux; - if (strcmp (id_aux, id_near2) == 0) - d2 = aux; - } - if ((NULL == o) || (NULL == d) || (NULL == d2) || (NULL == d_far)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Peers not found (hostkey file changed?)\n"); - GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_peers, NULL); - return; - } - } - else - { - GNUNET_assert (0); - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test_task\nfrom %s\n", - GNUNET_h2s_full (&o->id.hashPubKey)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " looking for %s\n", - GNUNET_h2s_full (&d->id.hashPubKey)); - get_h = GNUNET_DHT_get_start (hs[0], - GNUNET_BLOCK_TYPE_TEST, /* type */ - &d->id.hashPubKey, /*key to search */ - 4U, /* replication level */ - GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, - NULL, /* xquery */ - 0, /* xquery bits */ - &dht_get_id_handler, (void *)1); - if (TORUS == test_topology) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " looking for %s\n", - GNUNET_h2s_full (&d2->id.hashPubKey)); - get_h_2 = GNUNET_DHT_get_start (hs[0], - GNUNET_BLOCK_TYPE_TEST, /* type */ - &d2->id.hashPubKey, /*key to search */ - 4U, /* replication level */ - GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, - NULL, /* xquery */ - 0, /* xquery bits */ - &dht_get_id_handler, (void *)2); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " looking for %s\n", - GNUNET_h2s_full (&d_far->id.hashPubKey)); - get_h_far = GNUNET_DHT_get_start (hs[0], - GNUNET_BLOCK_TYPE_TEST, /* type */ - &d_far->id.hashPubKey, /*key to search */ - 4U, /* replication level */ - GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, - NULL, /* xquery */ - 0, /* xquery bits */ - &dht_get_id_handler, (void *)3); - } - GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = - GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, &disconnect_peers, NULL); -} - /** * Task to put the id of each peer into the DHT. * - * @param cls Closure (unused) + * @param cls array with NUM_PEERS DHT handles * @param tc Task context - * */ static void -put_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) +do_puts (void *cls, + const struct GNUNET_SCHEDULER_TaskContext *tc) { - struct GNUNET_TESTING_Daemon *d; + struct GNUNET_DHT_Handle **hs = cls; + struct GNUNET_HashCode key; + struct GNUNET_HashCode value; unsigned int i; - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "putting id's in DHT\n"); - for (i = 0; i < num_peers; i++) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Putting values into DHT\n"); + for (i = 0; i < NUM_PEERS; i++) { - d = GNUNET_TESTING_daemon_get (pg, i); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " putting into DHT: %s\n", - GNUNET_h2s_full (&d->id.hashPubKey)); - GNUNET_DHT_put (hs[i], &d->id.hashPubKey, 10U, + GNUNET_CRYPTO_hash (&i, sizeof (i), &key); + GNUNET_CRYPTO_hash (&key, sizeof (key), &value); + GNUNET_DHT_put (hs[i], &key, 10U, GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, - GNUNET_BLOCK_TYPE_TEST, sizeof (struct GNUNET_PeerIdentity), - (const char *) &d->id, GNUNET_TIME_UNIT_FOREVER_ABS, - GNUNET_TIME_UNIT_FOREVER_REL, NULL, NULL); - + GNUNET_BLOCK_TYPE_TEST, + sizeof (value), &value, + GNUNET_TIME_UNIT_FOREVER_ABS, + GNUNET_TIME_UNIT_FOREVER_REL, + NULL, NULL); } - put_task = GNUNET_SCHEDULER_add_delayed (PUT_FREQUENCY, &put_id, NULL); - if (GNUNET_SCHEDULER_NO_TASK == test_task) - test_task = GNUNET_SCHEDULER_add_now (&do_test, NULL); + put_task = GNUNET_SCHEDULER_add_delayed (PUT_FREQUENCY, + &do_puts, hs); } /** - * peergroup_ready: start test when all peers are connected - * - * @param cls closure - * @param emsg error message - * - */ -static void -peergroup_ready (void *cls, const char *emsg) -{ - struct GNUNET_TESTING_Daemon *d; - char *buf; - int buf_len; - unsigned int i; - - if (emsg != NULL) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Peergroup callback called with error, aborting test!\n"); - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Error from testing: `%s'\n", - emsg); - ok++; - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); - return; - } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Peer Group started successfully with %u connections\n", - total_connections); - if (data_file != NULL) - { - buf = NULL; - buf_len = GNUNET_asprintf (&buf, "CONNECTIONS_0: %u\n", total_connections); - if (buf_len > 0) - GNUNET_DISK_file_write (data_file, buf, buf_len); - GNUNET_free (buf); - } - peers_running = GNUNET_TESTING_daemons_running (pg); - - GNUNET_assert (peers_running == num_peers); - hs = GNUNET_malloc (num_peers * sizeof (struct GNUNET_DHT_Handle *)); - for (i = 0; i < num_peers; i++) - { - d = GNUNET_TESTING_daemon_get (pg, i); - hs[i] = GNUNET_DHT_connect (d->cfg, 32); - } - - test_task = GNUNET_SCHEDULER_NO_TASK; - put_task = GNUNET_SCHEDULER_add_now (&put_id, NULL); - disconnect_task = - GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, &disconnect_peers, NULL); - -} - - -/** - * Function that will be called whenever two daemons are connected by - * the testing library. + * Main function of the test. * - * @param cls closure - * @param first peer id for first daemon - * @param second peer id for the second daemon - * @param distance distance between the connected peers - * @param first_cfg config for the first daemon - * @param second_cfg config for the second daemon - * @param first_daemon handle for the first daemon - * @param second_daemon handle for the second daemon - * @param emsg error message (NULL on success) - */ -static void -connect_cb (void *cls, const struct GNUNET_PeerIdentity *first, - const struct GNUNET_PeerIdentity *second, uint32_t distance, - const struct GNUNET_CONFIGURATION_Handle *first_cfg, - const struct GNUNET_CONFIGURATION_Handle *second_cfg, - struct GNUNET_TESTING_Daemon *first_daemon, - struct GNUNET_TESTING_Daemon *second_daemon, const char *emsg) -{ - if (emsg == NULL) - { - total_connections++; - GNUNET_PEER_intern (first); - GNUNET_PEER_intern (second); - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, - "Problem with new connection (%s)\n", emsg); - } -} - - -/** - * run: load configuration options and schedule test to run (start peergroup) - * @param cls closure - * @param args argv - * @param cfgfile configuration file name (can be NULL) - * @param cfg configuration handle + * @param cls closure (NULL) + * @param ctx argument to give to GNUNET_DHT_TEST_cleanup on test end + * @param num_peers number of peers that are running + * @param peers array of peers + * @param dhts handle to each of the DHTs of the peers */ static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) +run (void *cls, + struct GNUNET_DHT_TEST_Context *ctx, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers, + struct GNUNET_DHT_Handle **dhts) { - char *temp_str; - struct GNUNET_TESTING_Host *hosts; - char *data_filename; - - ok = 1; - testing_cfg = GNUNET_CONFIGURATION_dup (cfg); - - GNUNET_log_setup ("test_dht_topo", - "WARNING", - NULL); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Starting daemons.\n"); - GNUNET_CONFIGURATION_set_value_string (testing_cfg, "testing_old", - "use_progressbars", "YES"); - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing_old", - "num_peers", &num_peers)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Option TESTING:NUM_PEERS is required!\n"); - return; - } - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (testing_cfg, "testing_old", - "topology_output_file", - &topology_file)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Option test_dht_topo:topology_output_file is required!\n"); - return; - } - - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (testing_cfg, "test_dht_topo", - "data_output_file", - &data_filename)) + unsigned int i; + unsigned int j; + struct GNUNET_HashCode key; + struct GetOperation *get_op; + + GNUNET_assert (NUM_PEERS == num_peers); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + "Peers setup, starting test\n"); + /* FIXME: once testbed is finished, this call should + no longer be needed */ + GNUNET_TESTBED_overlay_configure_topology (NULL, + num_peers, + peers, + GNUNET_TESTBED_TOPOLOGY_LINE, + GNUNET_TESTBED_TOPOLOGY_OPTION_END); + + put_task = GNUNET_SCHEDULER_add_now (&do_puts, dhts); + for (i=0;i<num_peers;i++) { - data_file = - GNUNET_DISK_file_open (data_filename, - GNUNET_DISK_OPEN_READWRITE | - GNUNET_DISK_OPEN_CREATE, - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE); - if (data_file == NULL) + GNUNET_CRYPTO_hash (&i, sizeof (i), &key); + for (j=0;j<num_peers;j++) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to open %s for output!\n", - data_filename); - GNUNET_free (data_filename); + get_op = GNUNET_malloc (sizeof (struct GetOperation)); + GNUNET_CONTAINER_DLL_insert (get_head, + get_tail, + get_op); + get_op->get = GNUNET_DHT_get_start (dhts[j], + GNUNET_BLOCK_TYPE_TEST, /* type */ + &key, /*key to search */ + 4U, /* replication level */ + GNUNET_DHT_RO_RECORD_ROUTE | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE, + NULL, /* xquery */ + 0, /* xquery bits */ + &dht_get_handler, get_op); } } - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "test_dht_topo", - "output_file", &temp_str)) - { - output_file = - GNUNET_DISK_file_open (temp_str, - GNUNET_DISK_OPEN_READWRITE | - GNUNET_DISK_OPEN_CREATE, - GNUNET_DISK_PERM_USER_READ | - GNUNET_DISK_PERM_USER_WRITE); - if (output_file == NULL) - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Failed to open %s for output!\n", - temp_str); - } - GNUNET_free_non_null (temp_str); - - hosts = GNUNET_TESTING_hosts_load (testing_cfg); - - pg = GNUNET_TESTING_peergroup_start (testing_cfg, num_peers, TIMEOUT, - &connect_cb, &peergroup_ready, NULL, - hosts); - GNUNET_assert (pg != NULL); - shutdown_handle = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, - &shutdown_task, NULL); + timeout_task = GNUNET_SCHEDULER_add_delayed (GET_TIMEOUT, + &shutdown_task, ctx); } @@ -560,62 +290,28 @@ run (void *cls, char *const *args, const char *cfgfile, int main (int xargc, char *xargv[]) { - static struct GNUNET_GETOPT_CommandLineOption options[] = { - GNUNET_GETOPT_OPTION_END - }; - static char *const argv_torus[] = { "test-dht-2dtorus", - "-c", - "test_dht_2dtorus.conf", - NULL - }; - static char *const argv_line[] = { "test-dht-line", - "-c", - "test_dht_line.conf", - NULL - }; - char *const *argv; - int argc; + const char *cfg_filename; + const char *test_name; - if (strstr (xargv[0], "test_dht_2dtorus") != NULL) + if (NULL != strstr (xargv[0], "test_dht_2dtorus")) { - argv = argv_torus; - argc = sizeof (argv_torus) / sizeof (char *); - test_topology = TORUS; + cfg_filename = "test_dht_2dtorus.conf"; + test_name = "test-dht-2dtorus"; } - else if (strstr (xargv[0], "test_dht_line") != NULL) + else if (NULL != strstr (xargv[0], "test_dht_line")) { - argv = argv_line; - argc = sizeof (argv_line) / sizeof (char *); - test_topology = LINE; + cfg_filename = "test_dht_line.conf"; + test_name = "test-dht-line"; } else { GNUNET_break (0); return 1; } - GNUNET_PROGRAM_run (argc - 1, argv, - xargv[0], - gettext_noop ("Test dht in different topologies."), - options, - &run, NULL); -#if REMOVE_DIR - GNUNET_DISK_directory_remove ("/tmp/test_dht_topo"); -#endif - if (0 == found_1) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "ID 1 not found!\n"); - } - if (TORUS == test_topology) - { - if (0 == found_2) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "ID 2 not found!\n"); - } - if (0 == found_far) - { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "ID far not found!\n"); - } - } + GNUNET_DHT_TEST_run (test_name, + cfg_filename, + NUM_PEERS, + &run, NULL); return ok; } diff --git a/src/include/gnunet_dht_service.h b/src/include/gnunet_dht_service.h index 83774826e5..89f42acb48 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, * (size too big) */ struct GNUNET_DHT_PutHandle * -GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, const struct GNUNET_HashCode * key, +GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle, + const struct GNUNET_HashCode * key, uint32_t desired_replication_level, enum GNUNET_DHT_RouteOption options, - enum GNUNET_BLOCK_Type type, size_t size, const char *data, + enum GNUNET_BLOCK_Type type, + size_t size, const void *data, struct GNUNET_TIME_Absolute exp, struct GNUNET_TIME_Relative timeout, GNUNET_DHT_PutContinuation cont, diff --git a/src/testbed/testbed_api_testbed.c b/src/testbed/testbed_api_testbed.c index 96ac22c2bd..a8f12f3610 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, * @param cls the tesbed run handle * @param tc the task context from scheduler */ -void +static void shutdown_run_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct RunContext *rc = cls; |