5f067e2473e9772a04759c2cba051cf3add70090
[multipath-tools/.git] / tests / directio.c
1 /*
2  * Copyright (c) 2018 Benjamin Marzinski, Redhat
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
16  *
17  */
18
19 #define _GNU_SOURCE
20 #include <stdint.h>
21 #include <stdbool.h>
22 #include <stdarg.h>
23 #include <stddef.h>
24 #include <setjmp.h>
25 #include <stdlib.h>
26 #define UNIT_TESTING /* enable memory testing in directio.c */
27 #include <cmocka.h>
28 #include "globals.c"
29 #include "../libmultipath/checkers/directio.c"
30
31 int test_fd = 111;
32 int ioctx_count = 0;
33 struct io_event mock_events[AIO_GROUP_SIZE]; /* same as the checker max */
34 int ev_off = 0;
35 struct timespec zero_timeout = {0};
36 struct timespec full_timeout = { .tv_sec = -1 };
37
38 int __wrap_ioctl(int fd, unsigned long request, void *argp)
39 {
40         int *blocksize = (int *)argp;
41
42         assert_int_equal(fd, test_fd);
43         assert_int_equal(request, BLKBSZGET);
44         assert_non_null(blocksize);
45         *blocksize = mock_type(int);
46         return 0;
47 }
48
49 int __wrap_fcntl(int fd, int cmd, long arg)
50 {
51         assert_int_equal(fd, test_fd);
52         assert_int_equal(cmd, F_GETFL);
53         return O_DIRECT;
54 }
55
56 int __wrap___fxstat(int ver, int fd, struct stat *statbuf)
57 {
58         assert_int_equal(fd, test_fd);
59         assert_non_null(statbuf);
60         memset(statbuf, 0, sizeof(struct stat));
61         return 0;
62 }
63
64 int __wrap_io_setup(int maxevents, io_context_t *ctxp)
65 {
66         ioctx_count++;
67         return mock_type(int);
68 }
69
70 int __wrap_io_destroy(io_context_t ctx)
71 {
72         ioctx_count--;
73         return mock_type(int);
74 }
75
76 int __wrap_io_submit(io_context_t ctx, long nr, struct iocb *ios[])
77 {
78         return mock_type(int);
79 }
80
81 int __wrap_io_cancel(io_context_t ctx, struct iocb *iocb, struct io_event *evt)
82 {
83         return mock_type(int);
84 }
85
86 int __wrap_io_getevents(io_context_t ctx, long min_nr, long nr,
87                         struct io_event *events, struct timespec *timeout)
88 {
89         int i, nr_evs;
90         struct timespec *sleep_tmo;
91         struct io_event *evs;
92
93         assert_non_null(timeout);
94         nr_evs = mock_type(int);
95         assert_true(nr_evs <= nr);
96         if (!nr_evs)
97                 return 0;
98         sleep_tmo = mock_ptr_type(struct timespec *);
99         if (sleep_tmo) {
100                 if (sleep_tmo->tv_sec < 0)
101                         nanosleep(timeout, NULL);
102                 else
103                         nanosleep(sleep_tmo, NULL);
104         }
105         if (nr_evs < 0) {
106                 errno = -nr_evs;
107                 return -1;
108         }
109         evs = mock_ptr_type(struct io_event *);
110         for (i = 0; i < nr_evs; i++)
111                 events[i] = evs[i];
112         ev_off -= nr_evs;
113         return nr_evs;
114 }
115
116 static void return_io_getevents_none(void)
117 {
118         will_return(__wrap_io_getevents, 0);
119 }
120
121 static void return_io_getevents_nr(struct timespec *ts, int nr,
122                                    struct async_req **reqs, int *res)
123 {
124         int i, off = 0;
125
126         for(i = 0; i < nr; i++) {
127                 mock_events[i + ev_off].obj = &reqs[i]->io;
128                 if (res[i] == 0)
129                         mock_events[i + ev_off].res = reqs[i]->blksize;
130         }
131         while (nr > 0) {
132                 will_return(__wrap_io_getevents, (nr > 128)? 128 : nr);
133                 will_return(__wrap_io_getevents, ts);
134                 will_return(__wrap_io_getevents, &mock_events[off + ev_off]);
135                 ts = NULL;
136                 off += 128;
137                 nr -= 128;
138         }
139         if (nr == 0)
140                 will_return(__wrap_io_getevents, 0);
141         ev_off += i;
142 }
143
144 void do_check_state(struct checker *c, int sync, int timeout, int chk_state)
145 {
146         struct directio_context * ct = (struct directio_context *)c->context;
147
148         if (!ct->running)
149                 will_return(__wrap_io_submit, 1);
150         assert_int_equal(check_state(test_fd, ct, sync, timeout), chk_state);
151         assert_int_equal(ev_off, 0);
152         memset(mock_events, 0, sizeof(mock_events));
153 }
154
155 void do_libcheck_unload(int nr_aio_grps)
156 {
157         int count = 0;
158         struct aio_group *aio_grp;
159
160         list_for_each_entry(aio_grp, &aio_grp_list, node)
161                 count++;
162         assert_int_equal(count, nr_aio_grps);
163         for (count = 0; count < nr_aio_grps; count++)
164                 will_return(__wrap_io_destroy, 0);
165         libcheck_unload();
166         assert_true(list_empty(&aio_grp_list));
167         assert_int_equal(ioctx_count, 0);
168 }
169
170 static void do_libcheck_init(struct checker *c, int blocksize,
171                              struct async_req **req)
172 {
173         struct directio_context * ct;
174
175         c->fd = test_fd;
176         will_return(__wrap_ioctl, blocksize);
177         assert_int_equal(libcheck_init(c), 0);
178         ct = (struct directio_context *)c->context;
179         assert_non_null(ct);
180         assert_non_null(ct->aio_grp);
181         assert_non_null(ct->req);
182         if (req)
183                 *req = ct->req;
184         assert_int_equal(ct->req->blksize, blocksize);
185 }
186
187 static int is_checker_running(struct checker *c)
188 {
189         struct directio_context * ct = (struct directio_context *)c->context;
190         return ct->running;
191 }
192
193 static struct aio_group *get_aio_grp(struct checker *c)
194 {
195         struct directio_context * ct = (struct directio_context *)c->context;
196
197         assert_non_null(ct);
198         return ct->aio_grp;
199 }
200
201 static void check_aio_grp(struct aio_group *aio_grp, int holders,
202                           int orphans)
203 {
204         int count = 0;
205         struct list_head *item;
206
207         list_for_each(item, &aio_grp->orphans)
208                 count++;
209         assert_int_equal(holders, aio_grp->holders);
210         assert_int_equal(orphans, count);
211 }
212
213 static void do_libcheck_load(void)
214 {
215         int count = 0;
216         struct aio_group *aio_grp;
217
218         assert_true(list_empty(&aio_grp_list));
219         will_return(__wrap_io_setup, 0);
220         assert_int_equal(libcheck_load(), 0);
221         list_for_each_entry(aio_grp, &aio_grp_list, node) {
222                 assert_int_equal(aio_grp->holders, 0);
223                 count++;
224         }
225         assert_int_equal(count, 1);
226 }
227
228 /* simple loading resetting and unloading test */
229 static void test_load_reset_unload(void **state)
230 {
231         struct list_head *item;
232         do_libcheck_load();
233         item = aio_grp_list.next;
234         assert_int_equal(libcheck_reset(), 0);
235         assert_false(list_empty(&aio_grp_list));
236         assert_true(item == aio_grp_list.next);
237         do_libcheck_unload(1);
238 }
239
240 /* test initializing and then freeing 4096 checkers */
241 static void test_init_free(void **state)
242 {
243         int i, count = 0;
244         struct checker c[4096] = {0};
245         struct aio_group *aio_grp;
246
247         do_libcheck_load();
248         aio_grp = list_entry(aio_grp_list.next, typeof(*aio_grp), node);
249         will_return(__wrap_io_setup, 0);
250         will_return(__wrap_io_setup, 0);
251         will_return(__wrap_io_setup, 0);
252         for (i = 0; i < 4096; i++) {
253                 struct directio_context * ct;
254
255                 if (i % 3 == 0)
256                         do_libcheck_init(&c[i], 512, NULL);
257                 else if (i % 3 == 1)
258                         do_libcheck_init(&c[i], 1024, NULL);
259                 else
260                         do_libcheck_init(&c[i], 4096, NULL);
261                 ct = (struct directio_context *)c[i].context;
262                 assert_non_null(ct->aio_grp);
263                 if (i && (i & 1023) == 0)
264                         aio_grp = ct->aio_grp;
265                 else {
266                         assert_ptr_equal(ct->aio_grp, aio_grp);
267                         assert_int_equal(aio_grp->holders, (i & 1023) + 1);
268                 }
269         }
270         count = 0;
271         list_for_each_entry(aio_grp, &aio_grp_list, node)
272                 count++;
273         assert_int_equal(count, 4);
274         for (i = 0; i < 4096; i++) {
275                 struct directio_context * ct = (struct directio_context *)c[i].context;
276
277                 aio_grp = ct->aio_grp;
278                 libcheck_free(&c[i]);
279                 assert_int_equal(aio_grp->holders, 1023 - (i & 1023));
280         }
281         count = 0;
282         list_for_each_entry(aio_grp, &aio_grp_list, node) {
283                 assert_int_equal(aio_grp->holders, 0);
284                 count++;
285         }
286         assert_int_equal(count, 4);
287         will_return(__wrap_io_destroy, 0);
288         will_return(__wrap_io_destroy, 0);
289         will_return(__wrap_io_destroy, 0);
290         assert_int_equal(libcheck_reset(), 0);
291         do_libcheck_unload(1);
292 }
293
294 /* check mixed initializing and freeing 4096 checkers */
295 static void test_multi_init_free(void **state)
296 {
297         int i, count;
298         struct checker c[4096] = {0};
299         struct aio_group *aio_grp;
300
301         do_libcheck_load();
302         will_return(__wrap_io_setup, 0);
303         will_return(__wrap_io_setup, 0);
304         will_return(__wrap_io_setup, 0);
305         for (count = 0, i = 0; i < 4096; count++) {
306                 /* usually init, but occasionally free checkers */
307                 if (count == 0 || (count % 5 != 0 && count % 7 != 0)) {
308                         do_libcheck_init(&c[i], 4096, NULL);
309                         i++;
310                 } else {
311                         i--;
312                         libcheck_free(&c[i]);
313                 }
314         }
315         count = 0;
316         list_for_each_entry(aio_grp, &aio_grp_list, node) {
317                 assert_int_equal(aio_grp->holders, 1024);
318                 count++;
319         }
320         assert_int_equal(count, 4);
321         for (count = 0, i = 4096; i > 0; count++) {
322                 /* usually free, but occasionally init checkers */
323                 if (count == 0 || (count % 5 != 0 && count % 7 != 0)) {
324                         i--;
325                         libcheck_free(&c[i]);
326                 } else {
327                         do_libcheck_init(&c[i], 4096, NULL);
328                         i++;
329                 }
330         }
331         do_libcheck_unload(4);
332 }
333
334 /* simple single checker sync test */
335 static void test_check_state_simple(void **state)
336 {
337         struct checker c = {0};
338         struct async_req *req;
339         int res = 0;
340
341         do_libcheck_load();
342         do_libcheck_init(&c, 4096, &req);
343         return_io_getevents_nr(NULL, 1, &req, &res);
344         do_check_state(&c, 1, 30, PATH_UP);
345         libcheck_free(&c);
346         do_libcheck_unload(1);
347 }
348
349 /* test sync timeout */
350 static void test_check_state_timeout(void **state)
351 {
352         struct checker c = {0};
353         struct aio_group *aio_grp;
354
355         do_libcheck_load();
356         do_libcheck_init(&c, 4096, NULL);
357         aio_grp = get_aio_grp(&c);
358         return_io_getevents_none();
359         will_return(__wrap_io_cancel, 0);
360         do_check_state(&c, 1, 30, PATH_DOWN);
361         check_aio_grp(aio_grp, 1, 0);
362         libcheck_free(&c);
363         do_libcheck_unload(1);
364 }
365
366 /* test async timeout */
367 static void test_check_state_async_timeout(void **state)
368 {
369         struct checker c = {0};
370         struct aio_group *aio_grp;
371
372         do_libcheck_load();
373         do_libcheck_init(&c, 4096, NULL);
374         aio_grp = get_aio_grp(&c);
375         return_io_getevents_none();
376         do_check_state(&c, 0, 3, PATH_PENDING);
377         return_io_getevents_none();
378         do_check_state(&c, 0, 3, PATH_PENDING);
379         return_io_getevents_none();
380         do_check_state(&c, 0, 3, PATH_PENDING);
381         return_io_getevents_none();
382         will_return(__wrap_io_cancel, 0);
383         do_check_state(&c, 0, 3, PATH_DOWN);
384         check_aio_grp(aio_grp, 1, 0);
385         libcheck_free(&c);
386         do_libcheck_unload(1);
387 }
388
389 /* test freeing checkers with outstanding requests */
390 static void test_free_with_pending(void **state)
391 {
392         struct checker c[2] = {0};
393         struct aio_group *aio_grp;
394         struct async_req *req;
395         int res = 0;
396
397         do_libcheck_load();
398         do_libcheck_init(&c[0], 4096, &req);
399         do_libcheck_init(&c[1], 4096, NULL);
400         aio_grp = get_aio_grp(c);
401         return_io_getevents_none();
402         do_check_state(&c[0], 0, 30, PATH_PENDING);
403         return_io_getevents_nr(NULL, 1, &req, &res);
404         return_io_getevents_none();
405         do_check_state(&c[1], 0, 30, PATH_PENDING);
406         assert_true(is_checker_running(&c[0]));
407         assert_true(is_checker_running(&c[1]));
408         check_aio_grp(aio_grp, 2, 0);
409         libcheck_free(&c[0]);
410         check_aio_grp(aio_grp, 1, 0);
411         will_return(__wrap_io_cancel, 0);
412         libcheck_free(&c[1]);
413         check_aio_grp(aio_grp, 0, 0);
414         do_libcheck_unload(1);
415 }
416
417 /* test removing orpahed aio_group on free */
418 static void test_orphaned_aio_group(void **state)
419 {
420         struct checker c[AIO_GROUP_SIZE] = {0};
421         struct aio_group *aio_grp, *tmp_grp;
422         int i;
423
424         do_libcheck_load();
425         for (i = 0; i < AIO_GROUP_SIZE; i++) {
426                 do_libcheck_init(&c[i], 4096, NULL);
427                 return_io_getevents_none();
428                 do_check_state(&c[i], 0, 30, PATH_PENDING);
429         }
430         aio_grp = get_aio_grp(c);
431         check_aio_grp(aio_grp, AIO_GROUP_SIZE, 0);
432         i = 0;
433         list_for_each_entry(tmp_grp, &aio_grp_list, node)
434                 i++;
435         assert_int_equal(i, 1);
436         for (i = 0; i < AIO_GROUP_SIZE; i++) {
437                 assert_true(is_checker_running(&c[i]));
438                 will_return(__wrap_io_cancel, -1);
439                 if (i == AIO_GROUP_SIZE - 1) {
440                         /* remove the orphaned group and create a new one */
441                         will_return(__wrap_io_destroy, 0);
442                         will_return(__wrap_io_setup, 0);
443                 }
444                 libcheck_free(&c[i]);
445         }
446         i = 0;
447         list_for_each_entry(tmp_grp, &aio_grp_list, node) {
448                 i++;
449                 check_aio_grp(aio_grp, 0, 0);
450         }
451         assert_int_equal(i, 1);
452         do_libcheck_unload(1);
453 }
454
455 /* test sync timeout with failed cancel and cleanup by another
456  * checker */
457 static void test_timeout_cancel_failed(void **state)
458 {
459         struct checker c[2] = {0};
460         struct aio_group *aio_grp;
461         struct async_req *reqs[2];
462         int res[] = {0,0};
463         int i;
464
465         do_libcheck_load();
466         for (i = 0; i < 2; i++)
467                 do_libcheck_init(&c[i], 4096, &reqs[i]);
468         aio_grp = get_aio_grp(c);
469         return_io_getevents_none();
470         will_return(__wrap_io_cancel, -1);
471         do_check_state(&c[0], 1, 30, PATH_DOWN);
472         assert_true(is_checker_running(&c[0]));
473         check_aio_grp(aio_grp, 2, 0);
474         return_io_getevents_none();
475         will_return(__wrap_io_cancel, -1);
476         do_check_state(&c[0], 1, 30, PATH_DOWN);
477         assert_true(is_checker_running(&c[0]));
478         return_io_getevents_nr(NULL, 2, reqs, res);
479         do_check_state(&c[1], 1, 30, PATH_UP);
480         do_check_state(&c[0], 1, 30, PATH_UP);
481         for (i = 0; i < 2; i++) {
482                 assert_false(is_checker_running(&c[i]));
483                 libcheck_free(&c[i]);
484         }
485         do_libcheck_unload(1);
486 }
487
488 /* test async timeout with failed cancel and cleanup by another
489  * checker */
490 static void test_async_timeout_cancel_failed(void **state)
491 {
492         struct checker c[2] = {0};
493         struct async_req *reqs[2];
494         int res[] = {0,0};
495         int i;
496
497         do_libcheck_load();
498         for (i = 0; i < 2; i++)
499                 do_libcheck_init(&c[i], 4096, &reqs[i]);
500         return_io_getevents_none();
501         do_check_state(&c[0], 0, 2, PATH_PENDING);
502         return_io_getevents_none();
503         do_check_state(&c[1], 0, 2, PATH_PENDING);
504         return_io_getevents_none();
505         do_check_state(&c[0], 0, 2, PATH_PENDING);
506         return_io_getevents_none();
507         do_check_state(&c[1], 0, 2, PATH_PENDING);
508         return_io_getevents_none();
509         will_return(__wrap_io_cancel, -1);
510         do_check_state(&c[0], 0, 2, PATH_DOWN);
511         return_io_getevents_nr(NULL, 1, &reqs[1], &res[1]);
512         do_check_state(&c[1], 0, 2, PATH_UP);
513         return_io_getevents_none();
514         will_return(__wrap_io_cancel, -1);
515         do_check_state(&c[0], 0, 2, PATH_DOWN);
516         assert_true(is_checker_running(&c[0]));
517         return_io_getevents_nr(NULL, 2, reqs, res);
518         do_check_state(&c[1], 0, 2, PATH_UP);
519         do_check_state(&c[0], 0, 2, PATH_UP);
520         for (i = 0; i < 2; i++) {
521                 assert_false(is_checker_running(&c[i]));
522                 libcheck_free(&c[i]);
523         }
524         do_libcheck_unload(1);
525 }
526
527 /* test orphaning a request, and having another checker clean it up */
528 static void test_orphan_checker_cleanup(void **state)
529 {
530         struct checker c[2] = {0};
531         struct async_req *reqs[2];
532         int res[] = {0,0};
533         struct aio_group *aio_grp;
534         int i;
535
536         do_libcheck_load();
537         for (i = 0; i < 2; i++)
538                 do_libcheck_init(&c[i], 4096, &reqs[i]);
539         aio_grp = get_aio_grp(c);
540         return_io_getevents_none();
541         do_check_state(&c[0], 0, 30, PATH_PENDING);
542         will_return(__wrap_io_cancel, -1);
543         check_aio_grp(aio_grp, 2, 0);
544         libcheck_free(&c[0]);
545         check_aio_grp(aio_grp, 2, 1);
546         return_io_getevents_nr(NULL, 2, reqs, res);
547         do_check_state(&c[1], 0, 2, PATH_UP);
548         check_aio_grp(aio_grp, 1, 0);
549         libcheck_free(&c[1]);
550         check_aio_grp(aio_grp, 0, 0);
551         do_libcheck_unload(1);
552 }
553
554 /* test orphaning a request, and having reset clean it up */
555 static void test_orphan_reset_cleanup(void **state)
556 {
557         struct checker c;
558         struct aio_group *orphan_aio_grp, *tmp_aio_grp;
559         int found, count;
560
561         do_libcheck_load();
562         do_libcheck_init(&c, 4096, NULL);
563         orphan_aio_grp = get_aio_grp(&c);
564         return_io_getevents_none();
565         do_check_state(&c, 0, 30, PATH_PENDING);
566         will_return(__wrap_io_cancel, -1);
567         check_aio_grp(orphan_aio_grp, 1, 0);
568         libcheck_free(&c);
569         check_aio_grp(orphan_aio_grp, 1, 1);
570         found = count = 0;
571         list_for_each_entry(tmp_aio_grp, &aio_grp_list, node) {
572                 count++;
573                 if (tmp_aio_grp == orphan_aio_grp)
574                         found = 1;
575         }
576         assert_int_equal(count, 1);
577         assert_int_equal(found, 1);
578         will_return(__wrap_io_setup, 0);
579         will_return(__wrap_io_destroy, 0);
580         assert_int_equal(libcheck_reset(), 0);
581         found = count = 0;
582         list_for_each_entry(tmp_aio_grp, &aio_grp_list, node) {
583                 count++;
584                 check_aio_grp(tmp_aio_grp, 0, 0);
585                 if (tmp_aio_grp == orphan_aio_grp)
586                         found = 1;
587         }
588         assert_int_equal(count, 1);
589         assert_int_equal(found, 0);
590         do_libcheck_unload(1);
591 }
592
593 /* test orphaning a request, and having unload clean it up */
594 static void test_orphan_unload_cleanup(void **state)
595 {
596         struct checker c;
597         struct aio_group *orphan_aio_grp, *tmp_aio_grp;
598         int found, count;
599
600         do_libcheck_load();
601         do_libcheck_init(&c, 4096, NULL);
602         orphan_aio_grp = get_aio_grp(&c);
603         return_io_getevents_none();
604         do_check_state(&c, 0, 30, PATH_PENDING);
605         will_return(__wrap_io_cancel, -1);
606         check_aio_grp(orphan_aio_grp, 1, 0);
607         libcheck_free(&c);
608         check_aio_grp(orphan_aio_grp, 1, 1);
609         found = count = 0;
610         list_for_each_entry(tmp_aio_grp, &aio_grp_list, node) {
611                 count++;
612                 if (tmp_aio_grp == orphan_aio_grp)
613                         found = 1;
614         }
615         assert_int_equal(count, 1);
616         assert_int_equal(found, 1);
617         do_libcheck_unload(1);
618 }
619
620 /* test checkers with different blocksizes */
621 static void test_check_state_blksize(void **state)
622 {
623         int i;
624         struct checker c[3] = {0};
625         int blksize[] = {4096, 1024, 512};
626         struct async_req *reqs[3];
627         int res[] = {0,1,0};
628         int chk_state[] = {PATH_UP, PATH_DOWN, PATH_UP};
629
630         do_libcheck_load();
631         for (i = 0; i < 3; i++)
632                 do_libcheck_init(&c[i], blksize[i], &reqs[i]);
633         for (i = 0; i < 3; i++) {
634                 return_io_getevents_nr(NULL, 1, &reqs[i], &res[i]);
635                 do_check_state(&c[i], 1, 30, chk_state[i]);
636         }
637         for (i = 0; i < 3; i++) {
638                 assert_false(is_checker_running(&c[i]));
639                 libcheck_free(&c[i]);
640         }
641         do_libcheck_unload(1);
642 }
643
644 /* test async checkers pending and getting resovled by another checker
645  * as well as the loops for getting multiple events */
646 static void test_check_state_async(void **state)
647 {
648         int i;
649         struct checker c[257] = {0};
650         struct async_req *reqs[257];
651         int res[257] = {0};
652
653         do_libcheck_load();
654         for (i = 0; i < 257; i++)
655                 do_libcheck_init(&c[i], 4096, &reqs[i]);
656         for (i = 0; i < 256; i++) {
657                 return_io_getevents_none();
658                 do_check_state(&c[i], 0, 30, PATH_PENDING);
659                 assert_true(is_checker_running(&c[i]));
660         }
661         return_io_getevents_nr(&full_timeout, 256, reqs, res);
662         return_io_getevents_nr(NULL, 1, &reqs[256], &res[256]);
663         do_check_state(&c[256], 0, 30, PATH_UP);
664         assert_false(is_checker_running(&c[256]));
665         libcheck_free(&c[256]);
666         for (i = 0; i < 256; i++) {
667                 do_check_state(&c[i], 0, 30, PATH_UP);
668                 assert_false(is_checker_running(&c[i]));
669                 libcheck_free(&c[i]);
670         }
671         do_libcheck_unload(1);
672 }
673
674 int test_directio(void)
675 {
676         const struct CMUnitTest tests[] = {
677                 cmocka_unit_test(test_load_reset_unload),
678                 cmocka_unit_test(test_init_free),
679                 cmocka_unit_test(test_multi_init_free),
680                 cmocka_unit_test(test_check_state_simple),
681                 cmocka_unit_test(test_check_state_timeout),
682                 cmocka_unit_test(test_check_state_async_timeout),
683                 cmocka_unit_test(test_free_with_pending),
684                 cmocka_unit_test(test_timeout_cancel_failed),
685                 cmocka_unit_test(test_async_timeout_cancel_failed),
686                 cmocka_unit_test(test_orphan_checker_cleanup),
687                 cmocka_unit_test(test_orphan_reset_cleanup),
688                 cmocka_unit_test(test_orphan_unload_cleanup),
689                 cmocka_unit_test(test_check_state_blksize),
690                 cmocka_unit_test(test_check_state_async),
691                 cmocka_unit_test(test_orphaned_aio_group),
692         };
693
694         return cmocka_run_group_tests(tests, NULL, NULL);
695 }
696
697 int main(void)
698 {
699         int ret = 0;
700
701         conf.verbosity = 2;
702         ret += test_directio();
703         return ret;
704 }