source: mainline/uspace/app/tmon/tests.c@ 84239b1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 84239b1 was 84239b1, checked in by Jiri Svoboda <jiri@…>, 7 years ago

And there was much fixing.

  • Property mode set to 100644
File size: 9.3 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.\n");
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.\n");
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_size = tmon_format_size(params->transfer_size, "%.3f %s");
133 printf("Transfer size: %s\n", str_size);
134 free(str_size);
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 puts("\nTesting... ");
185
186 usbdiag_test_results_t results;
187 errno_t rc = usbdiag_test_in(exch, params, &results);
188 if (rc != EOK) {
189 puts("failed\n");
190 printf(NAME ": %s\n", str_error(rc));
191 return 1;
192 }
193
194 puts("succeeded\n\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 puts("\nTesting... ");
210
211 usbdiag_test_results_t results;
212 errno_t rc = usbdiag_test_out(exch, params, &results);
213 if (rc) {
214 puts("failed\n");
215 printf(NAME ": %s\n", str_error(rc));
216 return 1;
217 }
218
219 puts("succeeded\n\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.