source: mainline/uspace/app/tmon/tests.c@ 08e103d4

Last change on this file since 08e103d4 was 08e103d4, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

Use clearer naming for string length functions

This and the following commit change the names of functions, as well as
their documentation, to use unambiguous terms "bytes" and "code points"
instead of ambiguous terms "size", "length", and "characters".

  • Property mode set to 100644
File size: 9.4 KB
Line 
1/*
2 * Copyright (c) 2017 Petr Manek
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup tmon
30 * @{
31 */
32/**
33 * @file
34 * USB tests.
35 */
36
37#include <stdio.h>
38#include <errno.h>
39#include <str.h>
40#include <str_error.h>
41#include <getopt.h>
42#include <usb/usb.h>
43#include <usbdiag_iface.h>
44#include "commands.h"
45#include "tf.h"
46
47#define NAME "tmon"
48#define INDENT " "
49
50/** Static array of long options, from which test parameters are parsed. */
51static struct option long_options[] = {
52 { "duration", required_argument, NULL, 't' },
53 { "size", required_argument, NULL, 's' },
54 { "validate", required_argument, NULL, 'v' },
55 { 0, 0, NULL, 0 }
56};
57
58/** String of short options, from which test parameters are parsed. */
59static const char *short_options = "t:s:v";
60
61/** Common option parser for all tests.
62 * @param[in] argc Number of arguments.
63 * @param[in] argv Argument values. Must point to exactly `argc` strings.
64 * @param[out] params Parsed test parameters (if successful).
65 *
66 * @return EOK if successful (in such case caller becomes the owner of `params`).
67 */
68static errno_t read_params(int argc, char *argv[], void **params)
69{
70 errno_t rc;
71 usbdiag_test_params_t *p = (usbdiag_test_params_t *) malloc(sizeof(usbdiag_test_params_t));
72 if (!p)
73 return ENOMEM;
74
75 // Default values.
76 p->transfer_size = 0;
77 p->min_duration = 5000;
78 p->validate_data = false;
79
80 // Parse other than default values.
81 int c;
82 uint32_t duration_uint;
83 c = 0;
84 optreset = 1;
85 optind = 0;
86 while (c != -1) {
87 c = getopt_long(argc, argv, short_options, long_options, NULL);
88 switch (c) {
89 case -1:
90 break;
91 case 'v':
92 p->validate_data = true;
93 break;
94 case 't':
95 if (!optarg || str_uint32_t(optarg, NULL, 10, false, &duration_uint) != EOK) {
96 puts(NAME ": Invalid duration.");
97 rc = EINVAL;
98 goto err_malloc;
99 }
100 p->min_duration = (usbdiag_dur_t) duration_uint * 1000;
101 break;
102 case 's':
103 if (!optarg || str_size_t(optarg, NULL, 10, false, &p->transfer_size) != EOK) {
104 puts(NAME ": Invalid data size.");
105 rc = EINVAL;
106 goto err_malloc;
107 }
108 break;
109 }
110 }
111
112 *params = (void *) p;
113 return EOK;
114
115err_malloc:
116 free(p);
117 *params = NULL;
118 return rc;
119}
120
121/** Print test parameters.
122 * @param[in] params Test parameters to print.
123 */
124static void print_params(const usbdiag_test_params_t *params)
125{
126 printf("Endpoint type: %s\n", usb_str_transfer_type(params->transfer_type));
127 char *str_min_duration = tmon_format_duration(params->min_duration, "%.3f %s");
128 printf("Min. duration: %s\n", str_min_duration);
129 free(str_min_duration);
130
131 if (params->transfer_size) {
132 char *str_bytes = tmon_format_size(params->transfer_size, "%.3f %s");
133 printf("Transfer size: %s\n", str_bytes);
134 free(str_bytes);
135 } else {
136 printf("Transfer size: (max. transfer size)\n");
137 }
138
139 printf("Validate data: %s\n", params->validate_data ? "yes" : "no");
140}
141
142/** Print test results.
143 * @param[in] params Test parameters.
144 * @param[in] results Test results.
145 */
146static void print_results(const usbdiag_test_params_t *params, const usbdiag_test_results_t *results)
147{
148 printf("Transfers performed: %u\n", results->transfer_count);
149
150 char *str_total_duration = tmon_format_duration(results->act_duration, "%.3f %s");
151 printf("Total duration: %s\n", str_total_duration);
152 free(str_total_duration);
153
154 char *str_size_per_transfer = tmon_format_size(results->transfer_size, "%.3f %s");
155 printf("Transfer size: %s\n", str_size_per_transfer);
156 free(str_size_per_transfer);
157
158 const size_t total_size = results->transfer_size * results->transfer_count;
159 char *str_total_size = tmon_format_size(total_size, "%.3f %s");
160 printf("Total size: %s\n", str_total_size);
161 free(str_total_size);
162
163 const double dur_per_transfer = (double) results->act_duration / (double) results->transfer_count;
164 char *str_dur_per_transfer = tmon_format_duration(dur_per_transfer, "%.3f %s");
165 printf("Avg. transfer duration: %s\n", str_dur_per_transfer);
166 free(str_dur_per_transfer);
167
168 const double speed = 1000.0 * (double) total_size / (double) results->act_duration;
169 char *str_speed = tmon_format_size(speed, "%.3f %s/s");
170 printf("Avg. speed: %s\n", str_speed);
171 free(str_speed);
172}
173
174/** Run test on "in" endpoint.
175 * @param[in] exch Open async exchange with the diagnostic device.
176 * @param[in] generic_params Test parameters. Must point to 'usbdiag_test_params_t'.
177 *
178 * @return Exit code
179 */
180static int test_in(async_exch_t *exch, const void *generic_params)
181{
182 const usbdiag_test_params_t *params = (usbdiag_test_params_t *) generic_params;
183 print_params(params);
184 fputs("\nTesting... ", stdout);
185
186 usbdiag_test_results_t results;
187 errno_t rc = usbdiag_test_in(exch, params, &results);
188 if (rc != EOK) {
189 puts("failed");
190 printf(NAME ": %s\n", str_error(rc));
191 return 1;
192 }
193
194 puts("succeeded\n");
195 print_results(params, &results);
196 return 0;
197}
198
199/** Run test on "out" endpoint.
200 * @param[in] exch Open async exchange with the diagnostic device.
201 * @param[in] generic_params Test parameters. Must point to 'usbdiag_test_params_t'.
202 *
203 * @return Exit code
204 */
205static int test_out(async_exch_t *exch, const void *generic_params)
206{
207 const usbdiag_test_params_t *params = (usbdiag_test_params_t *) generic_params;
208 print_params(params);
209 fputs("\nTesting... ", stdout);
210
211 usbdiag_test_results_t results;
212 errno_t rc = usbdiag_test_out(exch, params, &results);
213 if (rc) {
214 puts("failed");
215 printf(NAME ": %s\n", str_error(rc));
216 return 1;
217 }
218
219 puts("succeeded\n");
220 print_results(params, &results);
221 return 0;
222}
223
224#define GEN_PRE_RUN(FN, TYPE) \
225 static int pre_run_##FN(void *generic_params) \
226 { \
227 usbdiag_test_params_t *params = (usbdiag_test_params_t *) generic_params; \
228 params->transfer_type = USB_TRANSFER_##TYPE; \
229 return EOK; \
230 }
231
232GEN_PRE_RUN(intr, INTERRUPT);
233GEN_PRE_RUN(bulk, BULK);
234GEN_PRE_RUN(isoch, ISOCHRONOUS);
235
236#undef GEN_PRE_RUN
237
238/** Interrupt in test command handler.
239 * @param[in] argc Number of arguments.
240 * @param[in] argv Argument values. Must point to exactly `argc` strings.
241 *
242 * @return Exit code
243 */
244int tmon_test_intr_in(int argc, char *argv[])
245{
246 static const tmon_test_ops_t ops = {
247 .pre_run = pre_run_intr,
248 .run = test_in,
249 .read_params = read_params
250 };
251
252 return tmon_test_main(argc, argv, &ops);
253}
254
255/** Interrupt out test command handler.
256 * @param[in] argc Number of arguments.
257 * @param[in] argv Argument values. Must point to exactly `argc` strings.
258 *
259 * @return Exit code
260 */
261int tmon_test_intr_out(int argc, char *argv[])
262{
263 static const tmon_test_ops_t ops = {
264 .pre_run = pre_run_intr,
265 .run = test_out,
266 .read_params = read_params
267 };
268
269 return tmon_test_main(argc, argv, &ops);
270}
271
272/** Interrupt bulk test command handler.
273 * @param[in] argc Number of arguments.
274 * @param[in] argv Argument values. Must point to exactly `argc` strings.
275 *
276 * @return Exit code
277 */
278int tmon_test_bulk_in(int argc, char *argv[])
279{
280 static const tmon_test_ops_t ops = {
281 .pre_run = pre_run_bulk,
282 .run = test_in,
283 .read_params = read_params
284 };
285
286 return tmon_test_main(argc, argv, &ops);
287}
288
289/** Bulk out test command handler.
290 * @param[in] argc Number of arguments.
291 * @param[in] argv Argument values. Must point to exactly `argc` strings.
292 *
293 * @return Exit code
294 */
295int tmon_test_bulk_out(int argc, char *argv[])
296{
297 static const tmon_test_ops_t ops = {
298 .pre_run = pre_run_bulk,
299 .run = test_out,
300 .read_params = read_params
301 };
302
303 return tmon_test_main(argc, argv, &ops);
304}
305
306/** Isochronous in test command handler.
307 * @param[in] argc Number of arguments.
308 * @param[in] argv Argument values. Must point to exactly `argc` strings.
309 *
310 * @return Exit code
311 */
312int tmon_test_isoch_in(int argc, char *argv[])
313{
314 static const tmon_test_ops_t ops = {
315 .pre_run = pre_run_isoch,
316 .run = test_in,
317 .read_params = read_params
318 };
319
320 return tmon_test_main(argc, argv, &ops);
321}
322
323/** Isochronous out test command handler.
324 * @param[in] argc Number of arguments.
325 * @param[in] argv Argument values. Must point to exactly `argc` strings.
326 *
327 * @return Exit code
328 */
329int tmon_test_isoch_out(int argc, char *argv[])
330{
331 static const tmon_test_ops_t ops = {
332 .pre_run = pre_run_isoch,
333 .run = test_out,
334 .read_params = read_params
335 };
336
337 return tmon_test_main(argc, argv, &ops);
338}
339
340/** @}
341 */
Note: See TracBrowser for help on using the repository browser.