mirror of
https://gitlab.freedesktop.org/libinput/libei.git
synced 2025-12-26 21:30:13 +01:00
Add a test suite
This commit is contained in:
parent
ebd41833cb
commit
e860d24763
4 changed files with 688 additions and 0 deletions
15
meson.build
15
meson.build
|
|
@ -112,6 +112,21 @@ test('libei-unit-test',
|
|||
c_args: ['-D_enable_tests_'],
|
||||
dependencies: [munit, dep_libutil, dep_protobuf]))
|
||||
|
||||
lib_eierpecken = static_library('eierpecken',
|
||||
'test/eierpecken.h',
|
||||
'test/eierpecken.c',
|
||||
include_directories: 'src',
|
||||
dependencies: [munit, dep_libutil],
|
||||
)
|
||||
|
||||
test('libei-integration-test',
|
||||
executable('test-ei',
|
||||
'test/test-ei.c',
|
||||
link_with: lib_eierpecken,
|
||||
dependencies: [munit, dep_libei, dep_libeis]))
|
||||
|
||||
|
||||
|
||||
valgrind = find_program('valgrind', required : false)
|
||||
if valgrind.found()
|
||||
add_test_setup('valgrind',
|
||||
|
|
|
|||
356
test/eierpecken.c
Normal file
356
test/eierpecken.c
Normal file
|
|
@ -0,0 +1,356 @@
|
|||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <munit.h>
|
||||
|
||||
#include "eierpecken.h"
|
||||
|
||||
#include "util-bits.h"
|
||||
#include "util-mem.h"
|
||||
#include "util-tristate.h"
|
||||
#include "util-logger.h"
|
||||
#include "util-object.h"
|
||||
|
||||
DEFINE_TRISTATE(yes, no, unset);
|
||||
|
||||
struct peck {
|
||||
struct object object;
|
||||
struct ei *ei;
|
||||
struct eis *eis;
|
||||
uint32_t eis_behavior;
|
||||
uint32_t ei_behavior;
|
||||
struct logger *logger;
|
||||
};
|
||||
|
||||
static void
|
||||
peck_destroy(struct peck *peck)
|
||||
{
|
||||
ei_unref(peck->ei);
|
||||
eis_unref(peck->eis);
|
||||
logger_unref(peck->logger);
|
||||
}
|
||||
|
||||
OBJECT_IMPLEMENT_CREATE(peck);
|
||||
OBJECT_IMPLEMENT_UNREF(peck);
|
||||
OBJECT_IMPLEMENT_GETTER(peck, ei, struct ei*);
|
||||
OBJECT_IMPLEMENT_GETTER(peck, eis, struct eis*);
|
||||
|
||||
struct peck *
|
||||
peck_new(void)
|
||||
{
|
||||
struct peck *peck = peck_create(NULL);
|
||||
|
||||
int sv[2];
|
||||
int rc = socketpair(AF_UNIX, SOCK_DGRAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, sv);
|
||||
munit_assert_int(rc, ==, 0);
|
||||
|
||||
struct ei *ei = ei_new(NULL);
|
||||
ei_configure_name(ei, "eierpecken test context");
|
||||
rc = ei_setup_backend_fd(ei, sv[0]);
|
||||
munit_assert_int(rc, ==, 0);
|
||||
peck->ei = ei;
|
||||
peck->ei_behavior = PECK_EI_BEHAVIOR_AUTOCONNNECT;
|
||||
|
||||
struct eis *eis = eis_new(NULL);
|
||||
rc = eis_setup_backend_fd(eis);
|
||||
munit_assert_int(rc, ==, 0);
|
||||
rc = eis_backend_fd_add_fd(eis, sv[1]);
|
||||
peck->eis = eis;
|
||||
peck->eis_behavior = PECK_EIS_BEHAVIOR_NONE;
|
||||
|
||||
peck->logger = logger_new(NULL);
|
||||
logger_set_priority(peck->logger, LOGGER_DEBUG);
|
||||
|
||||
return peck;
|
||||
}
|
||||
|
||||
void
|
||||
peck_enable_eis_behavior(struct peck *peck, enum peck_eis_behavior behavior)
|
||||
{
|
||||
switch (behavior) {
|
||||
case PECK_EIS_BEHAVIOR_NONE:
|
||||
peck->eis_behavior = 0;
|
||||
break;
|
||||
case PECK_EIS_BEHAVIOR_ACCEPT_ALL:
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_DEVICE);
|
||||
break;
|
||||
case PECK_EIS_BEHAVIOR_REJECT_ALL:
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_REJECT_CLIENT);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_REJECT_DEVICE);
|
||||
break;
|
||||
case PECK_EIS_BEHAVIOR_ACCEPT_DEVICE:
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_POINTER);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_KEYBOARD);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_TOUCH);
|
||||
break;
|
||||
case PECK_EIS_BEHAVIOR_REJECT_DEVICE:
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_REJECT_POINTER);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_REJECT_KEYBOARD);
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_REJECT_TOUCH);
|
||||
break;
|
||||
case PECK_EIS_BEHAVIOR_REJECT_CLIENT:
|
||||
case PECK_EIS_BEHAVIOR_ACCEPT_CLIENT:
|
||||
case PECK_EIS_BEHAVIOR_ACCEPT_POINTER:
|
||||
case PECK_EIS_BEHAVIOR_REJECT_POINTER:
|
||||
case PECK_EIS_BEHAVIOR_ACCEPT_KEYBOARD:
|
||||
case PECK_EIS_BEHAVIOR_REJECT_KEYBOARD:
|
||||
case PECK_EIS_BEHAVIOR_ACCEPT_TOUCH:
|
||||
case PECK_EIS_BEHAVIOR_REJECT_TOUCH:
|
||||
flag_set(peck->eis_behavior, behavior);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
peck_enable_ei_behavior(struct peck *peck, enum peck_ei_behavior behavior)
|
||||
{
|
||||
switch (behavior) {
|
||||
case PECK_EI_BEHAVIOR_NONE:
|
||||
peck->ei_behavior = 0;
|
||||
break;
|
||||
case PECK_EI_BEHAVIOR_AUTOCONNNECT:
|
||||
flag_set(peck->ei_behavior, behavior);
|
||||
break;
|
||||
case PECK_EI_BEHAVIOR_HANDLE_ADDED:
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_ADDED_POINTER);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_ADDED_KEYBOARD);
|
||||
peck_enable_ei_behavior(peck, PECK_EI_BEHAVIOR_HANDLE_ADDED_TOUCH);
|
||||
break;
|
||||
case PECK_EI_BEHAVIOR_HANDLE_ADDED_POINTER:
|
||||
case PECK_EI_BEHAVIOR_HANDLE_ADDED_KEYBOARD:
|
||||
case PECK_EI_BEHAVIOR_HANDLE_ADDED_TOUCH:
|
||||
flag_set(peck->ei_behavior, behavior);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void
|
||||
peck_handle_eis_connect(struct peck *peck, struct eis_event *e)
|
||||
{
|
||||
struct eis_client *client = eis_event_get_client(e);
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT)) {
|
||||
log_debug(peck, "Accepting client: %s\n", eis_client_get_name(client));
|
||||
eis_client_connect(client);
|
||||
} else {
|
||||
log_debug(peck, "Disconnecting client: %s\n", eis_client_get_name(client));
|
||||
eis_client_disconnect(client);
|
||||
}
|
||||
}
|
||||
|
||||
static inline tristate
|
||||
peck_check_eis_added(struct peck *peck, struct eis_event *e)
|
||||
{
|
||||
struct eis_device *device = eis_event_get_device(e);
|
||||
tristate accept = tristate_unset;
|
||||
|
||||
if (eis_device_has_capability(device, EIS_DEVICE_CAP_POINTER)) {
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ACCEPT_POINTER))
|
||||
accept = tristate_yes;
|
||||
else if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_REJECT_POINTER))
|
||||
accept = tristate_no;
|
||||
}
|
||||
|
||||
if (eis_device_has_capability(device, EIS_DEVICE_CAP_KEYBOARD)) {
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ACCEPT_KEYBOARD))
|
||||
accept = tristate_yes;
|
||||
else if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_REJECT_KEYBOARD))
|
||||
accept = tristate_no;
|
||||
}
|
||||
|
||||
if (eis_device_has_capability(device, EIS_DEVICE_CAP_TOUCH)) {
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ACCEPT_TOUCH))
|
||||
accept = tristate_yes;
|
||||
else if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_REJECT_TOUCH))
|
||||
accept = tristate_no;
|
||||
}
|
||||
|
||||
return accept;
|
||||
}
|
||||
|
||||
void
|
||||
peck_dispatch_eis(struct peck *peck)
|
||||
{
|
||||
struct eis *eis = peck->eis;
|
||||
|
||||
while(true) {
|
||||
eis_dispatch(eis);
|
||||
tristate process_event = tristate_unset;
|
||||
|
||||
_cleanup_eis_event_ struct eis_event *e = eis_peek_event(eis);
|
||||
if (!e)
|
||||
break;
|
||||
|
||||
switch (eis_event_get_type(e)) {
|
||||
case EIS_EVENT_NONE:
|
||||
abort();
|
||||
case EIS_EVENT_CLIENT_CONNECT:
|
||||
case EIS_EVENT_CLIENT_DISCONNECT:
|
||||
if (flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_ACCEPT_CLIENT) ||
|
||||
flag_is_set(peck->eis_behavior, PECK_EIS_BEHAVIOR_REJECT_CLIENT))
|
||||
process_event = tristate_yes;
|
||||
break;
|
||||
case EIS_EVENT_DEVICE_ADDED:
|
||||
case EIS_EVENT_DEVICE_REMOVED:
|
||||
if (tristate_is_unset(peck_check_eis_added(peck, e)))
|
||||
process_event = tristate_no;
|
||||
else
|
||||
process_event = tristate_yes;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!tristate_is_yes(process_event))
|
||||
break;
|
||||
|
||||
/* manual unref, _cleanup_ will take care of the real event */
|
||||
eis_event_unref(e);
|
||||
e = eis_get_event(eis);
|
||||
|
||||
switch (eis_event_get_type(e)) {
|
||||
case EIS_EVENT_NONE:
|
||||
abort();
|
||||
case EIS_EVENT_CLIENT_CONNECT:
|
||||
peck_handle_eis_connect(peck, e);
|
||||
break;
|
||||
case EIS_EVENT_CLIENT_DISCONNECT:
|
||||
log_debug(peck, "Disconnecting client: %s\n",
|
||||
eis_client_get_name(eis_event_get_client(e)));
|
||||
eis_client_disconnect(eis_event_get_client(e));
|
||||
break;
|
||||
case EIS_EVENT_DEVICE_ADDED:
|
||||
if (tristate_is_yes(peck_check_eis_added(peck, e))) {
|
||||
eis_device_connect(eis_event_get_device(e));
|
||||
log_debug(peck, "Connecting device\n");
|
||||
} else {
|
||||
log_debug(peck, "Disconnecting device\n");
|
||||
eis_device_disconnect(eis_event_get_device(e));
|
||||
}
|
||||
break;
|
||||
case EIS_EVENT_DEVICE_REMOVED:
|
||||
log_debug(peck, "Disconnecting device\n");
|
||||
eis_device_disconnect(eis_event_get_device(e));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline tristate
|
||||
peck_check_ei_added(struct peck *peck, struct ei_event *e)
|
||||
{
|
||||
struct ei_device *device = ei_event_get_device(e);
|
||||
|
||||
if (ei_device_has_capability(device, EI_DEVICE_CAP_POINTER) &&
|
||||
flag_is_set(peck->ei_behavior, PECK_EI_BEHAVIOR_HANDLE_ADDED_POINTER))
|
||||
return tristate_yes;
|
||||
|
||||
if (ei_device_has_capability(device, EI_DEVICE_CAP_KEYBOARD) &&
|
||||
flag_is_set(peck->ei_behavior, PECK_EI_BEHAVIOR_HANDLE_ADDED_KEYBOARD))
|
||||
return tristate_yes;
|
||||
|
||||
if (ei_device_has_capability(device, EI_DEVICE_CAP_TOUCH) &
|
||||
flag_is_set(peck->ei_behavior, PECK_EI_BEHAVIOR_HANDLE_ADDED_TOUCH))
|
||||
return tristate_yes;
|
||||
|
||||
return tristate_unset;
|
||||
}
|
||||
|
||||
void
|
||||
peck_dispatch_ei(struct peck *peck)
|
||||
{
|
||||
struct ei *ei = peck->ei;
|
||||
|
||||
while (true) {
|
||||
ei_dispatch(ei);
|
||||
tristate process_event = tristate_no;
|
||||
|
||||
_cleanup_ei_event_ struct ei_event *e = ei_peek_event(ei);
|
||||
if (!e)
|
||||
break;
|
||||
|
||||
switch (ei_event_get_type(e)) {
|
||||
case EI_EVENT_NONE:
|
||||
abort();
|
||||
case EI_EVENT_CONNECT:
|
||||
if (flag_is_set(peck->ei_behavior,
|
||||
PECK_EI_BEHAVIOR_AUTOCONNNECT))
|
||||
process_event = tristate_yes;
|
||||
break;
|
||||
case EI_EVENT_DEVICE_ADDED:
|
||||
process_event = peck_check_ei_added(peck, e);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!tristate_is_yes(process_event))
|
||||
break;
|
||||
|
||||
/* manual unref, _cleanup_ will take care of the real event */
|
||||
ei_event_unref(e);
|
||||
e = ei_get_event(ei);
|
||||
|
||||
switch (ei_event_get_type(e)) {
|
||||
case EI_EVENT_NONE:
|
||||
abort();
|
||||
case EI_EVENT_CONNECT:
|
||||
/* Nothing to do here */
|
||||
break;
|
||||
case EI_EVENT_DEVICE_ADDED:
|
||||
/* Nothing to do here */
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
peck_drain_eis(struct eis *eis)
|
||||
{
|
||||
eis_dispatch(eis);
|
||||
|
||||
while (true) {
|
||||
_cleanup_eis_event_ struct eis_event *e = eis_get_event(eis);
|
||||
if (e == NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
peck_drain_ei(struct ei *ei)
|
||||
{
|
||||
ei_dispatch(ei);
|
||||
while (true) {
|
||||
_cleanup_ei_event_ struct ei_event *e = ei_get_event(ei);
|
||||
if (e == NULL)
|
||||
break;
|
||||
}
|
||||
}
|
||||
137
test/eierpecken.h
Normal file
137
test/eierpecken.h
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
* Copyright © 2020 Red Hat, Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice (including the next
|
||||
* paragraph) shall be included in all copies or substantial portions of the
|
||||
* Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
* DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "libei.h"
|
||||
#include "libeis.h"
|
||||
|
||||
#include "util-mem.h"
|
||||
|
||||
/**
|
||||
* An enum to define basic server behavior in peck_dispatch_eis().
|
||||
* Where a flag is **not** set for any specific behaviour, that event will
|
||||
* remain on the event queue after peck_dispatch_eis(). For example, a
|
||||
* caller setting @ref PECK_EIS_BEHAVIOR_ACCEPT_CLIENT will see
|
||||
* the device added event as first event in the queue.
|
||||
*/
|
||||
enum peck_eis_behavior {
|
||||
/**
|
||||
* Behavior of EIS is implemented in the test case. This is the
|
||||
* default.
|
||||
*/
|
||||
PECK_EIS_BEHAVIOR_NONE,
|
||||
/**
|
||||
* Accept all client connection requests and device additions.
|
||||
*/
|
||||
PECK_EIS_BEHAVIOR_ACCEPT_ALL,
|
||||
/**
|
||||
* Reject any client connection requests or device additions.
|
||||
*/
|
||||
PECK_EIS_BEHAVIOR_REJECT_ALL,
|
||||
|
||||
/**
|
||||
* Process connect/disconnect requests from the client.
|
||||
*/
|
||||
PECK_EIS_BEHAVIOR_ACCEPT_CLIENT,
|
||||
PECK_EIS_BEHAVIOR_REJECT_CLIENT,
|
||||
|
||||
/**
|
||||
* Process add/remove requests from the client.
|
||||
*/
|
||||
PECK_EIS_BEHAVIOR_ACCEPT_DEVICE,
|
||||
PECK_EIS_BEHAVIOR_REJECT_DEVICE,
|
||||
|
||||
PECK_EIS_BEHAVIOR_ACCEPT_POINTER,
|
||||
PECK_EIS_BEHAVIOR_REJECT_POINTER,
|
||||
|
||||
PECK_EIS_BEHAVIOR_ACCEPT_KEYBOARD,
|
||||
PECK_EIS_BEHAVIOR_REJECT_KEYBOARD,
|
||||
|
||||
PECK_EIS_BEHAVIOR_ACCEPT_TOUCH,
|
||||
PECK_EIS_BEHAVIOR_REJECT_TOUCH,
|
||||
};
|
||||
|
||||
enum peck_ei_behavior {
|
||||
PECK_EI_BEHAVIOR_NONE,
|
||||
/* the default - handle the Connect event */
|
||||
PECK_EI_BEHAVIOR_AUTOCONNNECT,
|
||||
PECK_EI_BEHAVIOR_HANDLE_ADDED,
|
||||
PECK_EI_BEHAVIOR_HANDLE_ADDED_POINTER,
|
||||
PECK_EI_BEHAVIOR_HANDLE_ADDED_KEYBOARD,
|
||||
PECK_EI_BEHAVIOR_HANDLE_ADDED_TOUCH,
|
||||
};
|
||||
|
||||
struct peck;
|
||||
|
||||
struct peck *
|
||||
peck_new(void);
|
||||
|
||||
void
|
||||
peck_enable_eis_behavior(struct peck *peck, enum peck_eis_behavior behavior);
|
||||
|
||||
void
|
||||
peck_enable_ei_behavior(struct peck *peck, enum peck_ei_behavior behavior);
|
||||
|
||||
struct ei *
|
||||
peck_get_ei(struct peck *peck);
|
||||
|
||||
struct eis *
|
||||
peck_get_eis(struct peck *peck);
|
||||
|
||||
void
|
||||
peck_dispatch_eis(struct peck *peck);
|
||||
|
||||
void
|
||||
peck_dispatch_ei(struct peck *peck);
|
||||
|
||||
struct peck *
|
||||
peck_unref(struct peck *peck);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct peck*, peck_unref);
|
||||
#define _cleanup_peck_ _cleanup_(peck_unrefp)
|
||||
|
||||
void
|
||||
peck_drain_eis(struct eis *eis);
|
||||
|
||||
void
|
||||
peck_drain_ei(struct ei *ei);
|
||||
|
||||
/* Define a bunch of _cleanup_foo_ macros for a struct foo */
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct ei *, ei_unref);
|
||||
#define _cleanup_ei_ _cleanup_(ei_unrefp)
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct ei_event *, ei_event_unref);
|
||||
#define _cleanup_ei_event_ _cleanup_(ei_event_unrefp)
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct ei_device *, ei_device_unref);
|
||||
#define _cleanup_ei_device_ _cleanup_(ei_device_unrefp)
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct eis *, eis_unref);
|
||||
#define _cleanup_eis_ _cleanup_(eis_unrefp)
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct eis_client *, eis_client_unref);
|
||||
#define _cleanup_eis_client_ _cleanup_(eis_client_unrefp)
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct eis_event *, eis_event_unref);
|
||||
#define _cleanup_eis_event_ _cleanup_(eis_event_unrefp)
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct eis_device *, eis_device_unref);
|
||||
#define _cleanup_eis_device_ _cleanup_(eis_device_unrefp)
|
||||
180
test/test-ei.c
Normal file
180
test/test-ei.c
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
|
||||
#include "config.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <munit.h>
|
||||
|
||||
#include "libei.h"
|
||||
#include "eierpecken.h"
|
||||
|
||||
/* Macros intended just for readability to make it more obvious which part
|
||||
of a test handles server vs client */
|
||||
#define with_server(peck_) for (struct eis *eis = peck_get_eis(peck_); eis; eis = NULL)
|
||||
#define with_client(peck_) for (struct ei *ei = peck_get_ei(peck_); ei; ei = NULL)
|
||||
|
||||
static MunitResult
|
||||
test_ei_ref_unref(const MunitParameter params[], void *user_data)
|
||||
{
|
||||
struct ei *ei = ei_new(NULL);
|
||||
|
||||
struct ei *refd = ei_ref(ei);
|
||||
munit_assert_ptr_equal(ei, refd);
|
||||
|
||||
struct ei *unrefd = ei_unref(ei);
|
||||
munit_assert_ptr_null(unrefd);
|
||||
unrefd = ei_unref(ei);
|
||||
munit_assert_ptr_null(unrefd);
|
||||
|
||||
/* memleak only shows up in valgrind */
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_ei_reject(const MunitParameter params[], void *user_data)
|
||||
{
|
||||
_cleanup_peck_ struct peck *peck = peck_new();
|
||||
|
||||
/* Client is immediately rejected */
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_REJECT_CLIENT);
|
||||
peck_dispatch_ei(peck);
|
||||
peck_dispatch_eis(peck);
|
||||
|
||||
/* Expect the client to get a disconnect event */
|
||||
with_client(peck) {
|
||||
ei_dispatch(ei);
|
||||
_cleanup_ei_event_ struct ei_event *e = ei_get_event(ei);
|
||||
munit_assert_ptr_not_null(e);
|
||||
munit_assert_int(ei_event_get_type(e), ==, EI_EVENT_DISCONNECT);
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_ei_reject_after_connect(const MunitParameter params[], void *user_data)
|
||||
{
|
||||
_cleanup_peck_ struct peck *peck = peck_new();
|
||||
_cleanup_eis_client_ struct eis_client *client = NULL;
|
||||
|
||||
peck_dispatch_ei(peck);
|
||||
|
||||
with_server(peck) {
|
||||
eis_dispatch(eis);
|
||||
_cleanup_eis_event_ struct eis_event *e = eis_get_event(eis);
|
||||
munit_assert_ptr_not_null(e);
|
||||
munit_assert_int(eis_event_get_type(e), ==, EIS_EVENT_CLIENT_CONNECT);
|
||||
client = eis_client_ref(eis_event_get_client(e));
|
||||
eis_client_connect(client);
|
||||
}
|
||||
|
||||
with_client(peck) {
|
||||
ei_dispatch(ei);
|
||||
_cleanup_ei_event_ struct ei_event *e = ei_get_event(ei);
|
||||
munit_assert_ptr_not_null(e);
|
||||
munit_assert_int(ei_event_get_type(e), ==, EI_EVENT_CONNECT);
|
||||
}
|
||||
|
||||
with_server(peck) {
|
||||
eis_client_disconnect(client);
|
||||
}
|
||||
|
||||
with_client(peck) {
|
||||
ei_dispatch(ei);
|
||||
_cleanup_ei_event_ struct ei_event *e = ei_get_event(ei);
|
||||
munit_assert_ptr_not_null(e);
|
||||
munit_assert_int(ei_event_get_type(e), ==, EI_EVENT_DISCONNECT);
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_ei_device_basics(const MunitParameter params[], void *user_data)
|
||||
{
|
||||
_cleanup_peck_ struct peck *peck = peck_new();
|
||||
_cleanup_ei_device_ struct ei_device *device = NULL;
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL);
|
||||
peck_dispatch_eis(peck);
|
||||
peck_dispatch_ei(peck);
|
||||
|
||||
/* device creation and getters/setters test */
|
||||
with_client(peck) {
|
||||
device = ei_device_new(ei);
|
||||
munit_assert_not_null(device);
|
||||
ei_device_configure_name(device, __func__);
|
||||
munit_assert_string_equal(ei_device_get_name(device), __func__);
|
||||
|
||||
bool success = ei_device_configure_capability(device, EI_DEVICE_CAP_POINTER);
|
||||
munit_assert(success);
|
||||
munit_assert(ei_device_has_capability(device, EI_DEVICE_CAP_POINTER));
|
||||
|
||||
/* Add it, but we don't care about whether it worked correctly in this test */
|
||||
ei_device_add(device);
|
||||
|
||||
/* Device is immutable after ei_device_add() */
|
||||
bool failed_caps = ei_device_configure_capability(device, EI_DEVICE_CAP_POINTER);
|
||||
munit_assert(failed_caps == false);
|
||||
munit_assert(ei_device_has_capability(device, EI_DEVICE_CAP_POINTER));
|
||||
}
|
||||
|
||||
/* Drain both sides, we don't care about the events themselves */
|
||||
with_server(peck) {
|
||||
peck_drain_eis(eis);
|
||||
}
|
||||
with_client(peck) {
|
||||
peck_drain_ei(ei);
|
||||
}
|
||||
|
||||
/* device is still immutable */
|
||||
with_client(peck) {
|
||||
bool failed_caps = ei_device_configure_capability(device, EI_DEVICE_CAP_POINTER);
|
||||
munit_assert(failed_caps == false);
|
||||
munit_assert(ei_device_has_capability(device, EI_DEVICE_CAP_POINTER));
|
||||
}
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitResult
|
||||
test_ei_device_add(const MunitParameter params[], void *user_data)
|
||||
{
|
||||
_cleanup_peck_ struct peck *peck = peck_new();
|
||||
struct ei *ei = peck_get_ei(peck);
|
||||
|
||||
peck_enable_eis_behavior(peck, PECK_EIS_BEHAVIOR_ACCEPT_ALL);
|
||||
peck_dispatch_eis(peck);
|
||||
|
||||
peck_drain_ei(ei);
|
||||
|
||||
_cleanup_ei_device_ struct ei_device *device = ei_device_new(ei);
|
||||
ei_device_configure_name(device, __func__);
|
||||
ei_device_configure_capability(device, EI_DEVICE_CAP_POINTER);
|
||||
ei_device_add(device);
|
||||
|
||||
return MUNIT_OK;
|
||||
}
|
||||
|
||||
static MunitTest ei_tests[] = {
|
||||
{ .name = "/ei/ref", .test = test_ei_ref_unref },
|
||||
{ .name = "/ei/reject", .test = test_ei_reject },
|
||||
{ .name = "/ei/reject_after_connect", .test = test_ei_reject_after_connect },
|
||||
{ .name = "/device/basics", .test = test_ei_device_basics },
|
||||
{ .name = "/device/add", .test = test_ei_device_add },
|
||||
};
|
||||
|
||||
static const MunitSuite iotest_suite = {
|
||||
"/ei",
|
||||
ei_tests,
|
||||
NULL,
|
||||
1,
|
||||
MUNIT_SUITE_OPTION_NONE,
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)])
|
||||
{
|
||||
return munit_suite_main(&iotest_suite, NULL, argc, argv);
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue