mirror of https://github.com/nirenjan/libx52.git
243 lines
6.3 KiB
Python
Executable File
243 lines
6.3 KiB
Python
Executable File
#!/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 <stdarg.h>
|
|
#include <stddef.h>
|
|
#include <setjmp.h>
|
|
#include <cmocka.h>
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
|
|
#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 <test-definitions>\n' %
|
|
sys.argv[0])
|
|
sys.exit(1)
|
|
|
|
TestSuite(sys.argv[1]).print()
|
|
|
|
if __name__ == "__main__":
|
|
main()
|