From 90ba89408fc2de902cc619be209ae56aa4a4f5ef Mon Sep 17 00:00:00 2001 From: Pawel Szewczyk Date: Thu, 12 Feb 2015 16:01:52 +0100 Subject: [PATCH] libusbgx: tests: Add simulation of configfs for gadget attrs get/set Before executing libusbgx functions which get and set gadget attributes, we must prepare virtual filesystem to behave as expected. push_* and pull_* functions take arguments similar to usbg functions which will be called after them, e.g. push_gadget_attrs(g, a) will prepare for calling usbg_get_gadget_attrs on gadget matching g, where a is value passed to be read. Change-Id: I805544dbd35a1a7f8c2e4073f9f4607d9c70bb95 Signed-off-by: Pawel Szewczyk [Update description] Signed-off-by: Krzysztof Opasiak --- include/usbg/usbg_internal.h | 4 ++ tests/usbg-test.c | 123 +++++++++++++++++++++++++++++++++++++++++++ tests/usbg-test.h | 67 +++++++++++++++++++++++ 3 files changed, 194 insertions(+) diff --git a/include/usbg/usbg_internal.h b/include/usbg/usbg_internal.h index a27a1db..9d99952 100644 --- a/include/usbg/usbg_internal.h +++ b/include/usbg/usbg_internal.h @@ -155,6 +155,10 @@ static inline int file_select(const struct dirent *dent) int usbg_translate_error(int error); +/** + * @brief Names of gadget attributes + */ +extern const char *gadget_attr_names[]; #endif /* USBG_INTERNAL_H */ diff --git a/tests/usbg-test.c b/tests/usbg-test.c index 492aa5a..7f24771 100644 --- a/tests/usbg-test.c +++ b/tests/usbg-test.c @@ -91,6 +91,28 @@ static int dir_id = 0; will_return(readlink, c);\ } while(0) +#define EXPECT_WRITE(file, content) do {\ + file_id++;\ + expect_path(fopen, path, file);\ + will_return(fopen, file_id);\ + expect_value(fputs, stream, file_id);\ + expect_string(fputs, s, content);\ + will_return(fputs, 0);\ + expect_value(fclose, fp, file_id);\ + will_return(fclose, 0);\ +} while(0) + +#define EXPECT_HEX_WRITE(file, content) do {\ + file_id++;\ + expect_path(fopen, path, file);\ + will_return(fopen, file_id);\ + expect_value(fputs, stream, file_id);\ + expect_check(fputs, s, hex_str_equal_display_error, content);\ + will_return(fputs, 0);\ + expect_value(fclose, fp, file_id);\ + will_return(fclose, 0);\ +} while(0) + /** * @brief Compare test gadgets' names */ @@ -334,6 +356,87 @@ void push_init(struct test_state *state) push_gadget(g); } +int get_gadget_attr(usbg_gadget_attrs *attrs, usbg_gadget_attr attr) { + switch (attr) { + case BCD_USB: + return attrs->bcdUSB; + case B_DEVICE_CLASS: + return attrs->bDeviceClass; + case B_DEVICE_SUB_CLASS: + return attrs->bDeviceSubClass; + case B_DEVICE_PROTOCOL: + return attrs->bDeviceProtocol; + case B_MAX_PACKET_SIZE_0: + return attrs->bMaxPacketSize0; + case ID_VENDOR: + return attrs->idVendor; + case ID_PRODUCT: + return attrs->idProduct; + case BCD_DEVICE: + return attrs->bcdDevice; + default: + return -1; + } +} + +void pull_gadget_attribute(struct test_gadget *gadget, + usbg_gadget_attr attr, int value) +{ + char *path; + char *content; + int tmp; + + tmp = asprintf(&path, "%s/%s/%s", + gadget->path, gadget->name, gadget_attr_names[attr]); + if (tmp >= USBG_MAX_PATH_LENGTH) + fail(); + free_later(path); + + tmp = asprintf(&content, "0x%x\n", value); + if (tmp < 0) + fail(); + free_later(content); + + EXPECT_HEX_WRITE(path, content); +} + +void push_gadget_attribute(struct test_gadget *gadget, + usbg_gadget_attr attr, int value) +{ + char *path; + char *content; + int tmp; + + tmp = asprintf(&path, "%s/%s/%s", + gadget->path, gadget->name, gadget_attr_names[attr]); + if (tmp < 0) + fail(); + free_later(path); + + tmp = asprintf(&content, "0x%x\n", value); + if (tmp < 0) + fail(); + free_later(content); + + PUSH_FILE(path, content); +} + +void push_gadget_attrs(struct test_gadget *gadget, usbg_gadget_attrs *attrs) +{ + int i; + + for (i = USBG_GADGET_ATTR_MIN; i < USBG_GADGET_ATTR_MAX; i++) + push_gadget_attribute(gadget, i, get_gadget_attr(attrs, i)); +} + +void pull_gadget_attrs(struct test_gadget *gadget, usbg_gadget_attrs *attrs) +{ + int i; + + for (i = USBG_GADGET_ATTR_MIN; i < USBG_GADGET_ATTR_MAX; i++) + pull_gadget_attribute(gadget, i, get_gadget_attr(attrs, i)); +} + void init_with_state(struct test_state *in, usbg_state **out) { int usbg_ret; @@ -432,6 +535,26 @@ void assert_path_equal(const char *actual, const char *expected) fail(); } +int hex_str_cmp(const char *actual, const char *expected) +{ + int a, b; + + sscanf(actual, "%x", &a); + sscanf(expected, "%x", &b); + + return SIGNUM(a - b); +} + +int hex_str_equal_display_error(const LargestIntegralType actual, const LargestIntegralType expected) +{ + if (hex_str_cmp((const char *)actual, (const char *)expected) == 0) { + return 1; + } + + fprintf(stderr, "%s != %s\n", (const char *)actual, (const char *)expected); + return 0; +} + void for_each_test_function(void **state, FunctionTest fun) { usbg_state *s = NULL; diff --git a/tests/usbg-test.h b/tests/usbg-test.h index 14b47dd..60546fa 100644 --- a/tests/usbg-test.h +++ b/tests/usbg-test.h @@ -113,6 +113,58 @@ void prepare_gadget(struct test_state *state, struct test_gadget *g); void push_init(struct test_state *state); /** + * Prepare specific attributes writting/reading + **/ + +/** + * @brief Get gadget attribute + * @param[in] attrs + * @param[in] attr + */ +int get_gadget_attr(usbg_gadget_attrs *attrs, usbg_gadget_attr attr); + +/** + * @brief Prepare to write given attribute by libusbg + * @param[in] gadget Test gadget related to given attribute + * @param[in] attr Attribute + * @param[in] value Attributes value + **/ +void push_gadget_attribute(struct test_gadget *gadget, + usbg_gadget_attr attr, int value); + +/** + * @brief Prepare to read given attribute by libusbg + * @param[in] gadget Test gadget related to given attribute + * @param[in] attr Attribute + * @param[in] value Attributes value + **/ +void pull_gadget_attribute(struct test_gadget *gadget, + usbg_gadget_attr attr, int value); + +/** + * @brief Prepare fake filesystem to get given gadget attributes + * @details Prepare queue of values passed to wrapped i/o functions, + * all values got from given attributes structure. + * @param[in] gadget Pointer to gadget + * @param[in] attrs Pointer to attributes which gadget should have + * @warning Calling usbg_get_gadget_attrs function whithout this + * preparation and with wrapped i/o may fail. + */ +void push_gadget_attrs(struct test_gadget *gadget, usbg_gadget_attrs *attrs); + +/** + * @brief Prepare fake filesystem for attributes setting attempt. + * @details Prepare queue of values passed to wrapped i/o functions, + * corresponding to functions called on attributes setting + * @param[in] gadget Pointer to gadget + * @param[in] attrs Pointer to expected attributes + * @warning Calling usbg_get_gadget_attrs function whithout this + * preparation and with wrapped i/o may fail. + */ +void pull_gadget_attrs(struct test_gadget *gadget, usbg_gadget_attrs *attrs); + + +/** * @brief Store given pointer on cleanup stack * @details All stacked pointers will be freed by calling cleanup_queue. * This can be used to manage memory needed for single test casees. @@ -178,6 +230,21 @@ int path_cmp(const char *a, const char *b); int path_equal_display_error(const LargestIntegralType actual, const LargestIntegralType expected); /** + * @brief Compare attributes (as strings) + * @return Integer less than, equal to, or greater than zero if a is (respectively) + * less than, equal to, or greater than b. + */ +int hex_str_cmp(const char *actual, const char *expected); + +/** + * @brief Print error when given attributes are not equal + * @return 1 if attributes are equal, 0 otherwise + * @note Argument type is defined by cmocka. This specific function type is defined + * as custom comparing function in cmocka framework. + */ +int hex_str_equal_display_error(const LargestIntegralType actual, const LargestIntegralType expected); + +/** * @brief Assert that given path strings are equal * @details Given pathes don't need to exist */ -- 2.7.4