test-log.c 5.58 KB
Newer Older
1 2 3
/*
 * Copyright © 2014 Red Hat, Inc.
 *
4 5 6 7 8 9
 * 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:
10
 *
11 12 13 14 15 16 17 18 19 20 21
 * 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.
22 23 24 25 26 27 28 29 30
 */

#include <config.h>

#include <check.h>
#include <errno.h>
#include <fcntl.h>
#include <libinput.h>
#include <unistd.h>
31
#include <stdarg.h>
32 33 34 35

#include "litest.h"

static int log_handler_called;
36
static struct libinput *log_handler_context;
37 38 39 40 41 42 43 44 45 46 47 48

static int open_restricted(const char *path, int flags, void *data)
{
	int fd;
	fd = open(path, flags);
	return fd < 0 ? -errno : fd;
}
static void close_restricted(int fd, void *data)
{
	close(fd);
}

49
static const struct libinput_interface simple_interface = {
50 51 52 53 54
	.open_restricted = open_restricted,
	.close_restricted = close_restricted,
};

static void
55 56
simple_log_handler(struct libinput *libinput,
		   enum libinput_log_priority priority,
57 58 59 60
		   const char *format,
		   va_list args)
{
	log_handler_called++;
61
	if (log_handler_context)
62 63
		litest_assert_ptr_eq(libinput, log_handler_context);
	litest_assert_notnull(format);
64 65 66 67 68 69 70 71
}

START_TEST(log_default_priority)
{
	enum libinput_log_priority pri;
	struct libinput *li;

	li = libinput_path_create_context(&simple_interface, NULL);
72
	pri = libinput_log_get_priority(li);
73

74
	ck_assert_int_eq(pri, LIBINPUT_LOG_PRIORITY_ERROR);
75

76
	libinput_unref(li);
77 78 79
}
END_TEST

80
START_TEST(log_handler_invoked)
81 82 83
{
	struct libinput *li;

84 85 86
	log_handler_context = NULL;
	log_handler_called = 0;

87 88
	li = libinput_path_create_context(&simple_interface, NULL);

89 90 91
	libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG);
	libinput_log_set_handler(li, simple_log_handler);
	log_handler_context = li;
92 93 94 95

	libinput_path_add_device(li, "/tmp");

	ck_assert_int_gt(log_handler_called, 0);
96

97
	libinput_unref(li);
98 99

	log_handler_context = NULL;
100
	log_handler_called = 0;
101 102 103 104 105 106 107
}
END_TEST

START_TEST(log_handler_NULL)
{
	struct libinput *li;

108 109
	log_handler_called = 0;

110
	li = libinput_path_create_context(&simple_interface, NULL);
111 112 113
	libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG);
	libinput_log_set_handler(li, NULL);

114 115 116
	libinput_path_add_device(li, "/tmp");

	ck_assert_int_eq(log_handler_called, 0);
117

118
	libinput_unref(li);
119 120

	log_handler_called = 0;
121 122 123 124 125 126 127
}
END_TEST

START_TEST(log_priority)
{
	struct libinput *li;

128 129 130
	log_handler_context = NULL;
	log_handler_called = 0;

131
	li = libinput_path_create_context(&simple_interface, NULL);
132 133 134 135
	libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_ERROR);
	libinput_log_set_handler(li, simple_log_handler);
	log_handler_context = li;

136 137
	libinput_path_add_device(li, "/tmp");

138
	ck_assert_int_eq(log_handler_called, 1);
139

140
	libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_INFO);
141 142
	/* event0 exists on any box we care to run the test suite on and we
	 * currently prints *something* for each device */
143 144
	libinput_path_add_device(li, "/dev/input/event0");
	ck_assert_int_gt(log_handler_called, 1);
145

146
	libinput_unref(li);
147

148
	log_handler_context = NULL;
149
	log_handler_called = 0;
150 151 152
}
END_TEST

153 154 155 156 157 158 159 160
static int axisrange_log_handler_called = 0;

static void
axisrange_warning_log_handler(struct libinput *libinput,
			      enum libinput_log_priority priority,
			      const char *format,
			      va_list args)
{
161 162
	const char *substr;

163 164
	axisrange_log_handler_called++;
	litest_assert_notnull(format);
165 166 167

	substr = strstr(format, "is outside expected range");
	litest_assert_notnull(substr);
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
}

START_TEST(log_axisrange_warning)
{
	struct litest_device *dev = litest_current_device();
	struct libinput *li = dev->libinput;
	const struct input_absinfo *abs;
	int axis = _i; /* looped test */

	litest_touch_down(dev, 0, 90, 100);
	litest_drain_events(li);

	libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_INFO);
	libinput_log_set_handler(li, axisrange_warning_log_handler);

	abs = libevdev_get_abs_info(dev->evdev, axis);

	for (int i = 0; i < 100; i++) {
		litest_event(dev, EV_ABS,
			     ABS_MT_POSITION_X + axis,
			     abs->maximum * 2 + i);
		litest_event(dev, EV_ABS, axis, abs->maximum * 2);
		litest_event(dev, EV_SYN, SYN_REPORT, 0);
		libinput_dispatch(li);
	}

	/* Expect only one message per 5 min */
	ck_assert_int_eq(axisrange_log_handler_called, 1);

197
	libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_ERROR);
198 199 200 201 202
	litest_restore_log_handler(li);
	axisrange_log_handler_called = 0;
}
END_TEST

203
TEST_COLLECTION(log)
204
{
205 206
	struct range axes = { ABS_X, ABS_Y + 1};

207 208 209
	litest_add_deviceless("log:defaults", log_default_priority);
	litest_add_deviceless("log:logging", log_handler_invoked);
	litest_add_deviceless("log:logging", log_handler_NULL);
210
	litest_add_no_device("log:logging", log_priority);
211 212 213

	litest_add_ranged("log:warnings", log_axisrange_warning, LITEST_TOUCH, LITEST_ANY, &axes);
	litest_add_ranged("log:warnings", log_axisrange_warning, LITEST_TOUCHPAD, LITEST_ANY, &axes);
214
}