Tests: Add libusbx stress test
[platform/upstream/libusb.git] / tests / stress.c
1 /*
2  * libusbx stress test program to perform simple stress tests
3  * Copyright © 2012 Toby Gray <toby.gray@realvnc.com>
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19
20 #include <stdio.h>
21 #include <sys/types.h>
22 #include <memory.h>
23
24 #include "libusb.h"
25
26 #include "libusbx_testlib.h"
27
28 /** Test that creates and destroys a single concurrent context
29  * 10000 times. */
30 static libusbx_testlib_result test_init_and_exit(libusbx_testlib_ctx * tctx)
31 {
32         libusb_context * ctx = NULL;
33         int i;
34         for (i = 0; i < 10000; ++i) {
35                 int r = libusb_init(&ctx);
36                 if (r != LIBUSB_SUCCESS) {
37                         libusbx_testlib_logf(tctx,
38                                 "Failed to init libusb on iteration %d: %d",
39                                 i, r);
40                         return TEST_STATUS_FAILURE;
41                 }
42                 libusb_exit(ctx);
43                 ctx = NULL;
44         }
45
46         return TEST_STATUS_SUCCESS;
47 }
48
49 /** Tests that devices can be listed 1000 times. */
50 static libusbx_testlib_result test_get_device_list(libusbx_testlib_ctx * tctx)
51 {
52         libusb_context * ctx = NULL;
53         int r, i;
54         r = libusb_init(&ctx);
55         if (r != LIBUSB_SUCCESS) {
56                 libusbx_testlib_logf(tctx, "Failed to init libusb: %d", r);
57                 return TEST_STATUS_FAILURE;
58         }
59         for (i = 0; i < 1000; ++i) {
60                 libusb_device ** device_list;
61                 ssize_t list_size = libusb_get_device_list(ctx, &device_list);
62                 if (list_size < 0 || device_list == NULL) {
63                         libusbx_testlib_logf(tctx,
64                                 "Failed to get device list on iteration %d: %d (%p)",
65                                 i, -list_size, device_list);
66                         return TEST_STATUS_FAILURE;
67                 }
68                 libusb_free_device_list(device_list, 1);
69         }
70         libusb_exit(ctx);
71         return TEST_STATUS_SUCCESS;
72 }
73
74 /** Tests that 100 concurrent device lists can be open at a time. */
75 static libusbx_testlib_result test_many_device_lists(libusbx_testlib_ctx * tctx)
76 {
77 #define LIST_COUNT 100
78         libusb_context * ctx = NULL;
79         libusb_device ** device_lists[LIST_COUNT];
80         int r, i;
81         memset(device_lists, 0, sizeof(device_lists));
82
83         r = libusb_init(&ctx);
84         if (r != LIBUSB_SUCCESS) {
85                 libusbx_testlib_logf(tctx, "Failed to init libusb: %d", r);
86                 return TEST_STATUS_FAILURE;
87         }
88
89         /* Create the 100 device lists. */
90         for (i = 0; i < LIST_COUNT; ++i) {
91                 ssize_t list_size = libusb_get_device_list(ctx, &(device_lists[i]));
92                 if (list_size < 0 || device_lists[i] == NULL) {
93                         libusbx_testlib_logf(tctx,
94                                 "Failed to get device list on iteration %d: %d (%p)",
95                                 i, -list_size, device_lists[i]);
96                         return TEST_STATUS_FAILURE;
97                 }
98         }
99
100         /* Destroy the 100 device lists. */
101         for (i = 0; i < LIST_COUNT; ++i) {
102                 if (device_lists[i]) {
103                         libusb_free_device_list(device_lists[i], 1);
104                         device_lists[i] = NULL;
105                 }
106         }
107
108         libusb_exit(ctx);
109         return TEST_STATUS_SUCCESS;
110 #undef LIST_COUNT
111 }
112
113 /** Tests that the default context (used for various things including
114  * logging) works correctly when the first context created in a
115  * process is destroyed. */
116 static libusbx_testlib_result test_default_context_change(libusbx_testlib_ctx * tctx)
117 {
118         libusb_context * ctx = NULL;
119         int r, i;
120
121         for (i = 0; i < 100; ++i) {
122                 /* First create a new context */
123                 r = libusb_init(&ctx);
124                 if (r != LIBUSB_SUCCESS) {
125                         libusbx_testlib_logf(tctx, "Failed to init libusb: %d", r);
126                         return TEST_STATUS_FAILURE;
127                 }
128
129                 /* Enable debug output, to be sure to use the context */
130                 libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_DEBUG);
131                 libusb_set_debug(ctx, LIBUSB_LOG_LEVEL_DEBUG);
132
133                 /* Now create a reference to the default context */
134                 r = libusb_init(NULL);
135                 if (r != LIBUSB_SUCCESS) {
136                         libusbx_testlib_logf(tctx, "Failed to init libusb: %d", r);
137                         return TEST_STATUS_FAILURE;
138                 }
139
140                 /* Destroy the first context */
141                 libusb_exit(ctx);
142                 /* Destroy the default context */
143                 libusb_exit(NULL);
144         }
145
146         return TEST_STATUS_SUCCESS;
147 }
148
149 /* Fill in the list of tests. */
150 static const libusbx_testlib_test tests[] = {
151         {"init_and_exit", &test_init_and_exit},
152         {"get_device_list", &test_get_device_list},
153         {"many_device_lists", &test_many_device_lists},
154         {"default_context_change", &test_default_context_change},
155         LIBUSBX_NULL_TEST
156 };
157
158 int main (int argc, char ** argv)
159 {
160         return libusbx_testlib_run_tests(argc, argv, tests);
161 }