test: switch the unit tests to something resembling a test suite

The tests have inadvertent dependencies on each other so let's avoid
those by changing to a system that returns a null-terminated list of
test functions and our test runner iterates over those and forks off one
process per function.
This commit is contained in:
Peter Hutterer 2024-01-05 11:26:26 +10:00
parent 133e0d651c
commit 46b579e8d5
26 changed files with 338 additions and 252 deletions

View File

@ -347,13 +347,15 @@ fixes_pointer_barrier_clamp_test(void)
assert(cy == barrier.y1);
}
int
const testfunc_t*
fixes_test(void)
{
static const testfunc_t testfuncs[] = {
fixes_pointer_barriers_test,
fixes_pointer_barrier_direction_test,
fixes_pointer_barrier_clamp_test,
NULL,
};
fixes_pointer_barriers_test();
fixes_pointer_barrier_direction_test();
fixes_pointer_barrier_clamp_test();
return 0;
return testfuncs;
}

View File

@ -24,7 +24,7 @@ print_int(void* ptr, void* v)
printf("%d", *x);
}
static int
static void
test1(void)
{
HashTable h;
@ -79,10 +79,10 @@ test1(void)
ht_destroy(h);
return ok;
assert(ok);
}
static int
static void
test2(void)
{
HashTable h;
@ -122,10 +122,10 @@ test2(void)
printf("Test with empty keys FAILED\n");
}
return ok;
assert(ok);
}
static int
static void
test3(void)
{
int ok = 1;
@ -152,15 +152,17 @@ test3(void)
ht_destroy(h);
return ok;
assert(ok);
}
int
const testfunc_t*
hashtabletest_test(void)
{
int ok = test1();
ok = ok && test2();
ok = ok && test3();
return ok ? 0 : 1;
static const testfunc_t testfuncs[] = {
test1,
test2,
test3,
NULL,
};
return testfuncs;
}

View File

@ -1926,28 +1926,31 @@ dix_enqueue_events(void)
inputInfo.devices = NULL;
}
int
const testfunc_t*
input_test(void)
{
dix_enqueue_events();
dix_double_fp_conversion();
dix_input_valuator_masks();
dix_input_valuator_masks_unaccel();
dix_input_attributes();
dix_init_valuators();
dix_event_to_core_conversion();
dix_event_to_xi1_conversion();
dix_check_grab_values();
xi2_struct_sizes();
dix_grab_matching();
dix_valuator_mode();
include_byte_padding_macros();
include_bit_test_macros();
xi_unregister_handlers();
dix_valuator_alloc();
dix_get_master();
input_option_test();
mieq_test();
static const testfunc_t testfuncs[] = {
dix_enqueue_events,
dix_double_fp_conversion,
dix_input_valuator_masks,
dix_input_valuator_masks_unaccel,
dix_input_attributes,
dix_init_valuators,
dix_event_to_core_conversion,
dix_event_to_xi1_conversion,
dix_check_grab_values,
xi2_struct_sizes,
dix_grab_matching,
dix_valuator_mode,
include_byte_padding_macros,
include_bit_test_macros,
xi_unregister_handlers,
dix_valuator_alloc,
dix_get_master,
input_option_test,
mieq_test,
NULL,
};
return 0;
return testfuncs;
}

View File

@ -377,19 +377,21 @@ test_nt_list_delete(void)
free(list);
}
int
const testfunc_t*
list_test(void)
{
test_xorg_list_init();
test_xorg_list_add();
test_xorg_list_append();
test_xorg_list_del();
test_xorg_list_for_each();
static const testfunc_t testfuncs[] = {
test_xorg_list_init,
test_xorg_list_add,
test_xorg_list_append,
test_xorg_list_del,
test_xorg_list_for_each,
test_nt_list_init();
test_nt_list_append();
test_nt_list_insert();
test_nt_list_delete();
return 0;
test_nt_list_init,
test_nt_list_append,
test_nt_list_insert,
test_nt_list_delete,
NULL,
};
return testfuncs;
}

View File

@ -223,13 +223,17 @@ bswap_test(void)
assert(result_64 == expect_64);
}
int
const testfunc_t*
misc_test(void)
{
dix_version_compare();
dix_update_desktop_dimensions();
dix_request_size_checks();
bswap_test();
static const testfunc_t testfuncs[] = {
dix_version_compare,
dix_update_desktop_dimensions,
dix_request_size_checks,
bswap_test,
NULL,
};
return testfuncs;
return 0;
}

View File

