source: mainline/uspace/app/tmon/tests.c@ 3b5a5e3

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3b5a5e3 was 3b5a5e3, checked in by Petr Manek <petr.manek@…>, 8 years ago

tmon: catch up with libdrv changes, simplify code

  • 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_error.h>
40#include <getopt.h>
41#include <usb/usb.h>
42#include <usbdiag_iface.h>
43#include "commands.h"
44#include "tf.h"
45
46#define NAME "tmon"
47#define INDENT " "
48
49/** Static array of long options, from which test parameters are parsed. */
50static struct option long_options[] = {
51 {"duration", required_argument, NULL, 't'},
52 {"size", required_argument, NULL, 's'},
53 {"validate", required_argument, NULL, 'v'},
54 {0, 0, NULL, 0}
55};
56
57/** String of short options, from which test parameters are parsed. */
58static const char *short_options = "t:s:v";
59
60/** Common option parser for all tests.
61 * @param[in] argc Number of arguments.
62 * @param[in] argv Argument values. Must point to exactly `argc` strings.
63 * @param[out] params Parsed test parameters (if successful).
64 *
65 * @return EOK if successful (in such case caller becomes the owner of `params`).
66 */
67static int read_params(int argc, char *argv[], void **params)
68{
69 int rc;
70 usbdiag_test_params_t *p = (usbdiag_test_params_t *) malloc(sizeof(usbdiag_test_params_t));
71 if (!p)
72 return ENOMEM;
73
74 // Default values.
75 p->transfer_size = 0;
76 p->min_duration = 5000;
77 p->validate_data = false;
78
79 // Parse other than default values.
80 int c;
81 uint32_t duration_uint;
82 for (c = 0, optreset = 1, optind = 0; c != -1;) {
83 c = getopt_long(argc, argv, short_options, long_options, NULL);
84 switch (c) {
85 case -1:
86 break;
87 case 'v':
88 p->validate_data = true;
89 break;
90 case 't':
91 if (!optarg || str_uint32_t(optarg, NULL, 10, false, &duration_uint) != EOK) {
92 puts(NAME ": Invalid duration.\n");
93 rc = EINVAL;
94 goto err_malloc;
95 }
96 p->min_duration = (usbdiag_dur_t) duration_uint * 1000;
97 break;
98 case 's':
99 if (!optarg || str_size_t(optarg, NULL, 10, false, &p->transfer_size) != EOK) {
100 puts(NAME ": Invalid data size.\n");
101 rc = EINVAL;
102 goto err_malloc;
103 }
104 break;
105 }
106 }
107
108 *params = (void *) p;
109 return EOK;
110
111err_malloc:
112 free(p);
113 *params = NULL;
114 return rc;
115}
116
117/** Print test parameters.
118 * @param[in] params Test parameters to print.
119 */
120static void print_params(const usbdiag_test_params_t *params)
121{
122 printf("Endpoint type: %s\n", usb_str_transfer_type(params->transfer_type));
123 char *str_min_duration = tmon_format_duration(params->min_duration, "%.3f %s");
124 printf("Min. duration: %s\n", str_min_duration);
125 free(str_min_duration);
126
127 if (params->transfer_size) {
128 char *str_size = tmon_format_size(params->transfer_size, "%.3f %s");
129 printf("Transfer size: %s\n", str_size);
130 free(str_size);
131 } else {
132 printf("Transfer size: (max. transfer size)\n");
133 }
134
135 printf("Validate data: %s\n", params->validate_data ? "yes" : "no");
136}
137
138/** Print test results.
139 * @param[in] params Test parameters.
140 * @param[in] results Test results.
141 */
142static void print_results(const usbdiag_test_params_t *params, const usbdiag_test_results_t *results)
143{
144 printf("Transfers performed: %u\n", results->transfer_count);
145
146 char *str_total_duration = tmon_format_duration(results->act_duration, "%.3f %s");
147 printf("Total duration: %s\n", str_total_duration);
148 free(str_total_duration);
149
150 char *str_size_per_transfer = tmon_format_size(results->transfer_size, "%.3f %s");
151 printf("Transfer size: %s\n", str_size_per_transfer);
152 free(str_size_per_transfer);
153
154 const size_t total_size = results->transfer_size * results->transfer_count;
155 char *str_total_size = tmon_format_size(total_size, "%.3f %s");
156 printf("Total size: %s\n", str_total_size);
157 free(str_total_size);
158
159 const double dur_per_transfer = (double) results->act_duration / (double) results->transfer_count;
160 char *str_dur_per_transfer = tmon_format_duration(dur_per_transfer, "%.3f %s");
161 printf("Avg. transfer duration: %s\n", str_dur_per_transfer);
162 free(str_dur_per_transfer);
163
164 const double speed = 1000.0 * (double) total_size / (double) results->act_duration;
165 char *str_speed = tmon_format_size(speed, "%.3f %s/s");
166 printf("Avg. speed: %s\n", str_speed);
167 free(str_speed);
168}
169
170/** Run test on "in" endpoint.
171 * @param[in] exch Open async exchange with the diagnostic device.
172 * @param[in] generic_params Test parameters. Must point to 'usbdiag_test_params_t'.
173 *
174 * @return Exit code
175 */
176static int test_in(async_exch_t *exch, const void *generic_params)
177{
178 const usbdiag_test_params_t *params = (usbdiag_test_params_t *) generic_params;
179 print_params(params);
180 puts("\nTesting... ");
181
182 usbdiag_test_results_t results;
183 int rc = usbdiag_test_in(exch, params, &results);
184 if (rc != EOK) {
185 puts("failed\n");
186 printf(NAME ": %s\n", str_error(rc));
187 return 1;
188 }
189
190 puts("succeeded\n\n");
191 print_results(params, &results);
192 return 0;
193}
194
195/** Run test on "out" endpoint.
196 * @param[in] exch Open async exchange with the diagnostic device.
197 * @param[in] generic_params Test parameters. Must point to 'usbdiag_test_params_t'.
198 *
199 * @return Exit code
200 */
201static int test_out(async_exch_t *exch, const void *generic_params)
202{
203 const usbdiag_test_params_t *params = (usbdiag_test_params_t *) generic_params;
204 print_params(params);
205 puts("\nTesting... ");
206
207 usbdiag_test_results_t results;
208 int rc = usbdiag_test_out(exch, params, &results);
209 if (rc) {
210 puts("failed\n");
211 printf(NAME ": %s\n", str_error(rc));
212 return 1;
213 }
214
215 puts("succeeded\n\n");
216 print_results(params, &results);
217 return 0;
218}
219
220#define GEN_PRE_RUN(FN, TYPE) \
221 static int pre_run_##FN(void *generic_params) \
222 { \
223 usbdiag_test_params_t *params = (usbdiag_test_params_t *) generic_params; \
224 params->transfer_type = USB_TRANSFER_##TYPE; \
225 return EOK; \
226 }
227
228GEN_PRE_RUN(intr, INTERRUPT)
229GEN_PRE_RUN(bulk, BULK)
230GEN_PRE_RUN(isoch, ISOCHRONOUS)
231
232#undef GEN_PRE_RUN
233
234/** Interrupt in test command handler.
235 * @param[in] argc Number of arguments.
236 * @param[in] argv Argument values. Must point to exactly `argc` strings.
237 *
238 * @return Exit code
239 */
240int tmon_test_intr_in(int argc, char *argv[])
241{
242 static const tmon_test_ops_t ops = {
243 .pre_run = pre_run_intr,
244 .run = test_in,
245 .read_params = read_params
246 };
247
248 return tmon_test_main(argc, argv, &ops);
249}
250
251/** Interrupt out test command handler.
252 * @param[in] argc Number of arguments.
253 * @param[in] argv Argument values. Must point to exactly `argc` strings.
254 *
255 * @return Exit code
256 */
257int tmon_test_intr_out(int argc, char *argv[])
258{
259 static const tmon_test_ops_t ops = {
260 .pre_run = pre_run_intr,
261 .run = test_out,
262 .read_params = read_params
263 };
264
265 return tmon_test_main(argc, argv, &ops);
266}
267
268/** Interrupt bulk test command handler.
269 * @param[in] argc Number of arguments.
270 * @param[in] argv Argument values. Must point to exactly `argc` strings.
271 *
272 * @return Exit code
273 */
274int tmon_test_bulk_in(int argc, char *argv[])
275{
276 static const tmon_test_ops_t ops = {
277 .pre_run = pre_run_bulk,
278 .run = test_in,
279 .read_params = read_params
280 };
281
282 return tmon_test_main(argc, argv, &ops);
283}
284
285/** Bulk out test command handler.
286 * @param[in] argc Number of arguments.
287 * @param[in] argv Argument values. Must point to exactly `argc` strings.
288 *
289 * @return Exit code
290 */
291int tmon_test_bulk_out(int argc, char *argv[])
292{
293 static const tmon_test_ops_t ops = {
294 .pre_run = pre_run_bulk,
295 .run = test_out,
296 .read_params = read_params
297 };
298
299 return tmon_test_main(argc, argv, &ops);
300}
301
302/** Isochronous in test command handler.
303 * @param[in] argc Number of arguments.
304 * @param[in] argv Argument values. Must point to exactly `argc` strings.
305 *
306 * @return Exit code
307 */
308int tmon_test_isoch_in(int argc, char *argv[])
309{
310 static const tmon_test_ops_t ops = {
311 .pre_run = pre_run_isoch,
312 .run = test_in,
313 .read_params = read_params
314 };
315
316 return tmon_test_main(argc, argv, &ops);
317}
318
319/** Isochronous out test command handler.
320 * @param[in] argc Number of arguments.
321 * @param[in] argv Argument values. Must point to exactly `argc` strings.
322 *
323 * @return Exit code
324 */
325int tmon_test_isoch_out(int argc, char *argv[])
326{
327 static const tmon_test_ops_t ops = {
328 .pre_run = pre_run_isoch,
329 .run = test_out,
330 .read_params = read_params
331 };
332
333 return tmon_test_main(argc, argv, &ops);
334}
335
336/** @}
337 */
Note: See TracBrowser for help on using the repository browser.