Anastasia Klimchuk has uploaded this change for review. ( https://review.coreboot.org/c/flashrom/+/57918 )
Change subject: [WIP] tests: Add init-shutdown test for raiden_debug_spi ......................................................................
[WIP] tests: Add init-shutdown test for raiden_debug_spi
This patch adds a test for raiden_debug_spi and lots of libusb wraps.
Marked as WIP because I feel my approach to libusb symbols is questionable. The test is working though.
Another thing less-than-ideal is USB_DEVICE_ADDRESS, can probably be done better.
BUG=b:181803212 TEST=builds and ninja test
Change-Id: I880a8637ab02de179df9169c1898230bce4dc1c7 Signed-off-by: Anastasia Klimchuk aklm@chromium.org --- M tests/init_shutdown.c M tests/io_mock.h M tests/libusb_wraps.c M tests/meson.build M tests/tests.c M tests/tests.h 6 files changed, 251 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/flashrom refs/changes/18/57918/1
diff --git a/tests/init_shutdown.c b/tests/init_shutdown.c index e64e58c..262c4c3 100644 --- a/tests/init_shutdown.c +++ b/tests/init_shutdown.c @@ -54,6 +54,97 @@ #endif }
+ssize_t raiden_debug_libusb_get_device_list(void *state, libusb_context *ctx, libusb_device ***list) +{ + *list = calloc(1, sizeof(**list)); + **list = calloc(1, sizeof(*list)); + + const struct libusb_device tmp = {}; + + *((*list)[0]) = tmp; + + return 1; +} + +void raiden_debug_libusb_free_device_list(void *state, libusb_device **list, int unref_devices) +{ + free(*list); + free(list); +} + +int raiden_debug_libusb_get_device_descriptor( + void *state, libusb_device *dev, libusb_device_descriptor *desc) +{ + desc->idVendor = 0x18D1; /* GOOGLE_VID */ + desc->idProduct = 0; + desc->bNumConfigurations = 1; + + return 0; +} + +int raiden_debug_libusb_get_config_descriptor( + void *state, libusb_device *dev, uint8_t config_index, libusb_config_descriptor **config) +{ + *config = calloc(1, sizeof(**config)); + + struct libusb_endpoint_descriptor *tmp_endpoint = calloc(2, sizeof(*tmp_endpoint)); + struct libusb_interface_descriptor *tmp_interface_descriptor = calloc(1, sizeof(*tmp_interface_descriptor)); + struct libusb_interface *tmp_interface = calloc(1, sizeof(*tmp_interface)); + + /* in endpoint */ + tmp_endpoint[0].bEndpointAddress = 0x80; + tmp_endpoint[0].bmAttributes = 0x2; + /* out endpoint */ + tmp_endpoint[1].bEndpointAddress = 0x0; + tmp_endpoint[1].bmAttributes = 0x2; + + tmp_interface_descriptor->bInterfaceClass = 0xff; /* LIBUSB_CLASS_VENDOR_SPEC */ + tmp_interface_descriptor->bInterfaceSubClass = 0x51; /* GOOGLE_RAIDEN_SPI_SUBCLASS */ + tmp_interface_descriptor->bInterfaceProtocol = 0x01; /* GOOGLE_RAIDEN_SPI_PROTOCOL_V1 */ + tmp_interface_descriptor->bNumEndpoints = 2; /* in_endpoint and out_endpoint */ + tmp_interface_descriptor->endpoint = tmp_endpoint; + + tmp_interface->num_altsetting = 1; + tmp_interface->altsetting = tmp_interface_descriptor; + + (*config)->bConfigurationValue = 0; + (*config)->bNumInterfaces = 1; + (*config)->interface = tmp_interface; + + return 0; +} + +void raiden_debug_libusb_free_config_descriptor(void *state, libusb_config_descriptor *config) +{ + free(config->interface->altsetting->endpoint); + free(config->interface->altsetting); + free(config->interface); + free(config); +} + +void raiden_debug_init_and_shutdown_test_success(void **state) +{ +#if CONFIG_RAIDEN_DEBUG_SPI == 1 + const struct io_mock raiden_debug_io = { + .libusb_get_device_list = raiden_debug_libusb_get_device_list, + .libusb_free_device_list = raiden_debug_libusb_free_device_list, + .libusb_get_device_descriptor = raiden_debug_libusb_get_device_descriptor, + .libusb_get_config_descriptor = raiden_debug_libusb_get_config_descriptor, + .libusb_free_config_descriptor = raiden_debug_libusb_free_config_descriptor, + }; + + char raiden_debug_param[20]; + sprintf(raiden_debug_param, "address=%s", USB_DEVICE_ADDRESS); + + io_mock_register(&raiden_debug_io); + + run_lifecycle(state, &programmer_raiden_debug_spi, raiden_debug_param); + + io_mock_register(NULL); +#else + skip(); +#endif +}
int dediprog_libusb_init(void *state, libusb_context **ctx) { diff --git a/tests/io_mock.h b/tests/io_mock.h index 237238c..425d9a9 100644 --- a/tests/io_mock.h +++ b/tests/io_mock.h @@ -43,8 +43,63 @@ void *not_null(void);
/* Define libusb symbols to avoid dependency on libusb.h */ + +/* Address value needs fit into uint8_t, represented as string to use as programmer param. */ +#define USB_DEVICE_ADDRESS "19" + +struct libusb_endpoint_descriptor { + uint8_t offset1[2]; + uint8_t bEndpointAddress; + uint8_t bmAttributes; + uint8_t offset2[5]; + unsigned char *extra; + int extra_length; +}; +typedef struct libusb_endpoint_descriptor libusb_endpoint_descriptor; + +struct libusb_interface_descriptor { + uint8_t offset1[2]; + uint8_t bInterfaceNumber; + uint8_t bAlternateSetting; + uint8_t bNumEndpoints; + uint8_t bInterfaceClass; + uint8_t bInterfaceSubClass; + uint8_t bInterfaceProtocol; + uint8_t offset2; + struct libusb_endpoint_descriptor *endpoint; +}; +typedef struct libusb_interface_descriptor libusb_interface_descriptor; + +struct libusb_interface { + struct libusb_interface_descriptor *altsetting; + int num_altsetting; +}; +typedef struct libusb_interface libusb_interface; + +struct libusb_config_descriptor { + uint8_t offset1[4]; + uint8_t bNumInterfaces; + uint8_t bConfigurationValue; + uint8_t offset2[3]; + struct libusb_interface *interface; +}; +typedef struct libusb_config_descriptor libusb_config_descriptor; + +struct libusb_device {}; +typedef struct libusb_device libusb_device; + +struct libusb_device_descriptor { + uint8_t offset1[8]; + uint16_t idVendor; + uint16_t idProduct; + uint8_t offset2[5]; + uint8_t bNumConfigurations; +}; +typedef struct libusb_device_descriptor libusb_device_descriptor; + struct libusb_device_handle; typedef struct libusb_device_handle libusb_device_handle; + struct libusb_context; typedef struct libusb_context libusb_context;
@@ -85,6 +140,14 @@ unsigned char *data, uint16_t wLength, unsigned int timeout); + ssize_t (*libusb_get_device_list)(void *state, libusb_context *ctx, libusb_device ***list); + void (*libusb_free_device_list)(void *state, libusb_device **list, int unref_devices); + int (*libusb_get_device_descriptor)(void *state, libusb_device *dev, libusb_device_descriptor *desc); + int (*libusb_get_config_descriptor)(void *state, + libusb_device *dev, + uint8_t config_index, + libusb_config_descriptor **config); + void (*libusb_free_config_descriptor)(void *state, libusb_config_descriptor *config);
/* POSIX File I/O */ int (*open)(void *state, const char *pathname, int flags); diff --git a/tests/libusb_wraps.c b/tests/libusb_wraps.c index 978108e..2454921 100644 --- a/tests/libusb_wraps.c +++ b/tests/libusb_wraps.c @@ -13,6 +13,8 @@ * GNU General Public License for more details. */
+#include <stdlib.h> + #include <include/test.h> #include "io_mock.h"
@@ -31,6 +33,76 @@ return 0; }
+int __wrap_libusb_open(libusb_device *dev, libusb_device_handle **devh) +{ + LOG_ME; + return 0; +} + +int __wrap_libusb_set_auto_detach_kernel_driver(libusb_device_handle *devh, int enable) +{ + LOG_ME; + return 0; +} + +ssize_t __wrap_libusb_get_device_list(libusb_context *ctx, libusb_device ***list) +{ + LOG_ME; + if (get_io() && get_io()->libusb_get_device_list) + return get_io()->libusb_get_device_list(get_io()->state, ctx, list); + return 0; +} + +void __wrap_libusb_free_device_list(libusb_device **list, int unref_devices) +{ + LOG_ME; + if (get_io() && get_io()->libusb_free_device_list) + get_io()->libusb_free_device_list(get_io()->state, list, unref_devices); +} + +uint8_t __wrap_libusb_get_bus_number(libusb_device *dev) +{ + LOG_ME; + return 0; +} + +uint8_t __wrap_libusb_get_device_address(libusb_device *dev) +{ + LOG_ME; + return atoi(USB_DEVICE_ADDRESS); +} + +int __wrap_libusb_get_device_descriptor(libusb_device *dev, libusb_device_descriptor *desc) +{ + LOG_ME; + if (get_io() && get_io()->libusb_get_device_descriptor) + return get_io()->libusb_get_device_descriptor(get_io()->state, dev, desc); + return 0; +} + +int __wrap_libusb_get_config_descriptor( + libusb_device *dev, uint8_t config_index, libusb_config_descriptor **config) +{ + LOG_ME; + if (get_io() && get_io()->libusb_get_config_descriptor) + return get_io()->libusb_get_config_descriptor(get_io()->state, dev, config_index, config); + return 0; +} + +void __wrap_libusb_free_config_descriptor(libusb_config_descriptor *config) +{ + LOG_ME; + if (get_io() && get_io()->libusb_free_config_descriptor) + return get_io()->libusb_free_config_descriptor(get_io()->state, config); + return; +} + +int __wrap_libusb_get_configuration(libusb_device_handle *devh, int *config) +{ + LOG_ME; + return 0; +} + int __wrap_libusb_set_configuration(libusb_device_handle *devh, int config) { LOG_ME; @@ -65,6 +137,17 @@ LOG_ME; }
+libusb_device *__wrap_libusb_ref_device(libusb_device *dev) +{ + LOG_ME; + return NULL; +} + +void __wrap_libusb_unref_device(libusb_device *dev) +{ + LOG_ME; +} + void __wrap_libusb_exit(libusb_context *ctx) { LOG_ME; diff --git a/tests/meson.build b/tests/meson.build index 9179258..587e7e2 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -59,10 +59,22 @@ '-Wl,--wrap=test_inl', '-Wl,--wrap=usb_dev_get_by_vid_pid_number', '-Wl,--wrap=libusb_init', + '-Wl,--wrap=libusb_open', + '-Wl,--wrap=libusb_set_auto_detach_kernel_driver', + '-Wl,--wrap=libusb_get_device_list', + '-Wl,--wrap=libusb_free_device_list', + '-Wl,--wrap=libusb_get_bus_number', + '-Wl,--wrap=libusb_get_device_address', + '-Wl,--wrap=libusb_get_device_descriptor', + '-Wl,--wrap=libusb_get_config_descriptor', + '-Wl,--wrap=libusb_free_config_descriptor', + '-Wl,--wrap=libusb_get_configuration', '-Wl,--wrap=libusb_set_configuration', '-Wl,--wrap=libusb_claim_interface', '-Wl,--wrap=libusb_control_transfer', '-Wl,--wrap=libusb_release_interface', + '-Wl,--wrap=libusb_ref_device', + '-Wl,--wrap=libusb_unref_device', '-Wl,--wrap=libusb_close', '-Wl,--wrap=libusb_exit', '-Wl,--gc-sections', diff --git a/tests/tests.c b/tests/tests.c index b59cb3c..cab093d 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -280,6 +280,7 @@ const struct CMUnitTest init_shutdown_tests[] = { cmocka_unit_test(dummy_init_and_shutdown_test_success), cmocka_unit_test(nicrealtek_init_and_shutdown_test_success), + cmocka_unit_test(raiden_debug_init_and_shutdown_test_success), cmocka_unit_test(dediprog_init_and_shutdown_test_success), cmocka_unit_test(linux_mtd_init_and_shutdown_test_success), cmocka_unit_test(linux_spi_init_and_shutdown_test_success), diff --git a/tests/tests.h b/tests/tests.h index 8e1b6da..b610315 100644 --- a/tests/tests.h +++ b/tests/tests.h @@ -43,6 +43,7 @@ /* init_shutdown.c */ void dummy_init_and_shutdown_test_success(void **state); void nicrealtek_init_and_shutdown_test_success(void **state); +void raiden_debug_init_and_shutdown_test_success(void **state); void dediprog_init_and_shutdown_test_success(void **state); void linux_mtd_init_and_shutdown_test_success(void **state); void linux_spi_init_and_shutdown_test_success(void **state);