mirror of
https://github.com/libusb/libusb
synced 2024-11-21 14:29:12 -07:00
66e63d68eb
In one case, renamed a variable from `larg` which codespell thought was a typo for `large`. Closes #1411
253 lines
9.3 KiB
C
253 lines
9.3 KiB
C
/* -*- Mode: C; indent-tabs-mode:nil -*- */
|
|
/*
|
|
* Unit tests for libusb_set_option
|
|
* Copyright © 2023 Nathan Hjelm <hjelmn@cs.unm.edu>
|
|
* Copyright © 2023 Google, LLC. All rights reserved.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <inttypes.h>
|
|
#include "libusbi.h"
|
|
#include "libusb_testlib.h"
|
|
|
|
#if defined(_WIN32) && !defined(__CYGWIN__)
|
|
#include <winbase.h>
|
|
|
|
#if defined(ENABLE_LOGGING)
|
|
static int unsetenv(const char *env) {
|
|
return _putenv_s(env, "");
|
|
}
|
|
|
|
static int setenv(const char *env, const char *value, int overwrite) {
|
|
if (getenv(env) && !overwrite)
|
|
return 0;
|
|
return _putenv_s(env, value);
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
#define LIBUSB_TEST_CLEAN_EXIT(code) \
|
|
do { \
|
|
if (test_ctx != NULL) { \
|
|
libusb_exit(test_ctx); \
|
|
} \
|
|
unsetenv("LIBUSB_DEBUG"); \
|
|
return (code); \
|
|
} while (0)
|
|
|
|
/**
|
|
* Fail the test if the expression does not evaluate to LIBUSB_SUCCESS.
|
|
*/
|
|
#define LIBUSB_TEST_RETURN_ON_ERROR(expr) \
|
|
do { \
|
|
int _result = (expr); \
|
|
if (LIBUSB_SUCCESS != _result) { \
|
|
libusb_testlib_logf("Not success (%s) at %s:%d", #expr, \
|
|
__FILE__, __LINE__); \
|
|
LIBUSB_TEST_CLEAN_EXIT(TEST_STATUS_FAILURE); \
|
|
} \
|
|
} while (0)
|
|
|
|
/**
|
|
* Use relational operator to compare two values and fail the test if the
|
|
* comparison is false. Intended to compare integer or pointer types.
|
|
*
|
|
* Example: LIBUSB_EXPECT(==, 0, 1) -> fail, LIBUSB_EXPECT(==, 0, 0) -> ok.
|
|
*/
|
|
#define LIBUSB_EXPECT(operator, lhs, rhs) \
|
|
do { \
|
|
int64_t _lhs = (int64_t)(intptr_t)(lhs), _rhs = (int64_t)(intptr_t)(rhs); \
|
|
if (!(_lhs operator _rhs)) { \
|
|
libusb_testlib_logf("Expected %s (%" PRId64 ") " #operator \
|
|
" %s (%" PRId64 ") at %s:%d", #lhs, \
|
|
(int64_t)(intptr_t)_lhs, #rhs, \
|
|
(int64_t)(intptr_t)_rhs, __FILE__, \
|
|
__LINE__); \
|
|
LIBUSB_TEST_CLEAN_EXIT(TEST_STATUS_FAILURE); \
|
|
} \
|
|
} while (0)
|
|
|
|
|
|
static libusb_testlib_result test_set_log_level_basic(void) {
|
|
#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
|
|
libusb_context *test_ctx = NULL;
|
|
|
|
/* unset LIBUSB_DEBUG if it is set */
|
|
unsetenv("LIBUSB_DEBUG");
|
|
|
|
/* test basic functionality */
|
|
LIBUSB_TEST_RETURN_ON_ERROR(libusb_init_context(&test_ctx, /*options=*/NULL,
|
|
/*num_options=*/0));
|
|
LIBUSB_TEST_RETURN_ON_ERROR(libusb_set_option(test_ctx,
|
|
LIBUSB_OPTION_LOG_LEVEL,
|
|
LIBUSB_LOG_LEVEL_ERROR));
|
|
LIBUSB_EXPECT(==, test_ctx->debug, LIBUSB_LOG_LEVEL_ERROR);
|
|
LIBUSB_TEST_RETURN_ON_ERROR(libusb_set_option(test_ctx,
|
|
LIBUSB_OPTION_LOG_LEVEL,
|
|
LIBUSB_LOG_LEVEL_NONE));
|
|
LIBUSB_EXPECT(==, test_ctx->debug, LIBUSB_LOG_LEVEL_NONE);
|
|
|
|
LIBUSB_TEST_CLEAN_EXIT(TEST_STATUS_SUCCESS);
|
|
#else
|
|
return TEST_STATUS_SKIP;
|
|
#endif
|
|
}
|
|
|
|
static libusb_testlib_result test_set_log_level_default(void) {
|
|
#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
|
|
libusb_context *test_ctx = NULL;
|
|
|
|
/* set the default debug level */
|
|
LIBUSB_TEST_RETURN_ON_ERROR(libusb_set_option(NULL, LIBUSB_OPTION_LOG_LEVEL,
|
|
LIBUSB_LOG_LEVEL_ERROR));
|
|
|
|
LIBUSB_TEST_RETURN_ON_ERROR(libusb_init_context(&test_ctx, /*options=*/NULL,
|
|
/*num_options=*/0));
|
|
/* check that debug level came from the default */
|
|
LIBUSB_EXPECT(==, test_ctx->debug, LIBUSB_LOG_LEVEL_ERROR);
|
|
|
|
/* try to override the old log level. since this was set from the default it
|
|
* should be possible to change it */
|
|
LIBUSB_TEST_RETURN_ON_ERROR(libusb_set_option(test_ctx,
|
|
LIBUSB_OPTION_LOG_LEVEL,
|
|
LIBUSB_LOG_LEVEL_NONE));
|
|
LIBUSB_EXPECT(==, test_ctx->debug, LIBUSB_LOG_LEVEL_NONE);
|
|
|
|
LIBUSB_TEST_CLEAN_EXIT(TEST_STATUS_SUCCESS);
|
|
#else
|
|
return TEST_STATUS_SKIP;
|
|
#endif
|
|
}
|
|
|
|
static libusb_testlib_result test_set_log_level_env(void) {
|
|
#if defined(ENABLE_LOGGING)
|
|
libusb_context *test_ctx = NULL;
|
|
|
|
/* check that libusb_set_option does not change the log level when it was set
|
|
* from the environment. */
|
|
setenv("LIBUSB_DEBUG", "4", /*overwrite=*/0);
|
|
LIBUSB_TEST_RETURN_ON_ERROR(libusb_init_context(&test_ctx, /*options=*/NULL,
|
|
/*num_options=*/0));
|
|
#ifndef ENABLE_DEBUG_LOGGING
|
|
LIBUSB_EXPECT(==, test_ctx->debug, 4);
|
|
#endif
|
|
|
|
LIBUSB_TEST_RETURN_ON_ERROR(libusb_set_option(test_ctx,
|
|
LIBUSB_OPTION_LOG_LEVEL,
|
|
LIBUSB_LOG_LEVEL_ERROR));
|
|
/* environment variable should always override LIBUSB_OPTION_LOG_LEVEL if set */
|
|
#ifndef ENABLE_DEBUG_LOGGING
|
|
LIBUSB_EXPECT(==, test_ctx->debug, 4);
|
|
#endif
|
|
|
|
LIBUSB_TEST_CLEAN_EXIT(TEST_STATUS_SUCCESS);
|
|
#else
|
|
return TEST_STATUS_SKIP;
|
|
#endif
|
|
}
|
|
|
|
|
|
static libusb_testlib_result test_no_discovery(void)
|
|
{
|
|
#if defined(__linux__)
|
|
libusb_context *test_ctx;
|
|
LIBUSB_TEST_RETURN_ON_ERROR(libusb_init_context(&test_ctx, /*options=*/NULL,
|
|
/*num_options=*/0));
|
|
libusb_device **device_list = NULL;
|
|
ssize_t num_devices = libusb_get_device_list(test_ctx, &device_list);
|
|
libusb_free_device_list(device_list, /*unref_devices=*/1);
|
|
libusb_exit(test_ctx);
|
|
test_ctx = NULL;
|
|
|
|
if (num_devices == 0) {
|
|
libusb_testlib_logf("Warning: no devices found, the test will only verify that setting LIBUSB_OPTION_NO_DEVICE_DISCOVERY succeeds.");
|
|
}
|
|
|
|
LIBUSB_EXPECT(>=, num_devices, 0);
|
|
|
|
LIBUSB_TEST_RETURN_ON_ERROR(libusb_set_option(NULL, LIBUSB_OPTION_NO_DEVICE_DISCOVERY));
|
|
LIBUSB_TEST_RETURN_ON_ERROR(libusb_init_context(&test_ctx, /*options=*/NULL,
|
|
/*num_options=*/0));
|
|
device_list = NULL;
|
|
num_devices = libusb_get_device_list(test_ctx, &device_list);
|
|
libusb_free_device_list(device_list, /*unref_devices=*/1);
|
|
|
|
LIBUSB_EXPECT(==, num_devices, 0);
|
|
LIBUSB_TEST_CLEAN_EXIT(TEST_STATUS_SUCCESS);
|
|
#else
|
|
return TEST_STATUS_SKIP;
|
|
#endif
|
|
}
|
|
|
|
#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
|
|
static void LIBUSB_CALL test_log_cb(libusb_context *ctx, enum libusb_log_level level,
|
|
const char *str) {
|
|
UNUSED(ctx);
|
|
UNUSED(level);
|
|
UNUSED(str);
|
|
}
|
|
#endif
|
|
|
|
|
|
static libusb_testlib_result test_set_log_cb(void)
|
|
{
|
|
#if defined(ENABLE_LOGGING) && !defined(ENABLE_DEBUG_LOGGING)
|
|
libusb_context *test_ctx = NULL;
|
|
|
|
/* set the log callback on the context */
|
|
LIBUSB_TEST_RETURN_ON_ERROR(libusb_init_context(&test_ctx, /*options=*/NULL,
|
|
/*num_options=*/0));
|
|
LIBUSB_TEST_RETURN_ON_ERROR(libusb_set_option(test_ctx, LIBUSB_OPTION_LOG_CB,
|
|
test_log_cb));
|
|
|
|
/* check that debug level came from the default */
|
|
LIBUSB_EXPECT(==, test_ctx->log_handler, test_log_cb);
|
|
|
|
libusb_exit(test_ctx);
|
|
test_ctx = NULL;
|
|
|
|
/* set the log callback for all future contexts */
|
|
LIBUSB_TEST_RETURN_ON_ERROR(libusb_set_option(/*ctx=*/NULL, LIBUSB_OPTION_LOG_CB,
|
|
test_log_cb));
|
|
LIBUSB_TEST_RETURN_ON_ERROR(libusb_init_context(&test_ctx, /*options=*/NULL,
|
|
/*num_options=*/0));
|
|
LIBUSB_EXPECT(==, test_ctx->log_handler, test_log_cb);
|
|
|
|
|
|
LIBUSB_TEST_CLEAN_EXIT(TEST_STATUS_SUCCESS);
|
|
#else
|
|
return TEST_STATUS_SKIP;
|
|
#endif
|
|
}
|
|
|
|
static const libusb_testlib_test tests[] = {
|
|
{ "test_set_log_level_basic", &test_set_log_level_basic },
|
|
{ "test_set_log_level_env", &test_set_log_level_env },
|
|
{ "test_no_discovery", &test_no_discovery },
|
|
/* since default options can't be unset, run this one last */
|
|
{ "test_set_log_level_default", &test_set_log_level_default },
|
|
{ "test_set_log_cb", &test_set_log_cb },
|
|
LIBUSB_NULL_TEST
|
|
};
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
return libusb_testlib_run_tests(argc, argv, tests);
|
|
}
|