source: mainline/uspace/app/tmon/tests.c@ 98b1d30

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

tmon: refactor to errno_t

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