diff options
Diffstat (limited to 'src/lib/testing/testing_api_cmd_stat.c')
-rw-r--r-- | src/lib/testing/testing_api_cmd_stat.c | 161 |
1 files changed, 161 insertions, 0 deletions
diff --git a/src/lib/testing/testing_api_cmd_stat.c b/src/lib/testing/testing_api_cmd_stat.c new file mode 100644 index 000000000..f751a01d0 --- /dev/null +++ b/src/lib/testing/testing_api_cmd_stat.c | |||
@@ -0,0 +1,161 @@ | |||
1 | /* | ||
2 | This file is part of GNUnet | ||
3 | (C) 2018, 2024 GNUnet e.V. | ||
4 | |||
5 | GNUnet is free software; you can redistribute it and/or modify | ||
6 | it under the terms of the GNU General Public License as | ||
7 | published by the Free Software Foundation; either version 3, or | ||
8 | (at your option) any later version. | ||
9 | |||
10 | GNUnet is distributed in the hope that it will be useful, but | ||
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
13 | GNU General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU General Public | ||
16 | License along with GNUnet; see the file COPYING. If not, see | ||
17 | <http://www.gnu.org/licenses/> | ||
18 | */ | ||
19 | /** | ||
20 | * @file testing/testing_api_cmd_stat.c | ||
21 | * @brief command(s) to get performance statistics on other commands | ||
22 | * @author Christian Grothoff | ||
23 | */ | ||
24 | #include "platform.h" | ||
25 | #include "gnunet_testing_lib.h" | ||
26 | #include "testing_api_cmd_batch.h" | ||
27 | |||
28 | /** | ||
29 | * Run a "stat" CMD. | ||
30 | * | ||
31 | * @param cls closure. | ||
32 | * @param is the interpreter state. | ||
33 | */ | ||
34 | static void | ||
35 | stat_run (void *cls, | ||
36 | struct GNUNET_TESTING_Interpreter *is); | ||
37 | |||
38 | |||
39 | /** | ||
40 | * Add the time @a cmd took to the respective duration in @a timings. | ||
41 | * | ||
42 | * @param timings where to add up times | ||
43 | * @param cmd command to evaluate | ||
44 | */ | ||
45 | static void | ||
46 | stat_cmd (struct GNUNET_TESTING_Timer *timings, | ||
47 | const struct GNUNET_TESTING_Command *cmd) | ||
48 | { | ||
49 | struct GNUNET_TIME_Relative duration; | ||
50 | struct GNUNET_TIME_Relative lat; | ||
51 | |||
52 | if (GNUNET_TIME_absolute_cmp (cmd->start_time, | ||
53 | >, | ||
54 | cmd->finish_time)) | ||
55 | { | ||
56 | /* This is a problem, except of course for | ||
57 | this command itself, as we clearly did not yet | ||
58 | finish... */ | ||
59 | if (cmd->run != &stat_run) | ||
60 | { | ||
61 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
62 | "Bad timings for `%s'\n", | ||
63 | cmd->label.value); | ||
64 | GNUNET_break (0); | ||
65 | } | ||
66 | return; | ||
67 | } | ||
68 | duration = GNUNET_TIME_absolute_get_difference (cmd->start_time, | ||
69 | cmd->finish_time); | ||
70 | lat = GNUNET_TIME_absolute_get_difference (cmd->last_req_time, | ||
71 | cmd->finish_time); | ||
72 | for (unsigned int i = 0; | ||
73 | NULL != timings[i].prefix; | ||
74 | i++) | ||
75 | { | ||
76 | if (0 == strncmp (timings[i].prefix, | ||
77 | cmd->label.value, | ||
78 | strlen (timings[i].prefix))) | ||
79 | { | ||
80 | timings[i].total_duration | ||
81 | = GNUNET_TIME_relative_add (duration, | ||
82 | timings[i].total_duration); | ||
83 | timings[i].success_latency | ||
84 | = GNUNET_TIME_relative_add (lat, | ||
85 | timings[i].success_latency); | ||
86 | timings[i].num_commands++; | ||
87 | timings[i].num_retries += cmd->num_tries; | ||
88 | break; | ||
89 | } | ||
90 | } | ||
91 | } | ||
92 | |||
93 | |||
94 | /** | ||
95 | * Obtain statistics for @a timings of @a cmd | ||
96 | * | ||
97 | * @param[in,out] cls what timings to get | ||
98 | * @param cmd command to process | ||
99 | */ | ||
100 | static void | ||
101 | do_stat (void *cls, | ||
102 | const struct GNUNET_TESTING_Command *cmd) | ||
103 | { | ||
104 | struct GNUNET_TESTING_Timer *timings = cls; | ||
105 | |||
106 | if (GNUNET_TESTING_cmd_is_batch_ (cmd)) | ||
107 | { | ||
108 | struct GNUNET_TESTING_Command **bcmd; | ||
109 | |||
110 | if (GNUNET_OK != | ||
111 | GNUNET_TESTING_get_trait_batch_cmds (cmd, | ||
112 | &bcmd)) | ||
113 | { | ||
114 | GNUNET_break (0); | ||
115 | return; | ||
116 | } | ||
117 | for (unsigned int j = 0; | ||
118 | NULL != (*bcmd)[j].run; | ||
119 | j++) | ||
120 | do_stat (timings, | ||
121 | &(*bcmd)[j]); | ||
122 | return; | ||
123 | } | ||
124 | stat_cmd (timings, | ||
125 | cmd); | ||
126 | } | ||
127 | |||
128 | |||
129 | /** | ||
130 | * Run a "stat" CMD. | ||
131 | * | ||
132 | * @param cls closure. | ||
133 | * @param cmd the command being run. | ||
134 | * @param is the interpreter state. | ||
135 | */ | ||
136 | static void | ||
137 | stat_run (void *cls, | ||
138 | struct GNUNET_TESTING_Interpreter *is) | ||
139 | { | ||
140 | struct GNUNET_TESTING_Timer *timings = cls; | ||
141 | |||
142 | GNUNET_TESTING_interpreter_commands_iterate (is, | ||
143 | true, | ||
144 | &do_stat, | ||
145 | timings); | ||
146 | } | ||
147 | |||
148 | |||
149 | struct GNUNET_TESTING_Command | ||
150 | GNUNET_TESTING_cmd_stat (const char *label, | ||
151 | struct GNUNET_TESTING_Timer *timers) | ||
152 | { | ||
153 | return GNUNET_TESTING_command_new ((void *) timers, | ||
154 | label, | ||
155 | &stat_run, | ||
156 | NULL, | ||
157 | NULL); | ||
158 | } | ||
159 | |||
160 | |||
161 | /* end of testing_api_cmd_stat.c */ | ||