@ -402,11 +402,13 @@ static void logging_format(void)
}
#pragma GCC diagnostic pop /* "-Wformat-security" */
int
const testfunc_t*
signal_logging_test(void)
{
number_formatting();
logging_format();
return 0;
static const testfunc_t testfuncs[] = {
number_formatting,
logging_format,
NULL,
};
return testfuncs;
}

View File

@ -65,10 +65,13 @@ strndup_checks(void)
free(allofit);
}
int
const testfunc_t*
string_test(void)
{
strndup_checks();
static const testfunc_t testfuncs[] = {
strndup_checks,
NULL,
};
return 0;
return testfuncs;
}

View File

@ -175,12 +175,14 @@ xkb_set_get_rules_test(void)
XkbFreeRMLVOSet(&rmlvo_backup, FALSE);
}
int
const testfunc_t*
xkb_test(void)
{
xkb_set_get_rules_test();
xkb_get_rules_test();
xkb_set_rules_test();
return 0;
static const testfunc_t testfuncs[] = {
xkb_set_get_rules_test,
xkb_get_rules_test,
xkb_set_rules_test,
NULL,
};
return testfuncs;
}

View File

@ -7,27 +7,34 @@
#include "tests-common.h"
void
run_test_in_child(int (*func)(void), const char *funcname)
run_test_in_child(const testfunc_t* (*suite)(void), const char *funcname)
{
int cpid;
int csts;
int exit_code = -1;
const testfunc_t *func = suite();
printf("\n---------------------\n%s...\n", funcname);
while (*func)
{
cpid = fork();
if (cpid) {
waitpid(cpid, &csts, 0);
if (!WIFEXITED(csts))
goto child_failed;
exit_code = WEXITSTATUS(csts);
if (exit_code == 0)
printf(" Pass\n");
else {
if (exit_code != 0) {
child_failed:
printf(" FAIL\n");
exit(exit_code);
}
} else {
exit(func());
testfunc_t f = *func;
f();
exit(0);
}
func++;
}
printf(" Pass\n");
}

View File

@ -3,10 +3,11 @@
#include "tests.h"
#define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a)[0]))
#define run_test(func) run_test_in_child(func, #func)
void run_test_in_child(int (*func)(void), const char *funcname);
void run_test_in_child(const testfunc_t* (*func)(void), const char *funcname);
#endif /* TESTS_COMMON_H */

View File

@ -1,31 +1,31 @@
#ifndef TESTS_H
#define TESTS_H
int fixes_test(void);
int hashtabletest_test(void);
int input_test(void);
int list_test(void);
int misc_test(void);
int signal_logging_test(void);
int string_test(void);
int touch_test(void);
int xfree86_test(void);
int xkb_test(void);
int xtest_test(void);
typedef void (*testfunc_t)(void);
int protocol_xchangedevicecontrol_test(void);
int protocol_xiqueryversion_test(void);
int protocol_xiquerydevice_test(void);
int protocol_xiselectevents_test(void);
int protocol_xigetselectedevents_test(void);
int protocol_xisetclientpointer_test(void);
int protocol_xigetclientpointer_test(void);
int protocol_xipassivegrabdevice_test(void);
int protocol_xiquerypointer_test(void);
int protocol_xiwarppointer_test(void);
int protocol_eventconvert_test(void);
int xi2_test(void);
const testfunc_t* fixes_test(void);
const testfunc_t* hashtabletest_test(void);
const testfunc_t* input_test(void);
const testfunc_t* list_test(void);
const testfunc_t* misc_test(void);
const testfunc_t* signal_logging_test(void);
const testfunc_t* string_test(void);
const testfunc_t* touch_test(void);
const testfunc_t* xfree86_test(void);
const testfunc_t* xkb_test(void);
const testfunc_t* xtest_test(void);
const testfunc_t* protocol_xchangedevicecontrol_test(void);
const testfunc_t* protocol_xiqueryversion_test(void);
const testfunc_t* protocol_xiquerydevice_test(void);
const testfunc_t* protocol_xiselectevents_test(void);
const testfunc_t* protocol_xigetselectedevents_test(void);
const testfunc_t* protocol_xisetclientpointer_test(void);
const testfunc_t* protocol_xigetclientpointer_test(void);
const testfunc_t* protocol_xipassivegrabdevice_test(void);
const testfunc_t* protocol_xiquerypointer_test(void);
const testfunc_t* protocol_xiwarppointer_test(void);
const testfunc_t* protocol_eventconvert_test(void);
const testfunc_t* xi2_test(void);
#ifndef INSIDE_PROTOCOL_COMMON

View File

@ -306,16 +306,16 @@ touch_init(void)
free_device(&dev);
}
int
const testfunc_t*
touch_test(void)
{
printf("touch_test: start...\n");
touch_grow_queue();
touch_find_ddxid();
touch_begin_ddxtouch();
touch_init();
touch_begin_touch();
printf("touch_test: exiting successfully\n");
return 0;
static const testfunc_t testfuncs[] = {
touch_grow_queue,
touch_find_ddxid,
touch_begin_ddxtouch,
touch_init,
touch_begin_touch,
NULL,
};
return testfuncs;
}

