diff --git a/lib/libusb/libusb10.c b/lib/libusb/libusb10.c --- a/lib/libusb/libusb10.c +++ b/lib/libusb/libusb10.c @@ -639,7 +639,20 @@ err = libusb20_dev_open(pdev, LIBUSB_NUM_SW_ENDPOINTS); if (err) { libusb_unref_device(dev); - return (LIBUSB_ERROR_NO_MEM); + switch (err) { + /* + * These are all equal in value to + * their LIBUSB_ERROR_* counterparts. + */ + case LIBUSB20_ERROR_ACCESS: + case LIBUSB20_ERROR_BUSY: + case LIBUSB20_ERROR_INVALID_PARAM: + case LIBUSB20_ERROR_NO_DEVICE: + case LIBUSB20_ERROR_NO_MEM: + return (err); + default: + return (LIBUSB_ERROR_OTHER); + } } /* diff --git a/lib/libusb/libusb20_ugen20.c b/lib/libusb/libusb20_ugen20.c --- a/lib/libusb/libusb20_ugen20.c +++ b/lib/libusb/libusb20_ugen20.c @@ -393,7 +393,8 @@ */ g = open(buf, O_RDWR); if (g < 0) { - return (LIBUSB20_ERROR_NO_DEVICE); + return (EACCES == errno ? + LIBUSB20_ERROR_ACCESS : LIBUSB20_ERROR_NO_DEVICE); } f = open(buf, O_RDWR); if (f < 0) { diff --git a/tests/lib/Kyuafile b/tests/lib/Kyuafile new file mode 100644 --- /dev/null +++ b/tests/lib/Kyuafile @@ -0,0 +1,7 @@ +-- Automatically generated by bsd.test.mk. + +syntax(2) + +test_suite("FreeBSD") + +include("libusb/Kyuafile") diff --git a/tests/lib/libusb/Kyuafile b/tests/lib/libusb/Kyuafile new file mode 100644 --- /dev/null +++ b/tests/lib/libusb/Kyuafile @@ -0,0 +1,5 @@ +syntax(2) + +test_suite("atf") + +atf_test_program{name="usb_opener"} diff --git a/tests/lib/libusb/Makefile b/tests/lib/libusb/Makefile new file mode 100644 --- /dev/null +++ b/tests/lib/libusb/Makefile @@ -0,0 +1,12 @@ +PACKAGE= tests + +TESTSDIR=${TESTSBASE}/lib/libusb + +ATF_TESTS_CXX+= usb_opener + +SRCS.usb_opener= usb_opener.cc backend.cc device.cc mock.cc + +LIBADD+= rt +LIBADD+= usb + +.include diff --git a/tests/lib/libusb/backend.cc b/tests/lib/libusb/backend.cc new file mode 100644 --- /dev/null +++ b/tests/lib/libusb/backend.cc @@ -0,0 +1,198 @@ +/* +* Copyright 2025 Rick Parrish +* +* SPDX-License-Identifier: BSD-2-Clause +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "libusb20_int.h" + +// imposter backend methods. +static struct libusb20_backend_methods bem; + +extern struct libusb20_device_methods *get_imposter_device_methods(); + +typedef struct libusb20_backend * libusb20_be_alloc_default_t(void); + +static libusb20_be_alloc_default_t *__libusb20_be_alloc_default = NULL; + +/* USB backend specific */ +static const char *imposter_get_backend_name(void) +{ + return "IMPOSTER"; +} + +static int imposter_root_get_dev_quirk(struct libusb20_backend *pbe, uint16_t /*index*/, struct libusb20_quirk *pq) +{ + assert(pbe != NULL); + assert(pq != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_root_get_quirk_name(struct libusb20_backend *pbe, uint16_t /*index*/, struct libusb20_quirk *pq) +{ + assert(pbe != NULL); + assert(pq != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_root_add_dev_quirk(struct libusb20_backend *pbe, struct libusb20_quirk *pq) +{ + assert(pbe != NULL); + assert(pq != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_root_remove_dev_quirk(struct libusb20_backend *pbe, struct libusb20_quirk *pq) +{ + assert(pbe != NULL); + assert(pq != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_close_device(struct libusb20_device *pdev) +{ + assert(pdev != NULL); + if (pdev->file == 0x1234) + { + pdev->file = 0; + return LIBUSB20_SUCCESS; + } + return LIBUSB20_ERROR_INVALID_PARAM; +} + +static int imposter_dev_get_info(struct libusb20_device *pdev, struct usb_device_info *pinfo) +{ + assert(pdev != NULL); + if (pdev->file != 0x1234) + return LIBUSB20_ERROR_INVALID_PARAM; + static struct usb_device_info info{}; + info.udi_addr = 9; + info.udi_bus = 0; + info.udi_bustypeNo = 0; + info.udi_class = 0; + info.udi_config_no = 1; + info.udi_config_index = 0; + info.udi_bustypeNo = 0; + info.udi_hubaddr = 0; + info.udi_hubport = 0; + info.udi_index = 0; + info.udi_mode = 0; + info.udi_nports = 0; + info.udi_power = 0; + info.udi_power_mode = 0; + info.udi_protocol = 0; + memcpy(info.udi_release, "0", 1); + info.udi_releaseNo = 0; + info.udi_suspended = 0; + memset(info.udi_reserved, 0, sizeof info.udi_reserved); + info.udi_speed = 0; + info.udi_subclass = 0; + memcpy(info.udi_serial, "12345678", 8); + memcpy(info.udi_product, "IMPOSTER", 8); + memcpy(info.udi_vendor, "IMPOSTER", 8); + info.udi_vendorNo = 0x1234; + info.udi_productNo = 0x1234; + *pinfo = info; + return LIBUSB20_SUCCESS; +} + +static int imposter_dev_get_iface_desc(struct libusb20_device *pdev, uint8_t /*iface_index*/, char *buf, uint8_t /*len*/) +{ + assert(pdev != NULL); + assert(buf != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_init_backend(struct libusb20_backend *pbe) +{ + assert(pbe != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_open_device(struct libusb20_device *pdev, uint16_t /*transfer_count_max*/) +{ + assert(pdev != NULL); + if (pdev->file == 0x1234) + return LIBUSB20_ERROR_BUSY; + + pdev->methods = get_imposter_device_methods(); + + pdev->file = 0x1234; + return LIBUSB20_SUCCESS; +} + +static void imposter_exit_backend(struct libusb20_backend *pbe) +{ + assert(pbe != NULL); +} + +static int imposter_root_set_template(struct libusb20_backend *pbe, int /*temp*/) +{ + assert(pbe != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_root_get_template(struct libusb20_backend *pbe, int *ptemp) +{ + assert(pbe != NULL); + assert(ptemp != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +struct libusb20_backend * +libusb20_be_alloc_default(void) +{ + if (__libusb20_be_alloc_default == NULL) + __libusb20_be_alloc_default = (libusb20_be_alloc_default_t *)dlsym(RTLD_NEXT, "libusb20_be_alloc_default"); + + auto backend = __libusb20_be_alloc_default(); + struct libusb20_device &imposter = *libusb20_dev_alloc(); + + // Replace the real backend's methods with the imposter. + // Now we can mock all sorts of behavior. + backend->methods = &bem; + + memcpy(imposter.port_path, "/dev/nul", 8); + imposter.usb_speed = 1; + imposter.ddesc.idVendor = 0x1234; + imposter.ddesc.idProduct = 0x5678; + + libusb20_be_enqueue_device(backend, &imposter); + + return backend; +} + +// imposter backend methods. +struct libusb20_backend_methods* get_imposter_backend_methods() +{ + bem.init_backend = imposter_init_backend; + bem.exit_backend = imposter_exit_backend; + bem.open_device = imposter_open_device; + bem.close_device = imposter_close_device; + bem.dev_get_iface_desc = imposter_dev_get_iface_desc; + bem.dev_get_info = imposter_dev_get_info; + bem.get_backend_name = imposter_get_backend_name; + bem.root_add_dev_quirk = imposter_root_add_dev_quirk; + bem.root_get_dev_quirk = imposter_root_get_dev_quirk; + bem.root_get_quirk_name = imposter_root_get_quirk_name; + bem.root_get_template = imposter_root_get_template; + bem.root_remove_dev_quirk = imposter_root_remove_dev_quirk; + bem.root_set_template = imposter_root_set_template; + return &bem; +} diff --git a/tests/lib/libusb/device.cc b/tests/lib/libusb/device.cc new file mode 100644 --- /dev/null +++ b/tests/lib/libusb/device.cc @@ -0,0 +1,173 @@ +/* +* Copyright 2025 Rick Parrish +* +* SPDX-License-Identifier: BSD-2-Clause +*/ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "libusb20_int.h" + +// imposter device methods. +static struct libusb20_device_methods dm{}; + +/* USB device specific */ +static int imposter_detach_kernel_driver(struct libusb20_device *pdev, uint8_t /*iface_index*/) +{ + assert(pdev != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_do_request_sync(struct libusb20_device *pdev, struct LIBUSB20_CONTROL_SETUP_DECODED *setup, void *data, uint16_t *pactlen, uint32_t /*timeout*/, uint8_t /*flags*/) +{ + assert(pdev != NULL); + assert(setup != NULL); + assert(data != NULL); + assert(pactlen != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_get_config_desc_full(struct libusb20_device *pdev, uint8_t **ppbuf, uint16_t *plen, uint8_t /*index*/) +{ + assert(pdev != NULL); + assert(ppbuf != NULL); + assert(plen != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_get_config_index(struct libusb20_device *pdev, uint8_t *pindex) +{ + assert(pdev != NULL); + assert(pindex != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_kernel_driver_active(struct libusb20_device *pdev, uint8_t /*iface_index*/) +{ + assert(pdev != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_process(struct libusb20_device *pdev) +{ + assert(pdev != NULL); + nice(0); + return pdev->file == 0x1234 ? LIBUSB20_SUCCESS : LIBUSB20_ERROR_INVALID_PARAM; +} + +static int imposter_reset_device(struct libusb20_device *pdev) +{ + assert(pdev != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_set_power_mode(struct libusb20_device *pdev, uint8_t /*power_mode*/) +{ + assert(pdev != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_get_power_mode(struct libusb20_device *pdev, uint8_t *power_mode) +{ + assert(pdev != NULL); + assert(power_mode != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_get_power_usage(struct libusb20_device *pdev, uint16_t *power_usage) +{ + assert(pdev != NULL); + assert(power_usage != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} +static int imposter_get_stats(struct libusb20_device *pdev, struct libusb20_device_stats *pstats) +{ + assert(pdev != NULL); + assert(pstats != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_set_alt_index(struct libusb20_device *pdev, uint8_t /*iface_index*/, uint8_t /*alt_index*/) +{ + assert(pdev != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_set_config_index(struct libusb20_device *pdev, uint8_t /*index*/) +{ + assert(pdev != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_check_connected(struct libusb20_device *pdev) +{ + assert(pdev != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +/* USB transfer specific */ +static int imposter_tr_open(struct libusb20_transfer *xfer, uint32_t /*MaxBufSize*/, uint32_t /*MaxFrameCount*/, uint8_t /*ep_no*/, uint16_t /*stream_id*/, uint8_t /*pre_scale*/) +{ + assert(xfer != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_tr_close(struct libusb20_transfer *xfer) +{ + assert(xfer != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static int imposter_tr_clear_stall_sync(struct libusb20_transfer *xfer) +{ + assert(xfer != NULL); + return LIBUSB20_ERROR_NOT_SUPPORTED; +} + +static void imposter_tr_submit(struct libusb20_transfer *xfer) +{ + assert(xfer != NULL); +} + +static void imposter_tr_cancel_async(struct libusb20_transfer *xfer) +{ + assert(xfer != NULL); +} + +struct libusb20_device_methods *get_imposter_device_methods(void) +{ + dm.check_connected = imposter_check_connected; + dm.detach_kernel_driver = imposter_detach_kernel_driver; + dm.do_request_sync = imposter_do_request_sync; + dm.get_config_desc_full = imposter_get_config_desc_full; + dm.get_config_index = imposter_get_config_index; + dm.get_power_mode = imposter_get_power_mode; + dm.get_power_usage = imposter_get_power_usage; + dm.get_stats = imposter_get_stats; + dm.kernel_driver_active = imposter_kernel_driver_active; + dm.process = imposter_process; + dm.reset_device = imposter_reset_device; + dm.set_alt_index = imposter_set_alt_index; + dm.set_config_index = imposter_set_config_index; + dm.set_power_mode = imposter_set_power_mode; + dm.tr_cancel_async = imposter_tr_cancel_async; + dm.tr_clear_stall_sync = imposter_tr_clear_stall_sync; + dm.tr_close = imposter_tr_close; + dm.tr_open = imposter_tr_open; + dm.tr_submit = imposter_tr_submit; + return &dm; +} diff --git a/tests/lib/libusb/libusb20_int.h b/tests/lib/libusb/libusb20_int.h new file mode 100644 --- /dev/null +++ b/tests/lib/libusb/libusb20_int.h @@ -0,0 +1,2 @@ +// point this to where ever the source is located on your system. +#include "../../../lib/libusb/libusb20_int.h" diff --git a/tests/lib/libusb/mock.h b/tests/lib/libusb/mock.h new file mode 100644 --- /dev/null +++ b/tests/lib/libusb/mock.h @@ -0,0 +1,30 @@ +/* +* Copyright 2025 Rick Parrish +* +* SPDX-License-Identifier: BSD-2-Clause +*/ + + +#pragma once + +// Create a mock libusb20 backend and wire the backend open_device method to return +// the given result and then call libusb20_dev_open on the mocked device. +// The purpose is to prove that backend errors do bubble up to the surface. +// returns true for success and false for failure. +bool execute_for_libusb20(int open_device_result); + +// Create a mock libusb20 backend and wire the backend open_device method to return +// the given result and then call libusb_open on the mocked device. +// The purpose is to prove that backend errors do bubble up to the surface. +// Beware that open_device_result is a LIBUSB20_ERROR_XXXX value while expected is a LIBUSB_ERROR_XXXX. +// In many cases these two are numerically the same but this cannot be guaranteed. +// returns true for success and false for failure. +bool execute_for_libusb(int open_device_result, int expected); + +// Create a mock libusb20 backend and wire the backend open_device method to return +// the given result and then call libusb_open on the mocked device. +// The purpose is to prove that backend errors do bubble up to the surface. +// Beware that open_device_result is a LIBUSB20_ERROR_XXXX (not a LIBUSB_ERROR_XXXX value). +// success = true implies a non-null pointer was returned by libusb_open_with_vid_pid. +// returns true for success and false for failure. +bool execute_for_libusb_with_vid_pid(int open_device_result, bool success); diff --git a/tests/lib/libusb/mock.cc b/tests/lib/libusb/mock.cc new file mode 100644 --- /dev/null +++ b/tests/lib/libusb/mock.cc @@ -0,0 +1,127 @@ +/* +* Copyright 2025 Rick Parrish +* +* SPDX-License-Identifier: BSD-2-Clause +*/ + + +#include +#include "mock.h" +#include +#include +#include +#include +#include +#include "libusb20_int.h" +#include +#include + +extern struct libusb20_backend_methods* get_imposter_backend_methods(); +extern struct libusb20_device_methods *get_imposter_device_methods(); + +static int mock_open_device_result = LIBUSB20_SUCCESS; + +static int mock_open_device(struct libusb20_device *pdev, uint16_t transfer_count_max) +{ + assert(pdev != NULL); + assert(transfer_count_max < 256); + if (mock_open_device_result == LIBUSB20_SUCCESS) + { + pdev->methods = get_imposter_device_methods(); + pdev->file = 0x1234; + pdev->file_ctrl = 0x1234; + } + + return mock_open_device_result; +} + +bool execute_for_libusb20(int open_device_result) +{ + auto methods = get_imposter_backend_methods(); + + methods->open_device = mock_open_device; + mock_open_device_result = open_device_result; + + auto backend = libusb20_be_alloc_default(); + + libusb20_device *device = NULL; + + bool success = false; + while ( (device = libusb20_be_device_foreach(backend, device)) != NULL) + { + auto describe = libusb20_dev_get_device_desc(device); + // look for our special test device. + if (describe->idVendor == 0x1234 && describe->idProduct == 0x5678) + { + int code = libusb20_dev_open(device, 0); + //fprintf(stdout, "%s %04hX:%04hX %s\n", libusb20_dev_get_backend_name(device), + // describe->idVendor, describe->idProduct, libusb20_error_name(code)); + if (code == LIBUSB20_SUCCESS) + { + libusb20_dev_close(device); + } + success = code == open_device_result; + break; + } + } + libusb20_be_free(backend); + return success; +} + +bool execute_for_libusb(int open_device_result, int expected) +{ + auto methods = get_imposter_backend_methods(); + + methods->open_device = mock_open_device; + mock_open_device_result = open_device_result; + + libusb_context *context = NULL; + libusb_init(&context); + + libusb_device **list = NULL; + int count = libusb_get_device_list(context, &list); + assert(count > 0); + + bool success = false; + for (int i = 0; i < count; i++) + { + auto device = list[i]; + + libusb_device_descriptor describe; + libusb_get_device_descriptor(device, &describe); + if (describe.idVendor == 0x1234 && describe.idProduct == 0x5678) + { + libusb_device_handle *handle = NULL; + int code = libusb_open(device, &handle); + //fprintf(stdout, "%s %04hX:%04hX %s\n", libusb20_dev_get_backend_name(device), + // describe->idVendor, describe->idProduct, libusb20_error_name(code)); + if (code == LIBUSB_SUCCESS) + { + libusb_close(handle); + } + success = code == expected; + break; + } + } + libusb_exit(context); + return success; +} + +bool execute_for_libusb_with_vid_pid(int open_device_result, bool success) +{ + auto methods = get_imposter_backend_methods(); + + methods->open_device = mock_open_device; + mock_open_device_result = open_device_result; + + libusb_context *context = NULL; + libusb_init(&context); + + auto handle = libusb_open_device_with_vid_pid(context, 0x1234, 0x5678); + bool pass = success ^ (handle == NULL); + if (handle != NULL) + libusb_close(handle); + + libusb_exit(context); + return pass; +} diff --git a/tests/lib/libusb/usb_opener.cc b/tests/lib/libusb/usb_opener.cc new file mode 100644 --- /dev/null +++ b/tests/lib/libusb/usb_opener.cc @@ -0,0 +1,411 @@ +/* + * Copyright 2025 Rick Parrish + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mock.h" +#include +#include + +// Copy kyua.conf and Kyuafile to the same directory as the usb_opener executable file. +// Run 'kyua test' to run all tests. + +// LIBUSB20 tests + +// SUCCESS + +ATF_TEST_CASE(test_case_libusb20_success); + +ATF_TEST_CASE_HEAD(test_case_libusb20_success) +{ + set_md_var("descr", "Cover LIBUSB20_SUCCESS"); +} + +ATF_TEST_CASE_BODY(test_case_libusb20_success) +{ + if (execute_for_libusb20(LIBUSB20_SUCCESS)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB20_SUCCESS"); +} + +// BUSY + +ATF_TEST_CASE(test_case_libusb20_busy); + +ATF_TEST_CASE_HEAD(test_case_libusb20_busy) +{ + set_md_var("descr", "Cover LIBUSB20_ERROR_BUSY"); +} + +ATF_TEST_CASE_BODY(test_case_libusb20_busy) +{ + if (execute_for_libusb20(LIBUSB20_ERROR_BUSY)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB20_ERROR_BUSY"); +} + +// ACCESS + +ATF_TEST_CASE(test_case_libusb20_access); + +ATF_TEST_CASE_HEAD(test_case_libusb20_access) +{ + set_md_var("descr", "Cover LIBUSB20_ERROR_ACCESS"); +} + +ATF_TEST_CASE_BODY(test_case_libusb20_access) +{ + if (execute_for_libusb20(LIBUSB20_ERROR_ACCESS)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB20_ERROR_ACCESS"); +} + +// NO DEVICE + +ATF_TEST_CASE(test_case_libusb20_no_device); + +ATF_TEST_CASE_HEAD(test_case_libusb20_no_device) +{ + set_md_var("descr", "Cover LIBUSB20_ERROR_NO_DEVICE"); +} + +ATF_TEST_CASE_BODY(test_case_libusb20_no_device) +{ + if (execute_for_libusb20(LIBUSB20_ERROR_NO_DEVICE)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB20_ERROR_NO_DEVICE"); +} + +// NO_MEM + +ATF_TEST_CASE(test_case_libusb20_no_mem); + +ATF_TEST_CASE_HEAD(test_case_libusb20_no_mem) +{ + set_md_var("descr", "Cover LIBUSB20_ERROR_NO_MEM"); +} + +ATF_TEST_CASE_BODY(test_case_libusb20_no_mem) +{ + if (execute_for_libusb20(LIBUSB20_ERROR_NO_MEM)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB20_ERROR_NO_MEM"); +} + +// INVALID_PARAM + +ATF_TEST_CASE(test_case_libusb20_invalid); + +ATF_TEST_CASE_HEAD(test_case_libusb20_invalid) +{ + set_md_var("descr", "Cover LIBUSB20_ERROR_INVALID_PARAM"); +} + +ATF_TEST_CASE_BODY(test_case_libusb20_invalid) +{ + if (execute_for_libusb20(LIBUSB20_ERROR_INVALID_PARAM)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB20_ERROR_INVALID_PARAM"); +} + +// OTHER + +ATF_TEST_CASE(test_case_libusb20_other); + +ATF_TEST_CASE_HEAD(test_case_libusb20_other) +{ + set_md_var("descr", "Cover LIBUSB20_ERROR_OTHER"); +} + +ATF_TEST_CASE_BODY(test_case_libusb20_other) +{ + if (execute_for_libusb20(LIBUSB20_ERROR_OTHER)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB20_ERROR_OTHER"); +} + +// LIBUSB tests + +// SUCCESS + +ATF_TEST_CASE(test_case_libusb_success); + +ATF_TEST_CASE_HEAD(test_case_libusb_success) +{ + set_md_var("descr", "Cover LIBUSB_SUCCESS"); +} + +ATF_TEST_CASE_BODY(test_case_libusb_success) +{ + if (execute_for_libusb(LIBUSB20_SUCCESS, LIBUSB_SUCCESS)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB_SUCCESS"); +} + +// BUSY + +ATF_TEST_CASE(test_case_libusb_busy); + +ATF_TEST_CASE_HEAD(test_case_libusb_busy) +{ + set_md_var("descr", "Cover LIBUSB_ERROR_BUSY"); +} + +ATF_TEST_CASE_BODY(test_case_libusb_busy) +{ + if (execute_for_libusb(LIBUSB20_ERROR_BUSY, LIBUSB_ERROR_BUSY)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB_ERROR_BUSY"); +} + +// ACCESS + +ATF_TEST_CASE(test_case_libusb_access); + +ATF_TEST_CASE_HEAD(test_case_libusb_access) +{ + set_md_var("descr", "Cover LIBUSB_ERROR_ACCESS"); +} + +ATF_TEST_CASE_BODY(test_case_libusb_access) +{ + if (execute_for_libusb(LIBUSB20_ERROR_ACCESS, LIBUSB_ERROR_ACCESS)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB_ERROR_ACCESS"); +} + +// NO DEVICE + +ATF_TEST_CASE(test_case_libusb_no_device); + +ATF_TEST_CASE_HEAD(test_case_libusb_no_device) +{ + set_md_var("descr", "Cover LIBUSB_ERROR_NO_DEVICE"); +} + +ATF_TEST_CASE_BODY(test_case_libusb_no_device) +{ + if (execute_for_libusb(LIBUSB20_ERROR_NO_DEVICE, LIBUSB_ERROR_NO_DEVICE)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB_ERROR_NO_DEVICE"); +} + +// NO_MEM + +ATF_TEST_CASE(test_case_libusb_no_mem); + +ATF_TEST_CASE_HEAD(test_case_libusb_no_mem) +{ + set_md_var("descr", "Cover LIBUSB_ERROR_NO_MEM"); +} + +ATF_TEST_CASE_BODY(test_case_libusb_no_mem) +{ + if (execute_for_libusb(LIBUSB20_ERROR_NO_MEM, LIBUSB_ERROR_NO_MEM)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB_ERROR_NO_MEM"); +} + +// INVALID_PARAM + +ATF_TEST_CASE(test_case_libusb_invalid); + +ATF_TEST_CASE_HEAD(test_case_libusb_invalid) +{ + set_md_var("descr", "Cover LIBUSB_ERROR_INVALID_PARAM"); +} + +ATF_TEST_CASE_BODY(test_case_libusb_invalid) +{ + if (execute_for_libusb(LIBUSB20_ERROR_INVALID_PARAM, LIBUSB_ERROR_INVALID_PARAM)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB_ERROR_INVALID_PARAM"); +} + +// OTHER + +ATF_TEST_CASE(test_case_libusb_other); + +ATF_TEST_CASE_HEAD(test_case_libusb_other) +{ + set_md_var("descr", "Cover LIBUSB_ERROR_OTHER"); +} + +ATF_TEST_CASE_BODY(test_case_libusb_other) +{ + if (execute_for_libusb(LIBUSB20_ERROR_OTHER, LIBUSB_ERROR_OTHER)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB_ERROR_OTHER"); +} + +// LIBUSB with vid/pid tests + +// SUCCESS + +ATF_TEST_CASE(test_case_libusb_with_vid_pid_success); + +ATF_TEST_CASE_HEAD(test_case_libusb_with_vid_pid_success) +{ + set_md_var("descr", "Cover LIBUSB_SUCCESS"); +} + +ATF_TEST_CASE_BODY(test_case_libusb_with_vid_pid_success) +{ + if (execute_for_libusb_with_vid_pid(LIBUSB20_SUCCESS, true)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB_SUCCESS"); +} + +// BUSY + +ATF_TEST_CASE(test_case_libusb_with_vid_pid_busy); + +ATF_TEST_CASE_HEAD(test_case_libusb_with_vid_pid_busy) +{ + set_md_var("descr", "Cover LIBUSB_ERROR_BUSY"); +} + +ATF_TEST_CASE_BODY(test_case_libusb_with_vid_pid_busy) +{ + if (execute_for_libusb_with_vid_pid(LIBUSB20_ERROR_BUSY, false)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB_ERROR_BUSY"); +} + +// ACCESS + +ATF_TEST_CASE(test_case_libusb_with_vid_pid_access); + +ATF_TEST_CASE_HEAD(test_case_libusb_with_vid_pid_access) +{ + set_md_var("descr", "Cover LIBUSB_ERROR_ACCESS"); +} + +ATF_TEST_CASE_BODY(test_case_libusb_with_vid_pid_access) +{ + if (execute_for_libusb_with_vid_pid(LIBUSB20_ERROR_ACCESS, false)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB_ERROR_ACCESS"); +} + +// NO DEVICE + +ATF_TEST_CASE(test_case_libusb_with_vid_pid_no_device); + +ATF_TEST_CASE_HEAD(test_case_libusb_with_vid_pid_no_device) +{ + set_md_var("descr", "Cover LIBUSB_ERROR_NO_DEVICE"); +} + +ATF_TEST_CASE_BODY(test_case_libusb_with_vid_pid_no_device) +{ + if (execute_for_libusb_with_vid_pid(LIBUSB20_ERROR_NO_DEVICE, false)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB_ERROR_NO_DEVICE"); +} + +// NO_MEM + +ATF_TEST_CASE(test_case_libusb_with_vid_pid_no_mem); + +ATF_TEST_CASE_HEAD(test_case_libusb_with_vid_pid_no_mem) +{ + set_md_var("descr", "Cover LIBUSB_ERROR_NO_MEM"); +} + +ATF_TEST_CASE_BODY(test_case_libusb_with_vid_pid_no_mem) +{ + if (execute_for_libusb_with_vid_pid(LIBUSB20_ERROR_NO_MEM, false)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB_ERROR_NO_MEM"); +} + +// INVALID_PARAM + +ATF_TEST_CASE(test_case_libusb_with_vid_pid_invalid); + +ATF_TEST_CASE_HEAD(test_case_libusb_with_vid_pid_invalid) +{ + set_md_var("descr", "Cover LIBUSB_ERROR_INVALID_PARAM"); +} + +ATF_TEST_CASE_BODY(test_case_libusb_with_vid_pid_invalid) +{ + if (execute_for_libusb_with_vid_pid(LIBUSB20_ERROR_INVALID_PARAM, false)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB_ERROR_INVALID_PARAM"); +} + +// OTHER + +ATF_TEST_CASE(test_case_libusb_with_vid_pid_other); + +ATF_TEST_CASE_HEAD(test_case_libusb_with_vid_pid_other) +{ + set_md_var("descr", "Cover LIBUSB_ERROR_OTHER"); +} + +ATF_TEST_CASE_BODY(test_case_libusb_with_vid_pid_other) +{ + if (execute_for_libusb_with_vid_pid(LIBUSB20_ERROR_OTHER, false)) + ATF_PASS(); + else + ATF_FAIL("LIBUSB_ERROR_OTHER"); +} + +ATF_INIT_TEST_CASES(tcs) +{ + ATF_ADD_TEST_CASE(tcs, test_case_libusb20_access); + ATF_ADD_TEST_CASE(tcs, test_case_libusb20_busy); + ATF_ADD_TEST_CASE(tcs, test_case_libusb20_invalid); + ATF_ADD_TEST_CASE(tcs, test_case_libusb20_no_device); + ATF_ADD_TEST_CASE(tcs, test_case_libusb20_no_mem); + ATF_ADD_TEST_CASE(tcs, test_case_libusb20_other); + ATF_ADD_TEST_CASE(tcs, test_case_libusb20_success); + + ATF_ADD_TEST_CASE(tcs, test_case_libusb_access); + ATF_ADD_TEST_CASE(tcs, test_case_libusb_busy); + ATF_ADD_TEST_CASE(tcs, test_case_libusb_invalid); + ATF_ADD_TEST_CASE(tcs, test_case_libusb_no_device); + ATF_ADD_TEST_CASE(tcs, test_case_libusb_no_mem); + ATF_ADD_TEST_CASE(tcs, test_case_libusb_other); + ATF_ADD_TEST_CASE(tcs, test_case_libusb_success); + + ATF_ADD_TEST_CASE(tcs, test_case_libusb_with_vid_pid_access); + ATF_ADD_TEST_CASE(tcs, test_case_libusb_with_vid_pid_busy); + ATF_ADD_TEST_CASE(tcs, test_case_libusb_with_vid_pid_invalid); + ATF_ADD_TEST_CASE(tcs, test_case_libusb_with_vid_pid_no_device); + ATF_ADD_TEST_CASE(tcs, test_case_libusb_with_vid_pid_no_mem); + ATF_ADD_TEST_CASE(tcs, test_case_libusb_with_vid_pid_other); + ATF_ADD_TEST_CASE(tcs, test_case_libusb_with_vid_pid_success); +}