Anastasia Klimchuk has uploaded this change for review.

View Change

[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);

To view, visit change 57918. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: I880a8637ab02de179df9169c1898230bce4dc1c7
Gerrit-Change-Number: 57918
Gerrit-PatchSet: 1
Gerrit-Owner: Anastasia Klimchuk <aklm@chromium.org>
Gerrit-MessageType: newchange