multipath: add unit tests for dmevents code
[multipath-tools/.git] / tests / dmevents.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, write to the Free Software
16  *
17  */
18
19 #include <stdint.h>
20 #include <stdbool.h>
21 #include <stdarg.h>
22 #include <stddef.h>
23 #include <setjmp.h>
24 #include <stdlib.h>
25 #include <cmocka.h>
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include "structs.h"
30 #include "structs_vec.h"
31
32 #include "globals.c"
33 /* I have to do this to get at the static variables */
34 #include "../multipathd/dmevents.c"
35
36 struct dm_device {
37         char name[WWID_SIZE];
38         int is_mpath;
39         uint32_t evt_nr;
40         uint32_t update_nr;
41 };
42
43 struct test_data {
44         struct vectors vecs;
45         vector dm_devices;
46         struct dm_names *names;
47 };
48
49 struct test_data data;
50
51 int add_dm_device_event(char *name, int is_mpath, uint32_t evt_nr)
52 {
53         struct dm_device *dev;
54         int i;
55
56         vector_foreach_slot(data.dm_devices, dev, i) {
57                 if (strcmp(name, dev->name) == 0) {
58                         dev->evt_nr = evt_nr;
59                         return 0;
60                 }
61         }
62         dev = (struct dm_device *)malloc(sizeof(struct dm_device));
63         if (!dev){
64                 condlog(0, "Testing error mallocing dm_device");
65                 return -1;
66         }
67         strncpy(dev->name, name, WWID_SIZE);
68         dev->name[WWID_SIZE - 1] = 0;
69         dev->is_mpath = is_mpath;
70         dev->evt_nr = evt_nr;
71         if (!vector_alloc_slot(data.dm_devices)) {
72                 condlog(0, "Testing error setting dm_devices slot");
73                 free(dev);
74                 return -1;
75         }
76         vector_set_slot(data.dm_devices, dev);
77         return 0;
78 }
79
80 struct dm_device *find_dm_device(const char *name)
81 {
82         struct dm_device *dev;
83         int i;
84
85         vector_foreach_slot(data.dm_devices, dev, i)
86                 if (strcmp(name, dev->name) == 0)
87                         return dev;
88         return NULL;
89 }
90
91 int remove_dm_device_event(const char *name)
92 {
93         struct dm_device *dev;
94         int i;
95
96         vector_foreach_slot(data.dm_devices, dev, i) {
97                 if (strcmp(name, dev->name) == 0) {
98                         vector_del_slot(data.dm_devices, i);
99                                 free(dev);
100                         return 0;
101                 }
102         }
103         return -1;
104 }
105
106 void remove_all_dm_device_events(void)
107 {
108         struct dm_device *dev;
109         int i;
110
111         vector_foreach_slot(data.dm_devices, dev, i)
112                 free(dev);
113         vector_reset(data.dm_devices);
114 }
115
116 static inline size_t align_val(size_t val)
117 {
118         return (val + 7) & ~7;
119 }
120 static inline void *align_ptr(void *ptr)
121 {
122         return (void *)align_val((size_t)ptr);
123 }
124
125 /* copied off of list_devices in dm-ioctl.c */
126 struct dm_names *build_dm_names(void)
127 {
128         struct dm_names *names, *np, *old_np = NULL;
129         uint32_t *event_nr;
130         struct dm_device *dev;
131         int i, size = 0;
132
133         if (VECTOR_SIZE(data.dm_devices) == 0) {
134                 names = (struct dm_names *)malloc(sizeof(struct dm_names));
135                 if (!names) {
136                         condlog(0, "Testing error allocating empty dm_names");
137                         return NULL;
138                 }
139                 names->dev = 0;
140                 names->next = 0;
141                 return names;
142         }
143         vector_foreach_slot(data.dm_devices, dev, i) {
144                 size += align_val(offsetof(struct dm_names, name) +
145                                   strlen(dev->name) + 1);
146                 size += align_val(sizeof(uint32_t));
147         }
148         names = (struct dm_names *)malloc(size);
149         if (!names) {
150                 condlog(0, "Testing error allocating dm_names");
151                 return NULL;
152         }
153         np = names;
154         vector_foreach_slot(data.dm_devices, dev, i) {
155                 if (old_np)
156                         old_np->next = (uint32_t) ((uintptr_t) np -
157                                                    (uintptr_t) old_np);
158                 np->dev = 1;
159                 np->next = 0;
160                 strcpy(np->name, dev->name);
161
162                 old_np = np;
163                 event_nr = align_ptr(np->name + strlen(dev->name) + 1);
164                 *event_nr = dev->evt_nr;
165                 np = align_ptr(event_nr + 1);
166         }
167         assert_int_equal((char *)np - (char *)names, size);
168         return names;
169 }
170
171 static int setup(void **state)
172 {
173         if (dmevent_poll_supported()) {
174                 data.dm_devices = vector_alloc();
175                 *state = &data;
176         } else
177                 *state = NULL;
178         return 0;
179 }
180
181 static int teardown(void **state)
182 {
183         struct dm_device *dev;
184         int i;
185         struct test_data *datap = (struct test_data *)(*state);
186         if (datap == NULL)
187                 return 0;
188         vector_foreach_slot(datap->dm_devices, dev, i)
189                 free(dev);
190         vector_free(datap->dm_devices);
191         datap = NULL;
192         return 0;
193 }
194
195 int __wrap_open(const char *pathname, int flags)
196 {
197         assert_ptr_equal(pathname, "/dev/mapper/control");
198         assert_int_equal(flags, O_RDWR);
199         return mock_type(int);
200 }
201
202 int __wrap_close(int fd)
203 {
204         assert_int_equal(fd, waiter->fd);
205         return 0;
206 }
207
208 int __wrap_dm_is_mpath(const char *name)
209 {
210         struct dm_device *dev;
211         int i;
212
213         vector_foreach_slot(data.dm_devices, dev, i)
214                 if (strcmp(name, dev->name) == 0)
215                         return dev->is_mpath;
216         return 0;
217 }
218
219 int __wrap_dm_geteventnr(const char *name)
220 {
221         struct dm_device *dev;
222         int fail = mock_type(int);
223
224         if (fail)
225                 return -1;
226         dev = find_dm_device(name);
227         if (dev) {
228                 /* simulate updating device state after adding it */
229                 dev->update_nr = dev->evt_nr;
230                 return dev->evt_nr;
231         }
232         return -1;
233 }
234
235 int __wrap_ioctl(int fd, unsigned long request, void *argp)
236 {
237         assert_int_equal(fd, waiter->fd);
238         assert_int_equal(request, DM_DEV_ARM_POLL);
239         return mock_type(int);
240 }
241
242 struct dm_task *__wrap_libmp_dm_task_create(int task)
243 {
244         assert_int_equal(task, DM_DEVICE_LIST);
245         return mock_type(struct dm_task *);
246 }
247
248 int __wrap_dm_task_no_open_count(struct dm_task *dmt)
249 {
250         assert_ptr_equal((struct test_data *)dmt, &data);
251         return mock_type(int);
252 }
253
254 int __wrap_dm_task_run(struct dm_task *dmt)
255 {
256         assert_ptr_equal((struct test_data *)dmt, &data);
257         return mock_type(int);
258 }
259
260 struct dm_names * __wrap_dm_task_get_names(struct dm_task *dmt)
261 {
262         int good = mock_type(int);
263         assert_ptr_equal((struct test_data *)dmt, &data);
264
265         if (data.names) {
266                 condlog(0, "Testing error. data.names already allocated");
267                 return NULL;
268         }
269         if (!good)
270                 return NULL;
271         data.names = build_dm_names();
272         return data.names;
273 }
274
275 void __wrap_dm_task_destroy(struct dm_task *dmt)
276 {
277         assert_ptr_equal((struct test_data *)dmt, &data);
278
279         if (data.names) {
280                 free(data.names);
281                 data.names = NULL;
282         }
283 }
284
285 int __wrap_poll(struct pollfd *fds, nfds_t nfds, int timeout)
286 {
287         assert_int_equal(nfds, 1);
288         assert_int_equal(timeout, -1);
289         assert_int_equal(fds->fd, waiter->fd);
290         assert_int_equal(fds->events, POLLIN);
291         return mock_type(int);
292 }
293
294 void __wrap_remove_map_by_alias(const char *alias, struct vectors * vecs,
295                                 int purge_vec)
296 {
297         check_expected(alias);
298         assert_ptr_equal(vecs, waiter->vecs);
299         assert_int_equal(purge_vec, 1);
300 }
301
302 int __wrap_update_multipath(struct vectors *vecs, char *mapname, int reset)
303 {
304         int fail;
305
306         check_expected(mapname);
307         assert_ptr_equal(vecs, waiter->vecs);
308         assert_int_equal(reset, 1);
309         fail = mock_type(int);
310         if (fail) {
311                 assert_int_equal(remove_dm_device_event(mapname), 0);
312                 return fail;
313         } else {
314                 struct dm_device *dev;
315                 int i;
316
317                 vector_foreach_slot(data.dm_devices, dev, i) {
318                         if (strcmp(mapname, dev->name) == 0) {
319                                 dev->update_nr = dev->evt_nr;
320                                 return 0;
321                         }
322                 }
323                 fail();
324         }
325         return fail;
326 }
327
328 struct dev_event *find_dmevents(const char *name)
329 {
330         struct dev_event *dev_evt;
331         int i;
332
333         vector_foreach_slot(waiter->events, dev_evt, i)
334                 if (!strcmp(dev_evt->name, name))
335                         return dev_evt;
336         return NULL;
337 }
338
339 static void test_init_waiter_bad0(void **state)
340 {
341         struct test_data *datap = (struct test_data *)(*state);
342         if (datap == NULL)
343                 skip();
344         assert_int_equal(init_dmevent_waiter(NULL), -1);
345 }
346
347 static void test_init_waiter_bad1(void **state)
348 {
349         struct test_data *datap = (struct test_data *)(*state);
350         if (datap == NULL)
351                 skip();
352         will_return(__wrap_open, -1);
353         assert_int_equal(init_dmevent_waiter(&datap->vecs), -1);
354         assert_ptr_equal(waiter, NULL);
355 }
356
357 static void test_init_waiter_good0(void **state)
358 {
359         struct test_data *datap = (struct test_data *)(*state);
360         if (datap == NULL)
361                 skip();
362         will_return(__wrap_open, 2);
363         assert_int_equal(init_dmevent_waiter(&datap->vecs), 0);
364         assert_ptr_not_equal(waiter, NULL);
365 }
366
367 static void test_watch_dmevents_bad0(void **state)
368 {
369         struct test_data *datap = (struct test_data *)(*state);
370         if (datap == NULL)
371                 skip();
372         assert_int_equal(watch_dmevents("foo"), -1);
373         assert_ptr_equal(find_dmevents("foo"), NULL);
374 }
375
376 static void test_watch_dmevents_bad1(void **state)
377 {
378         struct test_data *datap = (struct test_data *)(*state);
379         if (datap == NULL)
380                 skip();
381
382         assert_int_equal(add_dm_device_event("foo", 0, 5), 0);
383         assert_int_equal(watch_dmevents("foo"), -1);
384         assert_ptr_equal(find_dmevents("foo"), NULL);
385 }
386
387 static void test_watch_dmevents_bad2(void **state)
388 {
389         struct test_data *datap = (struct test_data *)(*state);
390         if (datap == NULL)
391                 skip();
392
393         remove_all_dm_device_events();
394         assert_int_equal(add_dm_device_event("foo", 1, 5), 0);
395         will_return(__wrap_dm_geteventnr, -1);
396         assert_int_equal(watch_dmevents("foo"), -1);
397         assert_ptr_equal(find_dmevents("foo"), NULL);
398 }
399 static void test_watch_dmevents_good0(void **state)
400 {
401         struct dev_event *dev_evt;
402         struct test_data *datap = (struct test_data *)(*state);
403         if (datap == NULL)
404                 skip();
405
406         remove_all_dm_device_events();
407         assert_int_equal(add_dm_device_event("foo", 1, 5), 0);
408         will_return(__wrap_dm_geteventnr, 0);
409         assert_int_equal(watch_dmevents("foo"), 0);
410         dev_evt = find_dmevents("foo");
411         assert_ptr_not_equal(dev_evt, NULL);
412         assert_int_equal(dev_evt->evt_nr, 5);
413         assert_int_equal(dev_evt->action, EVENT_NOTHING);
414         assert_int_equal(VECTOR_SIZE(waiter->events), 1);
415         unwatch_dmevents("foo");
416         assert_int_equal(VECTOR_SIZE(waiter->events), 0);
417         assert_ptr_equal(find_dmevents("foo"), NULL);
418 }
419
420 static void test_watch_dmevents_good1(void **state)
421 {
422         struct dev_event *dev_evt;
423         struct test_data *datap = (struct test_data *)(*state);
424         if (datap == NULL)
425                 skip();
426
427         remove_all_dm_device_events();
428         assert_int_equal(add_dm_device_event("foo", 1, 5), 0);  
429         will_return(__wrap_dm_geteventnr, 0);
430         assert_int_equal(watch_dmevents("foo"), 0);
431         dev_evt = find_dmevents("foo");
432         assert_ptr_not_equal(dev_evt, NULL);
433         assert_int_equal(dev_evt->evt_nr, 5);
434         assert_int_equal(dev_evt->action, EVENT_NOTHING);
435         assert_int_equal(add_dm_device_event("foo", 1, 6), 0);
436         will_return(__wrap_dm_geteventnr, 0);
437         assert_int_equal(watch_dmevents("foo"), 0);
438         dev_evt = find_dmevents("foo");
439         assert_ptr_not_equal(dev_evt, NULL);
440         assert_int_equal(dev_evt->evt_nr, 6);
441         assert_int_equal(dev_evt->action, EVENT_NOTHING);
442         assert_int_equal(VECTOR_SIZE(waiter->events), 1);
443         unwatch_dmevents("foo");
444         assert_int_equal(VECTOR_SIZE(waiter->events), 0);
445         assert_ptr_equal(find_dmevents("foo"), NULL);
446 }
447
448 static void test_watch_dmevents_good2(void **state)
449 {
450         struct dev_event *dev_evt;
451         struct test_data *datap = (struct test_data *)(*state);
452         if (datap == NULL)
453                 skip();
454
455         unwatch_all_dmevents();
456         remove_all_dm_device_events();
457         assert_int_equal(add_dm_device_event("foo", 1, 5), 0);
458         assert_int_equal(add_dm_device_event("bar", 1, 7), 0);
459         will_return(__wrap_dm_geteventnr, 0);
460         assert_int_equal(watch_dmevents("foo"), 0);
461         dev_evt = find_dmevents("foo");
462         assert_ptr_not_equal(dev_evt, NULL);
463         assert_int_equal(dev_evt->evt_nr, 5);
464         assert_int_equal(dev_evt->action, EVENT_NOTHING);
465         assert_ptr_equal(find_dmevents("bar"), NULL);
466         will_return(__wrap_dm_geteventnr, 0);
467         assert_int_equal(watch_dmevents("bar"), 0);
468         dev_evt = find_dmevents("foo");
469         assert_ptr_not_equal(dev_evt, NULL);
470         assert_int_equal(dev_evt->evt_nr, 5);
471         assert_int_equal(dev_evt->action, EVENT_NOTHING);
472         dev_evt = find_dmevents("bar");
473         assert_ptr_not_equal(dev_evt, NULL);
474         assert_int_equal(dev_evt->evt_nr, 7);
475         assert_int_equal(dev_evt->action, EVENT_NOTHING);
476         assert_int_equal(VECTOR_SIZE(waiter->events), 2);
477         unwatch_all_dmevents();
478         assert_int_equal(VECTOR_SIZE(waiter->events), 0);
479         assert_ptr_equal(find_dmevents("foo"), NULL);
480         assert_ptr_equal(find_dmevents("bar"), NULL);
481 }
482
483 static void test_get_events_bad0(void **state)
484 {
485         struct test_data *datap = (struct test_data *)(*state);
486         if (datap == NULL)
487                 skip();
488
489         unwatch_all_dmevents();
490         remove_all_dm_device_events();
491
492         will_return(__wrap_libmp_dm_task_create, NULL);
493         assert_int_equal(dm_get_events(), -1);
494 }
495
496 static void test_get_events_bad1(void **state)
497 {
498         struct test_data *datap = (struct test_data *)(*state);
499         if (datap == NULL)
500                 skip();
501
502         will_return(__wrap_libmp_dm_task_create, &data);
503         will_return(__wrap_dm_task_no_open_count, 1);
504         will_return(__wrap_dm_task_run, 0);
505         assert_int_equal(dm_get_events(), -1);
506 }
507
508 static void test_get_events_bad2(void **state)
509 {
510         struct test_data *datap = (struct test_data *)(*state);
511         if (datap == NULL)
512                 skip();
513
514         will_return(__wrap_libmp_dm_task_create, &data);
515         will_return(__wrap_dm_task_no_open_count, 1);
516         will_return(__wrap_dm_task_run, 1);
517         will_return(__wrap_dm_task_get_names, 0);
518         assert_int_equal(dm_get_events(), -1);
519 }
520
521 static void test_get_events_good0(void **state)
522 {
523         struct test_data *datap = (struct test_data *)(*state);
524         if (datap == NULL)
525                 skip();
526
527         assert_int_equal(add_dm_device_event("foo", 1, 5), 0);
528         will_return(__wrap_libmp_dm_task_create, &data);
529         will_return(__wrap_dm_task_no_open_count, 1);
530         will_return(__wrap_dm_task_run, 1);
531         will_return(__wrap_dm_task_get_names, 1);
532         assert_int_equal(dm_get_events(), 0);
533         assert_ptr_equal(find_dmevents("foo"), NULL);
534         assert_int_equal(VECTOR_SIZE(waiter->events), 0);
535 }
536
537 static void test_get_events_good1(void **state)
538 {
539         struct dev_event *dev_evt;
540         struct test_data *datap = (struct test_data *)(*state);
541         if (datap == NULL)
542                 skip();
543
544         remove_all_dm_device_events();
545         assert_int_equal(add_dm_device_event("foo", 1, 5), 0);
546         assert_int_equal(add_dm_device_event("bar", 1, 7), 0);
547         assert_int_equal(add_dm_device_event("baz", 1, 12), 0);
548         assert_int_equal(add_dm_device_event("qux", 0, 4), 0);
549         assert_int_equal(add_dm_device_event("xyzzy", 1, 8), 0);
550         will_return(__wrap_dm_geteventnr, 0);
551         assert_int_equal(watch_dmevents("foo"), 0);
552         will_return(__wrap_dm_geteventnr, 0);
553         assert_int_equal(watch_dmevents("bar"), 0);
554         will_return(__wrap_dm_geteventnr, 0);
555         assert_int_equal(watch_dmevents("xyzzy"), 0);
556         assert_int_equal(add_dm_device_event("foo", 1, 6), 0);
557         assert_int_equal(remove_dm_device_event("xyzzy"), 0);
558         will_return(__wrap_libmp_dm_task_create, &data);
559         will_return(__wrap_dm_task_no_open_count, 1);
560         will_return(__wrap_dm_task_run, 1);
561         will_return(__wrap_dm_task_get_names, 1);
562         assert_int_equal(dm_get_events(), 0);
563         dev_evt = find_dmevents("foo");
564         assert_ptr_not_equal(dev_evt, NULL);
565         assert_int_equal(dev_evt->evt_nr, 6);
566         assert_int_equal(dev_evt->action, EVENT_UPDATE);
567         dev_evt = find_dmevents("bar");
568         assert_ptr_not_equal(dev_evt, NULL);
569         assert_int_equal(dev_evt->evt_nr, 7);
570         assert_int_equal(dev_evt->action, EVENT_NOTHING);
571         dev_evt = find_dmevents("xyzzy");
572         assert_ptr_not_equal(dev_evt, NULL);
573         assert_int_equal(dev_evt->evt_nr, 8);
574         assert_int_equal(dev_evt->action, EVENT_REMOVE);
575         assert_ptr_equal(find_dmevents("baz"), NULL);
576         assert_ptr_equal(find_dmevents("qux"), NULL);
577         assert_int_equal(VECTOR_SIZE(waiter->events), 3);
578 }
579
580 static void test_dmevent_loop_bad0(void **state)
581 {
582         struct dm_device *dev;
583         struct dev_event *dev_evt;
584         struct test_data *datap = (struct test_data *)(*state);
585         if (datap == NULL)
586                 skip();
587
588         remove_all_dm_device_events();
589         unwatch_all_dmevents();
590         assert_int_equal(add_dm_device_event("foo", 1, 5), 0);
591         will_return(__wrap_dm_geteventnr, 0);
592         assert_int_equal(watch_dmevents("foo"), 0);
593         assert_int_equal(add_dm_device_event("foo", 1, 6), 0);
594         will_return(__wrap_poll, 0);
595         assert_int_equal(dmevent_loop(), 1);
596         dev_evt = find_dmevents("foo");
597         assert_ptr_not_equal(dev_evt, NULL);
598         assert_int_equal(dev_evt->evt_nr, 5);
599         assert_int_equal(dev_evt->action, EVENT_NOTHING);
600         dev = find_dm_device("foo");
601         assert_ptr_not_equal(dev, NULL);
602         assert_int_equal(dev->evt_nr, 6);
603         assert_int_equal(dev->update_nr, 5);
604 }
605
606 static void test_dmevent_loop_bad1(void **state)
607 {
608         struct dm_device *dev;
609         struct dev_event *dev_evt;
610         struct test_data *datap = (struct test_data *)(*state);
611         if (datap == NULL)
612                 skip();
613
614         will_return(__wrap_poll, 1);
615         will_return(__wrap_ioctl, -1);
616         assert_int_equal(dmevent_loop(), 1);
617         dev_evt = find_dmevents("foo");
618         assert_ptr_not_equal(dev_evt, NULL);
619         assert_int_equal(dev_evt->evt_nr, 5);
620         assert_int_equal(dev_evt->action, EVENT_NOTHING);
621         dev = find_dm_device("foo");
622         assert_ptr_not_equal(dev, NULL);
623         assert_int_equal(dev->evt_nr, 6);
624         assert_int_equal(dev->update_nr, 5);
625 }
626
627 static void test_dmevent_loop_bad2(void **state)
628 {
629         struct dm_device *dev;
630         struct dev_event *dev_evt;
631         struct test_data *datap = (struct test_data *)(*state);
632         if (datap == NULL)
633                 skip();
634
635         will_return(__wrap_poll, 1);
636         will_return(__wrap_ioctl, 0);
637         will_return(__wrap_libmp_dm_task_create, NULL);
638         assert_int_equal(dmevent_loop(), 1);
639         dev_evt = find_dmevents("foo");
640         assert_ptr_not_equal(dev_evt, NULL);
641         assert_int_equal(dev_evt->evt_nr, 5);
642         assert_int_equal(dev_evt->action, EVENT_NOTHING);
643         dev = find_dm_device("foo");
644         assert_ptr_not_equal(dev, NULL);
645         assert_int_equal(dev->evt_nr, 6);
646         assert_int_equal(dev->update_nr, 5);
647 }
648
649 static void test_dmevent_loop_good0(void **state)
650 {
651         struct test_data *datap = (struct test_data *)(*state);
652         if (datap == NULL)
653                 skip();
654
655         remove_all_dm_device_events();
656         unwatch_all_dmevents();
657         will_return(__wrap_poll, 1);
658         will_return(__wrap_ioctl, 0);
659         will_return(__wrap_libmp_dm_task_create, &data);
660         will_return(__wrap_dm_task_no_open_count, 1);
661         will_return(__wrap_dm_task_run, 1);
662         will_return(__wrap_dm_task_get_names, 1);
663         assert_int_equal(dmevent_loop(), 1);
664 }
665
666 static void test_dmevent_loop_good1(void **state)
667 {
668         struct dm_device *dev;
669         struct dev_event *dev_evt;
670         struct test_data *datap = (struct test_data *)(*state);
671         if (datap == NULL)
672                 skip();
673
674         remove_all_dm_device_events();
675         unwatch_all_dmevents();
676         assert_int_equal(add_dm_device_event("foo", 1, 5), 0);
677         assert_int_equal(add_dm_device_event("bar", 1, 7), 0);
678         assert_int_equal(add_dm_device_event("baz", 1, 12), 0);
679         assert_int_equal(add_dm_device_event("xyzzy", 1, 8), 0);
680         will_return(__wrap_dm_geteventnr, 0);
681         assert_int_equal(watch_dmevents("foo"), 0);
682         will_return(__wrap_dm_geteventnr, 0);
683         assert_int_equal(watch_dmevents("bar"), 0);
684         will_return(__wrap_dm_geteventnr, 0);
685         assert_int_equal(watch_dmevents("xyzzy"), 0);
686         assert_int_equal(add_dm_device_event("foo", 1, 6), 0);
687         assert_int_equal(remove_dm_device_event("xyzzy"), 0);
688         will_return(__wrap_poll, 1);
689         will_return(__wrap_ioctl, 0);
690         will_return(__wrap_libmp_dm_task_create, &data);
691         will_return(__wrap_dm_task_no_open_count, 1);
692         will_return(__wrap_dm_task_run, 1);
693         will_return(__wrap_dm_task_get_names, 1);
694         expect_string(__wrap_update_multipath, mapname, "foo");
695         will_return(__wrap_update_multipath, 0);
696         expect_string(__wrap_remove_map_by_alias, alias, "xyzzy");
697         assert_int_equal(dmevent_loop(), 1);
698         assert_int_equal(VECTOR_SIZE(waiter->events), 2);
699         assert_int_equal(VECTOR_SIZE(data.dm_devices), 3);
700         dev_evt = find_dmevents("foo");
701         assert_ptr_not_equal(dev_evt, NULL);
702         assert_int_equal(dev_evt->evt_nr, 6);
703         assert_int_equal(dev_evt->action, EVENT_NOTHING);
704         dev = find_dm_device("foo");
705         assert_ptr_not_equal(dev, NULL);
706         assert_int_equal(dev->evt_nr, 6);
707         assert_int_equal(dev->update_nr, 6);
708         dev_evt = find_dmevents("bar");
709         assert_ptr_not_equal(dev_evt, NULL);
710         assert_int_equal(dev_evt->evt_nr, 7);
711         assert_int_equal(dev_evt->action, EVENT_NOTHING);
712         dev = find_dm_device("bar");
713         assert_ptr_not_equal(dev, NULL);
714         assert_int_equal(dev->evt_nr, 7);
715         assert_int_equal(dev->update_nr, 7);
716         assert_ptr_equal(find_dmevents("xyzzy"), NULL);
717         assert_ptr_equal(find_dm_device("xyzzy"), NULL);
718 }
719
720 static void test_dmevent_loop_good2(void **state)
721 {
722         struct dm_device *dev;
723         struct dev_event *dev_evt;
724         struct test_data *datap = (struct test_data *)(*state);
725         if (datap == NULL)
726                 skip();
727
728         assert_int_equal(add_dm_device_event("bar", 1, 9), 0);
729         will_return(__wrap_dm_geteventnr, 0);
730         assert_int_equal(watch_dmevents("baz"), 0);
731         assert_int_equal(add_dm_device_event("baz", 1, 14), 0);
732         will_return(__wrap_poll, 1);
733         will_return(__wrap_ioctl, 0);
734         will_return(__wrap_libmp_dm_task_create, &data);
735         will_return(__wrap_dm_task_no_open_count, 1);
736         will_return(__wrap_dm_task_run, 1);
737         will_return(__wrap_dm_task_get_names, 1);
738         expect_string(__wrap_update_multipath, mapname, "bar");
739         will_return(__wrap_update_multipath, 0);
740         expect_string(__wrap_update_multipath, mapname, "baz");
741         will_return(__wrap_update_multipath, 1);
742         assert_int_equal(dmevent_loop(), 1);
743         assert_int_equal(VECTOR_SIZE(waiter->events), 2);
744         assert_int_equal(VECTOR_SIZE(data.dm_devices), 2);
745         dev_evt = find_dmevents("foo");
746         assert_ptr_not_equal(dev_evt, NULL);
747         assert_int_equal(dev_evt->evt_nr, 6);
748         assert_int_equal(dev_evt->action, EVENT_NOTHING);
749         dev = find_dm_device("foo");
750         assert_ptr_not_equal(dev, NULL);
751         assert_int_equal(dev->evt_nr, 6);
752         assert_int_equal(dev->update_nr, 6);
753         dev_evt = find_dmevents("bar");
754         assert_ptr_not_equal(dev_evt, NULL);
755         assert_int_equal(dev_evt->evt_nr, 9);
756         assert_int_equal(dev_evt->action, EVENT_NOTHING);
757         dev = find_dm_device("bar");
758         assert_ptr_not_equal(dev, NULL);
759         assert_int_equal(dev->evt_nr, 9);
760         assert_int_equal(dev->update_nr, 9);
761         assert_ptr_equal(find_dmevents("baz"), NULL);
762         assert_ptr_equal(find_dm_device("baz"), NULL);
763 }
764
765 static void test_dmevent_loop_good3(void **state)
766 {
767         struct dm_device *dev;
768         struct test_data *datap = (struct test_data *)(*state);
769         if (datap == NULL)
770                 skip();
771
772         assert_int_equal(remove_dm_device_event("foo"), 0);
773         unwatch_dmevents("bar");
774         will_return(__wrap_poll, 1);
775         will_return(__wrap_ioctl, 0);
776         will_return(__wrap_libmp_dm_task_create, &data);
777         will_return(__wrap_dm_task_no_open_count, 1);
778         will_return(__wrap_dm_task_run, 1);
779         will_return(__wrap_dm_task_get_names, 1);
780         expect_string(__wrap_remove_map_by_alias, alias, "foo");
781         assert_int_equal(dmevent_loop(), 1);
782         assert_int_equal(VECTOR_SIZE(waiter->events), 0);
783         assert_int_equal(VECTOR_SIZE(data.dm_devices), 1);
784         dev = find_dm_device("bar");
785         assert_ptr_not_equal(dev, NULL);
786         assert_int_equal(dev->evt_nr, 9);
787         assert_int_equal(dev->update_nr, 9);
788         assert_ptr_equal(find_dmevents("foo"), NULL);
789         assert_ptr_equal(find_dmevents("bar"), NULL);
790         assert_ptr_equal(find_dm_device("foo"), NULL);
791 }
792
793 static void test_arm_poll(void **state)
794 {
795         struct test_data *datap = (struct test_data *)(*state);
796         if (datap == NULL)
797                 skip();
798         will_return(__wrap_ioctl, 0);
799         assert_int_equal(arm_dm_event_poll(waiter->fd), 0);
800 }
801
802 static void test_cleanup_waiter(void **state)
803 {
804         struct test_data *datap = (struct test_data *)(*state);
805         if (datap == NULL)
806                 skip();
807         cleanup_dmevent_waiter();
808         assert_ptr_equal(waiter, NULL);
809 }
810
811 int test_dmevents(void)
812 {
813         const struct CMUnitTest tests[] = {
814                 cmocka_unit_test(test_init_waiter_bad0),
815                 cmocka_unit_test(test_init_waiter_bad1),
816                 cmocka_unit_test(test_init_waiter_good0),
817                 cmocka_unit_test(test_watch_dmevents_bad0),
818                 cmocka_unit_test(test_watch_dmevents_bad1),
819                 cmocka_unit_test(test_watch_dmevents_bad2),
820                 cmocka_unit_test(test_watch_dmevents_good0),
821                 cmocka_unit_test(test_watch_dmevents_good1),
822                 cmocka_unit_test(test_watch_dmevents_good2),
823                 cmocka_unit_test(test_get_events_bad0),
824                 cmocka_unit_test(test_get_events_bad1),
825                 cmocka_unit_test(test_get_events_bad2),
826                 cmocka_unit_test(test_get_events_good0),
827                 cmocka_unit_test(test_get_events_good1),
828                 cmocka_unit_test(test_arm_poll),
829                 cmocka_unit_test(test_dmevent_loop_bad0),
830                 cmocka_unit_test(test_dmevent_loop_bad1),
831                 cmocka_unit_test(test_dmevent_loop_bad2),
832                 cmocka_unit_test(test_dmevent_loop_good0),
833                 cmocka_unit_test(test_dmevent_loop_good1),
834                 cmocka_unit_test(test_dmevent_loop_good2),
835                 cmocka_unit_test(test_dmevent_loop_good3),
836                 cmocka_unit_test(test_cleanup_waiter),
837         };
838         return cmocka_run_group_tests(tests, setup, teardown);
839 }
840
841 int main(void)
842 {
843         int ret = 0;
844
845         ret += test_dmevents();
846         return ret;
847 }