• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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. */
test_init_and_exit(void)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. */
test_get_device_list(void)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. */
test_many_device_lists(void)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. */
test_default_context_change(void)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, to be sure to use the context */
134 		libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG);
135 		libusb_set_option(ctx, LIBUSB_OPTION_LOG_LEVEL, LIBUSB_LOG_LEVEL_DEBUG);
136 
137 		/* Now create a reference to the default context */
138 		r = libusb_init(NULL);
139 		if (r != LIBUSB_SUCCESS) {
140 			libusb_testlib_logf("Failed to init libusb: %d", r);
141 			libusb_exit(ctx);
142 			return TEST_STATUS_FAILURE;
143 		}
144 
145 		/* Destroy the first context */
146 		libusb_exit(ctx);
147 		/* Destroy the default context */
148 		libusb_exit(NULL);
149 	}
150 
151 	return TEST_STATUS_SUCCESS;
152 }
153 
154 /* Fill in the list of tests. */
155 static const libusb_testlib_test tests[] = {
156 	{ "init_and_exit", &test_init_and_exit },
157 	{ "get_device_list", &test_get_device_list },
158 	{ "many_device_lists", &test_many_device_lists },
159 	{ "default_context_change", &test_default_context_change },
160 	LIBUSB_NULL_TEST
161 };
162 
main(int argc,char * argv[])163 int main(int argc, char *argv[])
164 {
165 	return libusb_testlib_run_tests(argc, argv, tests);
166 }
167