1 /* Copyright (c) 2019 Dovecot authors, see the included COPYING file */
2 
3 #include "test-stats-common.h"
4 #include <time.h>
5 #include <unistd.h>
6 
7 struct event_category test_category = {
8 	.name = "test",
9 };
10 
11 struct event_category child_test_category = {
12 	.name = "child",
13 	.parent = &test_category,
14 };
15 
16 pool_t test_pool;
17 struct stats_metrics *stats_metrics = NULL;
18 time_t stats_startup_time;
19 
20 static bool callback_added = FALSE;
21 
read_settings(const char * settings)22 static struct stats_settings *read_settings(const char *settings)
23 {
24 	struct istream *is = test_istream_create(settings);
25 	const char *error;
26 	struct setting_parser_context *ctx =
27 		settings_parser_init(test_pool, &stats_setting_parser_info, 0);
28 	if (settings_parse_stream_read(ctx, is) < 0)
29 		i_fatal("Failed to parse settings: %s",
30 			settings_parser_get_error(ctx));
31 	if (!settings_parser_check(ctx, test_pool, &error))
32 		i_fatal("Failed to parse settings: %s",
33 			error);
34 	struct stats_settings *set = settings_parser_get(ctx);
35 	settings_parser_deinit(&ctx);
36 	i_stream_unref(&is);
37 	return set;
38 }
39 
test_init(const char * settings_blob)40 void test_init(const char *settings_blob)
41 {
42 	if (!callback_added) {
43 		event_register_callback(test_stats_callback);
44 		callback_added = TRUE;
45 	}
46 
47 	stats_event_categories_init();
48 	test_pool = pool_alloconly_create(MEMPOOL_GROWING"test pool", 2048);
49 	stats_startup_time = time(NULL);
50 
51 	/* register test categories */
52 	stats_event_category_register(test_category.name, NULL);
53 	stats_event_category_register(child_test_category.name,
54 				      &test_category);
55 	struct stats_settings *set = read_settings(settings_blob);
56 	stats_metrics = stats_metrics_init(set);
57 }
58 
test_deinit(void)59 void test_deinit(void)
60 {
61 	stats_metrics_deinit(&stats_metrics);
62 	stats_event_categories_deinit();
63 	pool_unref(&test_pool);
64 }
65 
test_event_send(struct event * event)66 void test_event_send(struct event *event)
67 {
68         struct failure_context ctx = {
69                 .type = LOG_TYPE_DEBUG,
70         };
71 
72 	usleep(1); /* make sure duration>0 always */
73         event_send(event, &ctx, "hello");
74 }
75 
get_stats_dist_field(const char * metric_name,enum stats_dist_field field)76 uint64_t get_stats_dist_field(const char *metric_name, enum stats_dist_field field)
77 {
78         struct stats_metrics_iter *iter =
79 		stats_metrics_iterate_init(stats_metrics);
80         const struct metric *metric;
81         while((metric = stats_metrics_iterate(iter)) != NULL)
82                 if (strcmp(metric->name, metric_name) == 0)
83                         break;
84 
85         /* bug in test if not found */
86         i_assert(metric != NULL);
87 
88         stats_metrics_iterate_deinit(&iter);
89 
90         switch(field) {
91         case STATS_DIST_COUNT:
92                 return stats_dist_get_count(metric->duration_stats);
93         case STATS_DIST_SUM:
94                 return stats_dist_get_sum(metric->duration_stats);
95         default:
96                 i_unreached();
97         }
98 }
99 
100