View File

@ -108,11 +108,13 @@ xfree86_add_comment(void)
free(current);
}
int
const testfunc_t*
xfree86_test(void)
{
xfree86_option_list_duplicate();
xfree86_add_comment();
return 0;
static const testfunc_t testfuncs[] = {
xfree86_option_list_duplicate,
xfree86_add_comment,
NULL,
};
return testfuncs;
}

View File

@ -85,6 +85,8 @@ static unsigned char *data[4096]; /* the request buffer */
static void
test_ChangeDeviceControl(void)
{
init_simple();
xChangeDeviceControlReq *request = (xChangeDeviceControlReq *) data;
xDeviceCtl *control = (xDeviceCtl *) (&request[1]);
@ -115,12 +117,12 @@ test_ChangeDeviceControl(void)
/* XXX: Test functionality! */
}
int
const testfunc_t*
protocol_xchangedevicecontrol_test(void)
{
init_simple();
test_ChangeDeviceControl();
return 0;
static const testfunc_t testfuncs[] = {
test_ChangeDeviceControl,
NULL,
};
return testfuncs;
}

View File

@ -1206,15 +1206,17 @@ test_convert_XIBarrierEvent(void)
test_XIBarrierEvent(&in);
}
int
const testfunc_t*
protocol_eventconvert_test(void)
{
test_convert_XIRawEvent();
test_convert_XIFocusEvent();
test_convert_XIDeviceEvent();
test_convert_XIDeviceChangedEvent();
test_convert_XITouchOwnershipEvent();
test_convert_XIBarrierEvent();
return 0;
static const testfunc_t testfuncs[] = {
test_convert_XIRawEvent,
test_convert_XIFocusEvent,
test_convert_XIDeviceEvent,
test_convert_XIDeviceChangedEvent,
test_convert_XITouchOwnershipEvent,
test_convert_XIBarrierEvent,
NULL,
};
return testfuncs;
}

View File

@ -100,6 +100,9 @@ test_XIGetClientPointer(void)
{
xXIGetClientPointerReq request;
init_simple();
client_window = init_client(0, NULL);
request_init(&request, XIGetClientPointer);
request.win = CLIENT_WINDOW_ID;
@ -144,13 +147,13 @@ test_XIGetClientPointer(void)
request_XIGetClientPointer(&client_request, &request, Success);
}
int
const testfunc_t*
protocol_xigetclientpointer_test(void)
{
init_simple();
client_window = init_client(0, NULL);
static const testfunc_t testfuncs[] = {
test_XIGetClientPointer,
NULL,
};
test_XIGetClientPointer();
return 0;
return testfuncs;
}

View File

@ -145,10 +145,15 @@ test_XIGetSelectedEvents(void)
{
int i, j;
xXIGetSelectedEventsReq request;
ClientRec client = init_client(0, NULL);
ClientRec client;
unsigned char *mask;
DeviceIntRec dev;
init_simple();
enable_GrabButton_wrap = 0;
enable_XISetEventMask_wrap = 0;
client = init_client(0, NULL);
request_init(&request, XIGetSelectedEvents);
printf("Testing for BadWindow on invalid window.\n");
@ -208,14 +213,14 @@ test_XIGetSelectedEvents(void)
}
}
int
const testfunc_t*
protocol_xigetselectedevents_test(void)
{
init_simple();
enable_GrabButton_wrap = 0;
enable_XISetEventMask_wrap = 0;
test_XIGetSelectedEvents();
static const testfunc_t testfuncs[] = {
test_XIGetSelectedEvents,
NULL,
};
return testfuncs;
return 0;
}

View File

