1// SPDX-License-Identifier: MIT
2/*
3 * Copyright © 2013 Red Hat, Inc.
4 */
5
6#include "config.h"
7#include <limits.h>
8#include <libevdev/libevdev-int.h>
9#include "test-common.h"
10
11START_TEST(test_queue_alloc)
12{
13	struct libevdev dev;
14	int rc;
15
16	rc = queue_alloc(&dev, 0);
17	ck_assert_int_eq(rc, -ENOMEM);
18
19	rc = queue_alloc(&dev, 100);
20	ck_assert_int_eq(rc, 0);
21
22	ck_assert_int_eq(dev.queue_size, 100);
23	ck_assert_int_eq(dev.queue_next, 0);
24
25	queue_free(&dev);
26	ck_assert_int_eq(dev.queue_size, 0);
27	ck_assert_int_eq(dev.queue_next, 0);
28
29}
30END_TEST
31
32START_TEST(test_queue_sizes)
33{
34	struct libevdev dev = {0};
35
36	queue_alloc(&dev, 0);
37	ck_assert_int_eq(queue_num_elements(&dev), 0);
38	ck_assert_int_eq(queue_num_free_elements(&dev), 0);
39	ck_assert_int_eq(queue_size(&dev), 0);
40
41	queue_alloc(&dev, 100);
42	ck_assert_int_eq(queue_num_elements(&dev), 0);
43	ck_assert_int_eq(queue_num_free_elements(&dev), 100);
44	ck_assert_int_eq(queue_size(&dev), 100);
45
46	queue_free(&dev);
47
48	ck_assert_int_eq(queue_num_elements(&dev), 0);
49	ck_assert_int_eq(queue_num_free_elements(&dev), 0);
50	ck_assert_int_eq(queue_size(&dev), 0);
51}
52END_TEST
53
54START_TEST(test_queue_push)
55{
56	struct libevdev dev = {0};
57	struct input_event *ev;
58
59	queue_alloc(&dev, 0);
60	ev = queue_push(&dev);
61	ck_assert(ev == NULL);
62
63	queue_alloc(&dev, 2);
64	ev = queue_push(&dev);
65	ck_assert(ev == dev.queue);
66	ck_assert_int_eq(queue_num_elements(&dev), 1);
67	ck_assert_int_eq(queue_num_free_elements(&dev), 1);
68
69	ev = queue_push(&dev);
70	ck_assert(ev == dev.queue + 1);
71
72	ev = queue_push(&dev);
73	ck_assert(ev == NULL);
74
75	queue_free(&dev);
76	ev = queue_push(&dev);
77	ck_assert(ev == NULL);
78
79}
80END_TEST
81
82START_TEST(test_queue_pop)
83{
84	struct libevdev dev = {0};
85	struct input_event ev, *e, tmp;
86	int rc;
87
88	queue_alloc(&dev, 0);
89	rc = queue_pop(&dev, &ev);
90	ck_assert_int_eq(rc, 1);
91
92	queue_alloc(&dev, 2);
93	e = queue_push(&dev);
94	memset(e, 0xab, sizeof(*e));
95	ck_assert_int_eq(queue_num_elements(&dev), 1);
96	ck_assert_int_eq(queue_num_free_elements(&dev), 1);
97
98	rc = queue_pop(&dev, &ev);
99	ck_assert_int_eq(rc, 0);
100	memset(&tmp, 0xab, sizeof(tmp));
101	rc = memcmp(&tmp, &ev, sizeof(tmp));
102	ck_assert_int_eq(rc, 0);
103
104	ck_assert_int_eq(queue_num_elements(&dev), 0);
105	ck_assert_int_eq(queue_num_free_elements(&dev), 2);
106
107	rc = queue_pop(&dev, &ev);
108	ck_assert_int_eq(rc, 1);
109
110	queue_free(&dev);
111}
112END_TEST
113
114START_TEST(test_queue_peek)
115{
116	struct libevdev dev = {0};
117	struct input_event ev, *e, tmp;
118	int rc;
119
120	queue_alloc(&dev, 0);
121	rc = queue_peek(&dev, 0, &ev);
122	ck_assert_int_eq(rc, 1);
123
124	queue_alloc(&dev, 2);
125	e = queue_push(&dev);
126	memset(e, 0xab, sizeof(*e));
127
128	rc = queue_peek(&dev, 0, &ev);
129	ck_assert_int_eq(rc, 0);
130	memset(&tmp, 0xab, sizeof(tmp));
131	rc = memcmp(&tmp, &ev, sizeof(tmp));
132	ck_assert_int_eq(rc, 0);
133
134	ck_assert_int_eq(queue_num_elements(&dev), 1);
135	e = queue_push(&dev);
136	memset(e, 0xbc, sizeof(*e));
137
138	rc = queue_peek(&dev, 1, &ev);
139	ck_assert_int_eq(rc, 0);
140	memset(&tmp, 0xbc, sizeof(tmp));
141	rc = memcmp(&tmp, &ev, sizeof(tmp));
142	ck_assert_int_eq(rc, 0);
143
144	rc = queue_peek(&dev, 0, &ev);
145	ck_assert_int_eq(rc, 0);
146	memset(&tmp, 0xab, sizeof(tmp));
147	rc = memcmp(&tmp, &ev, sizeof(tmp));
148	ck_assert_int_eq(rc, 0);
149
150	ck_assert_int_eq(queue_num_elements(&dev), 2);
151
152	queue_free(&dev);
153}
154END_TEST
155
156START_TEST(test_queue_shift)
157{
158	struct libevdev dev = {0};
159	struct input_event ev, *first, *second, e1, e2;
160	int rc;
161
162	ck_assert_int_eq(queue_shift(&dev, &ev), 1);
163
164	queue_alloc(&dev, 10);
165	ck_assert_int_eq(queue_shift(&dev, &ev), 1);
166
167	first = queue_push(&dev);
168	ck_assert(first != NULL);
169	memset(first, 0xab, sizeof(*first));
170
171	e1 = *first;
172
173	second = queue_push(&dev);
174	ck_assert(second != NULL);
175	memset(second, 0x12, sizeof(*second));
176
177	e2 = *second;
178
179	rc = queue_shift(&dev, &ev);
180	ck_assert_int_eq(rc, 0);
181	rc = memcmp(&ev, &e1, sizeof(ev));
182	ck_assert_int_eq(rc, 0);
183
184	rc = queue_shift(&dev, &ev);
185	ck_assert_int_eq(rc, 0);
186	rc = memcmp(&ev, &e2, sizeof(ev));
187	ck_assert_int_eq(rc, 0);
188
189	ck_assert_int_eq(queue_shift(&dev, &ev), 1);
190
191	queue_free(&dev);
192}
193END_TEST
194
195START_TEST(test_queue_shift_multiple)
196{
197	struct libevdev dev = {0};
198	struct input_event ev, *first, *second, e1, e2;
199	struct input_event events[5];
200	int rc;
201
202	ck_assert_int_eq(queue_shift_multiple(&dev, 1, &ev), 0);
203	ck_assert_int_eq(queue_shift_multiple(&dev, 0, &ev), 0);
204
205	queue_alloc(&dev, 10);
206	ck_assert_int_eq(queue_shift_multiple(&dev, 1, &ev), 0);
207	ck_assert_int_eq(queue_shift_multiple(&dev, 0, &ev), 0);
208
209	first = queue_push(&dev);
210	ck_assert(first != NULL);
211	memset(first, 0xab, sizeof(*first));
212	e1 = *first;
213
214	second = queue_push(&dev);
215	ck_assert(second != NULL);
216	memset(second, 0x12, sizeof(*second));
217	e2 = *second;
218
219	rc = queue_shift_multiple(&dev, 5, events);
220	ck_assert_int_eq(rc, 2);
221	rc = memcmp(&events[0], &e1, sizeof(ev));
222	ck_assert_int_eq(rc, 0);
223	rc = memcmp(&events[1], &e2, sizeof(ev));
224	ck_assert_int_eq(rc, 0);
225
226	first = queue_push(&dev);
227	ck_assert(first != NULL);
228	memset(first, 0xab, sizeof(*first));
229	e1 = *first;
230
231	second = queue_push(&dev);
232	ck_assert(second != NULL);
233	memset(second, 0x12, sizeof(*second));
234	e2 = *second;
235
236	rc = queue_shift_multiple(&dev, 1, events);
237	ck_assert_int_eq(rc, 1);
238	rc = memcmp(&events[0], &e1, sizeof(ev));
239	ck_assert_int_eq(rc, 0);
240
241	rc = queue_shift_multiple(&dev, 1, events);
242	ck_assert_int_eq(rc, 1);
243	rc = memcmp(&events[0], &e2, sizeof(ev));
244	ck_assert_int_eq(rc, 0);
245
246	ck_assert_int_eq(queue_shift_multiple(&dev, 1, events), 0);
247
248	queue_free(&dev);
249}
250END_TEST
251
252START_TEST(test_queue_next_element)
253{
254	struct libevdev dev = {0};
255	struct input_event ev, *first, *second;
256	int rc;
257
258	queue_alloc(&dev, 0);
259	first = queue_next_element(&dev);
260	ck_assert(first == NULL);
261
262	queue_alloc(&dev, 2);
263	first = queue_next_element(&dev);
264	ck_assert(first != NULL);
265	memset(first, 0xab, sizeof(*first));
266
267	second = queue_next_element(&dev);
268	ck_assert(second != NULL);
269	memset(second, 0xbc, sizeof(*second));
270
271	/* queue_next_element does not advance, so we overwrite */
272	memset(&ev, 0xbc, sizeof(ev));
273	rc = memcmp(&ev, first, sizeof(ev));
274	ck_assert_int_eq(rc, 0);
275
276	ck_assert_int_eq(queue_num_elements(&dev), 0);
277
278	first = queue_next_element(&dev);
279	ck_assert(first != NULL);
280	memset(first, 0xab, sizeof(*first));
281
282	queue_set_num_elements(&dev, 1);
283	ck_assert_int_eq(queue_num_elements(&dev), 1);
284
285	second = queue_next_element(&dev);
286	ck_assert(second != NULL);
287	memset(second, 0xbc, sizeof(*second));
288
289	memset(&ev, 0xab, sizeof(ev));
290	rc = memcmp(&ev, first, sizeof(ev));
291	ck_assert_int_eq(rc, 0);
292
293	queue_free(&dev);
294}
295END_TEST
296
297START_TEST(test_queue_set_num_elements)
298{
299	struct libevdev dev = {0};
300
301	queue_alloc(&dev, 0);
302	ck_assert_int_eq(queue_set_num_elements(&dev, 1), 1);
303
304	queue_alloc(&dev, 2);
305	ck_assert_int_eq(queue_set_num_elements(&dev, 3), 1);
306	ck_assert_int_eq(queue_set_num_elements(&dev, 2), 0);
307
308	queue_free(&dev);
309}
310END_TEST
311
312TEST_SUITE(queue_suite)
313{
314	Suite *s = suite_create("Event queue");
315
316	TCase *tc = tcase_create("Queue allocation");
317	tcase_add_test(tc, test_queue_alloc);
318	tcase_add_test(tc, test_queue_sizes);
319	suite_add_tcase(s, tc);
320
321	tc = tcase_create("Queue push/pop/peek");
322	tcase_add_test(tc, test_queue_push);
323	tcase_add_test(tc, test_queue_pop);
324	tcase_add_test(tc, test_queue_peek);
325	suite_add_tcase(s, tc);
326
327	tc = tcase_create("Queue shift");
328	tcase_add_test(tc, test_queue_shift);
329	tcase_add_test(tc, test_queue_shift_multiple);
330	suite_add_tcase(s, tc);
331
332	tc = tcase_create("Queue next elem");
333	tcase_add_test(tc, test_queue_next_element);
334	tcase_add_test(tc, test_queue_set_num_elements);
335	suite_add_tcase(s, tc);
336
337	return s;
338}
339