From bf9b1bdfbd3889d102c97ecd4d4a2e10a213d876 Mon Sep 17 00:00:00 2001 From: nirenjan Date: Tue, 16 Jun 2020 17:30:11 -0700 Subject: [PATCH 01/14] Remove manual tests in favor of cmocka Prior to this change, we needed to add a manual override function to mock the vendor command. Given that cmocka has built-in support for mocking functions, it's better to use that instead. This change simply removes the manual override and any tests that rely on it. --- configure.ac | 6 ++ lib/libx52/Makefile.am | 19 +---- lib/libx52/test_blink_shift.c | 59 ------------- lib/libx52/test_common.c | 155 ---------------------------------- lib/libx52/test_common.h | 94 --------------------- lib/libx52/test_led.c | 122 -------------------------- lib/libx52/test_offset.c | 60 ------------- lib/libx52/x52_common.h | 4 - lib/libx52/x52_control.c | 25 ++---- lib/libx52/x52_core.c | 4 - 10 files changed, 17 insertions(+), 531 deletions(-) delete mode 100644 lib/libx52/test_blink_shift.c delete mode 100644 lib/libx52/test_common.c delete mode 100644 lib/libx52/test_common.h delete mode 100644 lib/libx52/test_led.c delete mode 100644 lib/libx52/test_offset.c diff --git a/configure.ac b/configure.ac index 6599a1e..6d9f155 100644 --- a/configure.ac +++ b/configure.ac @@ -62,6 +62,12 @@ AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([Doxyfile])], [AC_MSG_WARN(["Doxygen not found; continuing without doxygen support"])]) +# cmocka unit tests +AX_PKG_CHECK_MODULES([CMOCKA], [cmocka], [], [have_cmocka=yes], [have_cmocka=no]) +AM_CONDITIONAL([HAVE_CMOCKA], [test "x$have_cmocka" = xyes]) +AM_COND_IF([HAVE_CMOCKA], [], + [AC_MSG_WARN(["cmocka not found; disabling unit test build"])]) + # Check for the presence of tm_gmtoff in struct tm. If we have this, then we # can use it to determine the true GMT offset AC_CHECK_MEMBERS([struct tm.tm_gmtoff],, diff --git a/lib/libx52/Makefile.am b/lib/libx52/Makefile.am index 7c01736..50cb4e5 100644 --- a/lib/libx52/Makefile.am +++ b/lib/libx52/Makefile.am @@ -31,25 +31,12 @@ x52include_HEADERS = libx52.h # pkg-config files pkgconfig_DATA = libx52.pc -check_PROGRAMS = test_offset test_led test_blink_shift - -test_offset_SOURCES = test_offset.c test_common.c -test_offset_CFLAGS = @LIBUSB_CFLAGS@ -test_offset_LDADD = libx52.la - -test_led_SOURCES = test_led.c test_common.c -test_led_CFLAGS = @LIBUSB_CFLAGS@ -test_led_LDADD = libx52.la - -test_blink_shift_SOURCES = test_blink_shift.c test_common.c -test_blink_shift_CFLAGS = @LIBUSB_CFLAGS@ -test_blink_shift_LDADD = libx52.la - +if HAVE_CMOCKA LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh -TESTS = test_offset test_led test_blink_shift +endif # Extra files that need to be in the distribution -EXTRA_DIST = libx52.h x52_commands.h x52_common.h test_common.h README.md +EXTRA_DIST = libx52.h x52_commands.h x52_common.h README.md # Add documentation files to the distribution EXTRA_DIST += \ diff --git a/lib/libx52/test_blink_shift.c b/lib/libx52/test_blink_shift.c deleted file mode 100644 index df54d6b..0000000 --- a/lib/libx52/test_blink_shift.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Saitek X52 Pro MFD & LED driver - * Test program for validating blink and shift functionality - * - * Copyright (C) 2020 Nirenjan Krishnan (nirenjan@nirenjan.org) - * - * SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0 - */ - -#include -#include -#include -#include "x52_common.h" -#include "test_common.h" -#include "x52_commands.h" - -typedef int (*blink_shift_fn)(libx52_device *, uint8_t); - -TEST_STRUCT ( - blink_shift_fn func; - uint8_t state; - struct ivpair data[2]; -) - -#define on 1 -#define off 0 - -#define x52_shift_indicator 0xfd -#define x52_shift_on 0x51 -#define x52_shift_off 0x50 - -#define x52_blink_indicator 0xb4 -#define x52_blink_on 0x51 -#define x52_blink_off 0x50 - -#define TEST(func, state) { #func "/" #state, libx52_set_ ## func, state, {{ x52_ ## func ## _indicator, x52_ ## func ## _ ## state}, {0, 0}}} - -TEST_CASES = { - TEST(blink, on), - TEST(blink, off), - TEST(shift, on), - TEST(shift, off), -}; - -TEST_FUNC() -{ - TEST_INIT(); - int rc = (*test.func)(dev, test.state); - - if (rc != LIBX52_SUCCESS) { - PRINT_FAIL(); - printf("# Expected success, got %d\n", rc); - return; - } - - TEST_VERIFY(test.data); -} - -TEST_MAIN() diff --git a/lib/libx52/test_common.c b/lib/libx52/test_common.c deleted file mode 100644 index 25440e4..0000000 --- a/lib/libx52/test_common.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Saitek X52 Pro MFD & LED driver - * Common functionality for test programs - * - * Copyright (C) 2020 Nirenjan Krishnan (nirenjan@nirenjan.org) - * - * SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0 - */ - -#define _GNU_SOURCE -#include -#include -#include -#include -#include -#include "x52_common.h" -#include "test_common.h" - -#define MAX_DIAGS 32 -#define MAX_DIAG_SZ 256 -static int diag_count; -static char diagnostic[MAX_DIAGS][MAX_DIAG_SZ]; - -#define ADD_DIAG(fmt_str, ...) do { \ - if (diag_count < MAX_DIAGS) { \ - snprintf(diagnostic[diag_count], MAX_DIAG_SZ, fmt_str, ##__VA_ARGS__); \ - diag_count++; \ - } \ -} while(0) - -/* Test vendor command function */ -int x52_test_vendor_command(libx52_device *dev, uint16_t index, uint16_t value) -{ - struct x52_vendor_data *vdata = (struct x52_vendor_data *)dev->hdl; - struct ivpair data = {index, value}; - - if (vdata->written < MAX_SZ) { - vdata->data[vdata->written] = data; - vdata->written++; - } - - return LIBX52_SUCCESS; -} - -/* Check expected data */ -bool x52_test_assert_expected(libx52_device *dev, struct ivpair *data) -{ - int written = 0; - struct x52_vendor_data *vdata = (struct x52_vendor_data *)dev->hdl; - - while((data[written].index != 0 || data[written].value != 0) && written < vdata->written) { - if ((data[written].index != vdata->data[written].index) || - (data[written].value != vdata->data[written].value)) { - ADD_DIAG("Mismatched data at position %d:", written); - ADD_DIAG("\tExpected: {%04x, %04x}", data[written].index, data[written].value); - ADD_DIAG("\tObserved: {%04x, %04x}", vdata->data[written].index, vdata->data[written].value); - return false; - } - - written++; - } - - if (data[written].index != 0 || data[written].value != 0) { - ADD_DIAG("data written %d", written); - ADD_DIAG("Insufficient data written, got only %d, additional expected:", written); - while (data[written].index != 0 && data[written].value != 0) { - ADD_DIAG("\t%04x %04x", data[written].index, data[written].value); - written++; - } - return false; - } - - if (vdata->written > written) { - ADD_DIAG("More data written, expected only %d, got %d", written, vdata->written); - return false; - } - - return true; -} - -void x52_test_print_diagnostics(void) -{ - int i; - for (i = 0; i < diag_count; i++) { - printf("# %s\n", diagnostic[i]); - } -} - -static void _x52_test_print_data(struct ivpair *data) -{ - while (data->index != 0 || data->value != 0) { - printf("%04x/%04x ", data->index, data->value); - data++; - } - puts(""); -} - -void x52_test_print_observed_data(libx52_device *dev) -{ - struct x52_vendor_data *vdata = (struct x52_vendor_data *)dev->hdl; - printf("Observed: "); - _x52_test_print_data(vdata->data); -} - -void x52_test_print_expected_data(struct ivpair *data) -{ - printf("Expected: "); - _x52_test_print_data(data); -} - -/* - * Initialize libx52, close any device handles, create a dummy handle - * and override the vendor command function. - */ -libx52_device *x52_test_init(void) -{ - libx52_device *dev; - struct x52_vendor_data *vdata; - int rc; - - rc = libx52_init(&dev); - if (rc != LIBX52_SUCCESS) { - fputs(libx52_strerror(rc), stderr); - exit(1); - } - - (void)libx52_disconnect(dev); - - /* Allocate memory for vendor data */ - vdata = calloc(1, sizeof(*vdata)); - if (vdata == NULL) { - perror("vendor data calloc"); - libx52_exit(dev); - return NULL; - } - - /* Reset the diagnostics buffers */ - memset(diagnostic, 0, sizeof(diagnostic)); - diag_count = 0; - - /* We don't need the device handle in test code, repurpose it */ - dev->hdl = (libusb_device_handle *)vdata; - - /* Setup vendor command function */ - dev->vendor_cmd_fn = x52_test_vendor_command; - - return dev; -} - -void x52_test_cleanup(libx52_device *dev) -{ - free(dev->hdl); - dev->hdl = NULL; - libx52_exit(dev); -} diff --git a/lib/libx52/test_common.h b/lib/libx52/test_common.h deleted file mode 100644 index 1aaa1a2..0000000 --- a/lib/libx52/test_common.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Saitek X52 Pro MFD & LED driver - * Common functionality for test programs - * - * Copyright (C) 2020 Nirenjan Krishnan (nirenjan@nirenjan.org) - * - * SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0 - */ - -#ifndef _TEST_COMMON_H -#define _TEST_COMMON_H -#include -#include -#include "x52_common.h" - -/* ivpair is a pair of index and value fields that are passed to the - * test vendor command function. - */ -struct ivpair { - uint16_t index; - uint16_t value; -}; - -#define MAX_SZ 100 -struct x52_vendor_data { - int written; - struct ivpair data[MAX_SZ]; -}; - -/* - * Initialize libx52, close any device handles, create a dummy handle - * and override the vendor command function. - */ -libx52_device *x52_test_init(void); - -/* - * Check if expected data matches with written data. Terminate expected - * data with a pair of NULLs - */ -bool x52_test_assert_expected(libx52_device *dev, struct ivpair *data); - -/* Print diagnostics to screen */ -void x52_test_print_diagnostics(void); - -/* Cleanup test data */ -void x52_test_cleanup(libx52_device *dev); - -void x52_test_print_observed_data(libx52_device *dev); -void x52_test_print_expected_data(struct ivpair *data); - -#define PRINT_FAIL() printf("not ok %d %s\n", tc_id+1, test.test_case_id) -#define PRINT_PASS() printf("ok %d %s\n", tc_id+1, test.test_case_id) -#define TEST_STRUCT(...) struct test_case { \ - const char *test_case_id; \ - __VA_ARGS__ \ -}; - -#define TEST_CASES const struct test_case test_cases[] -#define TEST_FUNC() void run_test(int tc_id) -#define TEST_INIT() \ - struct libx52_device *dev = x52_test_init(); \ - struct test_case test = test_cases[tc_id]; - -#define TEST_VERIFY(data) do { \ - int test_rc; \ - test_rc = libx52_update(dev); \ - if (test_rc != LIBX52_SUCCESS) { \ - PRINT_FAIL(); \ - printf("# libx52_update failed, rc = %d\n", test_rc); \ - return; \ - } \ - \ - if (!x52_test_assert_expected(dev, data)) { \ - PRINT_FAIL(); \ - x52_test_print_diagnostics(); \ - x52_test_print_expected_data(data); \ - x52_test_print_observed_data(dev); \ - return; \ - } \ - \ - PRINT_PASS(); \ - x52_test_cleanup(dev); \ -} while(0) - -#define TEST_MAIN() int main() { \ - int i; \ - size_t tc_count = sizeof(test_cases) / sizeof(test_cases[0]); \ - printf("1..%lu\n", tc_count); \ - for (i = 0; i < tc_count; i++) { \ - run_test(i); \ - } \ -} - -#endif // !defined _TEST_COMMON_H diff --git a/lib/libx52/test_led.c b/lib/libx52/test_led.c deleted file mode 100644 index 16b9213..0000000 --- a/lib/libx52/test_led.c +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Saitek X52 Pro MFD & LED driver - * Test program for validating LED sets - * - * Copyright (C) 2020 Nirenjan Krishnan (nirenjan@nirenjan.org) - * - * SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0 - */ - -#include -#include -#include -#include "x52_common.h" -#include "test_common.h" -#include "x52_commands.h" - -TEST_STRUCT ( - libx52_led_id led_id; - libx52_led_state state; - int retval; - struct ivpair data[3]; -) - -#define X52_LED_CMD 0xb8 -#define UNSUPPORTED(led, state) { #led "/" #state " unsupported", LIBX52_LED_ ## led, LIBX52_LED_STATE_ ## state, LIBX52_ERROR_NOT_SUPPORTED} -#define OFF_MONO(led) { #led "/Off", LIBX52_LED_## led, LIBX52_LED_STATE_OFF, LIBX52_SUCCESS, {{X52_LED_CMD, ((LIBX52_LED_ ## led) << 8)}, {0, 0}}} -#define ON(led) { #led "/On", LIBX52_LED_## led, LIBX52_LED_STATE_ON, LIBX52_SUCCESS, {{X52_LED_CMD, ((LIBX52_LED_ ## led) << 8) | 1}, {0, 0}}} -#define OFF_COLOR(led) { #led "/Off", LIBX52_LED_## led, LIBX52_LED_STATE_OFF, LIBX52_SUCCESS, {{X52_LED_CMD, ((LIBX52_LED_ ## led + 0) << 8)}, {X52_LED_CMD, ((LIBX52_LED_ ## led + 1) << 8)}, {0, 0}}} -#define RED(led) { #led "/Red", LIBX52_LED_## led, LIBX52_LED_STATE_RED, LIBX52_SUCCESS, {{X52_LED_CMD, ((LIBX52_LED_ ## led + 0) << 8) | 1}, {X52_LED_CMD, ((LIBX52_LED_ ## led + 1) << 8) | 0}, {0, 0}}} -#define AMBER(led) { #led "/Amber", LIBX52_LED_## led, LIBX52_LED_STATE_AMBER, LIBX52_SUCCESS, {{X52_LED_CMD, ((LIBX52_LED_ ## led + 0) << 8) | 1}, {X52_LED_CMD, ((LIBX52_LED_ ## led + 1) << 8) | 1}, {0, 0}}} -#define GREEN(led) { #led "/Green", LIBX52_LED_## led, LIBX52_LED_STATE_GREEN, LIBX52_SUCCESS, {{X52_LED_CMD, ((LIBX52_LED_ ## led + 0) << 8) | 0}, {X52_LED_CMD, ((LIBX52_LED_ ## led + 1) << 8) | 1}, {0, 0}}} - -TEST_CASES = { - OFF_MONO(FIRE), - ON(FIRE), - UNSUPPORTED(FIRE, RED), - UNSUPPORTED(FIRE, AMBER), - UNSUPPORTED(FIRE, GREEN), - - OFF_COLOR(A), - UNSUPPORTED(A, ON), - RED(A), - AMBER(A), - GREEN(A), - - OFF_COLOR(B), - UNSUPPORTED(B, ON), - RED(B), - AMBER(B), - GREEN(B), - - OFF_COLOR(D), - UNSUPPORTED(D, ON), - RED(D), - AMBER(D), - GREEN(D), - - OFF_COLOR(E), - UNSUPPORTED(E, ON), - RED(E), - AMBER(E), - GREEN(E), - - OFF_COLOR(T1), - UNSUPPORTED(T1, ON), - RED(T1), - AMBER(T1), - GREEN(T1), - - OFF_COLOR(T2), - UNSUPPORTED(T2, ON), - RED(T2), - AMBER(T2), - GREEN(T2), - - OFF_COLOR(T3), - UNSUPPORTED(T3, ON), - RED(T3), - AMBER(T3), - GREEN(T3), - - OFF_COLOR(POV), - UNSUPPORTED(POV, ON), - RED(POV), - AMBER(POV), - GREEN(POV), - - OFF_COLOR(CLUTCH), - UNSUPPORTED(CLUTCH, ON), - RED(CLUTCH), - AMBER(CLUTCH), - GREEN(CLUTCH), - - OFF_MONO(THROTTLE), - ON(THROTTLE), - UNSUPPORTED(THROTTLE, RED), - UNSUPPORTED(THROTTLE, AMBER), - UNSUPPORTED(THROTTLE, GREEN), -}; - - -TEST_FUNC() -{ - TEST_INIT(); - - /* Set the X52Pro flag in dev->flags, otherwise libx52_set_led_state will - * always return not supported - */ - dev->flags = 1; - - int rc = libx52_set_led_state(dev, test.led_id, test.state); - - if (rc != test.retval) { - PRINT_FAIL(); - printf("# Expected retval %d, got %d\n", test.retval, rc); - return; - } - - TEST_VERIFY(test.data); -} - -TEST_MAIN() diff --git a/lib/libx52/test_offset.c b/lib/libx52/test_offset.c deleted file mode 100644 index 6d48193..0000000 --- a/lib/libx52/test_offset.c +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Saitek X52 Pro MFD & LED driver - * Test program for validating offset calculation - * - * Copyright (C) 2020 Nirenjan Krishnan (nirenjan@nirenjan.org) - * - * SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0 - */ - -#include -#include -#include -#include "x52_common.h" -#include "test_common.h" - -TEST_STRUCT ( - int offset_primary; - int offset_secondary; - libx52_clock_id clock_id; - uint16_t x52_clock; - uint16_t x52_offset; -) - -#define TEST(id, o1, o23, offs) {id, o1, o23, LIBX52_CLOCK_2, 0xc1, offs}, {id, o1, o23, LIBX52_CLOCK_3, 0xc2, offs} - -TEST_CASES = { - TEST("Etc/UTC+24|Etc/UTC-24", -1440, +1440, 0), - TEST("Etc/UTC-24|Etc/UTC+24", +1440, -1440, 0x0400), // Negative 0 - TEST("Honolulu|Auckland", -600, +720, 0x0478), // -2 hours - TEST("Auckland|Honolulu", +720, -600, 0x0078), // +2 hours - TEST("Etc/UTC+12|Etc/UTC-14", -720, +840, 0x078), // +2 hours - TEST("Etc/UTC-14|Etc/UTC+12", +840, -720, 0x478), // -2 hours - TEST("PDT|UTC", -420, 0, 0x1a4), // +7 hours - TEST("UTC|PDT", 0, -420, 0x5a4), // -7 hours - TEST("PST|UTC", -480, 0, 0x1e0), // +8 hours - TEST("UTC|PST", 0, -480, 0x5e0), // -8 hours - TEST("Etc/UTC+12|Etc/UTC-12", -720, +720, 0), - TEST("Etc/UTC-12|Etc/UTC+12", +720, -720, 0x0400), -}; - -TEST_FUNC() -{ - TEST_INIT(); - int rc; - struct ivpair data[2] = { 0 }; - - dev->timezone[LIBX52_CLOCK_1] = test.offset_primary; - rc = libx52_set_clock_timezone(dev, test.clock_id, test.offset_secondary); - if (rc != LIBX52_SUCCESS) { - PRINT_FAIL(); - printf("# set_clock_timezone failed, rc = %d\n", rc); - return; - } - - data[0].index = test.x52_clock; - data[0].value = test.x52_offset; - TEST_VERIFY(data); -} - -TEST_MAIN(); diff --git a/lib/libx52/x52_common.h b/lib/libx52/x52_common.h index 8916e4a..c3e8533 100644 --- a/lib/libx52/x52_common.h +++ b/lib/libx52/x52_common.h @@ -25,8 +25,6 @@ #define X52_MFD_LINES 3 #define X52_MFD_CLOCKS 3 -typedef int (*x52_vendor_command)(libx52_device *x52, uint16_t index, uint16_t value); - struct x52_mfd_line { uint8_t text[X52_MFD_LINE_SIZE]; uint8_t length; @@ -53,7 +51,6 @@ struct libx52_device { int timezone[X52_MFD_CLOCKS]; libx52_clock_format time_format[X52_MFD_CLOCKS]; - x52_vendor_command vendor_cmd_fn; }; /** Flag bits */ @@ -108,6 +105,5 @@ static inline uint32_t tst_bit(uint32_t *value, uint32_t bit) } int _x52_translate_libusb_error(enum libusb_error errcode); -int _x52_vendor_command(libx52_device *x52, uint16_t index, uint16_t value); #endif /* !defined X52JOY_COMMON_H */ diff --git a/lib/libx52/x52_control.c b/lib/libx52/x52_control.c index dc3f0ed..420cfc3 100644 --- a/lib/libx52/x52_control.c +++ b/lib/libx52/x52_control.c @@ -66,11 +66,18 @@ int _x52_translate_libusb_error(enum libusb_error errcode) }; } -int _x52_vendor_command(libx52_device *x52, uint16_t index, uint16_t value) +int libx52_vendor_command(libx52_device *x52, uint16_t index, uint16_t value) { int j; int rc = 0; + /* It is possible for the vendor command to be called when the joystick + * is not connected. Check for this and return an appropriate error. + */ + if (!x52->hdl) { + return LIBX52_ERROR_NO_DEVICE; + } + /* Allow retry in case of failure */ for (j = 0; j < 3; j++) { rc = libusb_control_transfer(x52->hdl, @@ -82,22 +89,6 @@ int _x52_vendor_command(libx52_device *x52, uint16_t index, uint16_t value) } } - return rc; -} - -int libx52_vendor_command(libx52_device *x52, uint16_t index, uint16_t value) -{ - int rc = 0; - - /* It is possible for the vendor command to be called when the joystick - * is not connected. Check for this and return an appropriate error. - */ - if (!x52->hdl || !x52->vendor_cmd_fn) { - return LIBX52_ERROR_NO_DEVICE; - } - - rc = (*(x52->vendor_cmd_fn))(x52, index, value); - /* Handle device removal */ if (rc == LIBUSB_ERROR_NO_DEVICE) { /* Physical device has likely been disconnected, disconnect the virtual diff --git a/lib/libx52/x52_core.c b/lib/libx52/x52_core.c index fe42c58..8a0470d 100644 --- a/lib/libx52/x52_core.c +++ b/lib/libx52/x52_core.c @@ -61,7 +61,6 @@ int libx52_disconnect(libx52_device *dev) libusb_close(dev->hdl); dev->hdl = NULL; dev->flags = 0; - dev->vendor_cmd_fn = NULL; } return LIBX52_SUCCESS; @@ -103,9 +102,6 @@ int libx52_connect(libx52_device *dev) dev->hdl = hdl; - /* Use default vendor command function */ - dev->vendor_cmd_fn = _x52_vendor_command; - if (libx52_device_is_x52pro(desc.idProduct)) { set_bit(&(dev->flags), X52_FLAG_IS_PRO); } From 9f37cde7845f03abe51609946c232a9d9839db07 Mon Sep 17 00:00:00 2001 From: nirenjan Date: Wed, 17 Jun 2020 15:06:19 -0700 Subject: [PATCH 02/14] Add generated tests to verify libx52 functionality This change adds a suite of tests in JSON format using a Python script to generate the cmocka based test program. Because we need to wrap some of libusb functionality, we need to rebuild and relink the libx52 sources with the -Wl,--wrap option. --- lib/libx52/Makefile.am | 15 + lib/libx52/x52_test_gen.py | 242 +++++ lib/libx52/x52_tests.json | 1895 ++++++++++++++++++++++++++++++++++++ 3 files changed, 2152 insertions(+) create mode 100755 lib/libx52/x52_test_gen.py create mode 100644 lib/libx52/x52_tests.json diff --git a/lib/libx52/Makefile.am b/lib/libx52/Makefile.am index 50cb4e5..8c9e9ef 100644 --- a/lib/libx52/Makefile.am +++ b/lib/libx52/Makefile.am @@ -33,11 +33,26 @@ pkgconfig_DATA = libx52.pc if HAVE_CMOCKA LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh +TESTS = libx52test +check_PROGRAMS = libx52test + +libx52test_SOURCES = test_libx52.c $(libx52_la_SOURCES) +libx52test_CFLAGS = @LIBUSB_CFLAGS@ -DLOCALEDIR='"$(localedir)"' -I $(top_srcdir) +libx52test_CFLAGS += -DGENERATED_TESTS='"test_libx52.c"' +libx52test_LDFLAGS = -Wl,--wrap=libusb_control_transfer @CMOCKA_LIBS@ @LIBUSB_LIBS@ +libx52test_LDADD = libx52.la + +CLEANFILES = test_libx52.c +test_libx52.c: $(srcdir)/x52_test_gen.py $(srcdir)/x52_tests.json + $(AM_V_GEN) $(PYTHON) $(srcdir)/x52_test_gen.py $(srcdir)/x52_tests.json > $@ endif # Extra files that need to be in the distribution EXTRA_DIST = libx52.h x52_commands.h x52_common.h README.md +# Add test files to the distribution +EXTRA_DIST += x52_test_gen.py x52_tests.json + # Add documentation files to the distribution EXTRA_DIST += \ doc/main.dox \ diff --git a/lib/libx52/x52_test_gen.py b/lib/libx52/x52_test_gen.py new file mode 100755 index 0000000..c64d2d4 --- /dev/null +++ b/lib/libx52/x52_test_gen.py @@ -0,0 +1,242 @@ +#!/usr/bin/env python3 +"""libx52 test generator program, writes test program to stdout""" + +import sys +import json + +_TEST_FILE_HEADER = """/* + * libx52 test program + * + * This file is automatically generated. DO NOT EDIT! + */ + +#include +#include +#include +#include +#include +#include + +#include "x52_common.h" + +static int group_setup(void **state) +{ + libx52_device *dev; + int rc; + + rc = libx52_init(&dev); + if (rc != LIBX52_SUCCESS) { + return rc; + } + + /* Disconnect any potentially connected joysticks */ + (void)libx52_disconnect(dev); + + /* Create a dummy handle so that libx52_update doesn't abort early */ + dev->hdl = (void *)(uintptr_t)(-1); + + *state = dev; + + return 0; +} + +static int group_teardown(void **state) +{ + libx52_device *dev = *state; + + dev->hdl = NULL; + libx52_exit(dev); + return 0; +} + +static int test_setup(void **state) +{ + libx52_device *dev = *state; + void *context = dev->ctx; + void *handle = dev->hdl; + memset(dev, 0, sizeof(*dev)); + dev->ctx = context; + dev->hdl = handle; + /* Set flags to 1 to indicate that we are testing X52 Pro */ + dev->flags = 1; + + return 0; +} + +int __wrap_libusb_control_transfer(libusb_device_handle *dev_handle, + uint8_t request_type, + uint8_t bRequest, + uint16_t wValue, + uint16_t wIndex, + unsigned char *data, + uint16_t wLength, + unsigned int timeout) +{ + function_called(); + check_expected(wIndex); + check_expected(wValue); + assert_int_equal(request_type, + LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_OUT); + assert_int_equal(bRequest, 0x91); + assert_null(data); + assert_int_equal(wLength, 0); + assert_int_equal(timeout, 5000); + + return mock(); +} + +""" + +_TEST_FUNCTION_HEADER = """ +static void {}(void **state) +{{ + libx52_device *dev = *state; + int rc; +""" + +_TEST_FUNCTION_FOOTER_NORMAL = """ + assert_int_equal(rc, LIBX52_SUCCESS); + + rc = libx52_update(dev); + assert_int_equal(rc, LIBX52_SUCCESS); +} +""" + +_TEST_FUNCTION_FOOTER_ERROR = """ + assert_int_equal(rc, LIBX52_ERROR_{}); +}} +""" + +class Test(): + """Test case class, single test""" + + def __init__(self, group, obj): + """Load test case from an object""" + self.function = group.function + self.name = group.name + self.params_prefix = group.params_prefix + self.params = obj["params"] + if len(self.params_prefix) < len(self.params): + self.params_prefix.extend([''] * (len(self.params) - len(self.params_prefix))) + + self.output = obj.get("output", []) + self.retval = obj.get("retval", "") + + def definition(self): + test_name = self.name + '_' + '_'.join(p.strip('"') for p in self.params) + return test_name.lower() + + def print(self): + print(_TEST_FUNCTION_HEADER.format(self.definition())) + + if self.output: + print(" expect_function_calls(__wrap_libusb_control_transfer, {});".format(len(self.output))) + print(" will_return_count(__wrap_libusb_control_transfer, LIBUSB_SUCCESS, {});".format(len(self.output))) + + for idx, val in self.output: + print(" expect_value(__wrap_libusb_control_transfer, wIndex, 0x{});".format(idx)) + print(" expect_value(__wrap_libusb_control_transfer, wValue, 0x{});".format(val)) + + params = ', '.join(''.join(p) for p in zip(self.params_prefix, self.params)) + print(" rc = {}(dev, {});".format(self.function, params)) + + if self.retval: + print(_TEST_FUNCTION_FOOTER_ERROR.format(self.retval)) + else: + print(_TEST_FUNCTION_FOOTER_NORMAL); + +_TEST_GROUP_HEADER = "const struct CMUnitTest tests[] = {" +_TEST_GROUP_FOOTER = """}; + +""" + +class TestGroup(): + """Test group class, contains multiple tests""" + + def __init__(self, name, obj): + """Load test cases from an object""" + self.name = name + self.function = obj["function"] + self.setup_hook = obj.get("setup_hook") + self.params_prefix = obj.get("params_prefix", []) + self.tests = [] + for test in obj["tests"]: + self.tests.append(Test(self, test)) + + def definition(self): + return self.name.lower() + "_tests" + + def print(self): + """Print the test group""" + # Print the test definitions first + for test in self.tests: + test.print() + + # Print the list of test cases + # print(_TEST_GROUP_HEADER.format(self.definition())) + # for test in self.tests: + # print(" cmocka_unit_test_setup({}, test_setup),".format(test.definition())) + # print(_TEST_GROUP_FOOTER) + +_MAIN_HEADER = """ +int main(void) +{ + cmocka_set_message_output(CM_OUTPUT_TAP); + +""" +_MAIN_FOOTER = """ + return 0; +} +""" + +_MAIN = """ +int main(void) +{ + cmocka_set_message_output(CM_OUTPUT_TAP); + cmocka_run_group_tests(tests, group_setup, group_teardown); + return 0; +} +""" + +class TestSuite(): + """Test suite class, contains multiple test cases""" + + def __init__(self, file): + """Load test suite""" + with open(file, 'r') as infile: + self.data = json.load(infile) + self.groups = [] + for group, obj in self.data.items(): + self.groups.append(TestGroup(group, obj)) + + def print(self): + print(_TEST_FILE_HEADER) + + for group in self.groups: + group.print() + + print(_TEST_GROUP_HEADER) + for group in self.groups: + for test in group.tests: + print(" cmocka_unit_test_setup({}, test_setup),".format(test.definition())) + print(_TEST_GROUP_FOOTER) + + print(_MAIN) + # print(_MAIN_HEADER) + # for group in self.groups: + # print(' cmocka_run_group_tests_name("{}", {}, group_setup, group_teardown);'.format( + # group.name, group.definition())) + # print(_MAIN_FOOTER) + + + +def main(): + if len(sys.argv) != 2: + sys.stderr.write('Usage: %s \n' % + sys.argv[0]) + sys.exit(1) + + TestSuite(sys.argv[1]).print() + +if __name__ == "__main__": + main() diff --git a/lib/libx52/x52_tests.json b/lib/libx52/x52_tests.json new file mode 100644 index 0000000..9678f90 --- /dev/null +++ b/lib/libx52/x52_tests.json @@ -0,0 +1,1895 @@ +{ + "LED": { + "function": "libx52_set_led_state", + "params_prefix": ["LIBX52_LED_", "LIBX52_LED_STATE_"], + "tests": [ + { + "params": ["FIRE", "OFF"], + "output": [["00b8", "0100"]] + }, + { + "params": ["FIRE", "ON"], + "output": [["00b8", "0101"]] + }, + { + "params": ["FIRE", "RED"], + "retval": "NOT_SUPPORTED" + }, + { + "params": ["FIRE", "AMBER"], + "retval": "NOT_SUPPORTED" + }, + { + "params": ["FIRE", "GREEN"], + "retval": "NOT_SUPPORTED" + }, + { + "params": ["A", "OFF"], + "output": [["00b8", "0200"], ["00b8", "0300"]] + }, + { + "params": ["A", "ON"], + "retval": "NOT_SUPPORTED" + }, + { + "params": ["A", "RED"], + "output": [["00b8", "0201"], ["00b8", "0300"]] + }, + { + "params": ["A", "AMBER"], + "output": [["00b8", "0201"], ["00b8", "0301"]] + }, + { + "params": ["A", "GREEN"], + "output": [["00b8", "0200"], ["00b8", "0301"]] + }, + { + "params": ["B", "OFF"], + "output": [["00b8", "0400"], ["00b8", "0500"]] + }, + { + "params": ["B", "ON"], + "retval": "NOT_SUPPORTED" + }, + { + "params": ["B", "RED"], + "output": [["00b8", "0401"], ["00b8", "0500"]] + }, + { + "params": ["B", "AMBER"], + "output": [["00b8", "0401"], ["00b8", "0501"]] + }, + { + "params": ["B", "GREEN"], + "output": [["00b8", "0400"], ["00b8", "0501"]] + }, + { + "params": ["D", "OFF"], + "output": [["00b8", "0600"], ["00b8", "0700"]] + }, + { + "params": ["D", "ON"], + "retval": "NOT_SUPPORTED" + }, + { + "params": ["D", "RED"], + "output": [["00b8", "0601"], ["00b8", "0700"]] + }, + { + "params": ["D", "AMBER"], + "output": [["00b8", "0601"], ["00b8", "0701"]] + }, + { + "params": ["D", "GREEN"], + "output": [["00b8", "0600"], ["00b8", "0701"]] + }, + { + "params": ["E", "OFF"], + "output": [["00b8", "0800"], ["00b8", "0900"]] + }, + { + "params": ["E", "ON"], + "retval": "NOT_SUPPORTED" + }, + { + "params": ["E", "RED"], + "output": [["00b8", "0801"], ["00b8", "0900"]] + }, + { + "params": ["E", "AMBER"], + "output": [["00b8", "0801"], ["00b8", "0901"]] + }, + { + "params": ["E", "GREEN"], + "output": [["00b8", "0800"], ["00b8", "0901"]] + }, + { + "params": ["T1", "OFF"], + "output": [["00b8", "0a00"], ["00b8", "0b00"]] + }, + { + "params": ["T1", "ON"], + "retval": "NOT_SUPPORTED" + }, + { + "params": ["T1", "RED"], + "output": [["00b8", "0a01"], ["00b8", "0b00"]] + }, + { + "params": ["T1", "AMBER"], + "output": [["00b8", "0a01"], ["00b8", "0b01"]] + }, + { + "params": ["T1", "GREEN"], + "output": [["00b8", "0a00"], ["00b8", "0b01"]] + }, + { + "params": ["T2", "OFF"], + "output": [["00b8", "0c00"], ["00b8", "0d00"]] + }, + { + "params": ["T2", "ON"], + "retval": "NOT_SUPPORTED" + }, + { + "params": ["T2", "RED"], + "output": [["00b8", "0c01"], ["00b8", "0d00"]] + }, + { + "params": ["T2", "AMBER"], + "output": [["00b8", "0c01"], ["00b8", "0d01"]] + }, + { + "params": ["T2", "GREEN"], + "output": [["00b8", "0c00"], ["00b8", "0d01"]] + }, + { + "params": ["T3", "OFF"], + "output": [["00b8", "0e00"], ["00b8", "0f00"]] + }, + { + "params": ["T3", "ON"], + "retval": "NOT_SUPPORTED" + }, + { + "params": ["T3", "RED"], + "output": [["00b8", "0e01"], ["00b8", "0f00"]] + }, + { + "params": ["T3", "AMBER"], + "output": [["00b8", "0e01"], ["00b8", "0f01"]] + }, + { + "params": ["T3", "GREEN"], + "output": [["00b8", "0e00"], ["00b8", "0f01"]] + }, + { + "params": ["POV", "OFF"], + "output": [["00b8", "1000"], ["00b8", "1100"]] + }, + { + "params": ["POV", "ON"], + "retval": "NOT_SUPPORTED" + }, + { + "params": ["POV", "RED"], + "output": [["00b8", "1001"], ["00b8", "1100"]] + }, + { + "params": ["POV", "AMBER"], + "output": [["00b8", "1001"], ["00b8", "1101"]] + }, + { + "params": ["POV", "GREEN"], + "output": [["00b8", "1000"], ["00b8", "1101"]] + }, + { + "params": ["CLUTCH", "OFF"], + "output": [["00b8", "1200"], ["00b8", "1300"]] + }, + { + "params": ["CLUTCH", "ON"], + "retval": "NOT_SUPPORTED" + }, + { + "params": ["CLUTCH", "RED"], + "output": [["00b8", "1201"], ["00b8", "1300"]] + }, + { + "params": ["CLUTCH", "AMBER"], + "output": [["00b8", "1201"], ["00b8", "1301"]] + }, + { + "params": ["CLUTCH", "GREEN"], + "output": [["00b8", "1200"], ["00b8", "1301"]] + }, + { + "params": ["THROTTLE", "OFF"], + "output": [["00b8", "1400"]] + }, + { + "params": ["THROTTLE", "ON"], + "output": [["00b8", "1401"]] + }, + { + "params": ["THROTTLE", "RED"], + "retval": "NOT_SUPPORTED" + }, + { + "params": ["THROTTLE", "AMBER"], + "retval": "NOT_SUPPORTED" + }, + { + "params": ["THROTTLE", "GREEN"], + "retval": "NOT_SUPPORTED" + } + ] + }, + "MFD": { + "function": "libx52_set_text", + "tests": [ + { + "params": ["0", "\"\"", "0"], + "output": [ + ["00d9", "0000"] + ] + }, + { + "params": ["0", "\"a\"", "1"], + "output": [ + ["00d9", "0000"], + ["00d1", "2061"] + ] + }, + { + "params": ["0", "\"ab\"", "2"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"] + ] + }, + { + "params": ["0", "\"abc\"", "3"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"], + ["00d1", "2063"] + ] + }, + { + "params": ["0", "\"abcd\"", "4"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"], + ["00d1", "6463"] + ] + }, + { + "params": ["0", "\"abcde\"", "5"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"], + ["00d1", "6463"], + ["00d1", "2065"] + ] + }, + { + "params": ["0", "\"abcdef\"", "6"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"], + ["00d1", "6463"], + ["00d1", "6665"] + ] + }, + { + "params": ["0", "\"abcdefg\"", "7"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"], + ["00d1", "6463"], + ["00d1", "6665"], + ["00d1", "2067"] + ] + }, + { + "params": ["0", "\"abcdefgh\"", "8"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"], + ["00d1", "6463"], + ["00d1", "6665"], + ["00d1", "6867"] + ] + }, + { + "params": ["0", "\"abcdefghi\"", "9"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"], + ["00d1", "6463"], + ["00d1", "6665"], + ["00d1", "6867"], + ["00d1", "2069"] + ] + }, + { + "params": ["0", "\"abcdefghij\"", "10"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"], + ["00d1", "6463"], + ["00d1", "6665"], + ["00d1", "6867"], + ["00d1", "6a69"] + ] + }, + { + "params": ["0", "\"abcdefghijk\"", "11"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"], + ["00d1", "6463"], + ["00d1", "6665"], + ["00d1", "6867"], + ["00d1", "6a69"], + ["00d1", "206b"] + ] + }, + { + "params": ["0", "\"abcdefghijkl\"", "12"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"], + ["00d1", "6463"], + ["00d1", "6665"], + ["00d1", "6867"], + ["00d1", "6a69"], + ["00d1", "6c6b"] + ] + }, + { + "params": ["0", "\"abcdefghijklm\"", "13"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"], + ["00d1", "6463"], + ["00d1", "6665"], + ["00d1", "6867"], + ["00d1", "6a69"], + ["00d1", "6c6b"], + ["00d1", "206d"] + ] + }, + { + "params": ["0", "\"abcdefghijklmn\"", "14"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"], + ["00d1", "6463"], + ["00d1", "6665"], + ["00d1", "6867"], + ["00d1", "6a69"], + ["00d1", "6c6b"], + ["00d1", "6e6d"] + ] + }, + { + "params": ["0", "\"abcdefghijklmno\"", "15"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"], + ["00d1", "6463"], + ["00d1", "6665"], + ["00d1", "6867"], + ["00d1", "6a69"], + ["00d1", "6c6b"], + ["00d1", "6e6d"], + ["00d1", "206f"] + ] + }, + { + "params": ["0", "\"abcdefghijklmnop\"", "16"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"], + ["00d1", "6463"], + ["00d1", "6665"], + ["00d1", "6867"], + ["00d1", "6a69"], + ["00d1", "6c6b"], + ["00d1", "6e6d"], + ["00d1", "706f"] + ] + }, + { + "params": ["0", "\"abcdefghijklmnopq\"", "17"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"], + ["00d1", "6463"], + ["00d1", "6665"], + ["00d1", "6867"], + ["00d1", "6a69"], + ["00d1", "6c6b"], + ["00d1", "6e6d"], + ["00d1", "706f"] + ] + }, + { + "params": ["0", "\"abcdefghijklmnopqr\"", "18"], + "output": [ + ["00d9", "0000"], + ["00d1", "6261"], + ["00d1", "6463"], + ["00d1", "6665"], + ["00d1", "6867"], + ["00d1", "6a69"], + ["00d1", "6c6b"], + ["00d1", "6e6d"], + ["00d1", "706f"] + ] + }, + { + "params": ["1", "\"\"", "0"], + "output": [ + ["00da", "0000"] + ] + }, + { + "params": ["1", "\"a\"", "1"], + "output": [ + ["00da", "0000"], + ["00d2", "2061"] + ] + }, + { + "params": ["1", "\"ab\"", "2"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"] + ] + }, + { + "params": ["1", "\"abc\"", "3"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"], + ["00d2", "2063"] + ] + }, + { + "params": ["1", "\"abcd\"", "4"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"], + ["00d2", "6463"] + ] + }, + { + "params": ["1", "\"abcde\"", "5"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"], + ["00d2", "6463"], + ["00d2", "2065"] + ] + }, + { + "params": ["1", "\"abcdef\"", "6"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"], + ["00d2", "6463"], + ["00d2", "6665"] + ] + }, + { + "params": ["1", "\"abcdefg\"", "7"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"], + ["00d2", "6463"], + ["00d2", "6665"], + ["00d2", "2067"] + ] + }, + { + "params": ["1", "\"abcdefgh\"", "8"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"], + ["00d2", "6463"], + ["00d2", "6665"], + ["00d2", "6867"] + ] + }, + { + "params": ["1", "\"abcdefghi\"", "9"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"], + ["00d2", "6463"], + ["00d2", "6665"], + ["00d2", "6867"], + ["00d2", "2069"] + ] + }, + { + "params": ["1", "\"abcdefghij\"", "10"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"], + ["00d2", "6463"], + ["00d2", "6665"], + ["00d2", "6867"], + ["00d2", "6a69"] + ] + }, + { + "params": ["1", "\"abcdefghijk\"", "11"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"], + ["00d2", "6463"], + ["00d2", "6665"], + ["00d2", "6867"], + ["00d2", "6a69"], + ["00d2", "206b"] + ] + }, + { + "params": ["1", "\"abcdefghijkl\"", "12"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"], + ["00d2", "6463"], + ["00d2", "6665"], + ["00d2", "6867"], + ["00d2", "6a69"], + ["00d2", "6c6b"] + ] + }, + { + "params": ["1", "\"abcdefghijklm\"", "13"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"], + ["00d2", "6463"], + ["00d2", "6665"], + ["00d2", "6867"], + ["00d2", "6a69"], + ["00d2", "6c6b"], + ["00d2", "206d"] + ] + }, + { + "params": ["1", "\"abcdefghijklmn\"", "14"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"], + ["00d2", "6463"], + ["00d2", "6665"], + ["00d2", "6867"], + ["00d2", "6a69"], + ["00d2", "6c6b"], + ["00d2", "6e6d"] + ] + }, + { + "params": ["1", "\"abcdefghijklmno\"", "15"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"], + ["00d2", "6463"], + ["00d2", "6665"], + ["00d2", "6867"], + ["00d2", "6a69"], + ["00d2", "6c6b"], + ["00d2", "6e6d"], + ["00d2", "206f"] + ] + }, + { + "params": ["1", "\"abcdefghijklmnop\"", "16"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"], + ["00d2", "6463"], + ["00d2", "6665"], + ["00d2", "6867"], + ["00d2", "6a69"], + ["00d2", "6c6b"], + ["00d2", "6e6d"], + ["00d2", "706f"] + ] + }, + { + "params": ["1", "\"abcdefghijklmnopq\"", "17"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"], + ["00d2", "6463"], + ["00d2", "6665"], + ["00d2", "6867"], + ["00d2", "6a69"], + ["00d2", "6c6b"], + ["00d2", "6e6d"], + ["00d2", "706f"] + ] + }, + { + "params": ["1", "\"abcdefghijklmnopqr\"", "18"], + "output": [ + ["00da", "0000"], + ["00d2", "6261"], + ["00d2", "6463"], + ["00d2", "6665"], + ["00d2", "6867"], + ["00d2", "6a69"], + ["00d2", "6c6b"], + ["00d2", "6e6d"], + ["00d2", "706f"] + ] + }, + { + "params": ["2", "\"\"", "0"], + "output": [ + ["00dc", "0000"] + ] + }, + { + "params": ["2", "\"a\"", "1"], + "output": [ + ["00dc", "0000"], + ["00d4", "2061"] + ] + }, + { + "params": ["2", "\"ab\"", "2"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"] + ] + }, + { + "params": ["2", "\"abc\"", "3"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"], + ["00d4", "2063"] + ] + }, + { + "params": ["2", "\"abcd\"", "4"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"], + ["00d4", "6463"] + ] + }, + { + "params": ["2", "\"abcde\"", "5"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"], + ["00d4", "6463"], + ["00d4", "2065"] + ] + }, + { + "params": ["2", "\"abcdef\"", "6"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"], + ["00d4", "6463"], + ["00d4", "6665"] + ] + }, + { + "params": ["2", "\"abcdefg\"", "7"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"], + ["00d4", "6463"], + ["00d4", "6665"], + ["00d4", "2067"] + ] + }, + { + "params": ["2", "\"abcdefgh\"", "8"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"], + ["00d4", "6463"], + ["00d4", "6665"], + ["00d4", "6867"] + ] + }, + { + "params": ["2", "\"abcdefghi\"", "9"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"], + ["00d4", "6463"], + ["00d4", "6665"], + ["00d4", "6867"], + ["00d4", "2069"] + ] + }, + { + "params": ["2", "\"abcdefghij\"", "10"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"], + ["00d4", "6463"], + ["00d4", "6665"], + ["00d4", "6867"], + ["00d4", "6a69"] + ] + }, + { + "params": ["2", "\"abcdefghijk\"", "11"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"], + ["00d4", "6463"], + ["00d4", "6665"], + ["00d4", "6867"], + ["00d4", "6a69"], + ["00d4", "206b"] + ] + }, + { + "params": ["2", "\"abcdefghijkl\"", "12"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"], + ["00d4", "6463"], + ["00d4", "6665"], + ["00d4", "6867"], + ["00d4", "6a69"], + ["00d4", "6c6b"] + ] + }, + { + "params": ["2", "\"abcdefghijklm\"", "13"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"], + ["00d4", "6463"], + ["00d4", "6665"], + ["00d4", "6867"], + ["00d4", "6a69"], + ["00d4", "6c6b"], + ["00d4", "206d"] + ] + }, + { + "params": ["2", "\"abcdefghijklmn\"", "14"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"], + ["00d4", "6463"], + ["00d4", "6665"], + ["00d4", "6867"], + ["00d4", "6a69"], + ["00d4", "6c6b"], + ["00d4", "6e6d"] + ] + }, + { + "params": ["2", "\"abcdefghijklmno\"", "15"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"], + ["00d4", "6463"], + ["00d4", "6665"], + ["00d4", "6867"], + ["00d4", "6a69"], + ["00d4", "6c6b"], + ["00d4", "6e6d"], + ["00d4", "206f"] + ] + }, + { + "params": ["2", "\"abcdefghijklmnop\"", "16"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"], + ["00d4", "6463"], + ["00d4", "6665"], + ["00d4", "6867"], + ["00d4", "6a69"], + ["00d4", "6c6b"], + ["00d4", "6e6d"], + ["00d4", "706f"] + ] + }, + { + "params": ["2", "\"abcdefghijklmnopq\"", "17"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"], + ["00d4", "6463"], + ["00d4", "6665"], + ["00d4", "6867"], + ["00d4", "6a69"], + ["00d4", "6c6b"], + ["00d4", "6e6d"], + ["00d4", "706f"] + ] + }, + { + "params": ["2", "\"abcdefghijklmnopqr\"", "18"], + "output": [ + ["00dc", "0000"], + ["00d4", "6261"], + ["00d4", "6463"], + ["00d4", "6665"], + ["00d4", "6867"], + ["00d4", "6a69"], + ["00d4", "6c6b"], + ["00d4", "6e6d"], + ["00d4", "706f"] + ] + }, + { + "params": ["3", "\"\"", "0"], + "retval": "INVALID_PARAM" + } + ] + }, + "Brightness": { + "function": "libx52_set_brightness", + "tests": [ + { + "params": ["0", "0"], + "output": [["00b2", "0000"]] + }, + { + "params": ["0", "1"], + "output": [["00b2", "0001"]] + }, + { + "params": ["0", "2"], + "output": [["00b2", "0002"]] + }, + { + "params": ["0", "3"], + "output": [["00b2", "0003"]] + }, + { + "params": ["0", "4"], + "output": [["00b2", "0004"]] + }, + { + "params": ["0", "5"], + "output": [["00b2", "0005"]] + }, + { + "params": ["0", "6"], + "output": [["00b2", "0006"]] + }, + { + "params": ["0", "7"], + "output": [["00b2", "0007"]] + }, + { + "params": ["0", "8"], + "output": [["00b2", "0008"]] + }, + { + "params": ["0", "9"], + "output": [["00b2", "0009"]] + }, + { + "params": ["0", "10"], + "output": [["00b2", "000a"]] + }, + { + "params": ["0", "11"], + "output": [["00b2", "000b"]] + }, + { + "params": ["0", "12"], + "output": [["00b2", "000c"]] + }, + { + "params": ["0", "13"], + "output": [["00b2", "000d"]] + }, + { + "params": ["0", "14"], + "output": [["00b2", "000e"]] + }, + { + "params": ["0", "15"], + "output": [["00b2", "000f"]] + }, + { + "params": ["0", "16"], + "output": [["00b2", "0010"]] + }, + { + "params": ["0", "17"], + "output": [["00b2", "0011"]] + }, + { + "params": ["0", "18"], + "output": [["00b2", "0012"]] + }, + { + "params": ["0", "19"], + "output": [["00b2", "0013"]] + }, + { + "params": ["0", "20"], + "output": [["00b2", "0014"]] + }, + { + "params": ["0", "21"], + "output": [["00b2", "0015"]] + }, + { + "params": ["0", "22"], + "output": [["00b2", "0016"]] + }, + { + "params": ["0", "23"], + "output": [["00b2", "0017"]] + }, + { + "params": ["0", "24"], + "output": [["00b2", "0018"]] + }, + { + "params": ["0", "25"], + "output": [["00b2", "0019"]] + }, + { + "params": ["0", "26"], + "output": [["00b2", "001a"]] + }, + { + "params": ["0", "27"], + "output": [["00b2", "001b"]] + }, + { + "params": ["0", "28"], + "output": [["00b2", "001c"]] + }, + { + "params": ["0", "29"], + "output": [["00b2", "001d"]] + }, + { + "params": ["0", "30"], + "output": [["00b2", "001e"]] + }, + { + "params": ["0", "31"], + "output": [["00b2", "001f"]] + }, + { + "params": ["0", "32"], + "output": [["00b2", "0020"]] + }, + { + "params": ["0", "33"], + "output": [["00b2", "0021"]] + }, + { + "params": ["0", "34"], + "output": [["00b2", "0022"]] + }, + { + "params": ["0", "35"], + "output": [["00b2", "0023"]] + }, + { + "params": ["0", "36"], + "output": [["00b2", "0024"]] + }, + { + "params": ["0", "37"], + "output": [["00b2", "0025"]] + }, + { + "params": ["0", "38"], + "output": [["00b2", "0026"]] + }, + { + "params": ["0", "39"], + "output": [["00b2", "0027"]] + }, + { + "params": ["0", "40"], + "output": [["00b2", "0028"]] + }, + { + "params": ["0", "41"], + "output": [["00b2", "0029"]] + }, + { + "params": ["0", "42"], + "output": [["00b2", "002a"]] + }, + { + "params": ["0", "43"], + "output": [["00b2", "002b"]] + }, + { + "params": ["0", "44"], + "output": [["00b2", "002c"]] + }, + { + "params": ["0", "45"], + "output": [["00b2", "002d"]] + }, + { + "params": ["0", "46"], + "output": [["00b2", "002e"]] + }, + { + "params": ["0", "47"], + "output": [["00b2", "002f"]] + }, + { + "params": ["0", "48"], + "output": [["00b2", "0030"]] + }, + { + "params": ["0", "49"], + "output": [["00b2", "0031"]] + }, + { + "params": ["0", "50"], + "output": [["00b2", "0032"]] + }, + { + "params": ["0", "51"], + "output": [["00b2", "0033"]] + }, + { + "params": ["0", "52"], + "output": [["00b2", "0034"]] + }, + { + "params": ["0", "53"], + "output": [["00b2", "0035"]] + }, + { + "params": ["0", "54"], + "output": [["00b2", "0036"]] + }, + { + "params": ["0", "55"], + "output": [["00b2", "0037"]] + }, + { + "params": ["0", "56"], + "output": [["00b2", "0038"]] + }, + { + "params": ["0", "57"], + "output": [["00b2", "0039"]] + }, + { + "params": ["0", "58"], + "output": [["00b2", "003a"]] + }, + { + "params": ["0", "59"], + "output": [["00b2", "003b"]] + }, + { + "params": ["0", "60"], + "output": [["00b2", "003c"]] + }, + { + "params": ["0", "61"], + "output": [["00b2", "003d"]] + }, + { + "params": ["0", "62"], + "output": [["00b2", "003e"]] + }, + { + "params": ["0", "63"], + "output": [["00b2", "003f"]] + }, + { + "params": ["0", "64"], + "output": [["00b2", "0040"]] + }, + { + "params": ["0", "65"], + "output": [["00b2", "0041"]] + }, + { + "params": ["0", "66"], + "output": [["00b2", "0042"]] + }, + { + "params": ["0", "67"], + "output": [["00b2", "0043"]] + }, + { + "params": ["0", "68"], + "output": [["00b2", "0044"]] + }, + { + "params": ["0", "69"], + "output": [["00b2", "0045"]] + }, + { + "params": ["0", "70"], + "output": [["00b2", "0046"]] + }, + { + "params": ["0", "71"], + "output": [["00b2", "0047"]] + }, + { + "params": ["0", "72"], + "output": [["00b2", "0048"]] + }, + { + "params": ["0", "73"], + "output": [["00b2", "0049"]] + }, + { + "params": ["0", "74"], + "output": [["00b2", "004a"]] + }, + { + "params": ["0", "75"], + "output": [["00b2", "004b"]] + }, + { + "params": ["0", "76"], + "output": [["00b2", "004c"]] + }, + { + "params": ["0", "77"], + "output": [["00b2", "004d"]] + }, + { + "params": ["0", "78"], + "output": [["00b2", "004e"]] + }, + { + "params": ["0", "79"], + "output": [["00b2", "004f"]] + }, + { + "params": ["0", "80"], + "output": [["00b2", "0050"]] + }, + { + "params": ["0", "81"], + "output": [["00b2", "0051"]] + }, + { + "params": ["0", "82"], + "output": [["00b2", "0052"]] + }, + { + "params": ["0", "83"], + "output": [["00b2", "0053"]] + }, + { + "params": ["0", "84"], + "output": [["00b2", "0054"]] + }, + { + "params": ["0", "85"], + "output": [["00b2", "0055"]] + }, + { + "params": ["0", "86"], + "output": [["00b2", "0056"]] + }, + { + "params": ["0", "87"], + "output": [["00b2", "0057"]] + }, + { + "params": ["0", "88"], + "output": [["00b2", "0058"]] + }, + { + "params": ["0", "89"], + "output": [["00b2", "0059"]] + }, + { + "params": ["0", "90"], + "output": [["00b2", "005a"]] + }, + { + "params": ["0", "91"], + "output": [["00b2", "005b"]] + }, + { + "params": ["0", "92"], + "output": [["00b2", "005c"]] + }, + { + "params": ["0", "93"], + "output": [["00b2", "005d"]] + }, + { + "params": ["0", "94"], + "output": [["00b2", "005e"]] + }, + { + "params": ["0", "95"], + "output": [["00b2", "005f"]] + }, + { + "params": ["0", "96"], + "output": [["00b2", "0060"]] + }, + { + "params": ["0", "97"], + "output": [["00b2", "0061"]] + }, + { + "params": ["0", "98"], + "output": [["00b2", "0062"]] + }, + { + "params": ["0", "99"], + "output": [["00b2", "0063"]] + }, + { + "params": ["0", "100"], + "output": [["00b2", "0064"]] + }, + { + "params": ["0", "101"], + "output": [["00b2", "0065"]] + }, + { + "params": ["0", "102"], + "output": [["00b2", "0066"]] + }, + { + "params": ["0", "103"], + "output": [["00b2", "0067"]] + }, + { + "params": ["0", "104"], + "output": [["00b2", "0068"]] + }, + { + "params": ["0", "105"], + "output": [["00b2", "0069"]] + }, + { + "params": ["0", "106"], + "output": [["00b2", "006a"]] + }, + { + "params": ["0", "107"], + "output": [["00b2", "006b"]] + }, + { + "params": ["0", "108"], + "output": [["00b2", "006c"]] + }, + { + "params": ["0", "109"], + "output": [["00b2", "006d"]] + }, + { + "params": ["0", "110"], + "output": [["00b2", "006e"]] + }, + { + "params": ["0", "111"], + "output": [["00b2", "006f"]] + }, + { + "params": ["0", "112"], + "output": [["00b2", "0070"]] + }, + { + "params": ["0", "113"], + "output": [["00b2", "0071"]] + }, + { + "params": ["0", "114"], + "output": [["00b2", "0072"]] + }, + { + "params": ["0", "115"], + "output": [["00b2", "0073"]] + }, + { + "params": ["0", "116"], + "output": [["00b2", "0074"]] + }, + { + "params": ["0", "117"], + "output": [["00b2", "0075"]] + }, + { + "params": ["0", "118"], + "output": [["00b2", "0076"]] + }, + { + "params": ["0", "119"], + "output": [["00b2", "0077"]] + }, + { + "params": ["0", "120"], + "output": [["00b2", "0078"]] + }, + { + "params": ["0", "121"], + "output": [["00b2", "0079"]] + }, + { + "params": ["0", "122"], + "output": [["00b2", "007a"]] + }, + { + "params": ["0", "123"], + "output": [["00b2", "007b"]] + }, + { + "params": ["0", "124"], + "output": [["00b2", "007c"]] + }, + { + "params": ["0", "125"], + "output": [["00b2", "007d"]] + }, + { + "params": ["0", "126"], + "output": [["00b2", "007e"]] + }, + { + "params": ["0", "127"], + "output": [["00b2", "007f"]] + }, + { + "params": ["0", "128"], + "output": [["00b2", "0080"]] + }, + { + "params": ["1", "0"], + "output": [["00b1", "0000"]] + }, + { + "params": ["1", "1"], + "output": [["00b1", "0001"]] + }, + { + "params": ["1", "2"], + "output": [["00b1", "0002"]] + }, + { + "params": ["1", "3"], + "output": [["00b1", "0003"]] + }, + { + "params": ["1", "4"], + "output": [["00b1", "0004"]] + }, + { + "params": ["1", "5"], + "output": [["00b1", "0005"]] + }, + { + "params": ["1", "6"], + "output": [["00b1", "0006"]] + }, + { + "params": ["1", "7"], + "output": [["00b1", "0007"]] + }, + { + "params": ["1", "8"], + "output": [["00b1", "0008"]] + }, + { + "params": ["1", "9"], + "output": [["00b1", "0009"]] + }, + { + "params": ["1", "10"], + "output": [["00b1", "000a"]] + }, + { + "params": ["1", "11"], + "output": [["00b1", "000b"]] + }, + { + "params": ["1", "12"], + "output": [["00b1", "000c"]] + }, + { + "params": ["1", "13"], + "output": [["00b1", "000d"]] + }, + { + "params": ["1", "14"], + "output": [["00b1", "000e"]] + }, + { + "params": ["1", "15"], + "output": [["00b1", "000f"]] + }, + { + "params": ["1", "16"], + "output": [["00b1", "0010"]] + }, + { + "params": ["1", "17"], + "output": [["00b1", "0011"]] + }, + { + "params": ["1", "18"], + "output": [["00b1", "0012"]] + }, + { + "params": ["1", "19"], + "output": [["00b1", "0013"]] + }, + { + "params": ["1", "20"], + "output": [["00b1", "0014"]] + }, + { + "params": ["1", "21"], + "output": [["00b1", "0015"]] + }, + { + "params": ["1", "22"], + "output": [["00b1", "0016"]] + }, + { + "params": ["1", "23"], + "output": [["00b1", "0017"]] + }, + { + "params": ["1", "24"], + "output": [["00b1", "0018"]] + }, + { + "params": ["1", "25"], + "output": [["00b1", "0019"]] + }, + { + "params": ["1", "26"], + "output": [["00b1", "001a"]] + }, + { + "params": ["1", "27"], + "output": [["00b1", "001b"]] + }, + { + "params": ["1", "28"], + "output": [["00b1", "001c"]] + }, + { + "params": ["1", "29"], + "output": [["00b1", "001d"]] + }, + { + "params": ["1", "30"], + "output": [["00b1", "001e"]] + }, + { + "params": ["1", "31"], + "output": [["00b1", "001f"]] + }, + { + "params": ["1", "32"], + "output": [["00b1", "0020"]] + }, + { + "params": ["1", "33"], + "output": [["00b1", "0021"]] + }, + { + "params": ["1", "34"], + "output": [["00b1", "0022"]] + }, + { + "params": ["1", "35"], + "output": [["00b1", "0023"]] + }, + { + "params": ["1", "36"], + "output": [["00b1", "0024"]] + }, + { + "params": ["1", "37"], + "output": [["00b1", "0025"]] + }, + { + "params": ["1", "38"], + "output": [["00b1", "0026"]] + }, + { + "params": ["1", "39"], + "output": [["00b1", "0027"]] + }, + { + "params": ["1", "40"], + "output": [["00b1", "0028"]] + }, + { + "params": ["1", "41"], + "output": [["00b1", "0029"]] + }, + { + "params": ["1", "42"], + "output": [["00b1", "002a"]] + }, + { + "params": ["1", "43"], + "output": [["00b1", "002b"]] + }, + { + "params": ["1", "44"], + "output": [["00b1", "002c"]] + }, + { + "params": ["1", "45"], + "output": [["00b1", "002d"]] + }, + { + "params": ["1", "46"], + "output": [["00b1", "002e"]] + }, + { + "params": ["1", "47"], + "output": [["00b1", "002f"]] + }, + { + "params": ["1", "48"], + "output": [["00b1", "0030"]] + }, + { + "params": ["1", "49"], + "output": [["00b1", "0031"]] + }, + { + "params": ["1", "50"], + "output": [["00b1", "0032"]] + }, + { + "params": ["1", "51"], + "output": [["00b1", "0033"]] + }, + { + "params": ["1", "52"], + "output": [["00b1", "0034"]] + }, + { + "params": ["1", "53"], + "output": [["00b1", "0035"]] + }, + { + "params": ["1", "54"], + "output": [["00b1", "0036"]] + }, + { + "params": ["1", "55"], + "output": [["00b1", "0037"]] + }, + { + "params": ["1", "56"], + "output": [["00b1", "0038"]] + }, + { + "params": ["1", "57"], + "output": [["00b1", "0039"]] + }, + { + "params": ["1", "58"], + "output": [["00b1", "003a"]] + }, + { + "params": ["1", "59"], + "output": [["00b1", "003b"]] + }, + { + "params": ["1", "60"], + "output": [["00b1", "003c"]] + }, + { + "params": ["1", "61"], + "output": [["00b1", "003d"]] + }, + { + "params": ["1", "62"], + "output": [["00b1", "003e"]] + }, + { + "params": ["1", "63"], + "output": [["00b1", "003f"]] + }, + { + "params": ["1", "64"], + "output": [["00b1", "0040"]] + }, + { + "params": ["1", "65"], + "output": [["00b1", "0041"]] + }, + { + "params": ["1", "66"], + "output": [["00b1", "0042"]] + }, + { + "params": ["1", "67"], + "output": [["00b1", "0043"]] + }, + { + "params": ["1", "68"], + "output": [["00b1", "0044"]] + }, + { + "params": ["1", "69"], + "output": [["00b1", "0045"]] + }, + { + "params": ["1", "70"], + "output": [["00b1", "0046"]] + }, + { + "params": ["1", "71"], + "output": [["00b1", "0047"]] + }, + { + "params": ["1", "72"], + "output": [["00b1", "0048"]] + }, + { + "params": ["1", "73"], + "output": [["00b1", "0049"]] + }, + { + "params": ["1", "74"], + "output": [["00b1", "004a"]] + }, + { + "params": ["1", "75"], + "output": [["00b1", "004b"]] + }, + { + "params": ["1", "76"], + "output": [["00b1", "004c"]] + }, + { + "params": ["1", "77"], + "output": [["00b1", "004d"]] + }, + { + "params": ["1", "78"], + "output": [["00b1", "004e"]] + }, + { + "params": ["1", "79"], + "output": [["00b1", "004f"]] + }, + { + "params": ["1", "80"], + "output": [["00b1", "0050"]] + }, + { + "params": ["1", "81"], + "output": [["00b1", "0051"]] + }, + { + "params": ["1", "82"], + "output": [["00b1", "0052"]] + }, + { + "params": ["1", "83"], + "output": [["00b1", "0053"]] + }, + { + "params": ["1", "84"], + "output": [["00b1", "0054"]] + }, + { + "params": ["1", "85"], + "output": [["00b1", "0055"]] + }, + { + "params": ["1", "86"], + "output": [["00b1", "0056"]] + }, + { + "params": ["1", "87"], + "output": [["00b1", "0057"]] + }, + { + "params": ["1", "88"], + "output": [["00b1", "0058"]] + }, + { + "params": ["1", "89"], + "output": [["00b1", "0059"]] + }, + { + "params": ["1", "90"], + "output": [["00b1", "005a"]] + }, + { + "params": ["1", "91"], + "output": [["00b1", "005b"]] + }, + { + "params": ["1", "92"], + "output": [["00b1", "005c"]] + }, + { + "params": ["1", "93"], + "output": [["00b1", "005d"]] + }, + { + "params": ["1", "94"], + "output": [["00b1", "005e"]] + }, + { + "params": ["1", "95"], + "output": [["00b1", "005f"]] + }, + { + "params": ["1", "96"], + "output": [["00b1", "0060"]] + }, + { + "params": ["1", "97"], + "output": [["00b1", "0061"]] + }, + { + "params": ["1", "98"], + "output": [["00b1", "0062"]] + }, + { + "params": ["1", "99"], + "output": [["00b1", "0063"]] + }, + { + "params": ["1", "100"], + "output": [["00b1", "0064"]] + }, + { + "params": ["1", "101"], + "output": [["00b1", "0065"]] + }, + { + "params": ["1", "102"], + "output": [["00b1", "0066"]] + }, + { + "params": ["1", "103"], + "output": [["00b1", "0067"]] + }, + { + "params": ["1", "104"], + "output": [["00b1", "0068"]] + }, + { + "params": ["1", "105"], + "output": [["00b1", "0069"]] + }, + { + "params": ["1", "106"], + "output": [["00b1", "006a"]] + }, + { + "params": ["1", "107"], + "output": [["00b1", "006b"]] + }, + { + "params": ["1", "108"], + "output": [["00b1", "006c"]] + }, + { + "params": ["1", "109"], + "output": [["00b1", "006d"]] + }, + { + "params": ["1", "110"], + "output": [["00b1", "006e"]] + }, + { + "params": ["1", "111"], + "output": [["00b1", "006f"]] + }, + { + "params": ["1", "112"], + "output": [["00b1", "0070"]] + }, + { + "params": ["1", "113"], + "output": [["00b1", "0071"]] + }, + { + "params": ["1", "114"], + "output": [["00b1", "0072"]] + }, + { + "params": ["1", "115"], + "output": [["00b1", "0073"]] + }, + { + "params": ["1", "116"], + "output": [["00b1", "0074"]] + }, + { + "params": ["1", "117"], + "output": [["00b1", "0075"]] + }, + { + "params": ["1", "118"], + "output": [["00b1", "0076"]] + }, + { + "params": ["1", "119"], + "output": [["00b1", "0077"]] + }, + { + "params": ["1", "120"], + "output": [["00b1", "0078"]] + }, + { + "params": ["1", "121"], + "output": [["00b1", "0079"]] + }, + { + "params": ["1", "122"], + "output": [["00b1", "007a"]] + }, + { + "params": ["1", "123"], + "output": [["00b1", "007b"]] + }, + { + "params": ["1", "124"], + "output": [["00b1", "007c"]] + }, + { + "params": ["1", "125"], + "output": [["00b1", "007d"]] + }, + { + "params": ["1", "126"], + "output": [["00b1", "007e"]] + }, + { + "params": ["1", "127"], + "output": [["00b1", "007f"]] + }, + { + "params": ["1", "128"], + "output": [["00b1", "0080"]] + } + ] + }, + "Blink": { + "function": "libx52_set_blink", + "tests": [ + {"params": ["0"], "output": [["00b4", "0050"]]}, + {"params": ["1"], "output": [["00b4", "0051"]]} + ] + }, + "Shift": { + "function": "libx52_set_shift", + "tests": [ + {"params": ["0"], "output": [["00fd", "0050"]]}, + {"params": ["1"], "output": [["00fd", "0051"]]} + ] + } +} + From 3afe999fe89b2f42d9bf8a3db3b3e7b99a41158e Mon Sep 17 00:00:00 2001 From: nirenjan Date: Wed, 17 Jun 2020 15:12:01 -0700 Subject: [PATCH 03/14] Ensure generated sources are not packaged in distribution --- lib/libx52/Makefile.am | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/libx52/Makefile.am b/lib/libx52/Makefile.am index 8c9e9ef..757abf4 100644 --- a/lib/libx52/Makefile.am +++ b/lib/libx52/Makefile.am @@ -36,7 +36,8 @@ LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh TESTS = libx52test check_PROGRAMS = libx52test -libx52test_SOURCES = test_libx52.c $(libx52_la_SOURCES) +nodist_libx52test_SOURCES = test_libx52.c +libx52test_SOURCES = $(libx52_la_SOURCES) libx52test_CFLAGS = @LIBUSB_CFLAGS@ -DLOCALEDIR='"$(localedir)"' -I $(top_srcdir) libx52test_CFLAGS += -DGENERATED_TESTS='"test_libx52.c"' libx52test_LDFLAGS = -Wl,--wrap=libusb_control_transfer @CMOCKA_LIBS@ @LIBUSB_LIBS@ From e9167b4c208457adf40013c326eb974c6e635f8a Mon Sep 17 00:00:00 2001 From: nirenjan Date: Wed, 17 Jun 2020 16:00:25 -0700 Subject: [PATCH 04/14] Disable cmocka tests on non-Linux hosts --- configure.ac | 16 ++++++++++++++-- lib/libx52/Makefile.am | 2 ++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 6d9f155..7d17e94 100644 --- a/configure.ac +++ b/configure.ac @@ -17,6 +17,17 @@ LT_INIT PKG_PROG_PKG_CONFIG PKG_INSTALLDIR AX_COMPILER_FLAGS +AC_CANONICAL_HOST + +AC_MSG_NOTICE([Detected host OS is ${host_os}]) +build_linux=no +# Detect target system +case "${host_os}" in + linux*) + build_linux=yes + ;; +esac +AM_CONDITIONAL([LINUX], [test "x${build_linux}" = "xyes"]) # Internationalization AM_GNU_GETTEXT([external]) @@ -62,10 +73,11 @@ AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([Doxyfile])], [AC_MSG_WARN(["Doxygen not found; continuing without doxygen support"])]) -# cmocka unit tests +# cmocka unit tests, currently only supported on Linux AX_PKG_CHECK_MODULES([CMOCKA], [cmocka], [], [have_cmocka=yes], [have_cmocka=no]) AM_CONDITIONAL([HAVE_CMOCKA], [test "x$have_cmocka" = xyes]) -AM_COND_IF([HAVE_CMOCKA], [], +AM_COND_IF([HAVE_CMOCKA], [AM_COND_IF([LINUX], [], + [AC_MSG_WARN(["cmocka found, but cannot build on ${host_os}])])], [AC_MSG_WARN(["cmocka not found; disabling unit test build"])]) # Check for the presence of tm_gmtoff in struct tm. If we have this, then we diff --git a/lib/libx52/Makefile.am b/lib/libx52/Makefile.am index 757abf4..77f605c 100644 --- a/lib/libx52/Makefile.am +++ b/lib/libx52/Makefile.am @@ -31,6 +31,7 @@ x52include_HEADERS = libx52.h # pkg-config files pkgconfig_DATA = libx52.pc +if LINUX if HAVE_CMOCKA LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh TESTS = libx52test @@ -47,6 +48,7 @@ CLEANFILES = test_libx52.c test_libx52.c: $(srcdir)/x52_test_gen.py $(srcdir)/x52_tests.json $(AM_V_GEN) $(PYTHON) $(srcdir)/x52_test_gen.py $(srcdir)/x52_tests.json > $@ endif +endif # Extra files that need to be in the distribution EXTRA_DIST = libx52.h x52_commands.h x52_common.h README.md From 34b023b1fa7633e8e59468b34f2987d51a745e61 Mon Sep 17 00:00:00 2001 From: nirenjan Date: Wed, 17 Jun 2020 16:04:22 -0700 Subject: [PATCH 05/14] Add cmocka to Travis CI builds on Ubuntu --- .travis.yml | 1 + configure.ac | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 12a1427..a2ceac6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -36,6 +36,7 @@ addons: - libudev-dev - autopoint - faketime + - libcmocka-dev homebrew: packages: - libusb diff --git a/configure.ac b/configure.ac index 7d17e94..793db34 100644 --- a/configure.ac +++ b/configure.ac @@ -74,7 +74,7 @@ AM_COND_IF([HAVE_DOXYGEN], [AC_MSG_WARN(["Doxygen not found; continuing without doxygen support"])]) # cmocka unit tests, currently only supported on Linux -AX_PKG_CHECK_MODULES([CMOCKA], [cmocka], [], [have_cmocka=yes], [have_cmocka=no]) +AX_PKG_CHECK_MODULES([CMOCKA], [cmocka >= 1.1], [], [have_cmocka=yes], [have_cmocka=no]) AM_CONDITIONAL([HAVE_CMOCKA], [test "x$have_cmocka" = xyes]) AM_COND_IF([HAVE_CMOCKA], [AM_COND_IF([LINUX], [], [AC_MSG_WARN(["cmocka found, but cannot build on ${host_os}])])], From c4696f6055f9311921185a372836d1802d5f6987 Mon Sep 17 00:00:00 2001 From: nirenjan Date: Wed, 17 Jun 2020 18:52:07 -0700 Subject: [PATCH 06/14] Add clock time tests --- lib/libx52/x52_test_gen.py | 16 +---------- lib/libx52/x52_tests.json | 55 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/lib/libx52/x52_test_gen.py b/lib/libx52/x52_test_gen.py index c64d2d4..fa8cee6 100755 --- a/lib/libx52/x52_test_gen.py +++ b/lib/libx52/x52_test_gen.py @@ -123,7 +123,7 @@ class Test(): self.retval = obj.get("retval", "") def definition(self): - test_name = self.name + '_' + '_'.join(p.strip('"') for p in self.params) + test_name = self.name + '_' + '_'.join(p.strip('"').replace('-','_') for p in self.params) return test_name.lower() def print(self): @@ -168,16 +168,9 @@ class TestGroup(): def print(self): """Print the test group""" - # Print the test definitions first for test in self.tests: test.print() - # Print the list of test cases - # print(_TEST_GROUP_HEADER.format(self.definition())) - # for test in self.tests: - # print(" cmocka_unit_test_setup({}, test_setup),".format(test.definition())) - # print(_TEST_GROUP_FOOTER) - _MAIN_HEADER = """ int main(void) { @@ -220,14 +213,7 @@ class TestSuite(): for test in group.tests: print(" cmocka_unit_test_setup({}, test_setup),".format(test.definition())) print(_TEST_GROUP_FOOTER) - print(_MAIN) - # print(_MAIN_HEADER) - # for group in self.groups: - # print(' cmocka_run_group_tests_name("{}", {}, group_setup, group_teardown);'.format( - # group.name, group.definition())) - # print(_MAIN_FOOTER) - def main(): diff --git a/lib/libx52/x52_tests.json b/lib/libx52/x52_tests.json index 9678f90..77524e8 100644 --- a/lib/libx52/x52_tests.json +++ b/lib/libx52/x52_tests.json @@ -1890,6 +1890,61 @@ {"params": ["0"], "output": [["00fd", "0050"]]}, {"params": ["1"], "output": [["00fd", "0051"]]} ] + }, + "Time": { + "function": "libx52_set_time", + "tests": [ + {"params": ["0", "0"], "output": [["00c0", "0000"]]}, + {"params": ["0", "1"], "output": [["00c0", "0001"]]}, + {"params": ["0", "2"], "output": [["00c0", "0002"]]}, + {"params": ["1", "0"], "output": [["00c0", "0100"]]}, + {"params": ["1", "1"], "output": [["00c0", "0101"]]}, + {"params": ["1", "2"], "output": [["00c0", "0102"]]}, + {"params": ["2", "0"], "output": [["00c0", "0200"]]}, + {"params": ["2", "1"], "output": [["00c0", "0201"]]}, + {"params": ["2", "2"], "output": [["00c0", "0202"]]} + ] + }, + "Time_Format": { + "function": "libx52_set_clock_format", + "params_prefix": ["LIBX52_CLOCK_", "LIBX52_CLOCK_FORMAT_"], + "tests": [ + {"params": ["1", "12HR"], "output": [["00c0", "0000"]]}, + {"params": ["1", "24HR"], "output": [["00c0", "8000"]]}, + {"params": ["2", "12HR"], "output": [["00c1", "0000"]]}, + {"params": ["2", "24HR"], "output": [["00c1", "8000"]]}, + {"params": ["3", "12HR"], "output": [["00c2", "0000"]]}, + {"params": ["3", "24HR"], "output": [["00c2", "8000"]]} + ] + }, + "Offset": { + "function": "libx52_set_clock_timezone", + "params_prefix": ["LIBX52_CLOCK_"], + "tests": [ + {"params": ["1", "0"], "retval": "NOT_SUPPORTED"}, + {"params": ["2", "0"], "output": [["00c1", "0000"]]}, + {"params": ["2", "30"], "output": [["00c1", "001e"]]}, + {"params": ["2", "60"], "output": [["00c1", "003c"]]}, + {"params": ["2", "1200"], "output": [["00c1", "04f0"]]}, + {"params": ["2", "1440"], "output": [["00c1", "0000"]]}, + {"params": ["2", "1441"], "retval": "OUT_OF_RANGE"}, + {"params": ["2", "-30"], "output": [["00c1", "041e"]]}, + {"params": ["2", "-60"], "output": [["00c1", "043c"]]}, + {"params": ["2", "-1200"], "output": [["00c1", "00f0"]]}, + {"params": ["2", "-1440"], "output": [["00c1", "0400"]]}, + {"params": ["2", "-1441"], "retval": "OUT_OF_RANGE"}, + {"params": ["3", "0"], "output": [["00c2", "0000"]]}, + {"params": ["3", "30"], "output": [["00c2", "001e"]]}, + {"params": ["3", "60"], "output": [["00c2", "003c"]]}, + {"params": ["3", "1200"], "output": [["00c2", "04f0"]]}, + {"params": ["3", "1440"], "output": [["00c2", "0000"]]}, + {"params": ["3", "1441"], "retval": "OUT_OF_RANGE"}, + {"params": ["3", "-30"], "output": [["00c2", "041e"]]}, + {"params": ["3", "-60"], "output": [["00c2", "043c"]]}, + {"params": ["3", "-1200"], "output": [["00c2", "00f0"]]}, + {"params": ["3", "-1440"], "output": [["00c2", "0400"]]}, + {"params": ["3", "-1441"], "retval": "OUT_OF_RANGE"} + ] } } From 8388f3308eef05e18a4e4c9800c00effed3f0a50 Mon Sep 17 00:00:00 2001 From: nirenjan Date: Sun, 21 Jun 2020 08:48:44 -0700 Subject: [PATCH 07/14] Reword configure warning on non-Linux hosts --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 793db34..22ffcf8 100644 --- a/configure.ac +++ b/configure.ac @@ -77,7 +77,7 @@ AM_COND_IF([HAVE_DOXYGEN], AX_PKG_CHECK_MODULES([CMOCKA], [cmocka >= 1.1], [], [have_cmocka=yes], [have_cmocka=no]) AM_CONDITIONAL([HAVE_CMOCKA], [test "x$have_cmocka" = xyes]) AM_COND_IF([HAVE_CMOCKA], [AM_COND_IF([LINUX], [], - [AC_MSG_WARN(["cmocka found, but cannot build on ${host_os}])])], + [AC_MSG_WARN(["cmocka found; disabling mock tests on ${host_os}])])], [AC_MSG_WARN(["cmocka not found; disabling unit test build"])]) # Check for the presence of tm_gmtoff in struct tm. If we have this, then we From 681a8e8aa14c9c7987862db895c4d7d3f417f3e7 Mon Sep 17 00:00:00 2001 From: nirenjan Date: Sat, 27 Jun 2020 22:04:56 -0700 Subject: [PATCH 08/14] Change libx52 mock tests to use preprocessor overrides Prior to this change, libx52 tests needed a linker that supported the --wrap argument. This is not available on OSX, and therefore, we had to disable the unit tests on non-Linux systems. Since we needed to rebuild the libx52 library anyway for the test, it is simpler to just define libusb_control_transfer to point to our mock function. This allows us to verify libx52 on all supported platforms. --- configure.ac | 5 ++--- lib/libx52/Makefile.am | 6 ++---- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/configure.ac b/configure.ac index 22ffcf8..7e1e294 100644 --- a/configure.ac +++ b/configure.ac @@ -73,11 +73,10 @@ AM_COND_IF([HAVE_DOXYGEN], [AC_CONFIG_FILES([Doxyfile])], [AC_MSG_WARN(["Doxygen not found; continuing without doxygen support"])]) -# cmocka unit tests, currently only supported on Linux +# cmocka unit tests AX_PKG_CHECK_MODULES([CMOCKA], [cmocka >= 1.1], [], [have_cmocka=yes], [have_cmocka=no]) AM_CONDITIONAL([HAVE_CMOCKA], [test "x$have_cmocka" = xyes]) -AM_COND_IF([HAVE_CMOCKA], [AM_COND_IF([LINUX], [], - [AC_MSG_WARN(["cmocka found; disabling mock tests on ${host_os}])])], +AM_COND_IF([HAVE_CMOCKA], [], [AC_MSG_WARN(["cmocka not found; disabling unit test build"])]) # Check for the presence of tm_gmtoff in struct tm. If we have this, then we diff --git a/lib/libx52/Makefile.am b/lib/libx52/Makefile.am index 77f605c..43114ce 100644 --- a/lib/libx52/Makefile.am +++ b/lib/libx52/Makefile.am @@ -31,7 +31,6 @@ x52include_HEADERS = libx52.h # pkg-config files pkgconfig_DATA = libx52.pc -if LINUX if HAVE_CMOCKA LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh TESTS = libx52test @@ -40,15 +39,14 @@ check_PROGRAMS = libx52test nodist_libx52test_SOURCES = test_libx52.c libx52test_SOURCES = $(libx52_la_SOURCES) libx52test_CFLAGS = @LIBUSB_CFLAGS@ -DLOCALEDIR='"$(localedir)"' -I $(top_srcdir) -libx52test_CFLAGS += -DGENERATED_TESTS='"test_libx52.c"' -libx52test_LDFLAGS = -Wl,--wrap=libusb_control_transfer @CMOCKA_LIBS@ @LIBUSB_LIBS@ +libx52test_CFLAGS += -Dlibusb_control_transfer=__wrap_libusb_control_transfer +libx52test_LDFLAGS = @CMOCKA_LIBS@ @LIBUSB_LIBS@ libx52test_LDADD = libx52.la CLEANFILES = test_libx52.c test_libx52.c: $(srcdir)/x52_test_gen.py $(srcdir)/x52_tests.json $(AM_V_GEN) $(PYTHON) $(srcdir)/x52_test_gen.py $(srcdir)/x52_tests.json > $@ endif -endif # Extra files that need to be in the distribution EXTRA_DIST = libx52.h x52_commands.h x52_common.h README.md From 108b7e2522aba24fd188c105c34435052c4af06a Mon Sep 17 00:00:00 2001 From: nirenjan Date: Sat, 27 Jun 2020 22:20:40 -0700 Subject: [PATCH 09/14] Add cmocka to OSX build --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index a2ceac6..71b755e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,9 +42,9 @@ addons: - libusb - gettext -# Ensure that gettext is available on OSX +# Ensure that build dependencies are available on OSX before_script: - - if [ "$TRAVIS_OS_NAME" = osx ]; then brew install libusb gettext ; fi + - if [ "$TRAVIS_OS_NAME" = osx ]; then brew install libusb gettext cmocka ; fi # Enable parallel make env: From efd984ef633ae6aff597b300d917f93dd91160e1 Mon Sep 17 00:00:00 2001 From: nirenjan Date: Sun, 28 Jun 2020 08:24:49 -0700 Subject: [PATCH 10/14] Parse and add setup_hook and fields This change allows updates to the dev structure for individual test cases. This defines the "setup_hook" array, and "fields" map, at both the test group level and at the individual test case level, with the ones at the test case level overriding any parent level fields and/or hooks. The primary use case for this is to add new test definitions that would not be setup correctly by the default infrastructure, such as testing the LED function for the non-Pro X52, or setting up clock tests for local timezone, etc. --- lib/libx52/x52_test_gen.py | 18 +++++++++++++++++- lib/libx52/x52_tests.json | 17 +++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/lib/libx52/x52_test_gen.py b/lib/libx52/x52_test_gen.py index fa8cee6..6f7a85b 100755 --- a/lib/libx52/x52_test_gen.py +++ b/lib/libx52/x52_test_gen.py @@ -16,6 +16,7 @@ _TEST_FILE_HEADER = """/* #include #include #include +#include #include "x52_common.h" @@ -116,6 +117,10 @@ class Test(): self.name = group.name self.params_prefix = group.params_prefix self.params = obj["params"] + self.setup_hook = group.setup_hook + obj.get("setup_hook", []) + self.fields = group.fields.copy() + self.fields.update(obj.get("fields", {})) + if len(self.params_prefix) < len(self.params): self.params_prefix.extend([''] * (len(self.params) - len(self.params_prefix))) @@ -129,6 +134,16 @@ class Test(): def print(self): print(_TEST_FUNCTION_HEADER.format(self.definition())) + if self.fields: + for arg, val in self.fields.items(): + print(" dev->{} = {};".format(arg, val)) + + if self.setup_hook: + # Setup hook is an array of C commands that need to be executed + # prior to setting up the wrapper and running the tests + for hook in self.setup_hook: + print(" {}".format(hook)) + if self.output: print(" expect_function_calls(__wrap_libusb_control_transfer, {});".format(len(self.output))) print(" will_return_count(__wrap_libusb_control_transfer, LIBUSB_SUCCESS, {});".format(len(self.output))) @@ -157,7 +172,8 @@ class TestGroup(): """Load test cases from an object""" self.name = name self.function = obj["function"] - self.setup_hook = obj.get("setup_hook") + self.fields = obj.get("fields", {}) + self.setup_hook = obj.get("setup_hook", []) self.params_prefix = obj.get("params_prefix", []) self.tests = [] for test in obj["tests"]: diff --git a/lib/libx52/x52_tests.json b/lib/libx52/x52_tests.json index 77524e8..466f9ba 100644 --- a/lib/libx52/x52_tests.json +++ b/lib/libx52/x52_tests.json @@ -225,6 +225,23 @@ } ] }, + "LED_nonPro": { + "_comment": [ + "This suite checks if the LED state function returns not supported", + "when the device is an X52 (non-Pro) model" + ], + "function": "libx52_set_led_state", + "fields": { + "flags": "0" + }, + "params_prefix": ["LIBX52_LED_", "LIBX52_LED_STATE_"], + "tests": [ + { + "params": ["FIRE", "OFF"], + "retval": "NOT_SUPPORTED" + } + ] + }, "MFD": { "function": "libx52_set_text", "tests": [ From 7b423f4ea09dc9a5f9f46a834522a233947efcb2 Mon Sep 17 00:00:00 2001 From: nirenjan Date: Sun, 28 Jun 2020 08:35:14 -0700 Subject: [PATCH 11/14] Update libx52_set_led_state to use check_feature --- lib/libx52/x52_mfd_led.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/libx52/x52_mfd_led.c b/lib/libx52/x52_mfd_led.c index a7f8074..80d5cbd 100644 --- a/lib/libx52/x52_mfd_led.c +++ b/lib/libx52/x52_mfd_led.c @@ -116,19 +116,21 @@ static int x52pro_set_led_state(libx52_device *x52, libx52_led_id led, libx52_le int libx52_set_led_state(libx52_device *x52, libx52_led_id led, libx52_led_state state) { + int rc; if (!x52) { return LIBX52_ERROR_INVALID_PARAM; } - if (tst_bit(&x52->flags, X52_FLAG_IS_PRO)) { + rc = libx52_check_feature(x52, LIBX52_FEATURE_LED); + if (rc == LIBX52_SUCCESS) { return x52pro_set_led_state(x52, led, state); } /* - * For now, we only support setting the LEDs on the X52 Pro model. + * The non-Pro X52 does not support setting individual LED states. * Calling this API on a non-Pro model will return a not supported error. */ - return LIBX52_ERROR_NOT_SUPPORTED; + return rc; } int libx52_set_brightness(libx52_device *x52, uint8_t mfd, uint16_t brightness) From 87ad48a37f745cbbc8999ce44e689fa4dd2128eb Mon Sep 17 00:00:00 2001 From: nirenjan Date: Sun, 28 Jun 2020 08:57:01 -0700 Subject: [PATCH 12/14] Cleanup generated test formatting --- lib/libx52/x52_test_gen.py | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/lib/libx52/x52_test_gen.py b/lib/libx52/x52_test_gen.py index 6f7a85b..08c9539 100755 --- a/lib/libx52/x52_test_gen.py +++ b/lib/libx52/x52_test_gen.py @@ -161,9 +161,7 @@ class Test(): print(_TEST_FUNCTION_FOOTER_NORMAL); _TEST_GROUP_HEADER = "const struct CMUnitTest tests[] = {" -_TEST_GROUP_FOOTER = """}; - -""" +_TEST_GROUP_FOOTER = "};" class TestGroup(): """Test group class, contains multiple tests""" @@ -187,17 +185,6 @@ class TestGroup(): for test in self.tests: test.print() -_MAIN_HEADER = """ -int main(void) -{ - cmocka_set_message_output(CM_OUTPUT_TAP); - -""" -_MAIN_FOOTER = """ - return 0; -} -""" - _MAIN = """ int main(void) { From 3981b873e0f813a302c939f62c32d482a431d2cc Mon Sep 17 00:00:00 2001 From: nirenjan Date: Sun, 28 Jun 2020 08:57:23 -0700 Subject: [PATCH 13/14] Add date format tests --- lib/libx52/x52_tests.json | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/lib/libx52/x52_tests.json b/lib/libx52/x52_tests.json index 466f9ba..5d31a71 100644 --- a/lib/libx52/x52_tests.json +++ b/lib/libx52/x52_tests.json @@ -1962,6 +1962,18 @@ {"params": ["3", "-1440"], "output": [["00c2", "0400"]]}, {"params": ["3", "-1441"], "retval": "OUT_OF_RANGE"} ] + }, + "Date_Format": { + "function": "libx52_set_date_format", + "params_prefix": ["LIBX52_DATE_FORMAT_"], + "setup_hook": [ + "libx52_set_date(dev, 1, 2, 3);" + ], + "tests": [ + {"params": ["DDMMYY"], "output": [["00c4", "0201"], ["00c8", "0003"]]}, + {"params": ["MMDDYY"], "output": [["00c4", "0102"], ["00c8", "0003"]]}, + {"params": ["YYMMDD"], "output": [["00c4", "0203"], ["00c8", "0001"]]} + ] } } From c40847b833ee74a047e72f2a64a67a264f162bfd Mon Sep 17 00:00:00 2001 From: nirenjan Date: Sun, 28 Jun 2020 11:32:19 -0700 Subject: [PATCH 14/14] Add clock tests to verify PDT/PST/UTC --- lib/libx52/x52_tests.json | 49 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/lib/libx52/x52_tests.json b/lib/libx52/x52_tests.json index 5d31a71..f7a576d 100644 --- a/lib/libx52/x52_tests.json +++ b/lib/libx52/x52_tests.json @@ -1974,6 +1974,55 @@ {"params": ["MMDDYY"], "output": [["00c4", "0102"], ["00c8", "0003"]]}, {"params": ["YYMMDD"], "output": [["00c4", "0203"], ["00c8", "0001"]]} ] + }, + "Clock": { + "function": "libx52_set_clock", + "setup_hook": [ + "putenv(\"TZ=America/Los_Angeles\");" + ], + "tests": [ + { + "_comment": "2020-06-01 15:04:05 PDT", + "params": ["1591049045", "1"], + "output": [ + ["00c4", "0601"], + ["00c8", "0014"], + ["00c0", "0f04"], + ["00c1", "01a4"], + ["00c2", "01a4"] + ] + }, + { + "_comment": "2020-06-01 22:04:05 UTC", + "params": ["1591049045", "0"], + "output": [ + ["00c4", "0601"], + ["00c8", "0014"], + ["00c0", "1604"] + ] + }, + + { + "_comment": "2020-03-01 15:04:05 PST", + "params": ["1583103845", "1"], + "output": [ + ["00c4", "0301"], + ["00c8", "0014"], + ["00c0", "0f04"], + ["00c1", "01e0"], + ["00c2", "01e0"] + ] + }, + { + "_comment": "2020-03-01 23:04:05 UTC", + "params": ["1583103845", "0"], + "output": [ + ["00c4", "0301"], + ["00c8", "0014"], + ["00c0", "1704"] + ] + } + ] } }