1/* 2 * Copyright © 2014 Red Hat, Inc. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 21 * DEALINGS IN THE SOFTWARE. 22 */ 23 24#include <config.h> 25 26#include <check.h> 27#include <errno.h> 28#include <fcntl.h> 29#include <libinput.h> 30#include <unistd.h> 31#include <stdarg.h> 32 33#include "litest.h" 34 35static int log_handler_called; 36static struct libinput *log_handler_context; 37 38static void 39simple_log_handler(struct libinput *libinput, 40 enum libinput_log_priority priority, 41 const char *format, 42 va_list args) 43{ 44 log_handler_called++; 45 if (log_handler_context) 46 litest_assert_ptr_eq(libinput, log_handler_context); 47 litest_assert_notnull(format); 48} 49 50 51static int open_restricted(const char *path, int flags, void *data) 52{ 53 int fd; 54 fd = open(path, flags); 55 return fd < 0 ? -errno : fd; 56} 57static void close_restricted(int fd, void *data) 58{ 59 close(fd); 60} 61 62static const struct libinput_interface simple_interface = { 63 .open_restricted = open_restricted, 64 .close_restricted = close_restricted, 65}; 66 67START_TEST(log_default_priority) 68{ 69 enum libinput_log_priority pri; 70 struct libinput *li; 71 72 li = libinput_path_create_context(&simple_interface, NULL); 73 pri = libinput_log_get_priority(li); 74 75 ck_assert_int_eq(pri, LIBINPUT_LOG_PRIORITY_ERROR); 76 77 libinput_unref(li); 78} 79END_TEST 80 81START_TEST(log_handler_invoked) 82{ 83 struct libinput *li; 84 85 log_handler_context = NULL; 86 log_handler_called = 0; 87 88 li = litest_create_context(); 89 90 libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG); 91 libinput_log_set_handler(li, simple_log_handler); 92 log_handler_context = li; 93 94 libinput_path_add_device(li, "/tmp"); 95 96 ck_assert_int_gt(log_handler_called, 0); 97 98 litest_destroy_context(li); 99 100 log_handler_context = NULL; 101 log_handler_called = 0; 102} 103END_TEST 104 105START_TEST(log_handler_NULL) 106{ 107 struct libinput *li; 108 109 log_handler_called = 0; 110 111 li = litest_create_context(); 112 libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_DEBUG); 113 libinput_log_set_handler(li, NULL); 114 115 libinput_path_add_device(li, "/tmp"); 116 117 ck_assert_int_eq(log_handler_called, 0); 118 119 litest_destroy_context(li); 120 121 log_handler_called = 0; 122} 123END_TEST 124 125START_TEST(log_priority) 126{ 127 struct libinput *li; 128 129 log_handler_context = NULL; 130 log_handler_called = 0; 131 132 li = litest_create_context(); 133 libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_ERROR); 134 libinput_log_set_handler(li, simple_log_handler); 135 log_handler_context = li; 136 137 libinput_path_add_device(li, "/tmp"); 138 139 ck_assert_int_eq(log_handler_called, 1); 140 141 libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_INFO); 142 /* event0 exists on any box we care to run the test suite on and we 143 * currently prints *something* for each device */ 144 libinput_path_add_device(li, "/dev/input/event0"); 145 ck_assert_int_gt(log_handler_called, 1); 146 147 litest_destroy_context(li); 148 149 log_handler_context = NULL; 150 log_handler_called = 0; 151} 152END_TEST 153 154static int axisrange_log_handler_called = 0; 155 156static void 157axisrange_warning_log_handler(struct libinput *libinput, 158 enum libinput_log_priority priority, 159 const char *format, 160 va_list args) 161{ 162 const char *substr; 163 164 axisrange_log_handler_called++; 165 litest_assert_notnull(format); 166 167 substr = strstr(format, "is outside expected range"); 168 litest_assert_notnull(substr); 169} 170 171START_TEST(log_axisrange_warning) 172{ 173 struct litest_device *dev = litest_current_device(); 174 struct libinput *li = dev->libinput; 175 const struct input_absinfo *abs; 176 int axis = _i; /* looped test */ 177 178 litest_touch_down(dev, 0, 90, 100); 179 litest_drain_events(li); 180 181 libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_INFO); 182 libinput_log_set_handler(li, axisrange_warning_log_handler); 183 184 abs = libevdev_get_abs_info(dev->evdev, axis); 185 186 for (int i = 0; i < 100; i++) { 187 litest_event(dev, EV_ABS, 188 ABS_MT_POSITION_X + axis, 189 abs->maximum * 2 + i); 190 litest_event(dev, EV_ABS, axis, abs->maximum * 2); 191 litest_event(dev, EV_SYN, SYN_REPORT, 0); 192 libinput_dispatch(li); 193 } 194 195 /* Expect only one message per 5 min */ 196 ck_assert_int_eq(axisrange_log_handler_called, 1); 197 198 libinput_log_set_priority(li, LIBINPUT_LOG_PRIORITY_ERROR); 199 litest_restore_log_handler(li); 200 axisrange_log_handler_called = 0; 201} 202END_TEST 203 204TEST_COLLECTION(log) 205{ 206 struct range axes = { ABS_X, ABS_Y + 1}; 207 208 litest_add_deviceless(log_default_priority); 209 litest_add_deviceless(log_handler_invoked); 210 litest_add_deviceless(log_handler_NULL); 211 litest_add_no_device(log_priority); 212 213 /* mtdev clips to axis ranges */ 214 litest_add_ranged(log_axisrange_warning, LITEST_TOUCH, LITEST_PROTOCOL_A, &axes); 215 litest_add_ranged(log_axisrange_warning, LITEST_TOUCHPAD, LITEST_ANY, &axes); 216} 217