From: Aki Tuomi Date: Mon, 9 Dec 2019 17:57:32 +0000 (+0200) Subject: stats: Add unit test for group by X-Git-Tag: 2.3.10~174 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=977edff0d2dafa57f536ae2b65c4e0cd2a7d222a;p=thirdparty%2Fdovecot%2Fcore.git stats: Add unit test for group by --- diff --git a/src/stats/test-client-reader.c b/src/stats/test-client-reader.c index 3565708e97..77aeb9f2ee 100644 --- a/src/stats/test-client-reader.c +++ b/src/stats/test-client-reader.c @@ -122,6 +122,96 @@ static void test_client_reader(void) test_end(); } +static const char *settings_blob_2 = +"metric=test\n" +"metric/test/name=test\n" +"metric/test/event_name=test\n" +"metric/test/group_by=test_name\n" +"\n"; + +static int +test_reader_server_input_args_group_by(struct connection *conn, + const char *const *args) +{ + struct test_connection *tconn = + container_of(conn, struct test_connection, conn); + + if (args[0] == NULL) + return -1; + + tconn->row_count++; + + if (tconn->row_count == 1) { + test_assert_strcmp(args[0], "test"); + test_assert_strcmp(args[1], "1"); + } else if (tconn->row_count == 2) { + test_assert_strcmp(args[0], "test_alpha"); + test_assert_strcmp(args[1], "1"); + } + return 1; +} + +static void test_dump_metrics_group_by(void) +{ + int fds[2]; + + test_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, fds) == 0); + + struct test_connection *conn = i_new(struct test_connection, 1); + + struct ioloop *loop = io_loop_create(); + + client_reader_create(fds[1], metrics); + connection_init_client_fd(conn_list, &conn->conn, "stats", fds[0], fds[0]); + o_stream_nsend_str(conn->conn.output, "DUMP\tcount\n"); + + io_loop_run(loop); + connection_deinit(&conn->conn); + i_free(conn); + + io_loop_set_running(loop); + io_loop_handler_run(loop); + + io_loop_destroy(&loop); +} + +static void test_client_reader_group_by(void) +{ + const struct connection_vfuncs client_vfuncs = { + .input_args = test_reader_server_input_args_group_by, + .destroy = test_reader_server_destroy, + }; + + test_begin("client reader (group by)"); + + /* register some stats */ + test_init(settings_blob_2); + + client_readers_init(); + conn_list = connection_list_init(&client_set, &client_vfuncs); + + /* push event in */ + struct event *event = event_create(NULL); + event_add_category(event, &test_category); + event_set_name(event, "test"); + event_add_str(event, "event_name", "alpha"); + test_event_send(event); + event_unref(&event); + + test_assert(get_stats_dist_field("test", STATS_DIST_COUNT) == 1); + test_assert(get_stats_dist_field("test", STATS_DIST_SUM) > 0); + + /* check output from reader */ + test_dump_metrics_group_by(); + + test_deinit(); + + client_readers_deinit(); + connection_list_deinit(&conn_list); + + test_end(); +} + int main(void) { /* fake master service to pretend destroying connections. */ @@ -132,6 +222,7 @@ int main(void) { }; void (*const test_functions[])(void) = { test_client_reader, + test_client_reader_group_by, NULL }; diff --git a/src/stats/test-stats-metrics.c b/src/stats/test-stats-metrics.c index 90b935a7e3..7295231bf2 100644 --- a/src/stats/test-stats-metrics.c +++ b/src/stats/test-stats-metrics.c @@ -1,6 +1,7 @@ /* Copyright (c) 2019 Dovecot authors, see the included COPYING file */ #include "test-stats-common.h" +#include "array.h" bool test_stats_callback(struct event *event, enum event_callback_type type ATTR_UNUSED, @@ -89,10 +90,97 @@ static void test_stats_metrics_filter(void) test_end(); } +static const char *settings_blob_3 = +"metric=test\n" +"metric/test/name=test\n" +"metric/test/event_name=test\n" +"metric/test/group_by=test_name sub_name\n" +"\n"; + +static void test_stats_metrics_group_by(void) +{ + test_begin("stats metrics (group by)"); + + test_init(settings_blob_3); + + struct event *event; + + event = event_create(NULL); + event_add_category(event, &test_category); + event_set_name(event, "test"); + event_add_str(event, "test_name", "alpha"); + event_add_str(event, "sub_name", "eta"); + test_event_send(event); + event_unref(&event); + + event = event_create(NULL); + event_add_category(event, &test_category); + event_set_name(event, "test"); + event_add_str(event, "test_name", "phi"); + event_add_str(event, "sub_name", "beta"); + test_event_send(event); + event_unref(&event); + + event = event_create(NULL); + event_add_category(event, &test_category); + event_set_name(event, "test"); + event_add_str(event, "test_name", "omega"); + event_add_str(event, "sub_name", "pi"); + test_event_send(event); + event_unref(&event); + + /* we should have now three events */ + test_assert(get_stats_dist_field("test", STATS_DIST_COUNT) == 3); + + /* analyze the structure */ + const struct metric *root_metric, *leaf ATTR_UNUSED; + struct metric *const *children; + struct stats_metrics_iter *iter = stats_metrics_iterate_init(metrics); + root_metric = stats_metrics_iterate(iter); + stats_metrics_iterate_deinit(&iter); + + test_assert(array_is_created(&root_metric->sub_metrics)); + test_assert(array_count(&root_metric->sub_metrics) == 3); + + /* then look at each level */ + children = array_idx(&root_metric->sub_metrics, 0); + test_assert_strcmp(children[0]->sub_name, "alpha"); + test_assert(stats_dist_get_count(children[0]->duration_stats) == 1); + + test_assert(array_is_created(&children[0]->sub_metrics)); + test_assert(array_count(&children[0]->sub_metrics) == 1); + + leaf = *array_idx(&children[0]->sub_metrics, 0); + test_assert_strcmp(leaf->sub_name, "eta"); + test_assert(stats_dist_get_count(leaf->duration_stats) == 1); + + test_assert_strcmp(children[1]->sub_name, "phi"); + + test_assert(array_is_created(&children[1]->sub_metrics)); + test_assert(array_count(&children[1]->sub_metrics) == 1); + + leaf = *array_idx(&children[1]->sub_metrics, 0); + test_assert_strcmp(leaf->sub_name, "beta"); + test_assert(stats_dist_get_count(leaf->duration_stats) == 1); + + test_assert_strcmp(children[2]->sub_name, "omega"); + + test_assert(array_is_created(&children[2]->sub_metrics)); + test_assert(array_count(&children[2]->sub_metrics) == 1); + + leaf = *array_idx(&children[2]->sub_metrics, 0); + test_assert_strcmp(leaf->sub_name, "pi"); + test_assert(stats_dist_get_count(leaf->duration_stats) == 1); + + test_deinit(); + test_end(); +} + int main(void) { void (*const test_functions[])(void) = { test_stats_metrics, test_stats_metrics_filter, + test_stats_metrics_group_by, NULL };