mirror of
https://github.com/linux-usb-gadgets/libusbgx.git
synced 2025-07-13 08:59:43 +03:00
2754 lines
67 KiB
C
2754 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;
|
|
}
|
|
|
|
static void alloc_random_len_str(char **str)
|
|
{
|
|
int len;
|
|
|
|
len = rand() % USBG_MAX_FILE_SIZE;
|
|
*str = safe_malloc(len);
|
|
memset(*str, 'x', len - 1);
|
|
(*str)[len - 1] = '\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));
|
|
|
|
alloc_random_len_str(&strs->manufacturer);
|
|
alloc_random_len_str(&strs->product);
|
|
alloc_random_len_str(&strs->serial);
|
|
|
|
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);
|
|
usbg_free_gadget_strs(&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);
|
|
usbg_free_config_strs(&strs);
|
|
}
|
|
|
|
/**
|
|
* @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 */
|
|
|
|
__attribute__((unused))
|
|
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;
|
|
}
|
|
|
|
__attribute__((unused))
|
|
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;
|
|
}
|