1 /* 2 * libusb stress test program to perform simple stress tests 3 * Copyright 2012 Toby Gray <toby.gray (at) 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 <string.h> 22 #include <memory.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(libusb_testlib_ctx * tctx) 30 { 31 libusb_context * ctx = NULL; 32 int i; 33 for (i = 0; i < 10000; ++i) { 34 int r = libusb_init(&ctx); 35 if (r != LIBUSB_SUCCESS) { 36 libusb_testlib_logf(tctx, 37 "Failed to init libusb on iteration %d: %d", 38 i, r); 39 return TEST_STATUS_FAILURE; 40 } 41 libusb_exit(ctx); 42 ctx = NULL; 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(libusb_testlib_ctx * tctx) 50 { 51 libusb_context * ctx = NULL; 52 int r, i; 53 r = libusb_init(&ctx); 54 if (r != LIBUSB_SUCCESS) { 55 libusb_testlib_logf(tctx, "Failed to init libusb: %d", r); 56 return TEST_STATUS_FAILURE; 57 } 58 for (i = 0; i < 1000; ++i) { 59 libusb_device ** device_list; 60 ssize_t list_size = libusb_get_device_list(ctx, &device_list); 61 if (list_size < 0 || device_list == NULL) { 62 libusb_testlib_logf(tctx, 63 "Failed to get device list on iteration %d: %d (%p)", 64 i, -list_size, device_list); 65 return TEST_STATUS_FAILURE; 66 } 67 libusb_free_device_list(device_list, 1); 68 } 69 libusb_exit(ctx); 70 return TEST_STATUS_SUCCESS; 71 } 72 73 /** Tests that 100 concurrent device lists can be open at a time. */ 74 static libusb_testlib_result test_many_device_lists(libusb_testlib_ctx * tctx) 75 { 76 #define LIST_COUNT 100 77 libusb_context * ctx = NULL; 78 libusb_device ** device_lists[LIST_COUNT]; 79 int r, i; 80 memset(device_lists, 0, sizeof(device_lists)); 81 82 r = libusb_init(&ctx); 83 if (r != LIBUSB_SUCCESS) { 84 libusb_testlib_logf(tctx, "Failed to init libusb: %d", r); 85 return TEST_STATUS_FAILURE; 86 } 87 88 /* Create the 100 device lists. */ 89 for (i = 0; i < LIST_COUNT; ++i) { 90 ssize_t list_size = libusb_get_device_list(ctx, &(device_lists[i])); 91 if (list_size < 0 || device_lists[i] == NULL) { 92 libusb_testlib_logf(tctx, 93 "Failed to get device list on iteration %d: %d (%p)", 94 i, -list_size, device_lists[i]); 95 return TEST_STATUS_FAILURE; 96 } 97 } 98 99 /* Destroy the 100 device lists. */ 100 for (i = 0; i < LIST_COUNT; ++i) { 101 if (device_lists[i]) { 102 libusb_free_device_list(device_lists[i], 1); 103 device_lists[i] = NULL; 104 } 105 } 106 107 libusb_exit(ctx); 108 return TEST_STATUS_SUCCESS; 109 #undef LIST_COUNT 110 } 111 112 /** Tests that the default context (used for various things including 113 * logging) works correctly when the first context created in a 114 * process is destroyed. */ 115 static libusb_testlib_result test_default_context_change(libusb_testlib_ctx * tctx) 116 { 117 libusb_context * ctx = NULL; 118 int r, i; 119 120 for (i = 0; i < 100; ++i) { 121 /* First create a new context */ 122 r = libusb_init(&ctx); 123 if (r != LIBUSB_SUCCESS) { 124 libusb_testlib_logf(tctx, "Failed to init libusb: %d", r); 125 return TEST_STATUS_FAILURE; 126 } 127 128 /* Enable debug output, to be sure to use the context */ 129 libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_DEBUG); 130 libusb_set_debug(ctx, LIBUSB_LOG_LEVEL_DEBUG); 131 132 /* Now create a reference to the default context */ 133 r = libusb_init(NULL); 134 if (r != LIBUSB_SUCCESS) { 135 libusb_testlib_logf(tctx, "Failed to init libusb: %d", r); 136 return TEST_STATUS_FAILURE; 137 } 138 139 /* Destroy the first context */ 140 libusb_exit(ctx); 141 /* Destroy the default context */ 142 libusb_exit(NULL); 143 } 144 145 return TEST_STATUS_SUCCESS; 146 } 147 148 /* Fill in the list of tests. */ 149 static const libusb_testlib_test tests[] = { 150 {"init_and_exit", &test_init_and_exit}, 151 {"get_device_list", &test_get_device_list}, 152 {"many_device_lists", &test_many_device_lists}, 153 {"default_context_change", &test_default_context_change}, 154 LIBUSB_NULL_TEST 155 }; 156 157 int main (int argc, char ** argv) 158 { 159 return libusb_testlib_run_tests(argc, argv, tests); 160 } 161