1
0
Fork 0
mirror of https://github.com/linux-usb-gadgets/libusbgx.git synced 2025-07-13 06:39:44 +03:00
libusbgx/tests/test.c
Krzysztof Opasiak c02dbe391f libusbgx: Keep gadget strs in the same order as in device desc
Let's keep gadget strings in the same order as they appear
in USB device descriptor to avoid mistakes during structure
initialization.

Signed-off-by: Krzysztof Opasiak <k.opasiak@samsung.com>
2016-12-14 15:23:48 +01:00

2739 lines
67 KiB
C

#include <usbg/usbg.h>
#include <stdio.h>
#include <stdarg.h>
#include <setjmp.h>
#include <cmocka.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <getopt.h>
#include <time.h>
#ifdef HAS_LIBCONFIG
#include <libconfig.h>
#endif
#include "usbg-test.h"
/**
* @file tests/test.c
*/
#define USBG_TEST(name, test, setup, teardown) \
{name, test, setup, teardown}
#define FILLED_STR(len, c) \
{ [0 ... len - 2] = c, [len - 1] = '\0' }
/* two levels of macros allow to strigify result of macro expansion */
#define STR(s) #s
#define XSTR(s) STR(s)
/* unique string */
#define UNIQUE XSTR(__COUNTER__)
#define FUNC_FROM_TYPE(t) { \
.type = t, \
.instance = "instance"UNIQUE \
}
#define CONF_FROM_BOUND(b) { \
.label = "c", \
.id = __COUNTER__, \
.bound_funcs = b \
}
static struct usbg_gadget_attrs min_gadget_attrs = {
.bcdUSB = 0x0000,
.bDeviceClass = 0x0,
.bDeviceSubClass = 0x0,
.bDeviceProtocol = 0x0,
.bMaxPacketSize0 = 0x0,
.idVendor = 0x0000,
.idProduct = 0x0000,
.bcdDevice = 0x0000
};
static struct usbg_gadget_attrs max_gadget_attrs = {
.bcdUSB = 0xffff,
.bDeviceClass = 0xff,
.bDeviceSubClass = 0xff,
.bDeviceProtocol = 0xff,
.bMaxPacketSize0 = 0xff,
.idVendor = 0xffff,
.idProduct = 0xffff,
.bcdDevice = 0xffff
};
/* PATH_MAX is limit for path length */
#define LONG_PATH_LEN PATH_MAX/2
static char long_path_str[] = FILLED_STR(LONG_PATH_LEN, 'x');
/* NAME_MAX is limit for filename length */
static char long_usbg_string[] = FILLED_STR(NAME_MAX, 'x');
static struct usbg_config_strs simple_config_strs= {
.configuration = "configuration string"
};
static struct usbg_config_attrs max_config_attrs = {
.bmAttributes = 0xff,
.bMaxPower = 0xff
};
static struct usbg_config_attrs min_config_attrs = {
.bmAttributes = 0x00,
.bMaxPower = 0x00
};
/**
* @brief Simplest udcs names
* @details Used to go through init when testing other things
*/
static char *simple_udcs[] = {
"UDC1",
"UDC2",
NULL
};
static char *long_udcs[] = {
long_usbg_string,
"UDC1",
NULL
};
/**
* @brief Simplest functions names
* @details Used to go through init when testing other things
*/
static struct test_function simple_funcs[] = {
FUNC_FROM_TYPE(USBG_F_ECM),
FUNC_FROM_TYPE(USBG_F_ACM),
TEST_FUNCTION_LIST_END
};
/**
* @brief All functions types
* @details When testing with this in state, check if all func types are
* processed correctly
*/
static struct test_function all_funcs[] = {
FUNC_FROM_TYPE(USBG_F_SERIAL),
FUNC_FROM_TYPE(USBG_F_ACM),
FUNC_FROM_TYPE(USBG_F_OBEX),
FUNC_FROM_TYPE(USBG_F_ECM),
FUNC_FROM_TYPE(USBG_F_SUBSET),
FUNC_FROM_TYPE(USBG_F_NCM),
FUNC_FROM_TYPE(USBG_F_EEM),
FUNC_FROM_TYPE(USBG_F_RNDIS),
FUNC_FROM_TYPE(USBG_F_PHONET),
FUNC_FROM_TYPE(USBG_F_FFS),
TEST_FUNCTION_LIST_END
};
static struct test_function same_type_funcs[] = {
FUNC_FROM_TYPE(USBG_F_SERIAL),
FUNC_FROM_TYPE(USBG_F_SERIAL),
FUNC_FROM_TYPE(USBG_F_SERIAL),
TEST_FUNCTION_LIST_END
};
/**
* @brief No functions at all
* @details Check if gadget with no functions (or config with no bindings)
* is processed correctly.
*/
static struct test_function no_funcs[] = {
TEST_FUNCTION_LIST_END
};
/**
* @brief Simple configs
* @details Used to pass through init when testing other things
*/
static struct test_config simple_confs[] = {
CONF_FROM_BOUND(simple_funcs),
TEST_CONFIG_LIST_END
};
/**
* @brief Configs bound to all avaible function types
*/
static struct test_config all_bindings_confs[] = {
CONF_FROM_BOUND(no_funcs),
CONF_FROM_BOUND(all_funcs),
TEST_CONFIG_LIST_END
};
#define GADGET(n, u, c, f) \
{ \
.name = n, \
.udc = u, \
.configs = c, \
.functions = f \
}
/**
* @brief Simplest gadget
*/
static struct test_gadget simple_gadgets[] = {
GADGET("g1", "UDC1", simple_confs, simple_funcs),
TEST_GADGET_LIST_END
};
/**
* @brief Gadgets with all avaible functions
*/
static struct test_gadget all_funcs_gadgets[] = {
GADGET("all_funcs_gadget1", "UDC1", all_bindings_confs, all_funcs),
TEST_GADGET_LIST_END
};
static struct test_gadget long_udc_gadgets[] = {
GADGET("long_udc_gadgets", long_usbg_string,
simple_confs, simple_funcs),
TEST_GADGET_LIST_END
};
struct test_function_attrs_data {
struct test_state *state;
void *attrs;
};
struct test_data {
struct test_state *state;
struct usbg_state *usbg_state;
};
static int simple_serial_attrs = 42;
static struct usbg_f_net_attrs simple_net_attrs = {
.dev_addr = {}, .host_addr = {}, .ifname = "if", .qmult = 1,
};
static char *simple_phonet_attrs = "if";
static char *simple_ffs_attrs = "0";
static int writable_serial_attrs = 0;
static struct usbg_f_net_attrs writable_net_attrs = {
.dev_addr = {}, .host_addr = {}, .ifname = "", .qmult = 1,
};
static char *writable_phonet_attrs = "";
static char *writable_ffs_attrs = "";
struct test_gadget_strs_data {
struct test_state *state;
struct usbg_gadget_strs *strs;
};
#define STATE(p, g, u) { \
.configfs_path = p, \
.gadgets = g, \
.udcs = u \
}
/**
* @brief Simple state
*/
static struct test_state simple_state =
STATE("config", simple_gadgets, simple_udcs);
/**
* @brief State with all functions avaible
*/
static struct test_state all_funcs_state =
STATE("all_funcs_configfs", all_funcs_gadgets, simple_udcs);
static struct test_state long_path_state =
STATE(long_path_str, simple_gadgets, simple_udcs);
static struct test_state long_udc_state =
STATE("simple_path", long_udc_gadgets, long_udcs);
static struct usbg_config_attrs *get_random_config_attrs()
{
struct usbg_config_attrs *ret;
ret = safe_malloc(sizeof(*ret));
srand(time(NULL));
ret->bmAttributes = rand() % max_config_attrs.bmAttributes;
ret->bMaxPower = rand() % max_config_attrs.bMaxPower;
return ret;
}
static struct usbg_gadget_attrs *get_random_gadget_attrs()
{
struct usbg_gadget_attrs *ret;
ret = safe_malloc(sizeof(*ret));
srand(time(NULL));
ret->bcdUSB = rand() % max_gadget_attrs.bcdUSB;
ret->bDeviceClass = rand() % max_gadget_attrs.bDeviceClass;
ret->bDeviceSubClass = rand() % max_gadget_attrs.bDeviceSubClass;
ret->bDeviceProtocol = rand() % max_gadget_attrs.bDeviceProtocol;
ret->bMaxPacketSize0 = rand() % max_gadget_attrs.bMaxPacketSize0;
ret->idVendor = rand() % max_gadget_attrs.idVendor;
ret->idProduct = rand() % max_gadget_attrs.idProduct;
ret->bcdDevice = rand() % max_gadget_attrs.bcdDevice;
return ret;
}
/**
* @brief Add given attributes to all configs in state
* @return Prepared state where configs has given attributes
*/
static void *prepare_state_with_config_attrs(struct test_state *state,
struct usbg_config_attrs *attrs)
{
struct test_gadget *tg;
struct test_config *tc;
for (tg = state->gadgets; tg->name; ++tg)
for (tc = tg->configs; tc->label; ++tc)
tc->attrs = attrs;
state = prepare_state(state);
return state;
}
static int setup_max_config_attrs_state(void **state)
{
*state = prepare_state_with_config_attrs(&simple_state,
&max_config_attrs);
return 0;
}
static int setup_min_config_attrs_state(void **state)
{
*state = prepare_state_with_config_attrs(&simple_state,
&min_config_attrs);
return 0;
}
static int setup_random_config_attrs_state(void **state)
{
*state = prepare_state_with_config_attrs(&simple_state,
get_random_config_attrs());
return 0;
}
static int setup_simple_config_strs_state(void **state)
{
struct test_gadget *tg;
struct test_config *tc;
for (tg = simple_state.gadgets; tg->name; ++tg)
for (tc = tg->configs; tc->label; ++tc)
tc->strs = &simple_config_strs;
*state = prepare_state(&simple_state);
return 0;
}
/**
* @brief Prepare test_state with one gadget containing given function list
* @details For testing only functions. We put them in a gadget as simply
* as possible.
* @param[in] func Pointer to list of functions
* @return Pointer to test state with given functions
*/
static struct test_state *put_func_in_state(struct test_function *func)
{
struct test_state *st;
struct test_gadget *g;
struct test_config *c;
char **udcs;
st = safe_calloc(1, sizeof(*st));
/* Do not need config */
c = safe_calloc(1, sizeof(*c));
g = safe_calloc(2, sizeof(*g));
udcs = safe_calloc(2, sizeof(*udcs));
g[0].name = "g1";
g[0].udc = "UDC1";
g[0].configs = c;
g[0].functions = func;
g[0].writable = 1;
udcs[0] = "UDC1";
g[0].writable = 1;
st->configfs_path = "config";
st->gadgets = g;
st->udcs = udcs;
st->writable = 1;
st = prepare_state(st);
return st;
}
/**
* @brief Setup simple state with some gadgets, configs and functions
*/
static int setup_simple_state(void **state)
{
*state = prepare_state(&simple_state);
return 0;
}
/**
* @brief Setup state with all avaible functions
*/
static int setup_all_funcs_state(void **state)
{
*state = prepare_state(&all_funcs_state);
return 0;
}
/**
* @brief Setup state with few functions of the same type
*/
static int setup_same_type_funcs_state(void **state)
{
*state = put_func_in_state(same_type_funcs);
return 0;
}
/**
* @brief Setup state with very long path name
*/
static int setup_long_path_state(void **state)
{
*state = prepare_state(&long_path_state);
return 0;
}
/**
* @brief Setup state with long udc name
*/
static int setup_long_udc_state(void **state)
{
*state = prepare_state(&long_udc_state);
return 0;
}
/**
* @brief Setup state with gadget strings of random length
* @param[out] state Pointer to pointer to test_gadget_strs_data structure
* with initialized state and strings
*/
static int setup_random_len_gadget_strs_data(void **state)
{
struct usbg_gadget_strs *strs;
struct test_gadget_strs_data *data;
/* will fill memory with zeros */
strs = safe_calloc(1, sizeof(*strs));
data = safe_malloc(sizeof(*data));
srand(time(NULL));
memset(strs->serial, 'x', rand() % USBG_MAX_STR_LENGTH);
memset(strs->manufacturer, 'x', rand() % USBG_MAX_STR_LENGTH);
memset(strs->product, 'x', rand() % USBG_MAX_STR_LENGTH);
data->strs = strs;
data->state = prepare_state(&simple_state);
*state = data;
return 0;
}
static void *setup_f_attrs(int f_type, void *attrs)
{
struct test_function_attrs_data *data;
struct test_function *func;
data = safe_malloc(sizeof(*data));
func = safe_calloc(2, sizeof(*func));
func[0].type = f_type;
func[0].instance = "0";
func[0].writable = 1;
data->state = put_func_in_state(func);
data->attrs = attrs;
return data;
}
static int setup_f_serial_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_SERIAL, &simple_serial_attrs);
return 0;
}
static int setup_f_serial_writable_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_SERIAL, &writable_serial_attrs);
return 0;
}
static int setup_f_acm_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_ACM, &simple_serial_attrs);
return 0;
}
static int setup_f_acm_writable_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_ACM, &writable_serial_attrs);
return 0;
}
static int setup_f_obex_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_OBEX, &simple_serial_attrs);
return 0;
}
static int setup_f_obex_writable_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_OBEX, &writable_serial_attrs);
return 0;
}
static int setup_f_ecm_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_ECM, &simple_net_attrs);
return 0;
}
static int setup_f_ecm_writable_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_ECM, &writable_net_attrs);
return 0;
}
static int setup_f_subset_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_SUBSET, &simple_net_attrs);
return 0;
}
static int setup_f_subset_writable_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_SUBSET, &writable_net_attrs);
return 0;
}
static int setup_f_ncm_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_NCM, &simple_net_attrs);
return 0;
}
static int setup_f_ncm_writable_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_NCM, &writable_net_attrs);
return 0;
}
static int setup_f_eem_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_EEM, &simple_net_attrs);
return 0;
}
static int setup_f_eem_writable_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_EEM, &writable_net_attrs);
return 0;
}
static int setup_f_rndis_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_RNDIS, &simple_net_attrs);
return 0;
}
static int setup_f_rndis_writable_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_RNDIS, &writable_net_attrs);
return 0;
}
static int setup_f_phonet_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_PHONET, &simple_phonet_attrs);
return 0;
}
static int setup_f_phonet_writable_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_PHONET, &writable_phonet_attrs);
return 0;
}
static int setup_f_ffs_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_FFS, &simple_ffs_attrs);
return 0;
}
static int setup_f_ffs_writable_attrs(void **state)
{
*state = setup_f_attrs(USBG_F_FFS, &writable_ffs_attrs);
return 0;
}
/**
* @brief Tests usbg_get_gadget function with given state
* @details Check if gadgets are returned correctly
*/
static void test_get_gadget(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_gadget(ts, s, assert_gadget_equal);
}
/**
* @brief Tests usbg_get_gadget with non-existing gadget name
* @details Check if get_gadget will not find non-existing gadgets and
* will not cause crash.
*/
static void test_get_gadget_fail(void **state)
{
usbg_gadget *g = NULL;
usbg_state *s = NULL;
struct test_state *st;
safe_init_with_state(state, &st, &s);
g = usbg_get_gadget(s, "non-existing-gadget");
assert_null(g);
}
/**
* @brief Tests usbg_get_first_gadget function
* @details Check if gadget returned by get_first_gadget is actually first one
*/
static void test_get_first_gadget(void **state)
{
usbg_gadget *g = NULL;
usbg_state *s = NULL;
struct test_state *st;
safe_init_with_state(state, &st, &s);
g = usbg_get_first_gadget(s);
assert_non_null(g);
assert_gadget_equal(g, &st->gadgets[0]);
}
/**
* @brief Tests get_first_gadget with invalid arguments
*/
static void test_get_first_gadget_fail(void **state)
{
usbg_gadget *g;
g = usbg_get_first_gadget(NULL);
assert_null(g);
}
static void try_get_gadget_name(usbg_gadget *g, struct test_gadget *tg)
{
const char *name;
name = usbg_get_gadget_name(g);
assert_string_equal(name, tg->name);
}
/**
* @brief Tests getting name of gadget
* @details Check if gadget name is returned correctly
*/
static void test_get_gadget_name(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_gadget(ts, s, try_get_gadget_name);
}
static void try_get_gadget_name_len(usbg_gadget *g, struct test_gadget *tg)
{
int len;
char buf;
int expected;
expected = strlen(tg->name);
len = usbg_get_gadget_name_s(g, &buf, 0);
assert_int_equal(len, expected);
}
/**
* @brief Tests getting name length of gadget
* @details Check if returned name length is equal original
*/
static void test_get_gadget_name_len(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_gadget(ts, s, try_get_gadget_name_len);
}
/**
* @brief Tests getting name of gadget with invalid arguments
* @details Check if trying to get name of wrong (non-existing) gadget
* will not cause crash, but return NULL as expected.
*/
static void test_get_gadget_name_fail(void **state)
{
const char *name;
name = usbg_get_gadget_name(NULL);
assert_null(name);
}
static void try_get_gadget_name_s(usbg_gadget *g, struct test_gadget *tg)
{
char name[USBG_MAX_NAME_LENGTH];
int ret;
ret = usbg_get_gadget_name_s(g, name, USBG_MAX_NAME_LENGTH);
assert_int_equal(ret, strlen(tg->name));
assert_string_equal(name, tg->name);
}
/**
* @brief Tests copying gadget's name
* @details Check if copying gadget name copy actual name correctly
*/
static void test_get_gadget_name_s(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_gadget(ts, s, try_get_gadget_name_s);
}
/**
* @brief Test copying gadet name with invalid arguments
* @details Check if trying to copy gadget name into non-existing buffer,
* or give invalid buffer length, or invalid gadget will be handled by library
* and return correct error codes
*/
static void test_get_gadget_name_s_fail(void **state)
{
usbg_gadget *g = NULL;
usbg_state *s = NULL;
struct test_state *st;
int i = 0;
char name[USBG_MAX_NAME_LENGTH];
int ret;
safe_init_with_state(state, &st, &s);
for (i = 0; st->gadgets[i].name; i++) {
g = usbg_get_gadget(s, st->gadgets[i].name);
assert_non_null(g);
ret = usbg_get_gadget_name_s(g, NULL, USBG_MAX_NAME_LENGTH);
assert_int_equal(ret, USBG_ERROR_INVALID_PARAM);
}
ret = usbg_get_gadget_name_s(NULL, name, USBG_MAX_NAME_LENGTH);
assert_int_equal(ret, USBG_ERROR_INVALID_PARAM);
}
/**
* @brief Tests init by comparing test state and usbg state
* @details Check if usbg state after init match given state and
* if init returned success code
*/
static void test_init(void **state)
{
usbg_state *s = NULL;
struct test_state *st;
safe_init_with_state(state, &st, &s);
assert_state_equal(s, st);
}
/**
* @brief Test getting function by name
* @param[in] state Pointer to pointer to correctly initialized
* test_state structure
*/
static void test_get_function(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_function(ts, s, assert_func_equal);
}
/**
* @brief Tests usbg_get_function with some non-existing functions
* @details Check if get function will return NULL, when invalid
* functions names and types are passed as arguments and will not cause crash.
* @param[in] state Pointer to pointer to correctly initialized
* test_state structure
*/
static void test_get_function_fail(void **state)
{
usbg_state *s = NULL;
usbg_gadget *g = NULL;
usbg_function *f = NULL;
struct test_state *st;
safe_init_with_state(state, &st, &s);
g = usbg_get_first_gadget(s);
assert_non_null(g);
f = usbg_get_function(g, USBG_F_ACM, "non-existing-instance");
assert_null(f);
f = usbg_get_function(g, 9001, "0");
assert_null(f);
}
/**
* @brief Tests function type translation to string
* @param[in] state Pointer to pointer to correctly initialized
* test_state structure
* @details Check if get_function_type_str returns proper strings for all types.
*/
static void test_get_function_type_str(void **state)
{
struct {
usbg_function_type type;
const char *str;
} types[] = {
{USBG_F_SERIAL, "gser"},
{USBG_F_ACM, "acm"},
{USBG_F_OBEX, "obex"},
{USBG_F_ECM, "ecm"},
{USBG_F_SUBSET, "geth"},
{USBG_F_NCM, "ncm"},
{USBG_F_EEM, "eem"},
{USBG_F_RNDIS, "rndis"},
{USBG_F_PHONET, "phonet"},
{USBG_F_FFS, "ffs"},
};
const char *str;
int i;
for (i = 0; i < ARRAY_SIZE(types); i++) {
str = usbg_get_function_type_str(types[i].type);
assert_non_null(str);
assert_string_equal(str, types[i].str);
}
}
static struct {
usbg_gadget_str code;
const char *name;
} gadget_str_names[] = {
{USBG_STR_PRODUCT, "product"},
{USBG_STR_MANUFACTURER, "manufacturer"},
{USBG_STR_SERIAL_NUMBER, "serialnumber"},
};
/**
* @brief Tests gadget codeing name getting
* @param[in] state Pointer to pointer to correctly initialized
* test_state structure
* @details Check if usbg_get_gadget_code_name returns proper
* codeings for all types.
*/
static void test_get_gadget_str_name(void **state)
{
const char *name;
int i;
for (i = 0; i < ARRAY_SIZE(gadget_str_names); i++) {
name = usbg_get_gadget_str_name(gadget_str_names[i].code);
assert_non_null(name);
assert_string_equal(name, gadget_str_names[i].name);
}
}
/**
* @brief Tests gadget codeing code getting by its name
* @param[in] state Pointer to pointer to correctly initialized
* test_state structure
* @details Check if usbg_lookup_gadget_code returns values matching codeings
*/
static void test_lookup_gadget_str(void **state)
{
int i, code;
for (i = 0; i < ARRAY_SIZE(gadget_str_names); i++) {
code = usbg_lookup_gadget_str(gadget_str_names[i].name);
assert_return_code(code, 0);
assert_int_equal(code, gadget_str_names[i].code);
}
}
/**
* @brief Tests function type translation to string with unknown funcs
* @param[in] state Not used parameter
* @details Check if get_function_type_str returns NULL, when given
* function type is unknown.
*/
static void test_get_function_type_str_fail(void **state)
{
const char *str;
str = usbg_get_function_type_str(-1);
assert_null(str);
}
/**
* @brief Get instance of given function and check it
* @param[in] f Usbg function
* @param[in] tf Test function which should match f
*/
static void try_get_function_instance(usbg_function *f,
struct test_function *tf)
{
const char *str;
str = usbg_get_function_instance(f);
assert_string_equal(str, tf->instance);
}
/**
* @brief Tests getting function instance from usbg_function structure
* @param[in] state Pointer to pointer to correctly initialized
* test_state structure
* @details Check if returned instance name is correct.
*/
static void test_get_function_instance(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_function(ts, s, try_get_function_instance);
}
/**
* @brief Cpy instance of given usbg function and check it
* @param[in] f Usbg function
* @param[in] tf Test function which should match f
*/
static void try_get_function_instance_s(usbg_function *f,
struct test_function *tf)
{
char str[USBG_MAX_NAME_LENGTH];
int ret;
int small_len = 2;
ret = usbg_get_function_instance_s(f, str, USBG_MAX_NAME_LENGTH);
assert_int_equal(ret, strlen(tf->instance));
assert_string_equal(str, tf->instance);
ret = usbg_get_function_instance_s(f, str, small_len);
assert_int_equal(ret, strlen(tf->instance));
assert_memory_equal(str, tf->instance, small_len - 1);
assert_int_equal(str[small_len - 1], '\0');
}
/**
* @brief Tests copying function instance from usbg_function structure
* into buffer
* @param[in] state Pointer to pointer to correctly initialized state
* @details Check if buffer contains expected string
*/
static void test_get_function_instance_s(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_function(ts, s, try_get_function_instance_s);
}
/**
* @brief Get function type and check it
* @param[in] f Usbg function
* @param[in] tf Test function which should match f by type
*/
static void try_get_function_type(usbg_function *f, struct test_function *tf)
{
usbg_function_type type;
type = usbg_get_function_type(f);
assert_int_equal(type, tf->type);
}
/**
* @brief Tests getting function type
* @details Check if getting function type returns what was expected.
* State must be proper (init must end with success).
* @param[in] state Pointer to pointer to correctly initialized state
*/
static void test_get_function_type(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_function(ts, s, try_get_function_type);
}
/**
* @brief Check if function instance length is correct
* @param[in] f Usbg function
* @param[in] tf Test function which should match f
*/
static void try_get_function_instance_len(usbg_function *f,
struct test_function *tf)
{
size_t len;
char buf;
len = usbg_get_function_instance_s(f, &buf, 0);
assert_int_equal(len, strlen(tf->instance));
}
/**
* @brief Tests getting length of function instance name
* @details Check if returned instance name length matches
* actual length of instance name
* @param[in] state Pointer to pointer to correctly initialized state
*/
static void test_get_function_instance_len(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_function(ts, s, try_get_function_instance_len);
}
/**
* @brief Tests getting configfs path from usbg state
* @param[in,out] state Pointer to pointer to correctly initialized test state.
* When finished, it contains pointer to usbg_state which should be cleaned.
*/
static void test_get_configfs_path(void **state)
{
usbg_state *s = NULL;
struct test_state *st;
const char *path;
safe_init_with_state(state, &st, &s);
path = usbg_get_configfs_path(s);
assert_path_equal(path, st->configfs_path);
}
/**
* @brief Tests getting configfs path length from usbg state
* @param[in,out] state Pointer to pointer to correctly initialized test state.
* When finished, it contains pointer to usbg_state which should be cleaned.
*/
static void test_get_configfs_path_len(void **state)
{
usbg_state *s = NULL;
struct test_state *st;
char buf;
int ret, len;
safe_init_with_state(state, &st, &s);
ret = usbg_get_configfs_path_s(s, &buf, 0);
len = strlen(st->configfs_path);
assert_int_equal(ret, len);
}
/**
* @brief Tests copying configfs path into buffer
* @param[in,out] state Pointer to pointer to correctly initialized test state.
* When finished, it contains pointer to usbg_state which should be cleaned.
*/
static void test_get_configfs_path_s(void **state)
{
usbg_state *s = NULL;
struct test_state *st;
char path[PATH_MAX];
int ret;
safe_init_with_state(state, &st, &s);
ret = usbg_get_configfs_path_s(s, path, PATH_MAX);
assert_int_equal(ret, strlen(st->configfs_path));
assert_path_equal(path, st->configfs_path);
}
/**
* @brief Tests getting config by name
* @param[in,out] state Pointer to pointer to correctly initialized test state.
* When finished, it contains pointer to usbg_state which should be cleaned.
*/
static void test_get_config(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_config(ts, s, assert_config_equal);
}
static void test_get_config_without_label(void **state)
{
usbg_state *s = NULL;
usbg_gadget *g = NULL;
usbg_config *c = NULL;
struct test_state *ts;
struct test_gadget *tg;
struct test_config *tc;
safe_init_with_state(state, &ts, &s);
for (tg = ts->gadgets; tg->name; tg++) {
g = usbg_get_gadget(s, tg->name);
assert_non_null(g);
for (tc = tg->configs; tc->label; tc++) {
c = usbg_get_config(g, tc->id, NULL);
assert_non_null(c);
assert_config_equal(c, tc);
}
}
}
/**
* @bried Tests getting non-existing config
* @param[in,out] state Pointer to pointer to correctly initialized test state.
* When finished, it contains pointer to usbg_state which should be cleaned.
*/
static void test_get_config_fail(void **state)
{
usbg_state *s = NULL;
usbg_gadget *g = NULL;
usbg_config *c = NULL;
struct test_state *ts;
struct test_gadget *tg;
safe_init_with_state(state, &ts, &s);
for (tg = ts->gadgets; tg->name; tg++) {
g = usbg_get_gadget(s, tg->name);
assert_non_null(g);
c = usbg_get_config(g, 0, "non-existing-config");
assert_null(c);
c = usbg_get_config(g, -9001, "c");
assert_null(c);
c = usbg_get_config(g, -9001, NULL);
assert_null(c);
}
}
/**
* @brief Get config label and check it
* @param[in] c Usbg config
* @param[in] tc Test config which should match c
*/
static void try_get_config_label(usbg_config *c, struct test_config *tc)
{
const char *label;
label = usbg_get_config_label(c);
assert_string_equal(label, tc->label);
}
/**
* @brief Tests getting config label
* @param[in,out] state Pointer to pointer to correctly initialized test state.
* When finished, it contains pointer to usbg_state which should be cleaned.
*/
static void test_get_config_label(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_config(ts, s, try_get_config_label);
}
/**
* @brief Check config id with test structure
* @param[in] c Usbg config
* @param[in] tc Test config which should match c
*/
static void try_get_config_id(usbg_config *c, struct test_config *tc)
{
int id;
id = usbg_get_config_id(c);
assert_int_equal(id, tc->id);
}
/**
* @brief Tests getting config id
* @param[in,out] state Pointer to pointer to correctly initialized test state.
* When finished, it contains pointer to usbg_state which should be cleaned.
*/
static void test_get_config_id(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_config(ts, s, try_get_config_id);
}
/**
* @brief Test getting given attributes from gadgets present in state
* @param[in] s Pointer to usbg state
* @param[in] ts Pointer to test state matching given usbg state
* @param[in] attrs Pointer to gadget attributes which should be put in
* virtual filesystem for writting by usbg
*/
static void try_get_gadget_attrs(usbg_state *s, struct test_state *ts,
struct usbg_gadget_attrs *attrs)
{
usbg_gadget *g = NULL;
struct usbg_gadget_attrs actual;
struct test_gadget *tg;
int ret;
for (tg = ts->gadgets; tg->name; tg++) {
g = usbg_get_gadget(s, tg->name);
assert_non_null(g);
push_gadget_attrs(tg, attrs);
ret = usbg_get_gadget_attrs(g, &actual);
assert_int_equal(ret, 0);
assert_gadget_attrs_equal(&actual, attrs);
}
}
/**
* @brief Tests getting gadget attributes
* @param[in] state Pointer to correctly initialized test_state structure
**/
static void test_get_gadget_attrs(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
try_get_gadget_attrs(s, ts, &min_gadget_attrs);
try_get_gadget_attrs(s, ts, &max_gadget_attrs);
try_get_gadget_attrs(s, ts, get_random_gadget_attrs());
}
/**
* @brief Test setting given attributes on gadgets present in state
* @param[in] s Pointer to usbg state
* @param[in] ts Pointer to test state matching given usbg state
* @param[in] attrs Pointer to gadget attributes to be set
*/
static void try_set_gadget_attrs(usbg_state *s, struct test_state *ts,
struct usbg_gadget_attrs *attrs)
{
usbg_gadget *g = NULL;
struct test_gadget *tg;
int ret;
for (tg = ts->gadgets; tg->name; tg++) {
g = usbg_get_gadget(s, tg->name);
assert_non_null(g);
pull_gadget_attrs(tg, attrs);
ret = usbg_set_gadget_attrs(g, attrs);
assert_int_equal(ret, 0);
}
}
/**
* @brief Tests setting gadget attributes
* @param[in] state Pointer to correctly initialized test_state structure
**/
static void test_set_gadget_attrs(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
try_set_gadget_attrs(s, ts, &min_gadget_attrs);
try_set_gadget_attrs(s, ts, &max_gadget_attrs);
try_set_gadget_attrs(s, ts, get_random_gadget_attrs());
}
/**
* @brief Test setting given attributes on gadgets present in state one by one,
* using functions specific for each attribute
* @param[in] s Pointer to usbg state
* @param[in] ts Pointer to test state matching given usbg state
* @param[in] attrs Pointer to gadget attributes to be set
*/
static void try_set_specific_gadget_attr(usbg_state *s, struct test_state *ts,
struct usbg_gadget_attrs *attrs)
{
usbg_gadget *g = NULL;
struct test_gadget *tg;
int ret;
int i;
int attr;
for (tg = ts->gadgets; tg->name; tg++) {
g = usbg_get_gadget(s, tg->name);
assert_non_null(g);
for (i = USBG_GADGET_ATTR_MIN; i < USBG_GADGET_ATTR_MAX; i++) {
attr = get_gadget_attr(attrs, i);
pull_gadget_attribute(tg, i, attr);
usbg_set_gadget_attr(g, i, attr);
assert_int_equal(ret, 0);
}
}
}
/**
* @brief Tests setting gadget attributes one by one
* @param[in] state Pointer to correctly initialized test_state structure
**/
static void test_set_specific_gadget_attr(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
try_set_specific_gadget_attr(s, ts, &min_gadget_attrs);
try_set_specific_gadget_attr(s, ts, &max_gadget_attrs);
try_set_specific_gadget_attr(s, ts, get_random_gadget_attrs());
}
/**
* @brief Tests getting udc from state
* @param[in] state Pointer to correctly initialized test_state structure
**/
void test_get_udc(void **state)
{
struct test_state *ts;
char **tu;
struct test_gadget *tg;
usbg_state *s = NULL;
usbg_udc *u = NULL;
usbg_gadget *g = NULL;
safe_init_with_state(state, &ts, &s);
for (tu = ts->udcs; *tu; tu++) {
u = usbg_get_udc(s, *tu);
assert_non_null(u);
assert_string_equal(*tu, u->name);
assert_int_equal(s, u->parent);
}
for (tg = ts->gadgets; tg->name; tg++) {
u = usbg_get_udc(s, tg->udc);
g = usbg_get_gadget(s, tg->name);
assert_int_equal(u->gadget, g);
}
}
static void test_get_gadget_attr_str(void **state)
{
struct {
usbg_gadget_attr attr;
const char *str;
} attrs[] = {
{USBG_BCD_USB, "bcdUSB"},
{USBG_B_DEVICE_CLASS, "bDeviceClass"},
{USBG_B_DEVICE_SUB_CLASS, "bDeviceSubClass"},
{USBG_B_DEVICE_PROTOCOL, "bDeviceProtocol"},
{USBG_B_MAX_PACKET_SIZE_0, "bMaxPacketSize0"},
{USBG_ID_VENDOR, "idVendor"},
{USBG_ID_PRODUCT, "idProduct"},
{USBG_BCD_DEVICE, "bcdDevice"},
};
const char *str;
int i, j;
for (i = 0; i < ARRAY_SIZE(attrs); i++) {
str = usbg_get_gadget_attr_str(attrs[i].attr);
assert_non_null(str);
assert_string_equal(str, attrs[i].str);
}
/* Check if iteration over values works */
for (i = USBG_GADGET_ATTR_MIN; i < USBG_GADGET_ATTR_MAX; ++i) {
str = usbg_get_gadget_attr_str(i);
assert_non_null(str);
for (j = 0; j < ARRAY_SIZE(attrs); ++j)
if (attrs[j].attr == i) {
assert_string_equal(str, attrs[j].str);
break;
}
assert_int_not_equal(j, ARRAY_SIZE(attrs));
}
}
static void test_get_gadget_attr_str_fail(void **state)
{
const char *str;
str = usbg_get_gadget_attr_str(USBG_GADGET_ATTR_MIN - 1);
assert_null(str);
str = usbg_get_gadget_attr_str(USBG_GADGET_ATTR_MAX);
assert_null(str);
}
/**
* @brief set gadget strings
* @details Also do it one by one
* @param[in] data Pointer to correctly initialized
* test_gadget_strs_data structure
*/
static void test_set_gadget_strs(void **data)
{
struct test_gadget_strs_data *ts;
struct test_gadget *tg;
usbg_state *s = NULL;
usbg_gadget *g = NULL;
int i;
int ret;
ts = (struct test_gadget_strs_data *)(*data);
*data = NULL;
init_with_state(ts->state, &s);
*data = s;
for (tg = ts->state->gadgets; tg->name; tg++) {
g = usbg_get_gadget(s, tg->name);
pull_gadget_strs(tg, LANG_US_ENG, ts->strs);
ret = usbg_set_gadget_strs(g, LANG_US_ENG, ts->strs);
assert_int_equal(ret, 0);
for (i = 0; i < GADGET_STR_MAX; i++)
pull_gadget_string(tg, LANG_US_ENG, i,
get_gadget_str(ts->strs, i));
ret = usbg_set_gadget_manufacturer(g, LANG_US_ENG,
ts->strs->manufacturer);
assert_int_equal(ret, 0);
ret = usbg_set_gadget_product(g, LANG_US_ENG,
ts->strs->product);
assert_int_equal(ret, 0);
ret = usbg_set_gadget_serial_number(g, LANG_US_ENG,
ts->strs->serial);
assert_int_equal(ret, 0);
for (i = 0; i < GADGET_STR_MAX; i++)
pull_gadget_string(tg, LANG_US_ENG,
i, get_gadget_str(ts->strs, i));
ret = usbg_set_gadget_str(g, USBG_STR_MANUFACTURER,
LANG_US_ENG, ts->strs->manufacturer);
assert_int_equal(ret, 0);
ret = usbg_set_gadget_str(g, USBG_STR_PRODUCT,
LANG_US_ENG, ts->strs->product);
assert_int_equal(ret, 0);
ret = usbg_set_gadget_str(g, USBG_STR_SERIAL_NUMBER,
LANG_US_ENG, ts->strs->serial);
assert_int_equal(ret, 0);
}
}
/**
* @brief get gadget strings
* @param[in] data Pointer to correctly initialized
* test_gadget_strs_data structure
*/
static void test_get_gadget_strs(void **data)
{
struct test_gadget_strs_data *ts;
struct test_gadget *tg;
usbg_state *s = NULL;
usbg_gadget *g = NULL;
struct usbg_gadget_strs strs;
ts = (struct test_gadget_strs_data *)(*data);
*data = NULL;
init_with_state(ts->state, &s);
*data = s;
for (tg = ts->state->gadgets; tg->name; tg++) {
g = usbg_get_gadget(s, tg->name);
push_gadget_strs(tg, LANG_US_ENG, ts->strs);
usbg_get_gadget_strs(g, LANG_US_ENG, &strs);
assert_gadget_strs_equal(&strs, ts->strs);
}
}
/**
* @brief Get binding target
* @details Check if given function is target of given binding
* @param[in] tb Test function
* @param[in] b Binding
*/
static void try_get_binding_target(struct test_binding *tb, usbg_binding *b)
{
usbg_function *f;
f = usbg_get_binding_target(b);
assert_non_null(f);
assert_func_equal(f, tb->target);
}
/**
* @brief Test get binding target
* @details Test all bindings present in given state
* @param[in, out] state Pointer to pointer to correctly initialized test state,
* will point to usbg state when finished.
*/
static void test_get_binding_target(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_binding(ts, s, try_get_binding_target);
}
/**
* @brief Get binding name
* @details Check if name of given binding is equal name of given function
* @param[in] tb Test function
* @param[in] b Binding
*/
static void try_get_binding_name(struct test_binding *tb, usbg_binding *b)
{
const char *s;
s = usbg_get_binding_name(b);
assert_non_null(s);
assert_string_equal(s, tb->name);
}
/**
* @brief Test get bindig name from all binding present in state
* @param[in, out] state Pointer to pointer to correctly initialized test state,
* will point to usbg state when finished.
*/
static void test_get_binding_name(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_binding(ts, s, try_get_binding_name);
}
/**
* @brief Get binding name length
* @param[in] tb Test function
* @param[in] b Binding
*/
static void try_get_binding_name_len(struct test_binding *tb, usbg_binding *b)
{
int n;
char buf;
n = usbg_get_binding_name_s(b, &buf, 0);
assert_int_equal(n, strlen(tb->name));
}
/**
* @brief Test get binding name length from all bindings present in state
* @param[in, out] state Pointer to pointer to correctly initialized test state,
* will point to usbg state when finished.
*/
static void test_get_binding_name_len(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_binding(ts, s, try_get_binding_name_len);
}
/**
* @brief Set config strings
* @param[in] c Config on which string should be set
* @param[in] tc Test config containing strings to be set
*/
static void try_set_config_strs(usbg_config *c, struct test_config *tc)
{
pull_config_strs(tc, LANG_US_ENG, tc->strs);
usbg_set_config_strs(c, LANG_US_ENG, tc->strs);
}
/**
* @brief Test setting strings
* @details Set strings in all configs present in state
* @param[in, out] state Pointer to pointer to correctly initialized test state,
* will point to usbg state when finished.
*/
static void test_set_config_strs(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_config(ts, s, try_set_config_strs);
}
/**
* @brief Set strings one by one on config
* @param[in] c Config on which string should be set
* @param[in] tc Test config containing strings to be set
*/
static void try_set_config_string(usbg_config *c, struct test_config *tc)
{
pull_config_string(tc, LANG_US_ENG, tc->strs->configuration);
usbg_set_config_string(c, LANG_US_ENG, tc->strs->configuration);
}
/**
* @brief Test setting strings one by one
* @details Set strings on all configs present in given state
* @param[in, out] state Pointer to pointer to correctly initialized test state,
* will point to usbg state when finished.
*/
static void test_set_config_string(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_config(ts, s, try_set_config_string);
}
/**
* @brief Get config strings
* @details Assume that given configs have the same strings
* @param[in] c Config from which strings should be get
* @param[in] tc Test config expected to have the same string as c
*/
static void try_get_config_strs(usbg_config *c, struct test_config *tc)
{
struct usbg_config_strs strs;
push_config_strs(tc, LANG_US_ENG, tc->strs);
usbg_get_config_strs(c, LANG_US_ENG, &strs);
assert_string_equal(tc->strs->configuration, strs.configuration);
}
/**
* @brief Test getting congig strings
* @details Get config strings on all configs present in given state
* @param[in, out] state Pointer to pointer to correctly initialized test state,
* will point to usbg state when finished.
*/
static void test_get_config_strs(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_config(ts, s, try_get_config_strs);
}
/**
* @brief Get config attributes
* @details Assume that attributes which will be returned are the same as
* given test state contains.
* @param[in] c Usbg config
* @param[in] tc Test config with set attributes
*/
static void try_get_config_attrs(usbg_config *c, struct test_config *tc)
{
struct usbg_config_attrs attrs;
push_config_attrs(tc, tc->attrs);
usbg_get_config_attrs(c, &attrs);
assert_config_attrs_equal(tc->attrs, &attrs);
}
/**
* @brief Test getting config attributes
* @details Get config attributes on all configfs in state
* @param[in, out] state Pointer to pointer to correctly initialized test state,
* will point to usbg state when finished.
*/
static void test_get_config_attrs(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_config(ts, s, try_get_config_attrs);
}
/**
* @brief Set config attributes in given config
* @param[in] c Usbg config
* @param[in] tc Test config with attributes which will be set
*/
static void try_set_config_attrs(usbg_config *c, struct test_config *tc)
{
pull_config_attrs(tc, tc->attrs);
usbg_set_config_attrs(c, tc->attrs);
}
/**
* @brief Test setting config attributes
* @details Set config attributes on all configs in state
* @param[in, out] state Pointer to pointer to correctly initialized test state,
* will point to usbg state when finished.
*/
static void test_set_config_attrs(void **state)
{
usbg_state *s = NULL;
struct test_state *ts;
safe_init_with_state(state, &ts, &s);
for_each_test_config(ts, s, try_set_config_attrs);
}
/**
* @brieg Test creating config
* @details Start with empty gadgets, add all functions from given state
* @param[in, out] state Pointer to pointer to correctly initialized test state,
* will point to usbg state when finished.
*/
static void test_create_config(void **state)
{
usbg_state *s = NULL;
usbg_gadget *g = NULL;
usbg_config *c = NULL;
struct test_state *ts;
struct test_state *empty;
struct test_gadget *tg;
struct test_config *tc;
ts = (struct test_state *)(*state);
*state = NULL;
empty = build_empty_gadget_state(ts);
init_with_state(empty, &s);
*state = s;
for (tg = ts->gadgets; tg->name; tg++) {
g = usbg_get_gadget(s, tg->name);
assert_non_null(g);
for (tc = tg->configs; tc->label; tc++) {
pull_create_config(tc);
usbg_create_config(g, tc->id, tc->label,
tc->attrs, tc->strs, &c);
assert_config_equal(c, tc);
}
}
}
/**
* @brief Start with empty gadget, add all functions from given one
*/
static void test_create_function(void **state)
{
usbg_state *s = NULL;
usbg_gadget *g = NULL;
usbg_function *f = NULL;
struct test_state *ts;
struct test_state *empty;
struct test_gadget *tg;
struct test_function *tf;
ts = (struct test_state *)(*state);
*state = NULL;
empty = build_empty_gadget_state(ts);
init_with_state(empty, &s);
*state = s;
for (tg = ts->gadgets; tg->name; tg++) {
g = usbg_get_gadget(s, tg->name);
assert_non_null(g);
for (tf = tg->functions; tf->instance; tf++) {
pull_create_function(tf);
usbg_create_function(g, tf->type, tf->instance,
tf->attrs, &f);
assert_func_equal(f, tf);
}
}
}
/**
* @brief Test only one given function for attribute getting
* @param[in] state Pointer to pointer to correctly initialized state
*/
static void test_get_function_attrs(void **state)
{
struct test_function_attrs_data *data;
usbg_state *s;
usbg_function *f;
usbg_gadget *g;
union {
struct usbg_f_net_attrs net;
char *ffs_dev_name;
struct usbg_f_ms_attrs ms;
struct usbg_f_midi_attrs midi;
int serial_port_num;
char *phonet_ifname;
} actual;
int ret;
data = (struct test_function_attrs_data *)(*state);
*state = NULL;
init_with_state(data->state, &s);
*state = s;
g = usbg_get_first_gadget(s);
assert_non_null(g);
f = usbg_get_first_function(g);
assert_non_null(f);
push_function_attrs(&data->state->gadgets[0].functions[0], data->attrs);
ret = usbg_get_function_attrs(f, &actual);
assert_int_equal(ret, 0);
assert_function_attrs_equal(&actual, data->attrs, f->type);
usbg_cleanup_function_attrs(f, &actual);
}
/**
* @brief Test setting attributes in only one given function
* @param[in] state Pointer to pointer to correctly initialized state
*/
static void test_set_function_attrs(void **state)
{
struct test_function_attrs_data *data;
usbg_state *s;
usbg_function *f;
usbg_gadget *g;
int ret;
data = (struct test_function_attrs_data *)(*state);
*state = NULL;
init_with_state(data->state, &s);
*state = s;
g = usbg_get_first_gadget(s);
assert_non_null(g);
f = usbg_get_first_function(g);
assert_non_null(f);
pull_function_attrs(&data->state->gadgets[0].functions[0], data->attrs);
ret = usbg_set_function_attrs(f, data->attrs);
assert_int_equal(ret, 0);
}
/**
*
* @brief cleanup usbg state
*/
static int teardown_state(void **state)
{
usbg_state *s = NULL;
s = (usbg_state *)(*state);
if (s != NULL)
usbg_cleanup(s);
cleanup_stack();
return 0;
}
/* Custom macro for defining test with given name and fixed teardown function */
#define USBG_TEST_TS(name, test, setup) \
USBG_TEST(name, test, setup, teardown_state)
/**
* @page usbg_tests Tests
* @brief This is list of test cases
* @tests_start
*/
#ifndef DOXYGEN
static struct CMUnitTest tests[] = {
#endif
/**
* @usbg_test
* @test_desc{test_init_simple,
* Check if init was successfull on simple configfs state,
* usbg_init}
*/
USBG_TEST_TS("test_init_simple",
test_init, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_init_all_funcs,
* Check if init was successfull when all avaible functions
* are present in configfs,
* usbg_init}
*/
USBG_TEST_TS("test_init_all_funcs",
test_init, setup_all_funcs_state),
/**
* @usbg_test
* @test_desc{test_init_long_path,
* Try to initialize libusbg with long configfs path,
* usbg_init}
*/
USBG_TEST_TS("test_init_long_path",
test_init, setup_long_path_state),
/**
* @usbg_test
* @test_desc{test_init_long_udc,
* Try to initialize libusbg with long udc name,
* usbg_init}
*/
USBG_TEST_TS("test_init_long_udc",
test_init, setup_long_udc_state),
/**
* @usbg_test
* @test_desc{test_get_gadget_simple,
* Check if simple gadget will be correcty returned,
* usbg_get_gadget}
*/
USBG_TEST_TS("test_get_gadget_simple",
test_get_gadget, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_gadget_fail_simple,
* Check if getting non-existing and wrong gadgets cause
* expected failure and error codes are correct,
* usbg_get_gadget}
*/
USBG_TEST_TS("test_get_gadget_fail_simple",
test_get_gadget_fail, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_first_gadget_simple,
* Check if gadget returned by get_first_gadget
* is actually first one,
* usbg_get_first_gadget}
*/
USBG_TEST_TS("test_get_first_gadget_simple",
test_get_first_gadget, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_first_gadget_fail,
* Check if getting first gadget from state returns NULL when
* invalid parameters are passed,
* usbg_get_first_gadget}
*/
unit_test(test_get_first_gadget_fail),
/**
* @usbg_test
* @test_desc{test_get_gadget_name_simple,
* Check if returned gadget name matches expected value,
* usbg_get_gadget_name}
*/
USBG_TEST_TS("test_get_gadget_name_simple",
test_get_gadget_name, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_gadget_name_len,
* Check if returned simple gadget name length matches expected value,
* usbg_get_gadget_name}
*/
USBG_TEST_TS("test_get_gadget_name_len_simple",
test_get_gadget_name_len, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_gadget_name_fail,
* Check if trying to get name of invalid gadget
* cause expected failure (name is null),
* usbg_get_gadget_name}
*/
unit_test(test_get_gadget_name_fail),
/**
* @usbg_test
* @test_desc{test_get_gadget_name_s_simple,
* Check if getting simple gadget name into buffer work as expected,
* usbg_get_gadget_name_s}
*/
USBG_TEST_TS("test_get_gadget_name_s_simple",
test_get_gadget_name_s, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_gadget_name_s_fail_simple,
* Check if writting gadget name into buffer fail when
* invalid parameters are passed,
* usbg_get_gadget_name_s}
*/
USBG_TEST_TS("test_get_gadget_name_s_fail_simple",
test_get_gadget_name_s_fail, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_function_simple,
* Check if function can be correctly get from simple state,
* usbg_get_function}
*/
USBG_TEST_TS("test_get_function_simple",
test_get_function, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_function_all_funcs,
* Check if getting function work on all function types,
* usbg_get_function}
*/
USBG_TEST_TS("test_get_function_all_funcs",
test_get_function, setup_all_funcs_state),
/**
* @usbg_test
* @test_desc{test_get_function_same_type_funcs,
* Check if having multiple functions with the same type does not
* cause failure
* usbg_get_function}
*/
USBG_TEST_TS("test_get_function_same_type_funcs",
test_get_function, setup_same_type_funcs_state),
/**
* @usbg_test
* @test_desc{test_get_function_fail_simple,
* Check if trying to get invalid function's name ends
* with expected error,
* usbg_get_function}
*/
USBG_TEST_TS("test_get_function_fail_simple",
test_get_function_fail, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_function_instance_simple,
* Check if getting simple instance returns what expected,
* usbg_get_function_instance}
*/
USBG_TEST_TS("test_get_function_instance_simple",
test_get_function_instance, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_function_instance_s_simple,
* Check if copying simple instance into buffer returns what expected,
* usbg_get_function_instance_s}
*/
USBG_TEST_TS("test_get_function_instance_s_simple",
test_get_function_instance_s, setup_all_funcs_state),
/**
* @usbg_test
* @test_desc{test_get_function_type_simple,
* Check if function type is returned correctly,
* usbg_get_function_type}
*/
USBG_TEST_TS("test_get_function_type_simple",
test_get_function_type, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_function_type_all_funcs,
* Check if all function types are returned correctly,
* usbg_get_function_type}
*/
USBG_TEST_TS("test_get_function_type_all_funcs",
test_get_function_type, setup_all_funcs_state),
/**
* @usbg_test
* @test_desc{test_get_function_instance_len_simple,
* Check if function instance length is returned correctly,
* usbg_get_function_instance_len}
*/
USBG_TEST_TS("test_get_function_instance_len_simple",
test_get_function_instance_len, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_function_type_str,
* Compare returned function types strings with expected values,
* usbg_get_function_type_str}
*/
unit_test(test_get_function_type_str),
/**
* @usbg_test
* @test_desc{test_get_function_type_str_fail,
* Try to get type string of unknown type,
* usbg_get_function_type_str}
*/
unit_test(test_get_function_type_str_fail),
/**
* @usbg_test
* @test_desc{test_get_configfs_path_simple,
* heck if simple configfs path was returned correctly,
* usbg_get_configfs_path}
*/
USBG_TEST_TS("test_get_configfs_path_simple",
test_get_configfs_path, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_configfs_path_len,
* Check if configfs path length is correctly calculated,
* usbg_get_configfs_path_len}
*/
USBG_TEST_TS("test_get_configfs_path_len_simple",
test_get_configfs_path_len, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_configfs_path_s_simple,
* Copy simple configfs path into buffer and compare with original,
* usbg_get_configfs_path_s}
*/
USBG_TEST_TS("test_get_configfs_path_s_simple",
test_get_configfs_path_s, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_config_simple,
* Check if returned simple config matches original one,
* usbg_get_config}
*/
USBG_TEST_TS("test_get_config_simple",
test_get_config, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_config_without_label_simple,
* Check if returned simple config matches original one,
* usbg_get_config}
*/
USBG_TEST_TS("test_get_config_without_label_simple",
test_get_config_without_label, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_config_fail,
* Check if trying to get non-existing or invalid config
* fails as expected,
* usbg_get_config}*/
USBG_TEST_TS("test_get_config_fail",
test_get_config_fail, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_config_label_simple,
* Check if returned simple config label matches original one,
* usbg_get_config_label}
*/
USBG_TEST_TS("test_get_config_label_simple",
test_get_config_label, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_config_id_simple,
* Check if returned simple config id matches original one,
* usbg_get_config_id}
*/
USBG_TEST_TS("test_get_config_id_simple",
test_get_config_id, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_gadget_attrs_simple,
* Get gadget attributes list and compare them with original,
* usbg_get_gadget_attrs}
*/
USBG_TEST_TS("test_get_gadget_attrs_simple",
test_get_gadget_attrs, setup_simple_state),
/**
* @usbg_tets
* @test_desc{test_set_gadget_attrs_simple,
* Set gadget attributes list\, check if everything is wrote
* as expected,
* usbg_set_gadget_attrs}
*/
USBG_TEST_TS("test_set_gadget_attrs_simple",
test_set_gadget_attrs, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_set_specific_gadget_attr_simple,
* Set gadget attributes one by one,
* usbg_set_gadget_attrs}
*/
USBG_TEST_TS("test_set_specific_gadget_attr_simple",
test_set_specific_gadget_attr, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_udc_simple,
* Get udc name from state,
* usbg_get_udc}
*/
USBG_TEST_TS("test_get_udc_simple",
test_get_udc, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_udc_long,
* Get udc name witch very long name,
* usbg_get_udc}
*/
USBG_TEST_TS("test_get_udc_long",
test_get_udc, setup_long_udc_state),
/**
* @usbg_test
* @test_desc{test_get_gadget_attr_str,
* Compare returned gadget attribute strings witch expected values
* usbg_get_gadget_attr_str}
*/
unit_test(test_get_gadget_attr_str),
/**
* @usbg_test
* @test_desc{test_get_gadget_attr_str_fail,
* Check returned gadget attribute strings for invalid arguments
* usbg_get_gadget_attr_str}
*/
unit_test(test_get_gadget_attr_str_fail),
/**
* @usbg_test
* @test_desc{test_set_gadget_strs_random,
* Set gadget strings of random length,
* usbg_set_gadget_strs}
*/
USBG_TEST_TS("test_set_gadget_strs_random",
test_set_gadget_strs, setup_random_len_gadget_strs_data),
/**
* @usbg_test
* @test_desc{test_get_gadget_strs_random,
* Get gadget strings,
* usbg_get_gadget_strs}
*/
USBG_TEST_TS("test_get_gadget_strs_random",
test_get_gadget_strs, setup_random_len_gadget_strs_data),
/**
* @usbg_test
* @test_desc{test_get_binding_target_simple,
* Get binding target,
* usbg_get_binding_target}
*/
USBG_TEST_TS("test_get_binding_target_simple",
test_get_binding_target, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_binding_name_simple,
* Get binding name,
* usbg_get_binding_name}
*/
USBG_TEST_TS("test_get_binding_name_simple",
test_get_binding_name, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_get_binding_name_len_simple,
* Get binding name length,
* usbg_get_binding_name_len}
*/
USBG_TEST_TS("test_get_binding_name_len_simple",
test_get_binding_name_len, setup_simple_state),
/**
* @usbg_test
* @test_desc{test_set_config_strs_simple,
* Set simple strings in set of configurations,
* usbg_set_config_strs}
*/
USBG_TEST_TS("test_set_config_strs_simple",
test_set_config_strs, setup_simple_config_strs_state),
/**
* @usbg_test
* @test_desc{test_set_config_string_simple,
* Set simple string in set of configurations,
* usbg_set_config_string}
*/
USBG_TEST_TS("test_set_config_string_simple",
test_set_config_string, setup_simple_config_strs_state),
/**
* @usbg_test
* @test_desc{test_get_config_strs_simple,
* Get simple strings from set of configurations,
* usbg_get_config_strs}
*/
USBG_TEST_TS("test_get_config_strs_simple",
test_get_config_strs, setup_simple_config_strs_state),
/**
* @usbg_test
* @test_desc{test_get_config_attrs_max,
* Get config attributes with max values,
* usbg_get_config_attrs}
*/
USBG_TEST_TS("test_get_config_attrs_max",
test_get_config_attrs, setup_max_config_attrs_state),
/**
* @usbg_test
* @test_desc{test_get_config_attrs_min,
* Get config attributes with minimum values,
* usbg_get_config_attrs}
*/
USBG_TEST_TS("test_get_config_attrs_min",
test_get_config_attrs, setup_min_config_attrs_state),
/**
* @usbg_test
* @test_desc{test_get_config_attrs_random,
* Get config attributes with random values,
* usbg_get_config_attrs}
*/
USBG_TEST_TS("test_get_config_attrs_random",
test_get_config_attrs, setup_random_config_attrs_state),
/**
* @usbg_test
* @test_desc{test_set_config_attrs_max,
* Set config attributes with max values,
* usbg_set_config_attrs}
*/
USBG_TEST_TS("test_set_config_attrs_max",
test_set_config_attrs, setup_max_config_attrs_state),
/**
* @usbg_test
* @test_desc{test_set_config_attrs_min,
* Set config attributes with minimum values,
* usbg_set_config_attrs}
*/
USBG_TEST_TS("test_set_config_attrs_min",
test_set_config_attrs, setup_min_config_attrs_state),
/**
* @usbg_test
* @test_desc{test_set_config_attrs_random,
* Set config attributes with random values,
* usbg_set_config_attrs}
*/
USBG_TEST_TS("test_set_config_attrs_random",
test_set_config_attrs, setup_random_config_attrs_state),
/**
* @usbg_test
* @test_desc{test_create_config_random,
* Create config with random attributes
* usbg_create_config}
*/
USBG_TEST_TS("test_create_config_random",
test_create_config, setup_random_config_attrs_state),
/**
* @usbg_test
* @test_desc{test_get_f_serial_attrs,
* Get f_serial function attributes,
* usbg_get_function_attrs}
*/
USBG_TEST_TS("test_get_f_serial_attrs",
test_get_function_attrs, setup_f_serial_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_obex_attrs,
* Get f_obex function attributes,
* usbg_get_function_attrs}
*/
USBG_TEST_TS("test_get_f_obex_attrs",
test_get_function_attrs, setup_f_obex_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_acm_attrs,
* Get f_acm function attributes,
* usbg_get_function_attrs}
*/
USBG_TEST_TS("test_get_f_acm_attrs",
test_get_function_attrs, setup_f_acm_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_ecm_attrs,
* Get f_ecm function attributes,
* usbg_get_function_attrs}
*/
USBG_TEST_TS("test_get_f_ecm_attrs",
test_get_function_attrs, setup_f_ecm_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_eem_attrs,
* Get f_eem function attributes,
* usbg_get_function_attrs}
*/
USBG_TEST_TS("test_get_f_eem_attrs",
test_get_function_attrs, setup_f_eem_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_subset_attrs,
* Get f_subset function attributes,
* usbg_get_function_attrs}
*/
USBG_TEST_TS("test_get_f_subset_attrs",
test_get_function_attrs, setup_f_subset_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_ncm_attrs,
* Get f_ncm function attributes,
* usbg_get_function_attrs}
*/
USBG_TEST_TS("test_get_f_ncm_attrs",
test_get_function_attrs, setup_f_ncm_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_serial_attrs,
* Get f_rndis function attributes,
* usbg_get_function_attrs}
*/
USBG_TEST_TS("test_get_f_rndis_attrs",
test_get_function_attrs, setup_f_rndis_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_phonet_attrs,
* Get f_phonet function attributes,
* usbg_get_function_attrs}
*/
USBG_TEST_TS("test_get_f_phonet_attrs",
test_get_function_attrs, setup_f_phonet_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_serial_attrs,
* Get f_ffs function attributes,
* usbg_get_function_attrs}
*/
USBG_TEST_TS("test_get_f_ffs_attrs",
test_get_function_attrs, setup_f_ffs_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_serial_attrs,
* Set f_serial function attributes,
* usbg_set_function_attrs}
*/
USBG_TEST_TS("test_set_f_serial_attrs",
test_set_function_attrs, setup_f_serial_writable_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_acm_attrs,
* Set f_acm function attributes,
* usbg_set_function_attrs}
*/
USBG_TEST_TS("test_set_f_acm_attrs",
test_set_function_attrs, setup_f_acm_writable_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_serial_obex,
* Set f_obex function attributes,
* usbg_set_function_attrs}
*/
USBG_TEST_TS("test_set_f_obex_attrs",
test_set_function_attrs, setup_f_obex_writable_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_ecm_attrs,
* Set f_ecm function attributes,
* usbg_set_function_attrs}
*/
USBG_TEST_TS("test_set_f_ecm_attrs",
test_set_function_attrs, setup_f_ecm_writable_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_eem_attrs,
* Set f_eem function attributes,
* usbg_set_function_attrs}
*/
USBG_TEST_TS("test_set_f_eem_attrs",
test_set_function_attrs, setup_f_eem_writable_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_subset_attrs,
* Set f_subset function attributes,
* usbg_set_function_attrs}
*/
USBG_TEST_TS("test_set_f_subset_attrs",
test_set_function_attrs, setup_f_subset_writable_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_ncm_attrs,
* Set f_ncm function attributes,
* usbg_set_function_attrs}
*/
USBG_TEST_TS("test_set_f_ncm_attrs",
test_set_function_attrs, setup_f_ncm_writable_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_serial_attrs,
* Set f_rndis function attributes,
* usbg_get_function_attrs}
*/
USBG_TEST_TS("test_set_f_rndis_attrs",
test_set_function_attrs, setup_f_rndis_writable_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_phonet_attrs,
* Set f_phonet function attributes,
* usbg_set_function_attrs}
*/
USBG_TEST_TS("test_set_f_phonet_attrs",
test_set_function_attrs, setup_f_phonet_writable_attrs),
/**
* @usbg_test
* @test_desc{test_get_f_serial_attrs,
* Set f_ffs function attributes,
* usbg_set_function_attrs}
*/
USBG_TEST_TS("test_set_f_ffs_attrs",
test_set_function_attrs, setup_f_ffs_writable_attrs),
/**
* @usbg_test
* @test_desc{test_create_all_functions,
* Create full set of functions in empty state,
* usbg_get_binding_name_len}
*/
USBG_TEST_TS("test_create_all_functions",
test_create_function, setup_all_funcs_state),
/**
* @usbg_test
* @test_desc{test_get_gadget_str_name,
* Compare returned gadget string name with expected
* usbg_get_gadget_str_name}
*/
unit_test(test_get_gadget_str_name),
/**
* @usbg_test
* @test_desc{test_lookup_gadget_str,
* Compare returned gadget string code with expected
* usbg_lookup_gadget_str}
*/
unit_test(test_lookup_gadget_str),
#ifndef DOXYGEN
};
#endif
/**
* @usbg_test
* @tests_end
*/
#define TESTS_TAG "tests"
/* for autotools compability */
#define SKIPPED_CODE 77
#ifdef HAS_LIBCONFIG
static int gen_test_config(FILE *output)
{
config_t cfg;
config_setting_t *root;
config_setting_t *tests_node, *node;
int i;
int ret = SKIPPED_CODE, cfg_ret = 0;
config_init(&cfg);
config_set_tab_width(&cfg, 4);
root = config_root_setting(&cfg);
tests_node = config_setting_add(root, TESTS_TAG, CONFIG_TYPE_LIST);
if (!tests_node) {
ret = -ENOMEM;
goto out;
}
for (i = 0; i < ARRAY_SIZE(tests); ++i) {
node = config_setting_add(tests_node, NULL, CONFIG_TYPE_STRING);
if (!node) {
ret = -ENOMEM;
goto out;
}
cfg_ret = config_setting_set_string(node, tests[i].name);
if (cfg_ret != CONFIG_TRUE) {
ret = -EINVAL;
goto out;
}
}
config_write(&cfg, output);
out:
config_destroy(&cfg);
return ret;
}
#else
static int gen_test_config(FILE *output)
{
fprintf(stderr, "Libconfig is not supported\n");
return -ENOTSUP;
}
#endif /* HAS_LIBCONFIG */
static int lookup_test(const char *name)
{
int i;
for (i = 0; i < ARRAY_SIZE(tests); ++i)
if (!strcmp(name, tests[i].name))
return i;
return -1;
}
static void test_skipped(void **state)
{
skip();
}
#ifdef HAS_LIBCONFIG
static int apply_test_config(FILE *input)
{
config_t cfg;
config_setting_t *root;
config_setting_t *tests_node, *node;
int i, count, ind;
int ret = 0, cfg_ret = 0;
const char *test_name;
char selected[ARRAY_SIZE(tests)];
for (i = 0; i < ARRAY_SIZE(selected); ++i)
selected[i] = 0;
config_init(&cfg);
cfg_ret = config_read(&cfg, input);
if (cfg_ret != CONFIG_TRUE) {
fprintf(stderr, "Wrong config format\n");
ret = -EINVAL;
goto out;
}
root = config_root_setting(&cfg);
tests_node = config_setting_get_member(root, TESTS_TAG);
if (!tests_node || !config_setting_is_list(tests_node)) {
fprintf(stderr, "Missing or incorrect tests list\n");
ret = -EINVAL;
goto out;
}
count = config_setting_length(tests_node);
for (i = 0; i < count; ++i) {
node = config_setting_get_elem(tests_node, i);
if (!node) {
ret = -EINVAL;
goto out;
}
test_name = config_setting_get_string(node);
if (!test_name) {
fprintf(stderr,
"Incorrect tests list. Element %d\n", i);
ret = -EINVAL;
goto out;
}
ind = lookup_test(test_name);
if (ind < 0) {
fprintf(stderr, "Test %s not found.\n", test_name);
ret = -EINVAL;
goto out;
}
selected[ind] = 1;
}
for (i = 0; i < ARRAY_SIZE(selected); ++i) {
if (selected[i])
continue;
tests[i].test_func = &test_skipped;
tests[i].setup_func = NULL;
tests[i].teardown_func = NULL;
}
out:
config_destroy(&cfg);
return ret;
}
#else
static int apply_test_config(FILE *input)
{
fprintf(stderr, "Libconfig is not supported\n");
return -ENOTSUP;
}
#endif /* HAS_LIBCONFIG */
static void print_help()
{
fprintf(stderr,
"libusbgx test suit:\n"
" --generate-config - generates config to stdout and exit\n"
" --use-config - runs test suit using config from stdin\n"
" -h --help - print this message\n"
);
}
int main(int argc, char **argv)
{
enum {
GENERATE_CONFIG = 0x01,
USE_CONFIG = 0x02,
};
int options = 0;
int opt;
int ret = -EINVAL;
static struct option long_options[] = {
{"generate-config", no_argument, 0, 1},
{"use-config", no_argument, 0, 2},
{"help", no_argument, 0, 'h'},
{NULL, 0, 0, 0}
};
while (1) {
opt = getopt_long(argc, argv, "h", long_options, NULL);
if (opt < 0)
break;
switch (opt) {
case 1:
options |= GENERATE_CONFIG;
break;
case 2:
options |= USE_CONFIG;
break;
case 'h':
default:
print_help();
goto out;
}
}
if (optind < argc ||
((options & GENERATE_CONFIG) &&
(options & USE_CONFIG))) {
print_help();
goto out;
}
if (options & GENERATE_CONFIG) {
ret = gen_test_config(stdout);
goto out;
}
if (options & USE_CONFIG) {
ret = apply_test_config(stdin);
if (ret)
goto out;
}
ret = cmocka_run_group_tests(tests, NULL, NULL);
out:
return ret;
}