From ee1c5c74a2409a52af706e613bd86a26341abba8 Mon Sep 17 00:00:00 2001 From: Matthias Wachs Date: Thu, 23 Jan 2014 14:56:59 +0000 Subject: [PATCH] new logging functionality --- src/ats-tests/ats-testing-experiment.c | 148 +++++++++++++++++++++++-- src/ats-tests/ats-testing-log.c | 135 +++++++++++----------- src/ats-tests/ats-testing.c | 26 ++--- src/ats-tests/ats-testing.h | 65 ++++++++--- src/ats-tests/gnunet-ats-sim.c | 68 ++++++++++-- 5 files changed, 334 insertions(+), 108 deletions(-) diff --git a/src/ats-tests/ats-testing-experiment.c b/src/ats-tests/ats-testing-experiment.c index d0e74d1c3..fca374324 100644 --- a/src/ats-tests/ats-testing-experiment.c +++ b/src/ats-tests/ats-testing-experiment.c @@ -35,20 +35,141 @@ create_experiment () e->name = NULL; e->num_masters = 0; e->num_slaves = 0; - + e->start = NULL; + e->total_duration = GNUNET_TIME_UNIT_ZERO; return e; } static void free_experiment (struct Experiment *e) { + struct Episode *cur; + struct Episode *next; + + next = e->start; + for (cur = next; NULL != cur; cur = next) + { + next = cur->next; + GNUNET_free (cur); + } + GNUNET_free_non_null (e->name); GNUNET_free_non_null (e->cfg_file); GNUNET_free (e); } +static int +load_episodes (struct Experiment *e, struct GNUNET_CONFIGURATION_Handle *cfg) +{ + int e_counter = 0; + char *sec_name; + struct GNUNET_TIME_Relative e_duration; + struct Episode *cur; + struct Episode *last; + + e_counter = 0; + last = NULL; + while (1) + { + GNUNET_asprintf(&sec_name, "episode-%u", e_counter); + if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, + sec_name, "duration", &e_duration)) + { + GNUNET_free (sec_name); + break; + } + + cur = GNUNET_new (struct Episode); + cur->duration = e_duration; + cur->id = e_counter; + + fprintf (stderr, "Found episode %u with duration %s \n", + e_counter, + GNUNET_STRINGS_relative_time_to_string(cur->duration, GNUNET_YES)); + + /* Update experiment */ + e->num_episodes ++; + e->total_duration = GNUNET_TIME_relative_add(e->total_duration, cur->duration); + /* Put in linked list */ + if (NULL == last) + e->start = cur; + else + last->next = cur; + + GNUNET_free (sec_name); + e_counter ++; + last = cur; + } + return e_counter; +} + +static void +timeout_experiment (void *cls, const struct GNUNET_SCHEDULER_TaskContext* tc) +{ + struct Experiment *e = cls; + e->experiment_timeout_task = GNUNET_SCHEDULER_NO_TASK; + fprintf (stderr, "Experiment timeout!\n"); + + e->e_done_cb (e, GNUNET_SYSERR); +} + +static void +timeout_episode (void *cls, const struct GNUNET_SCHEDULER_TaskContext* tc) +{ + struct Experiment *e = cls; + e->episode_timeout_task = GNUNET_SCHEDULER_NO_TASK; + e->ep_done_cb (e->cur); + + /* Scheduling next */ + e->cur = e->cur->next; + if (NULL == e->cur) + { + /* done */ + fprintf (stderr, "Last episode done!\n"); + if (GNUNET_SCHEDULER_NO_TASK != e->experiment_timeout_task) + { + GNUNET_SCHEDULER_cancel (e->experiment_timeout_task); + e->experiment_timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + e->e_done_cb (e, GNUNET_OK); + return; + } + + fprintf (stderr, "Running episode %u with timeout %s\n", + e->cur->id, + GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES)); + e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration, + &timeout_episode, e); +} + + +void +GNUNET_ATS_TEST_experimentation_run (struct Experiment *e, + GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb, + GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb) +{ + fprintf (stderr, "Running experiment `%s' with timeout %s\n", e->name, + GNUNET_STRINGS_relative_time_to_string(e->max_duration, GNUNET_YES)); + e->e_done_cb = e_done_cb; + e->ep_done_cb = ep_done_cb; + + /* Start total time out */ + e->experiment_timeout_task = GNUNET_SCHEDULER_add_delayed (e->max_duration, + &timeout_experiment, e); + + /* Start */ + e->cur = e->start; + fprintf (stderr, "Running episode %u with timeout %s\n", + e->cur->id, + GNUNET_STRINGS_relative_time_to_string(e->cur->duration, GNUNET_YES)); + e->episode_timeout_task = GNUNET_SCHEDULER_add_delayed (e->cur->duration, + &timeout_episode, e); + + +} + struct Experiment * -GNUNET_ATS_TEST_experimentation_start (char *filename) +GNUNET_ATS_TEST_experimentation_load (char *filename) { struct Experiment *e; struct GNUNET_CONFIGURATION_Handle *cfg; @@ -57,7 +178,7 @@ GNUNET_ATS_TEST_experimentation_start (char *filename) cfg = GNUNET_CONFIGURATION_create(); if (GNUNET_SYSERR == GNUNET_CONFIGURATION_load (cfg, filename)) { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to load `%s'\n", filename); + fprintf (stderr, "Failed to load `%s'\n", filename); GNUNET_CONFIGURATION_destroy (cfg); return NULL; } @@ -72,7 +193,7 @@ GNUNET_ATS_TEST_experimentation_start (char *filename) return NULL; } else - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment name: `%s'\n", e->name); + fprintf (stderr, "Experiment name: `%s'\n", e->name); if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_filename (cfg, "experiment", "cfg_file", &e->cfg_file)) @@ -82,7 +203,7 @@ GNUNET_ATS_TEST_experimentation_start (char *filename) return NULL; } else - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment name: `%s'\n", e->cfg_file); + fprintf (stderr, "Experiment name: `%s'\n", e->cfg_file); if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg, "experiment", "masters", &e->num_masters)) @@ -92,7 +213,7 @@ GNUNET_ATS_TEST_experimentation_start (char *filename) return NULL; } else - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment masters: `%llu'\n", + fprintf (stderr, "Experiment masters: `%llu'\n", e->num_masters); if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(cfg, "experiment", @@ -103,7 +224,7 @@ GNUNET_ATS_TEST_experimentation_start (char *filename) return NULL; } else - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment slaves: `%llu'\n", + fprintf (stderr, "Experiment slaves: `%llu'\n", e->num_slaves); if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_time(cfg, "experiment", @@ -114,15 +235,26 @@ GNUNET_ATS_TEST_experimentation_start (char *filename) return NULL; } else - GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment duration: `%s'\n", + fprintf (stderr, "Experiment duration: `%s'\n", GNUNET_STRINGS_relative_time_to_string (e->max_duration, GNUNET_YES)); + load_episodes (e, cfg); + fprintf (stderr, "Loaded %u episodes with total duration %s\n", + e->num_episodes, + GNUNET_STRINGS_relative_time_to_string (e->total_duration, GNUNET_YES)); + + GNUNET_CONFIGURATION_destroy (cfg); return e; } void GNUNET_ATS_TEST_experimentation_stop (struct Experiment *e) { + if (GNUNET_SCHEDULER_NO_TASK != e->experiment_timeout_task) + { + GNUNET_SCHEDULER_cancel (e->experiment_timeout_task); + e->experiment_timeout_task = GNUNET_SCHEDULER_NO_TASK; + } free_experiment (e); } diff --git a/src/ats-tests/ats-testing-log.c b/src/ats-tests/ats-testing-log.c index 68caf15b6..2e3a89e5a 100644 --- a/src/ats-tests/ats-testing-log.c +++ b/src/ats-tests/ats-testing-log.c @@ -18,14 +18,14 @@ Boston, MA 02111-1307, USA. */ /** - * @file ats/perf_ats_logging.c + * @file ats-tests/ats-testing-log.c * @brief ats benchmark: logging for performance tests * @author Christian Grothoff * @author Matthias Wachs */ #include "platform.h" #include "gnunet_util_lib.h" -#include "perf_ats.h" +#include "ats-testing.h" #define THROUGHPUT_TEMPLATE "#!/usr/bin/gnuplot \n" \ "set datafile separator ';' \n" \ @@ -69,19 +69,6 @@ #define LOG_ITEM_ATS_UTIL_UP 16 #define LOG_ITEM_ATS_UTIL_DOWN 17 -/** - * Logging task - */ -static GNUNET_SCHEDULER_TaskIdentifier log_task; - -/** - * Reference to perf_ats' masters - */ -static int num_peers; -static int running; -static char *name; -static struct GNUNET_TIME_Relative frequency; - /** * A single logging time step for a partner */ @@ -238,10 +225,28 @@ struct LoggingPeer struct PeerLoggingTimestep *tail; }; -/** - * Log structure of length num_peers - */ -static struct LoggingPeer *lp; +struct LoggingHandle +{ + /** + * Logging task + */ + GNUNET_SCHEDULER_TaskIdentifier log_task; + + /** + * Reference to perf_ats' masters + */ + int num_peers; + int running; + char *name; + struct GNUNET_TIME_Relative frequency; + + /** + * Log structure of length num_peers + */ + struct LoggingPeer *lp; + +}; + static void @@ -397,8 +402,8 @@ write_bw_gnuplot_script (char * fn, struct LoggingPeer *lp) } -static void -write_to_file () +void +GNUNET_ATS_TEST_logging_write_to_file (struct LoggingHandle *l, char *test) { struct GNUNET_DISK_FileHandle *f; @@ -411,10 +416,10 @@ write_to_file () int c_m; int c_s; - for (c_m = 0; c_m < num_peers; c_m++) + for (c_m = 0; c_m < l->num_peers; c_m++) { - GNUNET_asprintf (&filename, "%llu_master_%u_%s_%s.data", GNUNET_TIME_absolute_get().abs_value_us, - lp[c_m].peer->no, GNUNET_i2s(&lp[c_m].peer->id), name); + GNUNET_asprintf (&filename, "%s_%llu_master_%u_%s_%s.data", test, GNUNET_TIME_absolute_get().abs_value_us, + l->lp[c_m].peer->no, GNUNET_i2s(&l->lp[c_m].peer->id), l->name); f = GNUNET_DISK_file_open (filename, GNUNET_DISK_OPEN_WRITE | GNUNET_DISK_OPEN_CREATE, @@ -426,16 +431,16 @@ write_to_file () return; } - for (cur_lt = lp[c_m].head; NULL != cur_lt; cur_lt = cur_lt->next) + for (cur_lt = l->lp[c_m].head; NULL != cur_lt; cur_lt = cur_lt->next) { GNUNET_log(GNUNET_ERROR_TYPE_INFO, - "Master [%u]: timestamp %llu %llu ; %u %u %u ; %u %u %u\n", lp[c_m].peer->no, - cur_lt->timestamp, GNUNET_TIME_absolute_get_difference(lp[c_m].start,cur_lt->timestamp).rel_value_us / 1000, + "Master [%u]: timestamp %llu %llu ; %u %u %u ; %u %u %u\n", l->lp[c_m].peer->no, + cur_lt->timestamp, GNUNET_TIME_absolute_get_difference(l->lp[c_m].start,cur_lt->timestamp).rel_value_us / 1000, cur_lt->total_messages_sent, cur_lt->total_bytes_sent, cur_lt->total_throughput_send, cur_lt->total_messages_received, cur_lt->total_bytes_received, cur_lt->total_throughput_recv); slave_string = GNUNET_strdup (";"); - for (c_s = 0; c_s < lp[c_m].peer->num_partners; c_s++) + for (c_s = 0; c_s < l->lp[c_m].peer->num_partners; c_s++) { plt = &cur_lt->slaves_log[c_s]; /* Log partners */ @@ -465,7 +470,7 @@ write_to_file () GNUNET_asprintf (&data, "%llu;%llu;%u;%u;%u;%u;%u;%u;;;;;;;;;;;%s\n", cur_lt->timestamp, - GNUNET_TIME_absolute_get_difference(lp[c_m].start,cur_lt->timestamp).rel_value_us / 1000, + GNUNET_TIME_absolute_get_difference(l->lp[c_m].start,cur_lt->timestamp).rel_value_us / 1000, cur_lt->total_messages_sent, cur_lt->total_bytes_sent, cur_lt->total_throughput_send, cur_lt->total_messages_received, cur_lt->total_bytes_received, cur_lt->total_throughput_recv, slave_string); @@ -482,9 +487,9 @@ write_to_file () return; } - write_throughput_gnuplot_script (filename, lp); - write_rtt_gnuplot_script (filename, lp); - write_bw_gnuplot_script (filename, lp); + write_throughput_gnuplot_script (filename, l->lp); + write_rtt_gnuplot_script (filename, l->lp); + write_bw_gnuplot_script (filename, l->lp); GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Data file successfully written to log file `%s'\n", filename); GNUNET_free (filename); @@ -493,7 +498,7 @@ write_to_file () void -GNUNET_ATS_TEST_logging_now (void) +GNUNET_ATS_TEST_logging_now (struct LoggingHandle *l) { struct LoggingPeer *bp; struct PeerLoggingTimestep *mlt; @@ -507,12 +512,12 @@ GNUNET_ATS_TEST_logging_now (void) unsigned int app_rtt; double mult; - if (GNUNET_YES != running) + if (GNUNET_YES != l->running) return; - for (c_m = 0; c_m < num_peers; c_m++) + for (c_m = 0; c_m < l->num_peers; c_m++) { - bp = &lp[c_m]; + bp = &l->lp[c_m]; mlt = GNUNET_new (struct PeerLoggingTimestep); GNUNET_CONTAINER_DLL_insert_tail(bp->head, bp->tail, mlt); prev_log_mlt = mlt->prev; @@ -530,7 +535,7 @@ GNUNET_ATS_TEST_logging_now (void) if (NULL == prev_log_mlt) { /* Get difference to start */ - delta = GNUNET_TIME_absolute_get_difference (lp[c_m].start, mlt->timestamp); + delta = GNUNET_TIME_absolute_get_difference (l->lp[c_m].start, mlt->timestamp); } else { @@ -639,75 +644,79 @@ GNUNET_ATS_TEST_logging_now (void) static void collect_log_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) { - log_task = GNUNET_SCHEDULER_NO_TASK; + struct LoggingHandle *l = cls; + l->log_task = GNUNET_SCHEDULER_NO_TASK; - GNUNET_ATS_TEST_logging_now(); + GNUNET_ATS_TEST_logging_now (l); if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) return; - log_task = GNUNET_SCHEDULER_add_delayed (frequency, - &collect_log_task, NULL); + l->log_task = GNUNET_SCHEDULER_add_delayed (l->frequency, + &collect_log_task, l); } void -GNUNET_ATS_TEST_logging_stop (void) +GNUNET_ATS_TEST_logging_stop (struct LoggingHandle *l) { int c_m; struct GNUNET_SCHEDULER_TaskContext tc; struct PeerLoggingTimestep *cur; - if (GNUNET_YES!= running) + if (GNUNET_YES!= l->running) return; - if (GNUNET_SCHEDULER_NO_TASK != log_task) - GNUNET_SCHEDULER_cancel (log_task); - log_task = GNUNET_SCHEDULER_NO_TASK; + if (GNUNET_SCHEDULER_NO_TASK != l->log_task) + GNUNET_SCHEDULER_cancel (l->log_task); + l->log_task = GNUNET_SCHEDULER_NO_TASK; tc.reason = GNUNET_SCHEDULER_REASON_SHUTDOWN; - collect_log_task (NULL, &tc); + collect_log_task (l, &tc); GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Stop logging\n")); - write_to_file (); - for (c_m = 0; c_m < num_peers; c_m++) + for (c_m = 0; c_m < l->num_peers; c_m++) { - while (NULL != (cur = lp[c_m].head)) + while (NULL != (cur = l->lp[c_m].head)) { - GNUNET_CONTAINER_DLL_remove (lp[c_m].head, lp[c_m].tail, cur); + GNUNET_CONTAINER_DLL_remove (l->lp[c_m].head, l->lp[c_m].tail, cur); GNUNET_free (cur->slaves_log); GNUNET_free (cur); } } - GNUNET_free (lp); + GNUNET_free (l->lp); + GNUNET_free (l); } -void +struct LoggingHandle * GNUNET_ATS_TEST_logging_start (struct GNUNET_TIME_Relative log_frequency, char * testname, struct BenchmarkPeer *masters, int num_masters) { + struct LoggingHandle *l; int c_m; GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Start logging `%s'\n"), testname); - num_peers = num_masters; - name = testname; - frequency = log_frequency; - - lp = GNUNET_malloc (num_masters * sizeof (struct LoggingPeer)); + l = GNUNET_new (struct LoggingHandle); + l->num_peers = num_masters; + l->name = testname; + l->frequency = log_frequency; + l->lp = GNUNET_malloc (num_masters * sizeof (struct LoggingPeer)); for (c_m = 0; c_m < num_masters; c_m ++) { - lp[c_m].peer = &masters[c_m]; - lp[c_m].start = GNUNET_TIME_absolute_get(); + l->lp[c_m].peer = &masters[c_m]; + l->lp[c_m].start = GNUNET_TIME_absolute_get(); } /* Schedule logging task */ - log_task = GNUNET_SCHEDULER_add_now (&collect_log_task, NULL); - running = GNUNET_YES; + l->log_task = GNUNET_SCHEDULER_add_now (&collect_log_task, l); + l->running = GNUNET_YES; + + return l; } -/* end of file perf_ats_logging.c */ +/* end of file ats-testing-log.c */ diff --git a/src/ats-tests/ats-testing.c b/src/ats-tests/ats-testing.c index 3d090c237..08a61367b 100644 --- a/src/ats-tests/ats-testing.c +++ b/src/ats-tests/ats-testing.c @@ -19,7 +19,7 @@ */ /** * @file ats-tests/ats-testing.c - * @brief ats testing library: setup topology and provide logging to test ats + * @brief ats testing library: setup topology * solvers * @author Christian Grothoff * @author Matthias Wachs @@ -65,9 +65,6 @@ do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) int c_op; struct BenchmarkPeer *p; - if (GNUNET_YES == top->logging) - GNUNET_ATS_TEST_logging_stop (); - top->shutdown_task = GNUNET_SCHEDULER_NO_TASK; top->state.benchmarking = GNUNET_NO; @@ -544,10 +541,13 @@ do_comm_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) } static void -ats_performance_info_cb (void *cls, const struct GNUNET_HELLO_Address *address, - int address_active, struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out, +ats_performance_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) + const struct GNUNET_ATS_Information *ats, + uint32_t ats_count) { struct BenchmarkPeer *me = cls; struct BenchmarkPartner *p; @@ -630,10 +630,8 @@ ats_performance_info_cb (void *cls, const struct GNUNET_HELLO_Address *address, break; } } - if ((GNUNET_YES == top->logging) && (GNUNET_YES == log)) - GNUNET_ATS_TEST_logging_now(); - - top->ats_perf_cb (cls, address, address_active, bandwidth_out, bandwidth_in, + if (GNUNET_YES == log) + top->ats_perf_cb (cls, address, address_active, bandwidth_out, bandwidth_in, ats, ats_count); GNUNET_free(peer_id); } @@ -843,10 +841,10 @@ GNUNET_ATS_TEST_create_topology (char *name, char *cfg_file, unsigned int num_slaves, unsigned int num_masters, int test_core, - GNUNET_ATS_TESTING_TopologySetupDoneCallback done_cb, + GNUNET_ATS_TEST_TopologySetupDoneCallback done_cb, void *done_cb_cls, GNUNET_TRANSPORT_ReceiveCallback transport_recv_cb, - GNUNET_ATS_AddressInformationCallback ats_perf_cb) + GNUNET_ATS_AddressInformationCallback log_request_cb) { static struct GNUNET_CORE_MessageHandler handlers[] = { @@ -862,7 +860,7 @@ GNUNET_ATS_TEST_create_topology (char *name, char *cfg_file, top->done_cb_cls = done_cb_cls; top->test_core = test_core; top->transport_recv_cb = transport_recv_cb; - top->ats_perf_cb = ats_perf_cb; + top->ats_perf_cb = log_request_cb; top->mps = GNUNET_malloc (num_masters * sizeof (struct BenchmarkPeer)); top->sps = GNUNET_malloc (num_slaves * sizeof (struct BenchmarkPeer)); diff --git a/src/ats-tests/ats-testing.h b/src/ats-tests/ats-testing.h index d57ce2667..028789d69 100644 --- a/src/ats-tests/ats-testing.h +++ b/src/ats-tests/ats-testing.h @@ -39,11 +39,19 @@ struct BenchmarkPartner; struct BenchmarkPeer; struct GNUNET_ATS_TEST_Topology; struct TrafficGenerator; +struct LoggingHandle; -typedef void (*GNUNET_ATS_TESTING_TopologySetupDoneCallback) (void *cls, +typedef void (*GNUNET_ATS_TEST_TopologySetupDoneCallback) (void *cls, struct BenchmarkPeer *masters, struct BenchmarkPeer *slaves); +typedef void +(*GNUNET_ATS_TEST_LogRequest) (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); + /** * Information we track for a peer in the testbed. */ @@ -309,11 +317,6 @@ struct GNUNET_ATS_TEST_Topology */ int result; - /** - * Test result logging - */ - int logging; - /**Test core (GNUNET_YES) or transport (GNUNET_NO) */ int test_core; @@ -377,11 +380,22 @@ struct GNUNET_ATS_TEST_Topology GNUNET_TRANSPORT_ReceiveCallback transport_recv_cb; - GNUNET_ATS_TESTING_TopologySetupDoneCallback done_cb; + GNUNET_ATS_TEST_TopologySetupDoneCallback done_cb; GNUNET_ATS_AddressInformationCallback ats_perf_cb; void *done_cb_cls; }; +struct Experiment; + +struct Episode; + +typedef void (*GNUNET_ATS_TESTING_EpisodeDoneCallback) ( + struct Episode *e); + +typedef void (*GNUNET_ATS_TESTING_ExperimentDoneCallback) ( + struct Experiment *e, int success); + + struct Experiment { char *name; @@ -389,10 +403,33 @@ struct Experiment unsigned long long int num_masters; unsigned long long int num_slaves; struct GNUNET_TIME_Relative max_duration; + struct GNUNET_TIME_Relative total_duration; + struct GNUNET_TIME_Absolute start_time; + unsigned int num_episodes; + struct Episode *start; + + GNUNET_SCHEDULER_TaskIdentifier experiment_timeout_task; + GNUNET_SCHEDULER_TaskIdentifier episode_timeout_task; + struct Episode *cur; + + GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb; + GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb; +}; + +struct Episode +{ + int id; + struct Episode *next; + struct GNUNET_TIME_Relative duration; }; +void +GNUNET_ATS_TEST_experimentation_run (struct Experiment *e, + GNUNET_ATS_TESTING_EpisodeDoneCallback ep_done_cb, + GNUNET_ATS_TESTING_ExperimentDoneCallback e_done_cb); + struct Experiment * -GNUNET_ATS_TEST_experimentation_start (char *filename); +GNUNET_ATS_TEST_experimentation_load (char *filename); void GNUNET_ATS_TEST_experimentation_stop (struct Experiment *e); @@ -415,7 +452,7 @@ GNUNET_ATS_TEST_generate_traffic_stop_all (); /** * Start logging */ -void +struct LoggingHandle * GNUNET_ATS_TEST_logging_start (struct GNUNET_TIME_Relative log_frequency, char * testname, struct BenchmarkPeer *masters, int num_masters); @@ -423,14 +460,16 @@ GNUNET_ATS_TEST_logging_start (struct GNUNET_TIME_Relative log_frequency, * Stop logging */ void -GNUNET_ATS_TEST_logging_stop (void); +GNUNET_ATS_TEST_logging_stop (struct LoggingHandle *); /** * Log all data now */ void -GNUNET_ATS_TEST_logging_now (void); +GNUNET_ATS_TEST_logging_now (struct LoggingHandle *); +void +GNUNET_ATS_TEST_logging_write_to_file (struct LoggingHandle *, char *test); void GNUNET_ATS_TEST_traffic_handle_ping (struct BenchmarkPartner *p); @@ -444,10 +483,10 @@ GNUNET_ATS_TEST_create_topology (char *name, char *cfg_file, unsigned int num_slaves, unsigned int num_masters, int test_core, - GNUNET_ATS_TESTING_TopologySetupDoneCallback done_cb, + GNUNET_ATS_TEST_TopologySetupDoneCallback done_cb, void *done_cb_cls, GNUNET_TRANSPORT_ReceiveCallback transport_recv_cb, - GNUNET_ATS_AddressInformationCallback ats_perf_cb); + GNUNET_ATS_TEST_LogRequest ats_perf_cb); void GNUNET_ATS_TEST_shutdown_topology (void); diff --git a/src/ats-tests/gnunet-ats-sim.c b/src/ats-tests/gnunet-ats-sim.c index 8ba68c957..e06ca8887 100644 --- a/src/ats-tests/gnunet-ats-sim.c +++ b/src/ats-tests/gnunet-ats-sim.c @@ -37,8 +37,10 @@ static struct BenchmarkPeer *masters_p; static struct BenchmarkPeer *slaves_p; -struct Experiment *e; +GNUNET_SCHEDULER_TaskIdentifier timeout_task; +struct Experiment *e; +struct LoggingHandle *l; static void evaluate () @@ -105,8 +107,12 @@ evaluate () static void do_shutdown () { - /* Shutdown a topology with */ - evaluate (); + /* timeout */ + if (NULL != e) + { + GNUNET_ATS_TEST_experimentation_stop (e); + e = NULL; + } GNUNET_ATS_TEST_shutdown_topology (); } @@ -119,12 +125,45 @@ transport_recv_cb (void *cls, } static void -ats_performance_info_cb (void *cls, const struct GNUNET_HELLO_Address *address, +log_request__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) { + if (NULL != l) + GNUNET_ATS_TEST_logging_now (l); +} + +static void +experiment_done_cb (struct Experiment *e, int success) +{ + if (GNUNET_OK == success) + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment `%s' done successful\n", e->name); + else + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Experiment `%s' failed \n", e->name); + if (GNUNET_SCHEDULER_NO_TASK != timeout_task) + { + GNUNET_SCHEDULER_cancel (timeout_task); + timeout_task = GNUNET_SCHEDULER_NO_TASK; + } + /* Stop logging */ + GNUNET_ATS_TEST_logging_stop (l); + evaluate (); + /* Stop traffic generation */ + GNUNET_ATS_TEST_generate_traffic_stop_all(); + /* Clean up experiment */ + GNUNET_ATS_TEST_experimentation_stop (e); + e = NULL; + + /* Shutdown topology */ + GNUNET_ATS_TEST_shutdown_topology (); +} + +static void +episode_done_cb (struct Episode *ep) +{ + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Episode %u done\n", ep->id); } static void topology_setup_done (void *cls, @@ -138,25 +177,31 @@ static void topology_setup_done (void *cls, masters_p = masters; slaves_p = slaves; + l = GNUNET_ATS_TEST_logging_start (GNUNET_TIME_UNIT_SECONDS, e->name, + masters_p, e->num_masters); + GNUNET_ATS_TEST_experimentation_run (e, &episode_done_cb, &experiment_done_cb); + for (c_m = 0; c_m < e->num_masters; c_m++) { for (c_s = 0; c_s < e->num_slaves; c_s++) { /* Generate maximum traffic to all peers */ - fprintf (stderr, "c_m %u c_s %u\n", c_m, c_s); GNUNET_ATS_TEST_generate_traffic_start (&masters[c_m], &masters[c_m].partners[c_s], 10000, GNUNET_TIME_UNIT_FOREVER_REL); } } - GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, &do_shutdown, NULL); + + timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_add (GNUNET_TIME_UNIT_MINUTES, + e->max_duration), &do_shutdown, NULL); } int main (int argc, char *argv[]) { + GNUNET_log_setup("gnunet-ats-sim", "INFO", NULL); if (argc < 2) { fprintf (stderr, "No experiment given...\n"); @@ -164,14 +209,17 @@ main (int argc, char *argv[]) } fprintf (stderr, "Loading experiment `%s' \n", argv[1]); - e = GNUNET_ATS_TEST_experimentation_start (argv[1]); + e = GNUNET_ATS_TEST_experimentation_load (argv[1]); if (NULL == e) { fprintf (stderr, "Invalid experiment\n"); return 1; } - - fprintf (stderr, "%llu %llu\n", e->num_masters, e->num_slaves); + if (0 == e->num_episodes) + { + fprintf (stderr, "No episodes included\n"); + return 1; + } /* Setup a topology with */ GNUNET_ATS_TEST_create_topology ("gnunet-ats-sim", e->cfg_file, @@ -181,7 +229,7 @@ main (int argc, char *argv[]) &topology_setup_done, NULL, &transport_recv_cb, - &ats_performance_info_cb); + &log_request__cb); return 0; } /* end of file gnunet-ats-sim.c */ -- 2.25.1