1
0
Fork 0
mirror of https://github.com/linux-usb-gadgets/libusbgx.git synced 2025-07-13 08:59:43 +03:00
libusbgx/tests/test.c
Andri Yngvason b93da70a34 tests: Mark possibly unused functions as such
This fixes compilation warnings
2024-09-24 22:14:19 +02:00

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;
}