diff options
Diffstat (limited to 'src/mesh/test_mesh_small.c')
-rw-r--r-- | src/mesh/test_mesh_small.c | 987 |
1 files changed, 485 insertions, 502 deletions
diff --git a/src/mesh/test_mesh_small.c b/src/mesh/test_mesh_small.c index 974b635..efe9398 100644 --- a/src/mesh/test_mesh_small.c +++ b/src/mesh/test_mesh_small.c @@ -24,35 +24,25 @@ */ #include <stdio.h> #include "platform.h" -#include "gnunet_testing_lib.h" +#include "mesh_test_lib.h" #include "gnunet_mesh_service.h" #include <gauger.h> -#define VERBOSE GNUNET_YES -#define REMOVE_DIR GNUNET_YES - -struct MeshPeer -{ - struct MeshPeer *prev; - - struct MeshPeer *next; - - struct GNUNET_TESTING_Daemon *daemon; - - struct GNUNET_MESH_Handle *mesh_handle; -}; - +/** + * How namy messages to send + */ +#define TOTAL_PACKETS 1000 /** * How long until we give up on connecting the peers? */ -#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1500) +#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 120) /** * Time to wait for stuff that should be rather fast */ -#define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 300) +#define SHORT_TIME GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 20) /** * DIFFERENT TESTS TO RUN @@ -62,6 +52,9 @@ struct MeshPeer #define MULTICAST 2 #define SPEED 3 #define SPEED_ACK 4 +#define SPEED_MIN 5 +#define SPEED_NOBUF 6 +#define P2P_SIGNAL 10 /** * Which test are we running? @@ -69,64 +62,92 @@ struct MeshPeer static int test; /** + * String with test name + */ +char *test_name; + +/** + * Flag to send traffic leaf->root in speed tests to test BCK_ACK logic. + */ +static int test_backwards = GNUNET_NO; + +/** * How many events have happened */ static int ok; -static int peers_in_tunnel; + /** + * Each peer is supposed to generate the following callbacks: + * 1 incoming tunnel (@dest) + * 1 connected peer (@orig) + * 1 received data packet (@dest) + * 1 received data packet (@orig) + * 1 received tunnel destroy (@dest) + * _________________________________ + * 5 x ok expected per peer + */ +int ok_goal; -static int peers_responded; -static int data_sent; +/** + * Size of each test packet + */ +size_t size_payload = sizeof (struct GNUNET_MessageHeader) + sizeof (uint32_t); -static int data_received; +/** + * Operation to get peer ids. + */ +struct GNUNET_TESTBED_Operation *t_op[3]; -static int data_ack; +/** + * Peer ids. + */ +struct GNUNET_PeerIdentity *p_id[3]; /** - * Be verbose + * Peer ids counter. */ -static int verbose; +unsigned int p_ids; /** - * Total number of peers in the test. + * Is the setup initialized? */ -static unsigned long long num_peers; +static int initialized; /** - * Global configuration file + * Peers that have been connected */ -static struct GNUNET_CONFIGURATION_Handle *testing_cfg; +static int peers_in_tunnel; /** - * Total number of currently running peers. + * Peers that have responded */ -static unsigned long long peers_running; +static int peers_responded; /** - * Total number of connections in the whole network. + * Number of payload packes sent */ -static unsigned int total_connections; +static int data_sent; /** - * The currently running peer group. + * Number of payload packets received */ -static struct GNUNET_TESTING_PeerGroup *pg; +static int data_received; /** - * File to report results to. + * Number of payload packed explicitly (app level) acknowledged */ -static struct GNUNET_DISK_FileHandle *output_file; +static int data_ack; /** - * File to log connection info, statistics to. + * Total number of currently running peers. */ -static struct GNUNET_DISK_FileHandle *data_file; +static unsigned long long peers_running; /** - * How many data points to capture before triggering next round? + * Test context (to shut down). */ -static struct GNUNET_TIME_Relative wait_time; +struct GNUNET_MESH_TEST_Context *test_ctx; /** * Task called to disconnect peers. @@ -143,151 +164,189 @@ static GNUNET_SCHEDULER_TaskIdentifier test_task; */ static GNUNET_SCHEDULER_TaskIdentifier shutdown_handle; -static char *topology_file; - -static struct GNUNET_TESTING_Daemon *d1; - -static GNUNET_PEER_Id pid1; - -static struct GNUNET_TESTING_Daemon *d2; - -static struct GNUNET_TESTING_Daemon *d3; - +/** + * Mesh handle for the root peer + */ static struct GNUNET_MESH_Handle *h1; +/** + * Mesh handle for the first leaf peer + */ static struct GNUNET_MESH_Handle *h2; +/** + * Mesh handle for the second leaf peer + */ static struct GNUNET_MESH_Handle *h3; +/** + * Tunnel handle for the root peer + */ static struct GNUNET_MESH_Tunnel *t; +/** + * Tunnel handle for the first leaf peer + */ static struct GNUNET_MESH_Tunnel *incoming_t; +/** + * Tunnel handle for the second leaf peer + */ static struct GNUNET_MESH_Tunnel *incoming_t2; +/** + * Time we started the data transmission (after tunnel has been established + * and initilized). + */ static struct GNUNET_TIME_Absolute start_time; -static struct GNUNET_TIME_Absolute end_time; - -static struct GNUNET_TIME_Relative total_time; - /** - * Check whether peers successfully shut down. + * Show the results of the test (banwidth acheived) and log them to GAUGER */ static void -shutdown_callback (void *cls, const char *emsg) +show_end_data (void) { - if (emsg != NULL) - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Shutdown of peers failed!\n"); -#endif - ok--; - } - else - { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "All peers successfully shut down!\n"); -#endif - } - GNUNET_CONFIGURATION_destroy (testing_cfg); + static struct GNUNET_TIME_Absolute end_time; + static struct GNUNET_TIME_Relative total_time; + + end_time = GNUNET_TIME_absolute_get(); + total_time = GNUNET_TIME_absolute_get_difference(start_time, end_time); + FPRINTF (stderr, "\nResults of test \"%s\"\n", test_name); + FPRINTF (stderr, "Test time %llu ms\n", + (unsigned long long) total_time.rel_value); + FPRINTF (stderr, "Test bandwidth: %f kb/s\n", + 4 * TOTAL_PACKETS * 1.0 / total_time.rel_value); // 4bytes * ms + FPRINTF (stderr, "Test throughput: %f packets/s\n\n", + TOTAL_PACKETS * 1000.0 / total_time.rel_value); // packets * ms + GAUGER ("MESH", test_name, + TOTAL_PACKETS * 1000.0 / total_time.rel_value, + "packets/s"); } /** * Shut down peergroup, clean up. + * + * @param cls Closure (unused). + * @param tc Task Context. */ static void shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Ending test.\n"); -#endif - - if (disconnect_task != GNUNET_SCHEDULER_NO_TASK) - { - GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = GNUNET_SCHEDULER_NO_TASK; - } - - if (NULL != h1) - { - GNUNET_MESH_disconnect (h1); - h1 = NULL; - } - if (NULL != h2) - { - GNUNET_MESH_disconnect (h2); - h2 = NULL; - } - if (test == MULTICAST && NULL != h3) - { - GNUNET_MESH_disconnect (h3); - h3 = NULL; - } - - if (data_file != NULL) - GNUNET_DISK_file_close (data_file); - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Ending test.\n"); + shutdown_handle = GNUNET_SCHEDULER_NO_TASK; } /** * Disconnect from mesh services af all peers, call shutdown. + * + * @param cls Closure (unused). + * @param tc Task Context. */ static void disconnect_mesh_peers (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { + long line = (long) cls; + unsigned int i; + + for (i = 0; i < 3; i++) + if (NULL != t_op[i]) + { + GNUNET_TESTBED_operation_done (t_op[i]); + t_op[i] = NULL; + } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "disconnecting mesh service of peers\n"); + "disconnecting mesh service of peers, called from line %ld\n", + line); disconnect_task = GNUNET_SCHEDULER_NO_TASK; if (NULL != t) { - GNUNET_MESH_tunnel_destroy(t); + GNUNET_MESH_tunnel_destroy (t); t = NULL; } if (NULL != incoming_t) { - GNUNET_MESH_tunnel_destroy(incoming_t); + GNUNET_MESH_tunnel_destroy (incoming_t); incoming_t = NULL; } if (NULL != incoming_t2) { - GNUNET_MESH_tunnel_destroy(incoming_t2); + GNUNET_MESH_tunnel_destroy (incoming_t2); incoming_t2 = NULL; } - GNUNET_MESH_disconnect (h1); - GNUNET_MESH_disconnect (h2); - h1 = h2 = NULL; - if (test == MULTICAST) - { - GNUNET_MESH_disconnect (h3); - h3 = NULL; - } + GNUNET_MESH_TEST_cleanup (test_ctx); if (GNUNET_SCHEDULER_NO_TASK != shutdown_handle) { GNUNET_SCHEDULER_cancel (shutdown_handle); - shutdown_handle = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); } + shutdown_handle = GNUNET_SCHEDULER_add_now (&shutdown_task, NULL); } -size_t + +/** + * Abort test: schedule disconnect and shutdown immediately + * + * @param line Line in the code the abort is requested from (__LINE__). + */ +void +abort_test (long line) +{ + if (disconnect_task != GNUNET_SCHEDULER_NO_TASK) + { + GNUNET_SCHEDULER_cancel (disconnect_task); + } + disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME, + &disconnect_mesh_peers, + (void *) line); +} + +/** + * Transmit ready callback. + * + * @param cls Closure (message type). + * @param size Size of the tranmist buffer. + * @param buf Pointer to the beginning of the buffer. + * + * @return Number of bytes written to buf. + */ +static size_t tmt_rdy (void *cls, size_t size, void *buf); + +/** + * Task to schedule a new data transmission. + * + * @param cls Closure (peer #). + * @param tc Task Context. + */ static void data_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { struct GNUNET_MESH_TransmitHandle *th; + struct GNUNET_MESH_Tunnel *tunnel; + struct GNUNET_PeerIdentity *destination; + if ((GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason) != 0) return; - th = GNUNET_MESH_notify_transmit_ready (t, GNUNET_NO, 0, - GNUNET_TIME_UNIT_FOREVER_REL, &d2->id, - sizeof (struct GNUNET_MessageHeader), - &tmt_rdy, (void *) 1L); + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Data task\n"); + if (GNUNET_YES == test_backwards) + { + tunnel = incoming_t; + destination = p_id[0]; + } + else + { + tunnel = t; + destination = p_id[2]; + } + th = GNUNET_MESH_notify_transmit_ready (tunnel, GNUNET_NO, + GNUNET_TIME_UNIT_FOREVER_REL, + destination, + size_payload, + &tmt_rdy, (void *) 1L); if (NULL == th) { unsigned long i = (unsigned long) cls; @@ -311,10 +370,11 @@ data_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } } + /** * Transmit ready callback * - * @param cls Closure. + * @param cls Closure (message type). * @param size Size of the buffer we have. * @param buf Buffer to copy data to. */ @@ -322,24 +382,38 @@ size_t tmt_rdy (void *cls, size_t size, void *buf) { struct GNUNET_MessageHeader *msg = buf; + uint32_t *data; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " tmt_rdy called\n"); - if (size < sizeof (struct GNUNET_MessageHeader) || NULL == buf) + if (size < size_payload || NULL == buf) + { + GNUNET_break (0); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "size %u, buf %p, data_sent %u, data_received %u\n", + size, + buf, + data_sent, + data_received); return 0; - msg->size = htons (sizeof (struct GNUNET_MessageHeader)); + } + msg->size = htons (size); msg->type = htons ((long) cls); - if (test == SPEED) + data = (uint32_t *) &msg[1]; + *data = htonl (data_sent); + if (SPEED == test && GNUNET_YES == initialized) { data_sent++; - if (data_sent < 1000) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, + " Sent packet %d\n", data_sent); + if (data_sent < TOTAL_PACKETS) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - " Scheduling %d packet\n", data_sent); + " Scheduling packet %d\n", data_sent + 1); GNUNET_SCHEDULER_add_now(&data_task, NULL); } } - return sizeof (struct GNUNET_MessageHeader); + return size_payload; } @@ -362,82 +436,121 @@ data_callback (void *cls, struct GNUNET_MESH_Tunnel *tunnel, void **tunnel_ctx, const struct GNUNET_ATS_Information *atsi) { long client = (long) cls; + long expected_target_client; + uint32_t *data; - switch (client) + ok++; + + if ((ok % 20) == 0) { - case 1L: - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Origin client got a response!\n"); - ok++; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok); - peers_responded++; - data_ack++; if (GNUNET_SCHEDULER_NO_TASK != disconnect_task) { GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = - GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &disconnect_mesh_peers, - NULL); } + disconnect_task = + GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &disconnect_mesh_peers, + (void *) __LINE__); + } + + switch (client) + { + case 0L: + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Root client got a message!\n"); + peers_responded++; if (test == MULTICAST && peers_responded < 2) return GNUNET_OK; - if (test == SPEED_ACK) - { - GNUNET_log (GNUNET_ERROR_TYPE_INFO, - " received ack %u\n", data_ack); - GNUNET_MESH_notify_transmit_ready (tunnel, GNUNET_NO, 0, - GNUNET_TIME_UNIT_FOREVER_REL, sender, - sizeof (struct GNUNET_MessageHeader), - &tmt_rdy, (void *) 1L); - if (data_ack < 1000) - return GNUNET_OK; - end_time = GNUNET_TIME_absolute_get(); - total_time = GNUNET_TIME_absolute_get_difference(start_time, end_time); - FPRINTF (stderr, "\nTest time %llu ms\n", - (unsigned long long) total_time.rel_value); - FPRINTF (stderr, "Test bandwidth: %f kb/s\n", - 4000.0 / total_time.rel_value); - FPRINTF (stderr, "Test throughput: %f packets/s\n", - 1000000.0 / total_time.rel_value); - GAUGER ("MESH", "Tunnel 5 peers", 1000000.0 / total_time.rel_value, - "packets/s"); - } - GNUNET_assert (tunnel == t); - GNUNET_MESH_tunnel_destroy (t); - t = NULL; break; - case 2L: case 3L: + case 4L: GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "Destination client %u got a message.\n", + "Leaf client %li got a message.\n", client); - ok++; - GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok); - if (SPEED != test) + client = 4L; + break; + default: + GNUNET_assert (0); + break; + } + GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: (%d/%d)\n", ok, ok_goal); + data = (uint32_t *) &message[1]; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, " payload: (%u)\n", ntohl (*data)); + if (SPEED == test && GNUNET_YES == test_backwards) + { + expected_target_client = 0L; + } + else + { + expected_target_client = 4L; + } + + if (GNUNET_NO == initialized) + { + initialized = GNUNET_YES; + start_time = GNUNET_TIME_absolute_get (); + if (SPEED == test) { - GNUNET_MESH_notify_transmit_ready (tunnel, GNUNET_NO, 0, + GNUNET_assert (4L == client); + GNUNET_SCHEDULER_add_now (&data_task, NULL); + return GNUNET_OK; + } + } + + if (client == expected_target_client) // Normally 3 or 4 + { + data_received++; + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + " received data %u\n", data_received); + if (SPEED != test || (ok_goal - 2) == ok) + { + GNUNET_MESH_notify_transmit_ready (tunnel, GNUNET_NO, GNUNET_TIME_UNIT_FOREVER_REL, sender, - sizeof (struct GNUNET_MessageHeader), + size_payload, &tmt_rdy, (void *) 1L); + return GNUNET_OK; } else { - data_received++; + if (data_received < TOTAL_PACKETS) + return GNUNET_OK; + } + } + else // Normally 0 + { + if (test == SPEED_ACK || test == SPEED) + { + data_ack++; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - " received data %u\n", data_received); - if (data_received < 1000) + " received ack %u\n", data_ack); + GNUNET_MESH_notify_transmit_ready (tunnel, GNUNET_NO, + GNUNET_TIME_UNIT_FOREVER_REL, sender, + size_payload, + &tmt_rdy, (void *) 1L); + if (data_ack < TOTAL_PACKETS && SPEED != test) return GNUNET_OK; + if (ok == 2 && SPEED == test) + return GNUNET_OK; + show_end_data(); } - if (GNUNET_SCHEDULER_NO_TASK != disconnect_task) + if (test == P2P_SIGNAL) { - GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = - GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &disconnect_mesh_peers, - NULL); + GNUNET_MESH_tunnel_destroy (incoming_t); + incoming_t = NULL; } - break; - default: - break; + else + { + GNUNET_MESH_tunnel_destroy (t); + t = NULL; + } + } + + if (GNUNET_SCHEDULER_NO_TASK != disconnect_task) + { + GNUNET_SCHEDULER_cancel (disconnect_task); } + disconnect_task = + GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &disconnect_mesh_peers, + (void *) __LINE__); + return GNUNET_OK; } @@ -472,7 +585,7 @@ incoming_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel, GNUNET_i2s (initiator), (long) cls); ok++; GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok); - if ((long) cls == 2L) + if ((long) cls == 4L) incoming_t = tunnel; else if ((long) cls == 3L) incoming_t2 = tunnel; @@ -480,13 +593,16 @@ incoming_tunnel (void *cls, struct GNUNET_MESH_Tunnel *tunnel, { GNUNET_log (GNUNET_ERROR_TYPE_WARNING, "Incoming tunnel for unknown client %lu\n", (long) cls); + GNUNET_break(0); } if (GNUNET_SCHEDULER_NO_TASK != disconnect_task) { GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = - GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &disconnect_mesh_peers, NULL); } + disconnect_task = + GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &disconnect_mesh_peers, + (void *) __LINE__); + return NULL; } @@ -508,7 +624,7 @@ tunnel_cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel, GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Incoming tunnel disconnected at peer %d\n", i); - if (2L == i) + if (4L == i) { ok++; incoming_t = NULL; @@ -529,8 +645,9 @@ tunnel_cleaner (void *cls, const struct GNUNET_MESH_Tunnel *tunnel, if (GNUNET_SCHEDULER_NO_TASK != disconnect_task) { GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_mesh_peers, NULL); } + disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_mesh_peers, + (void *) __LINE__); return; } @@ -548,6 +665,16 @@ dh (void *cls, const struct GNUNET_PeerIdentity *peer) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer %s disconnected\n", GNUNET_i2s (peer)); + if (P2P_SIGNAL == test) + { + ok ++; + if (GNUNET_SCHEDULER_NO_TASK != disconnect_task) + { + GNUNET_SCHEDULER_cancel (disconnect_task); + } + disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_mesh_peers, + (void *) __LINE__); + } return; } @@ -563,52 +690,59 @@ static void ch (void *cls, const struct GNUNET_PeerIdentity *peer, const struct GNUNET_ATS_Information *atsi) { + long i = (long) cls; + struct GNUNET_PeerIdentity *dest; GNUNET_log (GNUNET_ERROR_TYPE_INFO, - "peer %s connected\n", GNUNET_i2s (peer)); + "%ld peer %s connected\n", i, GNUNET_i2s (peer)); - if (0 == memcmp (&d2->id, peer, sizeof (d2->id)) && (long) cls == 1L) + if (0 == memcmp (p_id[2], peer, sizeof (struct GNUNET_PeerIdentity)) && + i == 0L) { ok++; } - if (test == MULTICAST && 0 == memcmp (&d3->id, peer, sizeof (d3->id)) && - (long) cls == 1L) + if (test == MULTICAST && + 0 == memcmp (p_id[1], peer, sizeof (struct GNUNET_PeerIdentity)) && + i == 0L) { ok++; } GNUNET_log (GNUNET_ERROR_TYPE_INFO, " ok: %d\n", ok); switch (test) { - case UNICAST: - case SPEED: - case SPEED_ACK: - dest = &d2->id; - break; - case MULTICAST: - peers_in_tunnel++; - if (peers_in_tunnel < 2) + case UNICAST: + case P2P_SIGNAL: + case SPEED: + case SPEED_ACK: + // incoming_t is NULL unless we send a relevant data packet + dest = p_id[2]; + break; + case MULTICAST: + peers_in_tunnel++; + if (peers_in_tunnel < 2) + return; + dest = NULL; + break; + default: + GNUNET_assert (0); return; - dest = NULL; - break; - default: - return; } if (GNUNET_SCHEDULER_NO_TASK != disconnect_task) { GNUNET_SCHEDULER_cancel (disconnect_task); disconnect_task = - GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &disconnect_mesh_peers, NULL); + GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &disconnect_mesh_peers, + (void *) __LINE__); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Sending data...\n"); + "Sending data initializer...\n"); peers_responded = 0; data_ack = 0; data_received = 0; data_sent = 0; - start_time = GNUNET_TIME_absolute_get(); - GNUNET_MESH_notify_transmit_ready (t, GNUNET_NO, 0, + GNUNET_MESH_notify_transmit_ready (t, GNUNET_NO, GNUNET_TIME_UNIT_FOREVER_REL, dest, - sizeof (struct GNUNET_MessageHeader), + size_payload, &tmt_rdy, (void *) 1L); } else @@ -622,376 +756,210 @@ ch (void *cls, const struct GNUNET_PeerIdentity *peer, } +/** + * START THE TESTCASE ITSELF, AS WE ARE CONNECTED TO THE MESH SERVICES. + * + * Testcase continues when the root receives confirmation of connected peers, + * on callback funtion ch. + * + * @param cls Closure (unsued). + * @param tc Task Context. + */ static void do_test (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test_task\n"); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "add peer 2\n"); + GNUNET_MESH_peer_request_connect_add (t, p_id[2]); + if (test == MULTICAST) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "add peer 3\n"); - GNUNET_MESH_peer_request_connect_add (t, &d3->id); + GNUNET_MESH_peer_request_connect_add (t, p_id[1]); } - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "add peer 2\n"); - GNUNET_MESH_peer_request_connect_add (t, &d2->id); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "schedule timeout in 90s\n"); + "schedule timeout in TIMEOUT\n"); if (GNUNET_SCHEDULER_NO_TASK != disconnect_task) { GNUNET_SCHEDULER_cancel (disconnect_task); - disconnect_task = - GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &disconnect_mesh_peers, NULL); } + disconnect_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, + &disconnect_mesh_peers, + (void *) __LINE__); } - /** - * connect_mesh_service: connect to the mesh service of one of the peers + * Callback to be called when the requested peer information is available * - */ -static void -connect_mesh_service (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) + * @param cls the closure from GNUNET_TETSBED_peer_get_information() + * @param op the operation this callback corresponds to + * @param pinfo the result; will be NULL if the operation has failed + * @param emsg error message if the operation has failed; + * NULL if the operation is successfull + */ +void +pi_cb (void *cls, + struct GNUNET_TESTBED_Operation *op, + const struct GNUNET_TESTBED_PeerInformation *pinfo, + const char *emsg) { - GNUNET_MESH_ApplicationType app; - - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "connect_mesh_service\n"); - - d2 = GNUNET_TESTING_daemon_get (pg, 4); - if (test == MULTICAST) - { - d3 = GNUNET_TESTING_daemon_get (pg, 3); - } - app = (GNUNET_MESH_ApplicationType) 0; - -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "connecting to mesh service of peer %s\n", - GNUNET_i2s (&d1->id)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "connecting to mesh service of peer %s\n", - GNUNET_i2s (&d2->id)); - if (test == MULTICAST) - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "connecting to mesh service of peer %s\n", - GNUNET_i2s (&d3->id)); - } -#endif - h1 = GNUNET_MESH_connect (d1->cfg, 5, (void *) 1L, NULL, &tunnel_cleaner, - handlers, &app); - h2 = GNUNET_MESH_connect (d2->cfg, 5, (void *) 2L, &incoming_tunnel, - &tunnel_cleaner, handlers, &app); - if (test == MULTICAST) - { - h3 = GNUNET_MESH_connect (d3->cfg, 5, (void *) 3L, &incoming_tunnel, - &tunnel_cleaner, handlers, &app); - } - t = GNUNET_MESH_tunnel_create (h1, NULL, &ch, &dh, (void *) 1L); - peers_in_tunnel = 0; - test_task = - GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply - (GNUNET_TIME_UNIT_SECONDS, 1), &do_test, - NULL); -} - - - -/** - * 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) -{ - char *buf; - int buf_len; - unsigned int i; + long i = (long) cls; - if (emsg != NULL) + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "id callback for %ld\n", i); + if (NULL == pinfo || NULL != emsg) { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Peergroup callback called with error, aborting test!\n"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Error from testing: `%s'\n", emsg); - ok--; - GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL); + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "pi_cb: %s\n", emsg); + abort_test (__LINE__); return; } -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "************************************************************\n"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Peer Group started successfully!\n"); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Have %u connections\n", - total_connections); -#endif - - 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); - for (i = 0; i < num_peers; i++) - { - GNUNET_PEER_Id peer_id; - - d1 = GNUNET_TESTING_daemon_get (pg, i); - peer_id = GNUNET_PEER_intern (&d1->id); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %u: %s\n", - peer_id, GNUNET_i2s (&d1->id)); - } - d1 = GNUNET_TESTING_daemon_get (pg, 0); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Peer looking: %s\n", - GNUNET_i2s (&d1->id)); - pid1 = GNUNET_PEER_intern (&d1->id); - - GNUNET_SCHEDULER_add_now (&connect_mesh_service, NULL); - disconnect_task = - GNUNET_SCHEDULER_add_delayed (wait_time, &disconnect_mesh_peers, NULL); - + p_id[i] = pinfo->result.id; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " id: %s\n", GNUNET_i2s (p_id[i])); + p_ids++; + if ((MULTICAST == test && p_ids < 3) || p_ids < 2) + return; + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got all IDs, starting test\n"); + test_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, + &do_test, NULL); } - /** - * Function that will be called whenever two daemons are connected by - * the testing library. + * test main: start test when all peers are connected * - * @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++; - } - else - { - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Problem with new connection (%s)\n", - emsg); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " (%s)\n", GNUNET_i2s (first)); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " (%s)\n", GNUNET_i2s (second)); - } - -} - - -/** - * 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. + * @param ctx Argument to give to GNUNET_MESH_TEST_cleanup on test end. + * @param num_peers Number of peers that are running. + * @param peers Array of peers. + * @param meshes Handle to each of the MESHs of the peers. */ static void -run (void *cls, char *const *args, const char *cfgfile, - const struct GNUNET_CONFIGURATION_Handle *cfg) +tmain (void *cls, + struct GNUNET_MESH_TEST_Context *ctx, + unsigned int num_peers, + struct GNUNET_TESTBED_Peer **peers, + struct GNUNET_MESH_Handle **meshes) { - char *temp_str; - struct GNUNET_TESTING_Host *hosts; - char *data_filename; - + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test main\n"); ok = 0; - testing_cfg = GNUNET_CONFIGURATION_dup (cfg); - - GNUNET_log_setup ("test_mesh_small", -#if VERBOSE - "DEBUG", -#else - "WARNING", -#endif - NULL); - -#if VERBOSE - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Starting daemons.\n"); - GNUNET_CONFIGURATION_set_value_string (testing_cfg, "testing", - "use_progressbars", "YES"); -#endif - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_number (testing_cfg, "testing", - "num_peers", &num_peers)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Option TESTING:NUM_PEERS is required!\n"); - return; + test_ctx = ctx; + peers_running = num_peers; + h1 = meshes[0]; + h2 = meshes[num_peers - 1]; + t = GNUNET_MESH_tunnel_create (h1, NULL, &ch, &dh, (void *) 0L); + if (SPEED_MIN == test) + { + GNUNET_MESH_tunnel_speed_min(t); + test = SPEED; } - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_time (testing_cfg, "test_mesh_small", - "WAIT_TIME", &wait_time)) + if (SPEED_NOBUF == test) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Option test_mesh_small:wait_time is required!\n"); - return; - } - - if (GNUNET_OK != - GNUNET_CONFIGURATION_get_value_string (testing_cfg, "testing", - "topology_output_file", - &topology_file)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Option test_mesh_small:topology_output_file is required!\n"); - return; + GNUNET_MESH_tunnel_buffer(t, GNUNET_NO); + test = SPEED; } - - if (GNUNET_OK == - GNUNET_CONFIGURATION_get_value_string (testing_cfg, "test_mesh_small", - "data_output_file", - &data_filename)) - { - 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_log (GNUNET_ERROR_TYPE_WARNING, "Failed to open %s for output!\n", - data_filename); - GNUNET_free (data_filename); - } + peers_in_tunnel = 0; + disconnect_task = GNUNET_SCHEDULER_add_delayed (SHORT_TIME, + &disconnect_mesh_peers, + (void *) __LINE__); + shutdown_handle = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, + &shutdown_task, NULL); + t_op[0] = GNUNET_TESTBED_peer_get_information (peers[0], + GNUNET_TESTBED_PIT_IDENTITY, + &pi_cb, (void *) 0L); + t_op[2] = GNUNET_TESTBED_peer_get_information (peers[num_peers - 1], + GNUNET_TESTBED_PIT_IDENTITY, + &pi_cb, (void *) 2L); + if (MULTICAST == test) + { + h3 = meshes[num_peers - 2]; + t_op[1] = GNUNET_TESTBED_peer_get_information (peers[num_peers - 2], + GNUNET_TESTBED_PIT_IDENTITY, + &pi_cb, (void *) 1L); } - - if (GNUNET_YES == - GNUNET_CONFIGURATION_get_value_string (cfg, "test_mesh_small", - "output_file", &temp_str)) + else { - 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); + t_op[1] = NULL; } - 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); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "requested peer ids\n"); } - -/** - * test_mesh_small command line options - */ -static struct GNUNET_GETOPT_CommandLineOption options[] = { - {'V', "verbose", NULL, - gettext_noop ("be verbose (print progress information)"), - 0, &GNUNET_GETOPT_set_one, &verbose}, - GNUNET_GETOPT_OPTION_END -}; - - /** * Main: start test */ int main (int argc, char *argv[]) { - char * argv2[] = { - argv[0], - "-c", - "test_mesh_small.conf", -#if VERBOSE - "-L", - "DEBUG", -#endif - NULL - }; - int argc2 = (sizeof (argv2) / sizeof (char *)) - 1; - - /* Each peer is supposed to generate the following callbacks: - * 1 incoming tunnel (@dest) - * 1 connected peer (@orig) - * 1 received data packet (@dest) - * 1 received data packet (@orig) - * 1 received tunnel destroy (@dest) - * _________________________________ - * 5 x ok expected per peer - */ - int ok_goal; + initialized = GNUNET_NO; + GNUNET_log_setup ("test", "DEBUG", NULL); + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Start\n"); if (strstr (argv[0], "test_mesh_small_unicast") != NULL) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "UNICAST\n"); test = UNICAST; + test_name = "unicast"; ok_goal = 5; } else if (strstr (argv[0], "test_mesh_small_multicast") != NULL) { GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MULTICAST\n"); test = MULTICAST; + test_name = "multicast"; ok_goal = 10; } + else if (strstr (argv[0], "test_mesh_small_signal") != NULL) + { + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SIGNAL\n"); + test = P2P_SIGNAL; + test_name = "signal"; + ok_goal = 5; + } else if (strstr (argv[0], "test_mesh_small_speed_ack") != NULL) { /* Each peer is supposed to generate the following callbacks: * 1 incoming tunnel (@dest) * 1 connected peer (@orig) - * 1000 received data packet (@dest) - * 1000 received data packet (@orig) + * TOTAL_PACKETS received data packet (@dest) + * TOTAL_PACKETS received data packet (@orig) * 1 received tunnel destroy (@dest) * _________________________________ * 5 x ok expected per peer */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SPEED_ACK\n"); test = SPEED_ACK; - ok_goal = 2003; - argv2 [3] = NULL; // remove -L DEBUG -#if VERBOSE - argc2 -= 2; -#endif + test_name = "speed ack"; + ok_goal = TOTAL_PACKETS * 2 + 3; } else if (strstr (argv[0], "test_mesh_small_speed") != NULL) { /* Each peer is supposed to generate the following callbacks: * 1 incoming tunnel (@dest) * 1 connected peer (@orig) - * 1000 received data packet (@dest) + * 1 initial packet (@dest) + * TOTAL_PACKETS received data packet (@dest) + * 1 received data packet (@orig) * 1 received tunnel destroy (@dest) * _________________________________ - * 5 x ok expected per peer */ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "SPEED\n"); - test = SPEED; - ok_goal = 1003; + ok_goal = TOTAL_PACKETS + 5; + if (strstr (argv[0], "_min") != NULL) + { + test = SPEED_MIN; + test_name = "speed min"; + } + else if (strstr (argv[0], "_nobuf") != NULL) + { + test = SPEED_NOBUF; + test_name = "speed nobuf"; + } + else + { + test = SPEED; + test_name = "speed"; + } } else { @@ -1000,16 +968,31 @@ main (int argc, char *argv[]) ok_goal = 0; } - GNUNET_PROGRAM_run (argc2, argv2, - "test_mesh_small", - gettext_noop ("Test mesh in a small network."), options, - &run, NULL); -#if REMOVE_DIR - GNUNET_DISK_directory_remove ("/tmp/test_mesh_small"); -#endif + if (strstr (argv[0], "backwards") != NULL) + { + char *aux; + + GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "BACKWARDS (LEAF TO ROOT)\n"); + test_backwards = GNUNET_YES; + aux = GNUNET_malloc (32); + sprintf (aux, "backwards %s", test_name); + test_name = aux; + } + + p_ids = 0; + GNUNET_MESH_TEST_run ("test_mesh_small", + "test_mesh_small.conf", + 5, + &tmain, + NULL, + &incoming_tunnel, + &tunnel_cleaner, + handlers, + NULL); + if (ok_goal > ok) { - GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "FAILED! (%d/%d)\n", ok, ok_goal); return 1; } |