@ -175,6 +175,8 @@ test_XIPassiveGrabDevice(void)
xXIPassiveGrabDeviceReq *request = (xXIPassiveGrabDeviceReq *) data;
unsigned char *mask;
init_simple();
request_init(request, XIPassiveGrabDevice);
request->grab_window = CLIENT_WINDOW_ID;
@ -247,12 +249,13 @@ test_XIPassiveGrabDevice(void)
request_XIPassiveGrabDevice(&client_request, request, Success, 0);
}
int
const testfunc_t*
protocol_xipassivegrabdevice_test(void)
{
init_simple();
static const testfunc_t testfuncs[] = {
test_XIPassiveGrabDevice,
NULL,
};
test_XIPassiveGrabDevice();
return 0;
return testfuncs;
}

View File

@ -317,6 +317,8 @@ test_XIQueryDevice(void)
xXIQueryDeviceReq request;
struct test_data data;
init_simple();
reply_handler = reply_XIQueryDevice;
global_userdata = &data;
request_init(&request, XIQueryDevice);
@ -338,12 +340,13 @@ test_XIQueryDevice(void)
}
int
const testfunc_t*
protocol_xiquerydevice_test(void)
{
init_simple();
static const testfunc_t testfuncs[] = {
test_XIQueryDevice,
NULL,
};
test_XIQueryDevice();
return 0;
return testfuncs;
}

View File

@ -139,6 +139,8 @@ test_XIQueryPointer(void)
int i;
xXIQueryPointerReq request;
init_simple();
memset(&request, 0, sizeof(request));
request_init(&request, XIQueryPointer);
@ -192,12 +194,12 @@ test_XIQueryPointer(void)
request_XIQueryPointer(&client_request, &request, BadLength);
}
int
const testfunc_t*
protocol_xiquerypointer_test(void)
{
init_simple();
test_XIQueryPointer();
return 0;
static const testfunc_t testfuncs[] = {
test_XIQueryPointer,
NULL,
};
return testfuncs;
}

View File

@ -151,6 +151,8 @@ request_XIQueryVersion(int smaj, int smin, int cmaj, int cmin, int error)
static void
test_XIQueryVersion(void)
{
init_simple();
reply_handler = reply_XIQueryVersion;
printf("Server version 2.0 - client versions [1..3].0\n");
@ -203,6 +205,8 @@ test_XIQueryVersion_multiple(void)
struct test_data versions;
int rc;
init_simple();
request_init(&request, XIQueryVersion);
client = init_client(request.length, &request);
@ -290,13 +294,14 @@ test_XIQueryVersion_multiple(void)
assert(rc == BadValue);
}
int
const testfunc_t*
protocol_xiqueryversion_test(void)
{
init_simple();
static const testfunc_t testfuncs[] = {
test_XIQueryVersion,
test_XIQueryVersion_multiple,
NULL,
};
test_XIQueryVersion();
test_XIQueryVersion_multiple();
return 0;
return testfuncs;
}

View File

@ -288,6 +288,8 @@ test_XISelectEvents(void)
xXIEventMask *mask;
xXISelectEventsReq *req;
init_simple();
req = (xXISelectEventsReq *) data;
request_init(req, XISelectEvents);
@ -364,12 +366,13 @@ test_XISelectEvents(void)
request_XISelectEvents_masks(req);
}
int
const testfunc_t*
protocol_xiselectevents_test(void)
{
init_simple();
static const testfunc_t testfuncs[] = {
test_XISelectEvents,
NULL,
};
test_XISelectEvents();
return 0;
return testfuncs;
}

View File

@ -85,6 +85,9 @@ test_XISetClientPointer(void)
int i;
xXISetClientPointerReq request;
init_simple();
client_window = init_client(0, NULL);
request_init(&request, XISetClientPointer);
request.win = CLIENT_WINDOW_ID;
@ -124,13 +127,13 @@ test_XISetClientPointer(void)
}
int
const testfunc_t*
protocol_xisetclientpointer_test(void)
{
init_simple();
client_window = init_client(0, NULL);
static const testfunc_t testfuncs[] = {
test_XISetClientPointer,
NULL,
};
test_XISetClientPointer();
return 0;
return testfuncs;
}

View File

@ -106,6 +106,9 @@ test_XIWarpPointer(void)
ClientRec client_request;
xXIWarpPointerReq request;
init_simple();
screen.SetCursorPosition = ScreenSetCursorPosition;
memset(&request, 0, sizeof(request));
request_init(&request, XIWarpPointer);
@ -188,13 +191,12 @@ test_XIWarpPointer(void)
request_XIWarpPointer(&client_request, &request, BadLength);
}
int
const testfunc_t*
protocol_xiwarppointer_test(void)
{
init_simple();
screen.SetCursorPosition = ScreenSetCursorPosition;
test_XIWarpPointer();
return 0;
static const testfunc_t testfuncs[] = {
test_XIWarpPointer,
NULL,
};
return testfuncs;
}

