xusb: add check for interface kernel driver
[platform/upstream/libusb.git] / tests / stress.c
1 /*
2  * libusb 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 <config.h>
21
22 #include <string.h>
23
24 #include "libusb.h"
25 #include "libusb_testlib.h"
26
27 /** Test that creates and destroys a single concurrent context
28  * 10000 times. */
29 static libusb_testlib_result test_init_and_exit(void)
30 {
31         for (int i = 0; i < 10000; ++i) {
32                 libusb_context *ctx = NULL;
33                 int r;
34
35                 r = libusb_init(&ctx);
36                 if (r != LIBUSB_SUCCESS) {
37                         libusb_testlib_logf(
38                                 "Failed to init libusb on iteration %d: %d",
39                                 i, r);
40                         return TEST_STATUS_FAILURE;
41                 }
42                 libusb_exit(ctx);
43         }
44
45         return TEST_STATUS_SUCCESS;
46 }
47
48 /** Tests that devices can be listed 1000 times. */
49 static libusb_testlib_result test_get_device_list(void)
50 {
51         libusb_context *ctx;
52         int r;
53
54         r = libusb_init(&ctx);
55         if (r != LIBUSB_SUCCESS) {
56                 libusb_testlib_logf("Failed to init libusb: %d", r);
57                 return TEST_STATUS_FAILURE;
58         }
59
60         for (int i = 0; i < 1000; ++i) {
61                 libusb_device **device_list = NULL;
62                 ssize_t list_size = libusb_get_device_list(ctx, &device_list);
63                 if (list_size < 0 || !device_list) {
64                         libusb_testlib_logf(
65                                 "Failed to get device list on iteration %d: %ld (%p)",
66                                 i, (long)-list_size, device_list);
67                         libusb_exit(ctx);
68                         return TEST_STATUS_FAILURE;
69                 }
70                 libusb_free_device_list(device_list, 1);
71         }
72
73         libusb_exit(ctx);
74         return TEST_STATUS_SUCCESS;
75 }
76
77 /** Tests that 100 concurrent device lists can be open at a time. */
78 static libusb_testlib_result test_many_device_lists(void)
79 {
80 #define LIST_COUNT 100
81         libusb_testlib_result result = TEST_STATUS_SUCCESS;
82         libusb_context *ctx = NULL;
83         libusb_device **device_lists[LIST_COUNT];
84         int r;
85
86         r = libusb_init(&ctx);
87         if (r != LIBUSB_SUCCESS) {
88                 libusb_testlib_logf("Failed to init libusb: %d", r);
89                 return TEST_STATUS_FAILURE;
90         }
91
92         memset(device_lists, 0, sizeof(device_lists));
93
94         /* Create the 100 device lists. */
95         for (int i = 0; i < LIST_COUNT; ++i) {
96                 ssize_t list_size = libusb_get_device_list(ctx, &device_lists[i]);
97                 if (list_size < 0 || !device_lists[i]) {
98                         libusb_testlib_logf(
99                                 "Failed to get device list on iteration %d: %ld (%p)",
100                                 i, (long)-list_size, device_lists[i]);
101                         result = TEST_STATUS_FAILURE;
102                         break;
103                 }
104         }
105
106         /* Destroy the 100 device lists. */
107         for (int i = 0; i < LIST_COUNT; ++i) {
108                 if (device_lists[i])
109                         libusb_free_device_list(device_lists[i], 1);
110         }
111
112         libusb_exit(ctx);
113         return result;
114 #undef LIST_COUNT
115 }
116
117 /** Tests that the default context (used for various things including
118  * logging) works correctly when the first context created in a
119  * process is destroyed. */
120 static libusb_testlib_result test_default_context_change(void)
121 {
122         for (int i = 0; i < 100; ++i) {
123                 libusb_context *ctx = NULL;
124                 int r;
125
126                 /* First create a new context */
127                 r = libusb_init(&ctx);
128                 if (r != LIBUSB_SUCCESS) {
129                         libusb_testlib_logf("Failed to init libusb: %d", r);
130                         return TEST_STATUS_FAILURE;
131                 }
132
133                 /* Enable debug output on new context, to be sure to use the context */
134                 libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG);
135
136                 /* Enable debug outout on the default context. This should work even before
137                  * the context has been created. */
138                 libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG);
139
140                 /* Now create a reference to the default context */
141                 r = libusb_init(NULL);
142                 if (r != LIBUSB_SUCCESS) {
143                         libusb_testlib_logf("Failed to init libusb: %d", r);
144                         libusb_exit(ctx);
145                         return TEST_STATUS_FAILURE;
146                 }
147
148                 /* Destroy the first context */
149                 libusb_exit(ctx);
150                 /* Destroy the default context */
151                 libusb_exit(NULL);
152         }
153
154         return TEST_STATUS_SUCCESS;
155 }
156
157 /* Fill in the list of tests. */
158 static const libusb_testlib_test tests[] = {
159         { "init_and_exit", &test_init_and_exit },
160         { "get_device_list", &test_get_device_list },
161         { "many_device_lists", &test_many_device_lists },
162         { "default_context_change", &test_default_context_change },
163         LIBUSB_NULL_TEST
164 };
165
166 int main(int argc, char *argv[])
167 {
168         return libusb_testlib_run_tests(argc, argv, tests);
169 }