test: make wrapping a function more generic

This cleans up some of the mess this code was in. Functions we need to
wrap can now have a standard implementation using WRAP_FUNCTION - that
macro declares the __real and __wrap functions and a wrapped_$func
global variable.

Tests can set that variable to their desired functions and it will be
then be called on demand.
This commit is contained in:
Peter Hutterer 2024-01-05 14:08:29 +10:00
parent 46b579e8d5
commit 7e9d167c9c
10 changed files with 87 additions and 81 deletions

View File

@ -1,6 +1,23 @@
#ifndef TESTS_H #ifndef TESTS_H
#define TESTS_H #define TESTS_H
#define DECLARE_WRAP_FUNCTION(f_, rval_, ...) \
extern rval_ (*wrapped_ ## f_)(__VA_ARGS__) \
#define IMPLEMENT_WRAP_FUNCTION(f_, ...) \
if (wrapped_ ## f_) wrapped_ ## f_(__VA_ARGS__); \
else __real_ ## f_(__VA_ARGS__)
#define IMPLEMENT_WRAP_FUNCTION_WITH_RETURN(f_, ...) \
if (wrapped_ ## f_) return wrapped_ ## f_(__VA_ARGS__); \
else return __real_ ## f_(__VA_ARGS__)
#define WRAP_FUNCTION(f_, rval_, ...) \
rval_ (*wrapped_ ## f_)(__VA_ARGS__); \
extern rval_ __real_ ## f_(__VA_ARGS__); \
rval_ __wrap_ ## f_(__VA_ARGS__); \
rval_ __wrap_ ## f_(__VA_ARGS__)
typedef void (*testfunc_t)(void); typedef void (*testfunc_t)(void);
const testfunc_t* fixes_test(void); const testfunc_t* fixes_test(void);

View File

@ -40,11 +40,13 @@
#include "protocol-common.h" #include "protocol-common.h"
DECLARE_WRAP_FUNCTION(WriteToClient, void, ClientPtr client, int len, void *data);
extern ClientRec client_window; extern ClientRec client_window;
static ClientRec client_request; static ClientRec client_request;
static void static void
reply_ChangeDeviceControl(ClientPtr client, int len, char *data, void *userdata) reply_ChangeDeviceControl(ClientPtr client, int len, void *data)
{ {
xChangeDeviceControlReply *rep = (xChangeDeviceControlReply *) data; xChangeDeviceControlReply *rep = (xChangeDeviceControlReply *) data;
@ -92,7 +94,7 @@ test_ChangeDeviceControl(void)
request_init(request, ChangeDeviceControl); request_init(request, ChangeDeviceControl);
reply_handler = reply_ChangeDeviceControl; wrapped_WriteToClient = reply_ChangeDeviceControl;
client_request = init_client(request->length, request); client_request = init_client(request->length, request);

View File

@ -287,12 +287,9 @@ init_simple(void)
devices = init_devices(); devices = init_devices();
} }
void WRAP_FUNCTION(WriteToClient, void, ClientPtr client, int len, void *data)
__wrap_WriteToClient(ClientPtr client, int len, void *data)
{ {
assert(reply_handler != NULL); IMPLEMENT_WRAP_FUNCTION(WriteToClient, client, len, data);
(*reply_handler) (client, len, data, global_userdata);
} }
/* dixLookupWindow requires a lot of setup not necessary for this test. /* dixLookupWindow requires a lot of setup not necessary for this test.

View File

@ -143,7 +143,6 @@ void init_window(WindowPtr window, WindowPtr parent, int id);
void init_simple(void); void init_simple(void);
/* Declarations for various overrides in the test files. */ /* Declarations for various overrides in the test files. */
void __wrap_WriteToClient(ClientPtr client, int len, void *data);
int __wrap_XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client, int __wrap_XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client,
int len, unsigned char *mask); int len, unsigned char *mask);
int __wrap_dixLookupWindow(WindowPtr *win, XID id, ClientPtr client, int __wrap_dixLookupWindow(WindowPtr *win, XID id, ClientPtr client,

View File

@ -43,6 +43,8 @@
#include "protocol-common.h" #include "protocol-common.h"
DECLARE_WRAP_FUNCTION(WriteToClient, void, ClientPtr client, int len, void *data);
static struct { static struct {
int cp_is_set; int cp_is_set;
DeviceIntPtr dev; DeviceIntPtr dev;
@ -53,7 +55,7 @@ extern ClientRec client_window;
static ClientRec client_request; static ClientRec client_request;
static void static void
reply_XIGetClientPointer(ClientPtr client, int len, char *data, void *userdata) reply_XIGetClientPointer(ClientPtr client, int len, void *data)
{ {
xXIGetClientPointerReply *rep = (xXIGetClientPointerReply *) data; xXIGetClientPointerReply *rep = (xXIGetClientPointerReply *) data;
@ -107,7 +109,7 @@ test_XIGetClientPointer(void)
request.win = CLIENT_WINDOW_ID; request.win = CLIENT_WINDOW_ID;
reply_handler = reply_XIGetClientPointer; wrapped_WriteToClient = reply_XIGetClientPointer;
client_request = init_client(request.length, &request); client_request = init_client(request.length, &request);

View File

@ -52,10 +52,10 @@
#include "protocol-common.h" #include "protocol-common.h"
static void reply_XIGetSelectedEvents(ClientPtr client, int len, char *data, DECLARE_WRAP_FUNCTION(WriteToClient, void, ClientPtr client, int len, void *data);
void *userdata);
static void reply_XIGetSelectedEvents_data(ClientPtr client, int len, static void reply_XIGetSelectedEvents(ClientPtr client, int len, void *data);
char *data, void *userdata); static void reply_XIGetSelectedEvents_data(ClientPtr client, int len, void *data);
static struct { static struct {
int num_masks_expected; int num_masks_expected;
@ -73,7 +73,7 @@ __wrap_AddResource(XID id, RESTYPE type, void *value)
} }
static void static void
reply_XIGetSelectedEvents(ClientPtr client, int len, char *data, void *userdata) reply_XIGetSelectedEvents(ClientPtr client, int len, void *data)
{ {
xXIGetSelectedEventsReply *rep = (xXIGetSelectedEventsReply *) data; xXIGetSelectedEventsReply *rep = (xXIGetSelectedEventsReply *) data;
@ -87,12 +87,11 @@ reply_XIGetSelectedEvents(ClientPtr client, int len, char *data, void *userdata)
assert(rep->num_masks == test_data.num_masks_expected); assert(rep->num_masks == test_data.num_masks_expected);
reply_handler = reply_XIGetSelectedEvents_data; wrapped_WriteToClient = reply_XIGetSelectedEvents_data;
} }
static void static void
reply_XIGetSelectedEvents_data(ClientPtr client, int len, char *data, reply_XIGetSelectedEvents_data(ClientPtr client, int len, void *data)
void *userdata)
{ {
int i; int i;
xXIEventMask *mask; xXIEventMask *mask;
@ -127,12 +126,12 @@ request_XIGetSelectedEvents(xXIGetSelectedEventsReq * req, int error)
client = init_client(req->length, req); client = init_client(req->length, req);
reply_handler = reply_XIGetSelectedEvents; wrapped_WriteToClient = reply_XIGetSelectedEvents;
rc = ProcXIGetSelectedEvents(&client); rc = ProcXIGetSelectedEvents(&client);
assert(rc == error); assert(rc == error);
reply_handler = reply_XIGetSelectedEvents; wrapped_WriteToClient = reply_XIGetSelectedEvents;
client.swapped = TRUE; client.swapped = TRUE;
swapl(&req->win); swapl(&req->win);
swaps(&req->length); swaps(&req->length);

View File

@ -44,6 +44,8 @@
#include "protocol-common.h" #include "protocol-common.h"
DECLARE_WRAP_FUNCTION(WriteToClient, void, ClientPtr client, int len, void *data);
extern ClientRec client_window; extern ClientRec client_window;
static ClientRec client_request; static ClientRec client_request;
@ -63,7 +65,7 @@ int __real_GrabButton(ClientPtr client, DeviceIntPtr dev,
GrabParameters *param, enum InputLevel grabtype, GrabParameters *param, enum InputLevel grabtype,
GrabMask *mask); GrabMask *mask);
static void reply_XIPassiveGrabDevice_data(ClientPtr client, int len, static void reply_XIPassiveGrabDevice_data(ClientPtr client, int len,
char *data, void *closure); void *data);
int int
__wrap_GrabButton(ClientPtr client, DeviceIntPtr dev, __wrap_GrabButton(ClientPtr client, DeviceIntPtr dev,
@ -82,7 +84,7 @@ __wrap_GrabButton(ClientPtr client, DeviceIntPtr dev,
} }
static void static void
reply_XIPassiveGrabDevice(ClientPtr client, int len, char *data, void *closure) reply_XIPassiveGrabDevice(ClientPtr client, int len, void *data)
{ {
xXIPassiveGrabDeviceReply *rep = (xXIPassiveGrabDeviceReply *) data; xXIPassiveGrabDeviceReply *rep = (xXIPassiveGrabDeviceReply *) data;
@ -99,12 +101,11 @@ reply_XIPassiveGrabDevice(ClientPtr client, int len, char *data, void *closure)
/* ProcXIPassiveGrabDevice sends the data in two batches, let the second /* ProcXIPassiveGrabDevice sends the data in two batches, let the second
* handler handle the modifier data */ * handler handle the modifier data */
if (rep->num_modifiers > 0) if (rep->num_modifiers > 0)
reply_handler = reply_XIPassiveGrabDevice_data; wrapped_WriteToClient = reply_XIPassiveGrabDevice_data;
} }
static void static void
reply_XIPassiveGrabDevice_data(ClientPtr client, int len, char *data, reply_XIPassiveGrabDevice_data(ClientPtr client, int len, void *data)
void *closure)
{ {
int i; int i;
@ -124,7 +125,7 @@ reply_XIPassiveGrabDevice_data(ClientPtr client, int len, char *data,
assert(mods->pad1 == 0); assert(mods->pad1 == 0);
} }
reply_handler = reply_XIPassiveGrabDevice; wrapped_WriteToClient = reply_XIPassiveGrabDevice;
} }
static void static void
@ -181,7 +182,7 @@ test_XIPassiveGrabDevice(void)
request->grab_window = CLIENT_WINDOW_ID; request->grab_window = CLIENT_WINDOW_ID;
reply_handler = reply_XIPassiveGrabDevice; wrapped_WriteToClient = reply_XIPassiveGrabDevice;
client_request = init_client(request->length, request); client_request = init_client(request->length, request);
printf("Testing invalid device\n"); printf("Testing invalid device\n");

View File

@ -42,6 +42,8 @@
#include "xiquerydevice.h" #include "xiquerydevice.h"
#include "protocol-common.h" #include "protocol-common.h"
DECLARE_WRAP_FUNCTION(WriteToClient, void, ClientPtr client, int len, void *data);
/* /*
* Protocol testing for XIQueryDevice request and reply. * Protocol testing for XIQueryDevice request and reply.
* *
@ -52,24 +54,20 @@
* Repeatedly test with varying deviceids and check against data in reply. * Repeatedly test with varying deviceids and check against data in reply.
*/ */
struct test_data { static struct test_data {
int which_device; int which_device;
int num_devices_in_reply; int num_devices_in_reply;
}; } test_data;
extern ClientRec client_window; extern ClientRec client_window;
static void reply_XIQueryDevice_data(ClientPtr client, int len, char *data, static void reply_XIQueryDevice_data(ClientPtr client, int len, void *data);
void *closure);
static void reply_XIQueryDevice(ClientPtr client, int len, char *data,
void *closure);
/* reply handling for the first bytes that constitute the reply */ /* reply handling for the first bytes that constitute the reply */
static void static void
reply_XIQueryDevice(ClientPtr client, int len, char *data, void *userdata) reply_XIQueryDevice(ClientPtr client, int len, void *data)
{ {
xXIQueryDeviceReply *rep = (xXIQueryDeviceReply *) data; xXIQueryDeviceReply *rep = (xXIQueryDeviceReply *) data;
struct test_data *querydata = (struct test_data *) userdata;
if (client->swapped) { if (client->swapped) {
swapl(&rep->length); swapl(&rep->length);
@ -79,29 +77,29 @@ reply_XIQueryDevice(ClientPtr client, int len, char *data, void *userdata)
reply_check_defaults(rep, len, XIQueryDevice); reply_check_defaults(rep, len, XIQueryDevice);
if (querydata->which_device == XIAllDevices) if (test_data.which_device == XIAllDevices)
assert(rep->num_devices == devices.num_devices); assert(rep->num_devices == devices.num_devices);
else if (querydata->which_device == XIAllMasterDevices) else if (test_data.which_device == XIAllMasterDevices)
assert(rep->num_devices == devices.num_master_devices); assert(rep->num_devices == devices.num_master_devices);
else else
assert(rep->num_devices == 1); assert(rep->num_devices == 1);
querydata->num_devices_in_reply = rep->num_devices; test_data.num_devices_in_reply = rep->num_devices;
reply_handler = reply_XIQueryDevice_data;
wrapped_WriteToClient = reply_XIQueryDevice_data;
} }
/* reply handling for the trailing bytes that constitute the device info */ /* reply handling for the trailing bytes that constitute the device info */
static void static void
reply_XIQueryDevice_data(ClientPtr client, int len, char *data, void *closure) reply_XIQueryDevice_data(ClientPtr client, int len, void *data)
{ {
int i, j; int i, j;
struct test_data *querydata = (struct test_data *) closure;
DeviceIntPtr dev; DeviceIntPtr dev;
xXIDeviceInfo *info = (xXIDeviceInfo *) data; xXIDeviceInfo *info = (xXIDeviceInfo *) data;
xXIAnyInfo *any; xXIAnyInfo *any;
for (i = 0; i < querydata->num_devices_in_reply; i++) { for (i = 0; i < test_data.num_devices_in_reply; i++) {
if (client->swapped) { if (client->swapped) {
swaps(&info->deviceid); swaps(&info->deviceid);
swaps(&info->attachment); swaps(&info->attachment);
@ -110,8 +108,8 @@ reply_XIQueryDevice_data(ClientPtr client, int len, char *data, void *closure)
swaps(&info->name_len); swaps(&info->name_len);
} }
if (querydata->which_device > XIAllMasterDevices) if (test_data.which_device > XIAllMasterDevices)
assert(info->deviceid == querydata->which_device); assert(info->deviceid == test_data.which_device);
assert(info->deviceid >= 2); /* 0 and 1 is reserved */ assert(info->deviceid >= 2); /* 0 and 1 is reserved */
@ -287,7 +285,7 @@ request_XIQueryDevice(struct test_data *querydata, int deviceid, int error)
request_init(&request, XIQueryDevice); request_init(&request, XIQueryDevice);
client = init_client(request.length, &request); client = init_client(request.length, &request);
reply_handler = reply_XIQueryDevice; wrapped_WriteToClient = reply_XIQueryDevice;
querydata->which_device = deviceid; querydata->which_device = deviceid;
@ -298,7 +296,7 @@ request_XIQueryDevice(struct test_data *querydata, int deviceid, int error)
if (rc != Success) if (rc != Success)
assert(client.errorValue == deviceid); assert(client.errorValue == deviceid);
reply_handler = reply_XIQueryDevice; wrapped_WriteToClient = reply_XIQueryDevice;
client.swapped = TRUE; client.swapped = TRUE;
swaps(&request.length); swaps(&request.length);
@ -315,29 +313,24 @@ test_XIQueryDevice(void)
{ {
int i; int i;
xXIQueryDeviceReq request; xXIQueryDeviceReq request;
struct test_data data;
init_simple(); init_simple();
reply_handler = reply_XIQueryDevice; wrapped_WriteToClient = reply_XIQueryDevice;
global_userdata = &data;
request_init(&request, XIQueryDevice); request_init(&request, XIQueryDevice);
printf("Testing XIAllDevices.\n"); printf("Testing XIAllDevices.\n");
request_XIQueryDevice(&data, XIAllDevices, Success); request_XIQueryDevice(&test_data, XIAllDevices, Success);
printf("Testing XIAllMasterDevices.\n"); printf("Testing XIAllMasterDevices.\n");
request_XIQueryDevice(&data, XIAllMasterDevices, Success); request_XIQueryDevice(&test_data, XIAllMasterDevices, Success);
printf("Testing existing device ids.\n"); printf("Testing existing device ids.\n");
for (i = 2; i < 6; i++) for (i = 2; i < 6; i++)
request_XIQueryDevice(&data, i, Success); request_XIQueryDevice(&test_data, i, Success);
printf("Testing non-existing device ids.\n"); printf("Testing non-existing device ids.\n");
for (i = 6; i <= 0xFFFF; i++) for (i = 6; i <= 0xFFFF; i++)
request_XIQueryDevice(&data, i, BadDevice); request_XIQueryDevice(&test_data, i, BadDevice);
reply_handler = NULL;
} }
const testfunc_t* const testfunc_t*

View File

@ -44,10 +44,11 @@
#include "protocol-common.h" #include "protocol-common.h"
DECLARE_WRAP_FUNCTION(WriteToClient, void, ClientPtr client, int len, void *data);
extern ClientRec client_window; extern ClientRec client_window;
static ClientRec client_request; static ClientRec client_request;
static void reply_XIQueryPointer_data(ClientPtr client, int len, static void reply_XIQueryPointer_data(ClientPtr client, int len, void *data);
char *data, void *closure);
static struct { static struct {
DeviceIntPtr dev; DeviceIntPtr dev;
@ -55,7 +56,7 @@ static struct {
} test_data; } test_data;
static void static void
reply_XIQueryPointer(ClientPtr client, int len, char *data, void *closure) reply_XIQueryPointer(ClientPtr client, int len, void *data)
{ {
xXIQueryPointerReply *rep = (xXIQueryPointerReply *) data; xXIQueryPointerReply *rep = (xXIQueryPointerReply *) data;
SpritePtr sprite; SpritePtr sprite;
@ -102,13 +103,13 @@ reply_XIQueryPointer(ClientPtr client, int len, char *data, void *closure)
assert(rep->same_screen == xTrue); assert(rep->same_screen == xTrue);
reply_handler = reply_XIQueryPointer_data; wrapped_WriteToClient = reply_XIQueryPointer_data;
} }
static void static void
reply_XIQueryPointer_data(ClientPtr client, int len, char *data, void *closure) reply_XIQueryPointer_data(ClientPtr client, int len, void *data)
{ {
reply_handler = reply_XIQueryPointer; wrapped_WriteToClient = reply_XIQueryPointer;
} }
static void static void
@ -145,7 +146,7 @@ test_XIQueryPointer(void)
request_init(&request, XIQueryPointer); request_init(&request, XIQueryPointer);
reply_handler = reply_XIQueryPointer; wrapped_WriteToClient = reply_XIQueryPointer;
client_request = init_client(request.length, &request); client_request = init_client(request.length, &request);

View File

@ -50,24 +50,26 @@
#include "protocol-common.h" #include "protocol-common.h"
#include "exglobals.h" #include "exglobals.h"
DECLARE_WRAP_FUNCTION(WriteToClient, void, ClientPtr client, int len, void *data);
extern XExtensionVersion XIVersion; extern XExtensionVersion XIVersion;
struct test_data { static struct test_data {
int major_client; int major_client;
int minor_client; int minor_client;
int major_server; int major_server;
int minor_server; int minor_server;
int major_expected; int major_expected;
int minor_expected; int minor_expected;
}; } versions;
extern ClientRec client_window; extern ClientRec client_window;
static void static void
reply_XIQueryVersion(ClientPtr client, int len, char *data, void *closure) reply_XIQueryVersion(ClientPtr client, int len, void *data)
{ {
xXIQueryVersionReply *rep = (xXIQueryVersionReply *) data; xXIQueryVersionReply *rep = (xXIQueryVersionReply *) data;
struct test_data *versions = (struct test_data *) closure;
unsigned int sver, cver, ver; unsigned int sver, cver, ver;
if (client->swapped) { if (client->swapped) {
@ -81,8 +83,8 @@ reply_XIQueryVersion(ClientPtr client, int len, char *data, void *closure)
assert(rep->length == 0); assert(rep->length == 0);
sver = versions->major_server * 1000 + versions->minor_server; sver = versions.major_server * 1000 + versions.minor_server;
cver = versions->major_client * 1000 + versions->minor_client; cver = versions.major_client * 1000 + versions.minor_client;
ver = rep->major_version * 1000 + rep->minor_version; ver = rep->major_version * 1000 + rep->minor_version;
assert(ver >= 2000); assert(ver >= 2000);
@ -90,16 +92,15 @@ reply_XIQueryVersion(ClientPtr client, int len, char *data, void *closure)
} }
static void static void
reply_XIQueryVersion_multiple(ClientPtr client, int len, char *data, void *closure) reply_XIQueryVersion_multiple(ClientPtr client, int len, void *data)
{ {
xXIQueryVersionReply *rep = (xXIQueryVersionReply *) data; xXIQueryVersionReply *rep = (xXIQueryVersionReply *) data;
struct test_data *versions = (struct test_data *) closure;
reply_check_defaults(rep, len, XIQueryVersion); reply_check_defaults(rep, len, XIQueryVersion);
assert(rep->length == 0); assert(rep->length == 0);
assert(versions->major_expected == rep->major_version); assert(versions.major_expected == rep->major_version);
assert(versions->minor_expected == rep->minor_version); assert(versions.minor_expected == rep->minor_version);
} }
/** /**
@ -112,13 +113,11 @@ static void
request_XIQueryVersion(int smaj, int smin, int cmaj, int cmin, int error) request_XIQueryVersion(int smaj, int smin, int cmaj, int cmin, int error)
{ {
int rc; int rc;
struct test_data versions;
xXIQueryVersionReq request; xXIQueryVersionReq request;
ClientRec client; ClientRec client;
request_init(&request, XIQueryVersion); request_init(&request, XIQueryVersion);
client = init_client(request.length, &request); client = init_client(request.length, &request);
global_userdata = (void *) &versions;
/* Change the server to support smaj.smin */ /* Change the server to support smaj.smin */
XIVersion.major_version = smaj; XIVersion.major_version = smaj;
@ -153,7 +152,7 @@ test_XIQueryVersion(void)
{ {
init_simple(); init_simple();
reply_handler = reply_XIQueryVersion; wrapped_WriteToClient = reply_XIQueryVersion;
printf("Server version 2.0 - client versions [1..3].0\n"); printf("Server version 2.0 - client versions [1..3].0\n");
/* some simple tests to catch common errors quickly */ /* some simple tests to catch common errors quickly */
@ -191,8 +190,6 @@ test_XIQueryVersion(void)
} }
#endif #endif
reply_handler = NULL;
} }
@ -202,7 +199,6 @@ test_XIQueryVersion_multiple(void)
xXIQueryVersionReq request; xXIQueryVersionReq request;
ClientRec client; ClientRec client;
XIClientPtr pXIClient; XIClientPtr pXIClient;
struct test_data versions;
int rc; int rc;
init_simple(); init_simple();
@ -214,8 +210,7 @@ test_XIQueryVersion_multiple(void)
XIVersion.major_version = 2; XIVersion.major_version = 2;
XIVersion.minor_version = 2; XIVersion.minor_version = 2;
reply_handler = reply_XIQueryVersion_multiple; wrapped_WriteToClient = reply_XIQueryVersion_multiple;
global_userdata = (void *) &versions;
/* run 1 */ /* run 1 */