View File

@ -139,10 +139,14 @@ xi2mask_test(void)
free(mask);
}
int
const testfunc_t*
xi2_test(void)
{
xi2mask_test();
static const testfunc_t testfuncs[] = {
xi2mask_test,
NULL,
};
return testfuncs;
return 0;
}

View File

@ -60,57 +60,12 @@ device_cursor_cleanup(DeviceIntPtr dev, ScreenPtr screen)
}
static void
xtest_init_devices(void)
xtest_init(void)
{
assert(xtestpointer);
assert(xtestkeyboard);
assert(IsXTestDevice(xtestpointer, NULL));
assert(IsXTestDevice(xtestkeyboard, NULL));
assert(IsXTestDevice(xtestpointer, inputInfo.pointer));
assert(IsXTestDevice(xtestkeyboard, inputInfo.keyboard));
assert(GetXTestDevice(inputInfo.pointer) == xtestpointer);
assert(GetXTestDevice(inputInfo.keyboard) == xtestkeyboard);
}
/**
* Each xtest devices has a property attached marking it. This property
* cannot be changed.
*/
static void
xtest_properties(void)
{
int rc;
char value = 1;
XIPropertyValuePtr prop;
Atom xtest_prop = XIGetKnownProperty(XI_PROP_XTEST_DEVICE);
rc = XIGetDeviceProperty(xtestpointer, xtest_prop, &prop);
assert(rc == Success);
assert(prop);
rc = XIGetDeviceProperty(xtestkeyboard, xtest_prop, &prop);
assert(rc == Success);
assert(prop != NULL);
rc = XIChangeDeviceProperty(xtestpointer, xtest_prop,
XA_INTEGER, 8, PropModeReplace, 1, &value,
FALSE);
assert(rc == BadAccess);
rc = XIChangeDeviceProperty(xtestkeyboard, xtest_prop,
XA_INTEGER, 8, PropModeReplace, 1, &value,
FALSE);
assert(rc == BadAccess);
}
int
xtest_test(void)
{
ScreenRec screen = {0};
ClientRec server_client = {0};
WindowRec root = {{0}};
WindowOptRec optional = {0};
static ScreenRec screen = {0};
static ClientRec server_client = {0};
static WindowRec root = {{0}};
static WindowOptRec optional = {0};
/* random stuff that needs initialization */
root.drawable.id = 0xab;
@ -134,11 +89,75 @@ xtest_test(void)
/* this also inits the xtest devices */
InitCoreDevices();
xtest_init_devices();
xtest_properties();
CloseDownDevices();
return 0;
}
static void
xtest_cleanup(void)
{
CloseDownDevices();
}
static void
xtest_init_devices(void)
{
xtest_init();
assert(xtestpointer);
assert(xtestkeyboard);
assert(IsXTestDevice(xtestpointer, NULL));
assert(IsXTestDevice(xtestkeyboard, NULL));
assert(IsXTestDevice(xtestpointer, inputInfo.pointer));
assert(IsXTestDevice(xtestkeyboard, inputInfo.keyboard));
assert(GetXTestDevice(inputInfo.pointer) == xtestpointer);
assert(GetXTestDevice(inputInfo.keyboard) == xtestkeyboard);
xtest_cleanup();
}
/**
* Each xtest devices has a property attached marking it. This property
* cannot be changed.
*/
static void
xtest_properties(void)
{
int rc;
char value = 1;
XIPropertyValuePtr prop;
Atom xtest_prop;
xtest_init();
xtest_prop = XIGetKnownProperty(XI_PROP_XTEST_DEVICE);
rc = XIGetDeviceProperty(xtestpointer, xtest_prop, &prop);
assert(rc == Success);
assert(prop);
rc = XIGetDeviceProperty(xtestkeyboard, xtest_prop, &prop);
assert(rc == Success);
assert(prop != NULL);
rc = XIChangeDeviceProperty(xtestpointer, xtest_prop,
XA_INTEGER, 8, PropModeReplace, 1, &value,
FALSE);
assert(rc == BadAccess);
rc = XIChangeDeviceProperty(xtestkeyboard, xtest_prop,
XA_INTEGER, 8, PropModeReplace, 1, &value,
FALSE);
assert(rc == BadAccess);
xtest_cleanup();
}
const testfunc_t*
xtest_test(void)
{
static const testfunc_t testfuncs[] = {
xtest_init_devices,
xtest_properties,
NULL,
};
return testfuncs;
}