aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNathan S. Evans <evans@in.tum.de>2010-08-10 15:17:00 +0000
committerNathan S. Evans <evans@in.tum.de>2010-08-10 15:17:00 +0000
commit49f3bd45e74b2723ef94f66ca5077e23c00685d5 (patch)
treed71009f020b61282c0f5fac1a8f3f4628538eea6 /src
parent71cc9ab8f420c4724987647c11d679084269bc5a (diff)
downloadgnunet-49f3bd45e74b2723ef94f66ca5077e23c00685d5.tar.gz
gnunet-49f3bd45e74b2723ef94f66ca5077e23c00685d5.zip
add statistics iteration to testing_group, test case for same.
Diffstat (limited to 'src')
-rw-r--r--src/testing/Makefile.am1
-rw-r--r--src/testing/test_testing_topology.c43
-rw-r--r--src/testing/testing_group.c205
3 files changed, 229 insertions, 20 deletions
diff --git a/src/testing/Makefile.am b/src/testing/Makefile.am
index fa56e1726..bd4495035 100644
--- a/src/testing/Makefile.am
+++ b/src/testing/Makefile.am
@@ -16,6 +16,7 @@ libgnunettesting_la_SOURCES = \
16 testing_group.c 16 testing_group.c
17libgnunettesting_la_LIBADD = $(XLIB) \ 17libgnunettesting_la_LIBADD = $(XLIB) \
18 $(top_builddir)/src/core/libgnunetcore.la \ 18 $(top_builddir)/src/core/libgnunetcore.la \
19 $(top_builddir)/src/statistics/libgnunetstatistics.la \
19 $(top_builddir)/src/transport/libgnunettransport.la \ 20 $(top_builddir)/src/transport/libgnunettransport.la \
20 -lm \ 21 -lm \
21 $(top_builddir)/src/util/libgnunetutil.la 22 $(top_builddir)/src/util/libgnunetutil.la
diff --git a/src/testing/test_testing_topology.c b/src/testing/test_testing_topology.c
index f357862c5..3d03d7611 100644
--- a/src/testing/test_testing_topology.c
+++ b/src/testing/test_testing_topology.c
@@ -270,12 +270,40 @@ disconnect_cores (void *cls, const struct GNUNET_SCHEDULER_TaskContext * tc)
270 total_server_connections -= 2; 270 total_server_connections -= 2;
271} 271}
272 272
273void topology_cb (void *cls, 273static void stats_finished (void *cls, int result)
274 const struct GNUNET_PeerIdentity *first, 274{
275 const struct GNUNET_PeerIdentity *second, 275 fprintf(stderr, "Finished getting all peers statistics!\n");
276 struct GNUNET_TIME_Relative latency, 276 GNUNET_SCHEDULER_add_now (sched, &finish_testing, NULL);
277 uint32_t distance, 277}
278 const char *emsg) 278
279/**
280 * Callback function to process statistic values.
281 *
282 * @param cls closure
283 * @param peer the peer the statistics belong to
284 * @param subsystem name of subsystem that created the statistic
285 * @param name the name of the datum
286 * @param value the current value
287 * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not
288 * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration
289 */
290static int stats_print (void *cls,
291 const struct GNUNET_PeerIdentity *peer,
292 const char *subsystem,
293 const char *name,
294 uint64_t value,
295 int is_persistent)
296{
297 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, "%s:%s:%s -- %llu\n", GNUNET_i2s(peer), subsystem, name, value);
298 return GNUNET_OK;
299}
300
301static void topology_cb (void *cls,
302 const struct GNUNET_PeerIdentity *first,
303 const struct GNUNET_PeerIdentity *second,
304 struct GNUNET_TIME_Relative latency,
305 uint32_t distance,
306 const char *emsg)
279{ 307{
280 FILE *outfile; 308 FILE *outfile;
281 outfile = cls; 309 outfile = cls;
@@ -295,7 +323,8 @@ void topology_cb (void *cls,
295 { 323 {
296 fprintf(outfile, "}\n"); 324 fprintf(outfile, "}\n");
297 fclose(outfile); 325 fclose(outfile);
298 GNUNET_SCHEDULER_add_now (sched, &finish_testing, NULL); 326 GNUNET_TESTING_get_statistics(pg, &stats_finished, &stats_print, NULL);
327 //GNUNET_SCHEDULER_add_now (sched, &finish_testing, NULL);
299 } 328 }
300 } 329 }
301} 330}
diff --git a/src/testing/testing_group.c b/src/testing/testing_group.c
index 2dace413a..df66720ef 100644
--- a/src/testing/testing_group.c
+++ b/src/testing/testing_group.c
@@ -333,9 +333,52 @@ struct TopologyIterateContext
333 unsigned int total; 333 unsigned int total;
334}; 334};
335 335
336struct TopologyCoreContext 336struct StatsIterateContext
337{ 337{
338 struct TopologyIterateContext *topology_context; 338 /**
339 * Handle to the statistics service.
340 */
341 struct GNUNET_STATISTICS_Handle *stats_handle;
342
343 /**
344 * Handle for getting statistics.
345 */
346 struct GNUNET_STATISTICS_GetHandle *stats_get_handle;
347
348 /**
349 * Continuation to call once all stats information has been retrieved.
350 */
351 GNUNET_STATISTICS_Callback cont;
352
353 /**
354 * Proc function to call on each value received.
355 */
356 GNUNET_TESTING_STATISTICS_Iterator proc;
357
358 /**
359 * Closure for topology_cb
360 */
361 void *cls;
362
363 /**
364 * Number of peers currently connected to.
365 */
366 unsigned int connected;
367
368 /**
369 * Number of peers we have finished iterating.
370 */
371 unsigned int completed;
372
373 /**
374 * Number of peers total.
375 */
376 unsigned int total;
377};
378
379struct CoreContext
380{
381 void *iter_context;
339 struct GNUNET_TESTING_Daemon *daemon; 382 struct GNUNET_TESTING_Daemon *daemon;
340}; 383};
341 384
@@ -2755,13 +2798,15 @@ internal_topology_callback(void *cls,
2755 const struct GNUNET_PeerIdentity *peer, 2798 const struct GNUNET_PeerIdentity *peer,
2756 struct GNUNET_TIME_Relative latency, uint32_t distance) 2799 struct GNUNET_TIME_Relative latency, uint32_t distance)
2757{ 2800{
2758 struct TopologyCoreContext *core_ctx = cls; 2801 struct CoreContext *core_ctx = cls;
2759 struct TopologyIterateContext *iter_ctx = core_ctx->topology_context; 2802 struct TopologyIterateContext *iter_ctx = core_ctx->iter_context;
2760 2803
2761 if (peer == NULL) /* Either finished, or something went wrongo */ 2804 if (peer == NULL) /* Either finished, or something went wrong */
2762 { 2805 {
2763 iter_ctx->completed++; 2806 iter_ctx->completed++;
2764 iter_ctx->connected--; 2807 iter_ctx->connected--;
2808 /* One core context allocated per iteration, must free! */
2809 GNUNET_free(core_ctx);
2765 } 2810 }
2766 else 2811 else
2767 { 2812 {
@@ -2771,8 +2816,8 @@ internal_topology_callback(void *cls,
2771 if (iter_ctx->completed == iter_ctx->total) 2816 if (iter_ctx->completed == iter_ctx->total)
2772 { 2817 {
2773 iter_ctx->topology_cb(iter_ctx->cls, NULL, NULL, GNUNET_TIME_relative_get_zero(), 0, NULL); 2818 iter_ctx->topology_cb(iter_ctx->cls, NULL, NULL, GNUNET_TIME_relative_get_zero(), 0, NULL);
2819 /* Once all are done, free the iteration context */
2774 GNUNET_free(iter_ctx); 2820 GNUNET_free(iter_ctx);
2775 GNUNET_free(core_ctx);
2776 } 2821 }
2777} 2822}
2778 2823
@@ -2784,12 +2829,12 @@ internal_topology_callback(void *cls,
2784static void 2829static void
2785schedule_get_topology(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 2830schedule_get_topology(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2786{ 2831{
2787 struct TopologyCoreContext *core_context = cls; 2832 struct CoreContext *core_context = cls;
2788 2833 struct TopologyIterateContext *topology_context = (struct TopologyIterateContext *)core_context->iter_context;
2789 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) 2834 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
2790 return; 2835 return;
2791 2836
2792 if (core_context->topology_context->connected > MAX_OUTSTANDING_CONNECTIONS) 2837 if (topology_context->connected > MAX_OUTSTANDING_CONNECTIONS)
2793 { 2838 {
2794#if VERBOSE_TESTING > 2 2839#if VERBOSE_TESTING > 2
2795 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2840 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2803,7 +2848,7 @@ schedule_get_topology(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2803 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2848 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2804 _("Creating connection, outstanding_connections is %d\n"), outstanding_connects); 2849 _("Creating connection, outstanding_connections is %d\n"), outstanding_connects);
2805#endif 2850#endif
2806 core_context->topology_context->connected++; 2851 topology_context->connected++;
2807 if (GNUNET_OK != GNUNET_CORE_iterate_peers (core_context->daemon->sched, core_context->daemon->cfg, &internal_topology_callback, core_context)) 2852 if (GNUNET_OK != GNUNET_CORE_iterate_peers (core_context->daemon->sched, core_context->daemon->cfg, &internal_topology_callback, core_context))
2808 internal_topology_callback(core_context, NULL, GNUNET_TIME_relative_get_zero(), 0); 2853 internal_topology_callback(core_context, NULL, GNUNET_TIME_relative_get_zero(), 0);
2809 2854
@@ -2818,10 +2863,11 @@ void
2818GNUNET_TESTING_get_topology (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_TESTING_NotifyTopology cb, void *cls) 2863GNUNET_TESTING_get_topology (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_TESTING_NotifyTopology cb, void *cls)
2819{ 2864{
2820 struct TopologyIterateContext *topology_context; 2865 struct TopologyIterateContext *topology_context;
2821 struct TopologyCoreContext *core_ctx; 2866 struct CoreContext *core_ctx;
2822 unsigned int i; 2867 unsigned int i;
2823 unsigned int total_count; 2868 unsigned int total_count;
2824 2869
2870 /* Allocate a single topology iteration context */
2825 topology_context = GNUNET_malloc(sizeof(struct TopologyIterateContext)); 2871 topology_context = GNUNET_malloc(sizeof(struct TopologyIterateContext));
2826 topology_context->topology_cb = cb; 2872 topology_context->topology_cb = cb;
2827 topology_context->cls = cls; 2873 topology_context->cls = cls;
@@ -2830,9 +2876,11 @@ GNUNET_TESTING_get_topology (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_TESTING
2830 { 2876 {
2831 if (pg->peers[i].daemon->running == GNUNET_YES) 2877 if (pg->peers[i].daemon->running == GNUNET_YES)
2832 { 2878 {
2833 core_ctx = GNUNET_malloc(sizeof(struct TopologyCoreContext)); 2879 /* Allocate one core context per core we need to connect to */
2880 core_ctx = GNUNET_malloc(sizeof(struct CoreContext));
2834 core_ctx->daemon = pg->peers[i].daemon; 2881 core_ctx->daemon = pg->peers[i].daemon;
2835 core_ctx->topology_context = topology_context; 2882 /* Set back pointer to topology iteration context */
2883 core_ctx->iter_context = topology_context;
2836 GNUNET_SCHEDULER_add_now(pg->sched, &schedule_get_topology, core_ctx); 2884 GNUNET_SCHEDULER_add_now(pg->sched, &schedule_get_topology, core_ctx);
2837 total_count++; 2885 total_count++;
2838 } 2886 }
@@ -2842,6 +2890,137 @@ GNUNET_TESTING_get_topology (struct GNUNET_TESTING_PeerGroup *pg, GNUNET_TESTING
2842} 2890}
2843 2891
2844/** 2892/**
2893 * Callback function to process statistic values.
2894 * This handler is here only really to insert a peer
2895 * identity (or daemon) so the statistics can be uniquely
2896 * tied to a single running peer.
2897 *
2898 * @param cls closure
2899 * @param subsystem name of subsystem that created the statistic
2900 * @param name the name of the datum
2901 * @param value the current value
2902 * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not
2903 * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration
2904 */
2905static int internal_stats_callback (void *cls,
2906 const char *subsystem,
2907 const char *name,
2908 uint64_t value,
2909 int is_persistent)
2910{
2911 struct CoreContext *core_context = cls;
2912 struct StatsIterateContext *stats_context = (struct StatsIterateContext *)core_context->iter_context;
2913
2914 return stats_context->proc(stats_context->cls, &core_context->daemon->id, subsystem, name, value, is_persistent);
2915}
2916
2917/**
2918 * Internal continuation call for statistics iteration.
2919 *
2920 * @param cls closure, the CoreContext for this iteration
2921 * @param success whether or not the statistics iterations
2922 * was canceled or not (we don't care)
2923 */
2924static void internal_stats_cont (void *cls, int success)
2925{
2926 struct CoreContext *core_context = cls;
2927 struct StatsIterateContext *stats_context = (struct StatsIterateContext *)core_context->iter_context;
2928
2929 stats_context->connected--;
2930 stats_context->completed++;
2931
2932 if (stats_context->completed == stats_context->total)
2933 {
2934 stats_context->cont(stats_context->cls, GNUNET_YES);
2935 if (stats_context->stats_handle != NULL)
2936 GNUNET_STATISTICS_destroy(stats_context->stats_handle, GNUNET_NO);
2937 GNUNET_free(stats_context);
2938 }
2939 GNUNET_free(core_context);
2940}
2941
2942/**
2943 * Check running topology iteration tasks, if below max start a new one, otherwise
2944 * schedule for some time in the future.
2945 */
2946static void
2947schedule_get_statistics(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2948{
2949 struct CoreContext *core_context = cls;
2950 struct StatsIterateContext *stats_context = (struct StatsIterateContext *)core_context->iter_context;
2951
2952 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
2953 return;
2954
2955 if (stats_context->connected > MAX_OUTSTANDING_CONNECTIONS)
2956 {
2957#if VERBOSE_TESTING > 2
2958 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2959 _("Delaying connect, we have too many outstanding connections!\n"));
2960#endif
2961 GNUNET_SCHEDULER_add_delayed(core_context->daemon->sched, GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MILLISECONDS, 100), &schedule_get_statistics, core_context);
2962 }
2963 else
2964 {
2965#if VERBOSE_TESTING > 2
2966 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2967 _("Creating connection, outstanding_connections is %d\n"), outstanding_connects);
2968#endif
2969
2970 stats_context->connected++;
2971 stats_context->stats_handle = GNUNET_STATISTICS_create(core_context->daemon->sched, "testing", core_context->daemon->cfg);
2972 if (stats_context->stats_handle == NULL)
2973 {
2974 internal_stats_cont (core_context, GNUNET_NO);
2975 return;
2976 }
2977
2978 stats_context->stats_get_handle = GNUNET_STATISTICS_get(stats_context->stats_handle, NULL, NULL, GNUNET_TIME_relative_get_forever(), &internal_stats_cont, &internal_stats_callback, core_context);
2979 if (stats_context->stats_get_handle == NULL)
2980 internal_stats_cont (core_context, GNUNET_NO);
2981
2982 }
2983}
2984
2985
2986/**
2987 * Iterate over all (running) peers in the peer group, retrieve
2988 * all statistics from each.
2989 */
2990void
2991GNUNET_TESTING_get_statistics (struct GNUNET_TESTING_PeerGroup *pg,
2992 GNUNET_STATISTICS_Callback cont,
2993 GNUNET_TESTING_STATISTICS_Iterator proc, void *cls)
2994{
2995 struct StatsIterateContext *stats_context;
2996 struct CoreContext *core_ctx;
2997 unsigned int i;
2998 unsigned int total_count;
2999
3000 /* Allocate a single stats iteration context */
3001 stats_context = GNUNET_malloc(sizeof(struct StatsIterateContext));
3002 stats_context->cont = cont;
3003 stats_context->proc = proc;
3004 stats_context->cls = cls;
3005 total_count = 0;
3006 for (i = 0; i < pg->total; i++)
3007 {
3008 if (pg->peers[i].daemon->running == GNUNET_YES)
3009 {
3010 /* Allocate one core context per core we need to connect to */
3011 core_ctx = GNUNET_malloc(sizeof(struct CoreContext));
3012 core_ctx->daemon = pg->peers[i].daemon;
3013 /* Set back pointer to topology iteration context */
3014 core_ctx->iter_context = stats_context;
3015 GNUNET_SCHEDULER_add_now(pg->sched, &schedule_get_statistics, core_ctx);
3016 total_count++;
3017 }
3018 }
3019 stats_context->total = total_count;
3020 return;
3021}
3022
3023/**
2845 * There are many ways to connect peers that are supported by this function. 3024 * There are many ways to connect peers that are supported by this function.
2846 * To connect peers in the same topology that was created via the 3025 * To connect peers in the same topology that was created via the
2847 * GNUNET_TESTING_create_topology, the topology variable must be set to 3026 * GNUNET_TESTING_create_topology, the topology variable must be set to