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
#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);
const testfunc_t* fixes_test(void);

View File

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

View File

@ -287,12 +287,9 @@ init_simple(void)
devices = init_devices();
}
void
__wrap_WriteToClient(ClientPtr client, int len, void *data)
WRAP_FUNCTION(WriteToClient, void, ClientPtr client, int len, void *data)
{
assert(reply_handler != NULL);
(*reply_handler) (client, len, data, global_userdata);
IMPLEMENT_WRAP_FUNCTION(WriteToClient, client, len, data);
}
/* 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);
/* 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 len, unsigned char *mask);
int __wrap_dixLookupWindow(WindowPtr *win, XID id, ClientPtr client,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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