ad863b0899ed46065745b4124979df916a4cecda
[multipath-tools/.git] / tests / hwtable.c
1 /* Set BROKEN to 1 to treat broken behavior as success */
2 #define BROKEN 1
3 #define VERBOSITY 2
4
5 #include <stdbool.h>
6 #include <stdarg.h>
7 #include <stddef.h>
8 #include <setjmp.h>
9 #include <stdlib.h>
10 #include <cmocka.h>
11 #include <libudev.h>
12 #include <sys/stat.h>
13 #include <fcntl.h>
14 #include <unistd.h>
15 #include <stdio.h>
16 #include <errno.h>
17 #include <limits.h>
18 #include <sys/sysmacros.h>
19 #include "structs.h"
20 #include "structs_vec.h"
21 #include "config.h"
22 #include "debug.h"
23 #include "defaults.h"
24 #include "pgpolicies.h"
25 #include "test-lib.h"
26 #include "print.h"
27 #include "util.h"
28
29 #define N_CONF_FILES 2
30
31 static const char tmplate[] = "/tmp/hwtable-XXXXXX";
32 /* pretend new dm, use minio_rq */
33 static const unsigned int dm_tgt_version[3] = { 1, 1, 1 };
34
35 struct key_value {
36         const char *key;
37         const char *value;
38 };
39
40 struct hwt_state {
41         char *tmpname;
42         char *dirname;
43         FILE *config_file;
44         FILE *conf_dir_file[N_CONF_FILES];
45         struct vectors *vecs;
46         void (*test)(const struct hwt_state *);
47         const char *test_name;
48 };
49
50 #define SET_TEST_FUNC(hwt, func) do {           \
51                 hwt->test = func;               \
52                 hwt->test_name = #func;         \
53         } while (0)
54
55 static struct config *_conf;
56 struct udev *udev;
57 int logsink;
58
59 struct config *get_multipath_config(void)
60 {
61         return _conf;
62 }
63
64 void put_multipath_config(void *arg)
65 {}
66
67 void make_config_file_path(char *buf, int buflen,
68                           const struct hwt_state *hwt, int i)
69 {
70         static const char fn_template[] = "%s/test-%02d.conf";
71
72         if (i == -1)
73                 /* main config file */
74                 snprintf(buf, buflen, fn_template, hwt->tmpname, 0);
75         else
76                 snprintf(buf, buflen, fn_template, hwt->dirname, i);
77 }
78
79 static void reset_vecs(struct vectors *vecs)
80 {
81         remove_maps(vecs);
82         free_pathvec(vecs->pathvec, FREE_PATHS);
83
84         vecs->pathvec = vector_alloc();
85         assert_ptr_not_equal(vecs->pathvec, NULL);
86         vecs->mpvec = vector_alloc();
87         assert_ptr_not_equal(vecs->mpvec, NULL);
88 }
89
90 static void free_hwt(struct hwt_state *hwt)
91 {
92         char buf[PATH_MAX];
93         int i;
94
95         if (hwt->config_file != NULL)
96                 fclose(hwt->config_file);
97         for (i = 0; i < N_CONF_FILES; i++) {
98                 if (hwt->conf_dir_file[i] != NULL)
99                         fclose(hwt->conf_dir_file[i]);
100         }
101
102         if (hwt->tmpname != NULL) {
103                 make_config_file_path(buf, sizeof(buf), hwt, -1);
104                 unlink(buf);
105                 rmdir(hwt->tmpname);
106                 free(hwt->tmpname);
107         }
108
109         if (hwt->dirname != NULL) {
110                 for (i = 0; i < N_CONF_FILES; i++) {
111                         make_config_file_path(buf, sizeof(buf), hwt, i);
112                         unlink(buf);
113                 }
114                 rmdir(hwt->dirname);
115                 free(hwt->dirname);
116         }
117
118         if (hwt->vecs != NULL) {
119                 if (hwt->vecs->mpvec != NULL)
120                         remove_maps(hwt->vecs);
121                 if (hwt->vecs->pathvec != NULL)
122                         free_pathvec(hwt->vecs->pathvec, FREE_PATHS);
123                 pthread_mutex_destroy(&hwt->vecs->lock.mutex);
124                 free(hwt->vecs);
125         }
126         free(hwt);
127 }
128
129 static int setup(void **state)
130 {
131         struct hwt_state *hwt;
132         char buf[PATH_MAX];
133         int i;
134
135         *state = NULL;
136         hwt = calloc(1, sizeof(*hwt));
137         if (hwt == NULL)
138                 return -1;
139
140         snprintf(buf, sizeof(buf), "%s", tmplate);
141         if (mkdtemp(buf) == NULL) {
142                 condlog(0, "mkdtemp: %s", strerror(errno));
143                 goto err;
144         }
145         hwt->tmpname = strdup(buf);
146
147         snprintf(buf, sizeof(buf), "%s", tmplate);
148         if (mkdtemp(buf) == NULL) {
149                 condlog(0, "mkdtemp (2): %s", strerror(errno));
150                 goto err;
151         }
152         hwt->dirname = strdup(buf);
153
154         make_config_file_path(buf, sizeof(buf), hwt, -1);
155         hwt->config_file = fopen(buf, "w+");
156         if (hwt->config_file == NULL)
157                 goto err;
158
159         for (i = 0; i < N_CONF_FILES; i++) {
160                 make_config_file_path(buf, sizeof(buf), hwt, i);
161                 hwt->conf_dir_file[i] = fopen(buf, "w+");
162                 if (hwt->conf_dir_file[i] == NULL)
163                         goto err;
164         }
165
166         hwt->vecs = calloc(1, sizeof(*hwt->vecs));
167         if (hwt->vecs == NULL)
168                 goto err;
169         pthread_mutex_init(&hwt->vecs->lock.mutex, NULL);
170         hwt->vecs->pathvec = vector_alloc();
171         hwt->vecs->mpvec = vector_alloc();
172         if (hwt->vecs->pathvec == NULL || hwt->vecs->mpvec == NULL)
173                 goto err;
174
175         *state = hwt;
176         return 0;
177
178 err:
179         free_hwt(hwt);
180         return -1;
181 }
182
183 static int teardown(void **state)
184 {
185         if (state == NULL || *state == NULL)
186                 return -1;
187
188         free_hwt(*state);
189         *state = NULL;
190
191         return 0;
192 }
193
194 /*
195  * Helpers for creating the config file(s)
196  */
197
198 static void reset_config(FILE *ff)
199 {
200         if (ff == NULL)
201                 return;
202         rewind(ff);
203         if (ftruncate(fileno(ff), 0) == -1)
204                 condlog(1, "ftruncate: %s", strerror(errno));
205 }
206
207 static void reset_configs(const struct hwt_state *hwt)
208 {
209         int i;
210
211         reset_config(hwt->config_file);
212         for (i = 0; i < N_CONF_FILES; i++)
213                 reset_config(hwt->conf_dir_file[i]);
214 }
215
216 static void write_key_values(FILE *ff, int nkv, const struct key_value *kv)
217 {
218         int i;
219
220         for (i = 0; i < nkv; i++) {
221                 if (strchr(kv[i].value, ' ') == NULL &&
222                     strchr(kv[i].value, '\"') == NULL)
223                         fprintf(ff, "\t%s %s\n", kv[i].key, kv[i].value);
224                 else
225                         fprintf(ff, "\t%s \"%s\"\n", kv[i].key, kv[i].value);
226         }
227 }
228
229 static void begin_section(FILE *ff, const char *section)
230 {
231         fprintf(ff, "%s {\n", section);
232 }
233
234 static void end_section(FILE *ff)
235 {
236         fprintf(ff, "}\n");
237 }
238
239 static void write_section(FILE *ff, const char *section,
240                           int nkv, const struct key_value *kv)
241 {
242         begin_section(ff, section);
243         write_key_values(ff, nkv, kv);
244         end_section(ff);
245 }
246
247 static void write_defaults(const struct hwt_state *hwt)
248 {
249         static const char bindings_name[] = "bindings";
250         static struct key_value defaults[] = {
251                 { "config_dir", NULL },
252                 { "bindings_file", NULL },
253                 { "multipath_dir", NULL },
254                 { "detect_prio", "no" },
255                 { "detect_checker", "no" },
256         };
257         char buf[sizeof(tmplate) + sizeof(bindings_name)];
258         char dirbuf[PATH_MAX];
259
260         snprintf(buf, sizeof(buf), "%s/%s", hwt->tmpname, bindings_name);
261         defaults[0].value = hwt->dirname;
262         defaults[1].value = buf;
263         assert_ptr_not_equal(getcwd(dirbuf, sizeof(dirbuf)), NULL);
264         strncat(dirbuf, "/lib", sizeof(dirbuf));
265         defaults[2].value = dirbuf;
266         write_section(hwt->config_file, "defaults",
267                       ARRAY_SIZE(defaults), defaults);
268 }
269
270 static void begin_config(const struct hwt_state *hwt)
271 {
272         reset_configs(hwt);
273         write_defaults(hwt);
274 }
275
276 static void begin_section_all(const struct hwt_state *hwt, const char *section)
277 {
278         int i;
279
280         begin_section(hwt->config_file, section);
281         for (i = 0; i < N_CONF_FILES; i++)
282                 begin_section(hwt->conf_dir_file[i], section);
283 }
284
285 static void end_section_all(const struct hwt_state *hwt)
286 {
287         int i;
288
289         end_section(hwt->config_file);
290         for (i = 0; i < N_CONF_FILES; i++)
291                 end_section(hwt->conf_dir_file[i]);
292 }
293
294 static void finish_config(const struct hwt_state *hwt)
295 {
296         int i;
297
298         fflush(hwt->config_file);
299         for (i = 0; i < N_CONF_FILES; i++) {
300                 fflush(hwt->conf_dir_file[i]);
301         }
302 }
303
304 static void write_device(FILE *ff, int nkv, const struct key_value *kv)
305 {
306         write_section(ff, "device", nkv, kv);
307 }
308
309 /*
310  * Some macros to avoid boilerplace code
311  */
312
313 #define CHECK_STATE(state) ({ \
314         assert_ptr_not_equal(state, NULL); \
315         assert_ptr_not_equal(*(state), NULL);   \
316         *state; })
317
318 #define WRITE_EMPTY_CONF(hwt) do {                              \
319                 begin_config(hwt);                              \
320                 finish_config(hwt);                             \
321         } while (0)
322
323 #define WRITE_ONE_DEVICE(hwt, kv) do {                                  \
324                 begin_config(hwt);                                      \
325                 begin_section_all(hwt, "devices");                      \
326                 write_device(hwt->config_file, ARRAY_SIZE(kv), kv);     \
327                 end_section_all(hwt);                                   \
328                 finish_config(hwt);                                     \
329         } while (0)
330
331 #define WRITE_TWO_DEVICES(hwt, kv1, kv2) do {                           \
332                 begin_config(hwt);                                      \
333                 begin_section_all(hwt, "devices");                      \
334                 write_device(hwt->config_file, ARRAY_SIZE(kv1), kv1);   \
335                 write_device(hwt->config_file, ARRAY_SIZE(kv2), kv2);   \
336                 end_section_all(hwt);                                   \
337                 finish_config(hwt);                                     \
338         } while (0)
339
340 #define WRITE_TWO_DEVICES_W_DIR(hwt, kv1, kv2) do {                     \
341                 begin_config(hwt);                                      \
342                 begin_section_all(hwt, "devices");                      \
343                 write_device(hwt->config_file, ARRAY_SIZE(kv1), kv1);   \
344                 write_device(hwt->conf_dir_file[0],                     \
345                              ARRAY_SIZE(kv2), kv2);                     \
346                 end_section_all(hwt);                                   \
347                 finish_config(hwt);                                     \
348         } while (0)
349
350 #define LOAD_CONFIG(hwt) ({ \
351         char buf[PATH_MAX];        \
352         struct config *__cf;                                            \
353                                                                         \
354         make_config_file_path(buf, sizeof(buf), hwt, -1);               \
355         __cf = load_config(buf);                                        \
356         assert_ptr_not_equal(__cf, NULL);                               \
357         assert_ptr_not_equal(__cf->hwtable, NULL);                      \
358         __cf->verbosity = VERBOSITY;                                    \
359         memcpy(&__cf->version, dm_tgt_version, sizeof(__cf->version));  \
360         __cf; })
361
362 #define FREE_CONFIG(conf) do {                  \
363                 free_config(conf);              \
364                 conf = NULL;                    \
365         } while (0)
366
367 static void replace_config(const struct hwt_state *hwt,
368                            const char *conf_str)
369 {
370         FREE_CONFIG(_conf);
371         reset_configs(hwt);
372         fprintf(hwt->config_file, "%s", conf_str);
373         fflush(hwt->config_file);
374         _conf = LOAD_CONFIG(hwt);
375 }
376
377 #define TEST_PROP(prop, val) do {                               \
378                 if (val == NULL)                                \
379                         assert_ptr_equal(prop, NULL);           \
380                 else {                                          \
381                         assert_ptr_not_equal(prop, NULL);       \
382                         assert_string_equal(prop, val);         \
383                 }                                               \
384         } while (0)
385
386 #if BROKEN
387 #define TEST_PROP_BROKEN(name, prop, bad, good) do {                    \
388                 condlog(1, "%s: WARNING: Broken test for %s == \"%s\" on line %d, should be \"%s\"", \
389                         __func__, name, bad ? bad : "NULL",             \
390                         __LINE__, good ? good : "NULL");                        \
391                 TEST_PROP(prop, bad);                                   \
392         } while (0)
393 #else
394 #define TEST_PROP_BROKEN(name, prop, bad, good) TEST_PROP(prop, good)
395 #endif
396
397 /*
398  * Some predefined key/value pairs
399  */
400
401 static const char _wwid[] = "wwid";
402 static const char _vendor[] = "vendor";
403 static const char _product[] = "product";
404 static const char _prio[] = "prio";
405 static const char _checker[] = "path_checker";
406 static const char _getuid[] = "getuid_callout";
407 static const char _uid_attr[] = "uid_attribute";
408 static const char _bl_product[] = "product_blacklist";
409 static const char _minio[] = "rr_min_io_rq";
410 static const char _no_path_retry[] = "no_path_retry";
411
412 /* Device identifiers */
413 static const struct key_value vnd_foo = { _vendor, "foo" };
414 static const struct key_value prd_bar = { _product, "bar" };
415 static const struct key_value prd_bam = { _product, "bam" };
416 static const struct key_value prd_baq = { _product, "\"bar\"" };
417 static const struct key_value prd_baqq = { _product, "\"\"bar\"\"" };
418 static const struct key_value prd_barz = { _product, "barz" };
419 static const struct key_value vnd_boo = { _vendor, "boo" };
420 static const struct key_value prd_baz = { _product, "baz" };
421 static const struct key_value wwid_test = { _wwid, default_wwid };
422
423 /* Regular expresssions */
424 static const struct key_value vnd__oo = { _vendor, ".oo" };
425 static const struct key_value vnd_t_oo = { _vendor, "^.oo" };
426 static const struct key_value prd_ba_ = { _product, "ba." };
427 static const struct key_value prd_ba_s = { _product, "(bar|baz|ba\\.)$" };
428 /* Pathological cases, see below */
429 static const struct key_value prd_barx = { _product, "ba[[rxy]" };
430 static const struct key_value prd_bazy = { _product, "ba[zy]" };
431 static const struct key_value prd_bazy1 = { _product, "ba(z|y)" };
432
433 /* Properties */
434 static const struct key_value prio_emc = { _prio, "emc" };
435 static const struct key_value prio_hds = { _prio, "hds" };
436 static const struct key_value prio_rdac = { _prio, "rdac" };
437 static const struct key_value chk_hp = { _checker, "hp_sw" };
438 static const struct key_value gui_foo = { _getuid, "/tmp/foo" };
439 static const struct key_value uid_baz = { _uid_attr, "BAZ_ATTR" };
440 static const struct key_value bl_bar = { _bl_product, "bar" };
441 static const struct key_value bl_baz = { _bl_product, "baz" };
442 static const struct key_value bl_barx = { _bl_product, "ba[[rxy]" };
443 static const struct key_value bl_bazy = { _bl_product, "ba[zy]" };
444 static const struct key_value minio_99 = { _minio, "99" };
445 static const struct key_value npr_37 = { _no_path_retry, "37" };
446 static const struct key_value npr_queue = { _no_path_retry, "queue" };
447
448 /***** BEGIN TESTS SECTION *****/
449
450 /*
451  * Dump the configuration, subistitute the dumped configuration
452  * for the current one, and verify that the result is identical.
453  */
454 static void replicate_config(const struct hwt_state *hwt, bool local)
455 {
456         char *cfg1, *cfg2;
457         vector hwtable;
458         struct config *conf;
459
460         condlog(1, "--- %s: replicating %s configuration", __func__,
461                 local ? "local" : "full");
462
463         conf = get_multipath_config();
464         if (!local)
465                 /* "full" configuration */
466                 cfg1 = snprint_config(conf, NULL, NULL, NULL);
467         else {
468                 /* "local" configuration */
469                 hwtable = get_used_hwes(hwt->vecs->pathvec);
470                 cfg1 = snprint_config(conf, NULL, hwtable, hwt->vecs->mpvec);
471         }
472
473         assert_non_null(cfg1);
474         put_multipath_config(conf);
475
476         replace_config(hwt, cfg1);
477
478         /*
479          * The local configuration adds multipath entries, and may move device
480          * entries for local devices to the end of the list. Identical config
481          * strings therefore can't be expected in the "local" case.
482          * That doesn't matter. The important thing is that, with the reloaded
483          * configuration, the test case still passes.
484          */
485         if (local) {
486                 free(cfg1);
487                 return;
488         }
489
490         conf = get_multipath_config();
491         cfg2 = snprint_config(conf, NULL, NULL, NULL);
492         assert_non_null(cfg2);
493         put_multipath_config(conf);
494
495 // #define DBG_CONFIG 1
496 #ifdef DBG_CONFIG
497 #define DUMP_CFG_STR(x) do {                                            \
498                 FILE *tmp = fopen("/tmp/hwtable-" #x ".txt", "w");      \
499                 fprintf(tmp, "%s", x);                                  \
500                 fclose(tmp);                                            \
501         } while (0)
502
503         DUMP_CFG_STR(cfg1);
504         DUMP_CFG_STR(cfg2);
505 #endif
506
507         assert_int_equal(strlen(cfg2), strlen(cfg1));
508         assert_string_equal(cfg2, cfg1);
509         free(cfg1);
510         free(cfg2);
511 }
512
513 /*
514  * Run hwt->test three times; once with the constructed configuration,
515  * once after re-reading the full dumped configuration, and once with the
516  * dumped local configuration.
517  *
518  * Expected: test passes every time.
519  */
520 static void test_driver(void **state)
521 {
522         const struct hwt_state *hwt;
523
524         hwt = CHECK_STATE(state);
525         _conf = LOAD_CONFIG(hwt);
526         hwt->test(hwt);
527
528         replicate_config(hwt, false);
529         reset_vecs(hwt->vecs);
530         hwt->test(hwt);
531
532         replicate_config(hwt, true);
533         reset_vecs(hwt->vecs);
534         hwt->test(hwt);
535
536         reset_vecs(hwt->vecs);
537         FREE_CONFIG(_conf);
538 }
539
540 /*
541  * Sanity check for the test itself, because defaults may be changed
542  * in libmultipath.
543  *
544  * Our checking for match or non-match relies on the defaults being
545  * different from what our device sections contain.
546  */
547 static void test_sanity_globals(void **state)
548 {
549         assert_string_not_equal(prio_emc.value, DEFAULT_PRIO);
550         assert_string_not_equal(prio_hds.value, DEFAULT_PRIO);
551         assert_string_not_equal(chk_hp.value, DEFAULT_CHECKER);
552         assert_int_not_equal(MULTIBUS, DEFAULT_PGPOLICY);
553         assert_int_not_equal(NO_PATH_RETRY_QUEUE, DEFAULT_NO_PATH_RETRY);
554         assert_int_not_equal(atoi(minio_99.value), DEFAULT_MINIO_RQ);
555         assert_int_not_equal(atoi(npr_37.value), DEFAULT_NO_PATH_RETRY);
556 }
557
558 /*
559  * Regression test for internal hwtable. NVME is an example of two entries
560  * in the built-in hwtable, one if which matches a subset of the other.
561  */
562 static void test_internal_nvme(const struct hwt_state *hwt)
563 {
564         struct path *pp;
565         struct multipath *mp;
566
567         /*
568          * Generic NVMe: expect defaults for pgpolicy and no_path_retry
569          */
570         pp = mock_path("NVME", "NoName");
571         mp = mock_multipath(pp);
572         assert_ptr_not_equal(mp, NULL);
573         TEST_PROP(checker_name(&pp->checker), NONE);
574         TEST_PROP(pp->uid_attribute, "ID_WWN");
575         assert_int_equal(mp->pgpolicy, DEFAULT_PGPOLICY);
576         assert_int_equal(mp->no_path_retry, DEFAULT_NO_PATH_RETRY);
577         assert_int_equal(mp->retain_hwhandler, RETAIN_HWHANDLER_OFF);
578
579         /*
580          * NetApp NVMe: expect special values for pgpolicy and no_path_retry
581          */
582         pp = mock_path_wwid("NVME", "NetApp ONTAP Controller",
583                             default_wwid_1);
584         mp = mock_multipath(pp);
585         assert_ptr_not_equal(mp, NULL);
586         TEST_PROP(checker_name(&pp->checker), NONE);
587         TEST_PROP(pp->uid_attribute, "ID_WWN");
588         assert_int_equal(mp->pgpolicy, MULTIBUS);
589         assert_int_equal(mp->no_path_retry, NO_PATH_RETRY_QUEUE);
590         assert_int_equal(mp->retain_hwhandler, RETAIN_HWHANDLER_OFF);
591 }
592
593 static int setup_internal_nvme(void **state)
594 {
595         struct hwt_state *hwt = CHECK_STATE(state);
596
597         WRITE_EMPTY_CONF(hwt);
598         SET_TEST_FUNC(hwt, test_internal_nvme);
599
600         return 0;
601 }
602
603 /*
604  * Device section with a simple entry qith double quotes ('foo:"bar"')
605  */
606 static void test_quoted_hwe(const struct hwt_state *hwt)
607 {
608         struct path *pp;
609
610         /* foo:"bar" matches */
611         pp = mock_path(vnd_foo.value, prd_baq.value);
612         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
613
614         /* foo:bar doesn't match */
615         pp = mock_path(vnd_foo.value, prd_bar.value);
616         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
617 }
618
619 static int setup_quoted_hwe(void **state)
620 {
621         struct hwt_state *hwt = CHECK_STATE(state);
622         const struct key_value kv[] = { vnd_foo, prd_baqq, prio_emc };
623
624         WRITE_ONE_DEVICE(hwt, kv);
625         SET_TEST_FUNC(hwt, test_quoted_hwe);
626         return 0;
627 }
628
629 /*
630  * Device section with a single simple entry ("foo:bar")
631  */
632 static void test_string_hwe(const struct hwt_state *hwt)
633 {
634         struct path *pp;
635
636         /* foo:bar matches */
637         pp = mock_path(vnd_foo.value, prd_bar.value);
638         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
639
640         /* foo:baz doesn't match */
641         pp = mock_path(vnd_foo.value, prd_baz.value);
642         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
643
644         /* boo:bar doesn't match */
645         pp = mock_path(vnd_boo.value, prd_bar.value);
646         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
647 }
648
649 static int setup_string_hwe(void **state)
650 {
651         struct hwt_state *hwt = CHECK_STATE(state);
652         const struct key_value kv[] = { vnd_foo, prd_bar, prio_emc };
653
654         WRITE_ONE_DEVICE(hwt, kv);
655         SET_TEST_FUNC(hwt, test_string_hwe);
656         return 0;
657 }
658
659 /*
660  * Device section with a broken entry (no product)
661  * It should be ignored.
662  */
663 static void test_broken_hwe(const struct hwt_state *hwt)
664 {
665         struct path *pp;
666
667         /* foo:bar doesn't match, as hwentry is ignored */
668         pp = mock_path(vnd_foo.value, prd_bar.value);
669         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
670
671         /* boo:bar doesn't match */
672         pp = mock_path(vnd_boo.value, prd_bar.value);
673         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
674 }
675
676 static int setup_broken_hwe(void **state)
677 {
678         struct hwt_state *hwt = CHECK_STATE(state);
679         const struct key_value kv[] = { vnd_foo, prio_emc };
680
681         WRITE_ONE_DEVICE(hwt, kv);
682         SET_TEST_FUNC(hwt, test_broken_hwe);
683         return 0;
684 }
685
686 /*
687  * Like test_broken_hwe, but in config_dir file.
688  */
689 static int setup_broken_hwe_dir(void **state)
690 {
691         struct hwt_state *hwt = CHECK_STATE(state);
692         const struct key_value kv[] = { vnd_foo, prio_emc };
693
694         begin_config(hwt);
695         begin_section_all(hwt, "devices");
696         write_device(hwt->conf_dir_file[0], ARRAY_SIZE(kv), kv);
697         end_section_all(hwt);
698         finish_config(hwt);
699         hwt->test = test_broken_hwe;
700         hwt->test_name = "test_broken_hwe_dir";
701         return 0;
702 }
703
704 /*
705  * Device section with a single regex entry ("^.foo:(bar|baz|ba\.)$")
706  */
707 static void test_regex_hwe(const struct hwt_state *hwt)
708 {
709         struct path *pp;
710
711         /* foo:bar matches */
712         pp = mock_path(vnd_foo.value, prd_bar.value);
713         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
714
715         /* foo:baz matches */
716         pp = mock_path(vnd_foo.value, prd_baz.value);
717         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
718
719         /* boo:baz matches */
720         pp = mock_path(vnd_boo.value, prd_bar.value);
721         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
722
723         /* foo:BAR doesn't match */
724         pp = mock_path(vnd_foo.value, "BAR");
725         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
726
727         /* bboo:bar doesn't match */
728         pp = mock_path("bboo", prd_bar.value);
729         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
730 }
731
732 static int setup_regex_hwe(void **state)
733 {
734         struct hwt_state *hwt = CHECK_STATE(state);
735         const struct key_value kv[] = { vnd_t_oo, prd_ba_s, prio_emc };
736
737         WRITE_ONE_DEVICE(hwt, kv);
738         SET_TEST_FUNC(hwt, test_regex_hwe);
739         return 0;
740 }
741
742 /*
743  * Two device entries, kv1 is a regex match ("^.foo:(bar|baz|ba\.)$"),
744  * kv2 a string match (foo:bar) which matches a subset of the regex.
745  * Both are added to the main config file.
746  *
747  * Expected: Devices matching both get properties from both, kv2 taking
748  * precedence. Devices matching kv1 only just get props from kv1.
749  */
750 static void test_regex_string_hwe(const struct hwt_state *hwt)
751 {
752         struct path *pp;
753
754         /* foo:baz matches kv1 */
755         pp = mock_path(vnd_foo.value, prd_baz.value);
756         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
757         TEST_PROP(pp->getuid, NULL);
758         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
759
760         /* boo:baz matches kv1 */
761         pp = mock_path(vnd_boo.value, prd_baz.value);
762         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
763         TEST_PROP(pp->getuid, NULL);
764         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
765
766         /* .oo:ba. matches kv1 */
767         pp = mock_path(vnd__oo.value, prd_ba_.value);
768         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
769         TEST_PROP(pp->getuid, NULL);
770         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
771
772         /* .foo:(bar|baz|ba\.) doesn't match */
773         pp = mock_path(vnd__oo.value, prd_ba_s.value);
774         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
775         TEST_PROP(pp->getuid, NULL);
776         TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
777
778         /* foo:bar matches kv2 and kv1 */
779         pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
780         TEST_PROP(prio_name(&pp->prio), prio_hds.value);
781         TEST_PROP(pp->getuid, gui_foo.value);
782         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
783 }
784
785 static int setup_regex_string_hwe(void **state)
786 {
787         struct hwt_state *hwt = CHECK_STATE(state);
788         const struct key_value kv1[] = { vnd_t_oo, prd_ba_s, prio_emc, chk_hp };
789         const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, gui_foo };
790
791         WRITE_TWO_DEVICES(hwt, kv1, kv2);
792         SET_TEST_FUNC(hwt, test_regex_string_hwe);
793         return 0;
794 }
795
796 /*
797  * Two device entries, kv1 is a regex match ("^.foo:(bar|baz|ba\.)$"),
798  * kv2 a string match (foo:bar) which matches a subset of the regex.
799  * kv1 is added to the main config file, kv2 to a config_dir file.
800  * This case is more important as you may think, because it's equivalent
801  * to kv1 being in the built-in hwtable and kv2 in multipath.conf.
802  *
803  * Expected: Devices matching kv2 (and thus, both) get properties
804  * from both, kv2 taking precedence.
805  * Devices matching kv1 only just get props from kv1.
806  */
807 static void test_regex_string_hwe_dir(const struct hwt_state *hwt)
808 {
809         struct path *pp;
810
811         /* foo:baz matches kv1 */
812         pp = mock_path(vnd_foo.value, prd_baz.value);
813         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
814         TEST_PROP(pp->getuid, NULL);
815         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
816
817         /* boo:baz matches kv1 */
818         pp = mock_path(vnd_boo.value, prd_baz.value);
819         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
820         TEST_PROP(pp->getuid, NULL);
821         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
822
823         /* .oo:ba. matches kv1 */
824         pp = mock_path(vnd__oo.value, prd_ba_.value);
825         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
826         TEST_PROP(pp->getuid, NULL);
827         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
828
829         /* .oo:(bar|baz|ba\.)$ doesn't match */
830         pp = mock_path(vnd__oo.value, prd_ba_s.value);
831         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
832         TEST_PROP(pp->getuid, NULL);
833         TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
834
835         /* foo:bar matches kv2 */
836         pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
837         /* Later match takes prio */
838         TEST_PROP(prio_name(&pp->prio), prio_hds.value);
839         TEST_PROP(pp->getuid, gui_foo.value);
840         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
841 }
842
843 static int setup_regex_string_hwe_dir(void **state)
844 {
845         const struct key_value kv1[] = { vnd_t_oo, prd_ba_s, prio_emc, chk_hp };
846         const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, gui_foo };
847         struct hwt_state *hwt = CHECK_STATE(state);
848
849         WRITE_TWO_DEVICES_W_DIR(hwt, kv1, kv2);
850         SET_TEST_FUNC(hwt, test_regex_string_hwe_dir);
851         return 0;
852 }
853
854 /*
855  * Three device entries, kv1 is a regex match and kv2 and kv3 string
856  * matches, where kv3 is a substring of kv2. All in different config
857  * files.
858  *
859  * Expected: Devices matching kv3 get props from all, devices matching
860  * kv2 from kv2 and kv1, and devices matching kv1 only just from kv1.
861  */
862 static void test_regex_2_strings_hwe_dir(const struct hwt_state *hwt)
863 {
864         struct path *pp;
865
866         /* foo:baz matches kv1 */
867         pp = mock_path(vnd_foo.value, prd_baz.value);
868         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
869         TEST_PROP(pp->getuid, NULL);
870         TEST_PROP(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE);
871         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
872
873         /* boo:baz doesn't match */
874         pp = mock_path(vnd_boo.value, prd_baz.value);
875         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
876         TEST_PROP(pp->getuid, NULL);
877         TEST_PROP(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE);
878         TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
879
880         /* foo:bar matches kv2 and kv1 */
881         pp = mock_path(vnd_foo.value, prd_bar.value);
882         TEST_PROP(prio_name(&pp->prio), prio_hds.value);
883         TEST_PROP(pp->getuid, NULL);
884         TEST_PROP(pp->uid_attribute, uid_baz.value);
885         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
886
887         /* foo:barz matches kv3 and kv2 and kv1 */
888         pp = mock_path_flags(vnd_foo.value, prd_barz.value, USE_GETUID);
889         TEST_PROP(prio_name(&pp->prio), prio_rdac.value);
890         TEST_PROP(pp->getuid, gui_foo.value);
891         TEST_PROP(pp->uid_attribute, NULL);
892         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
893 }
894
895 static int setup_regex_2_strings_hwe_dir(void **state)
896 {
897         const struct key_value kv1[] = { vnd_foo, prd_ba_, prio_emc, chk_hp };
898         const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, uid_baz };
899         const struct key_value kv3[] = { vnd_foo, prd_barz,
900                                          prio_rdac, gui_foo };
901         struct hwt_state *hwt = CHECK_STATE(state);
902
903         begin_config(hwt);
904         begin_section_all(hwt, "devices");
905         write_device(hwt->config_file, ARRAY_SIZE(kv1), kv1);
906         write_device(hwt->conf_dir_file[0], ARRAY_SIZE(kv2), kv2);
907         write_device(hwt->conf_dir_file[1], ARRAY_SIZE(kv3), kv3);
908         end_section_all(hwt);
909         finish_config(hwt);
910         SET_TEST_FUNC(hwt, test_regex_2_strings_hwe_dir);
911         return 0;
912 }
913
914 /*
915  * Like test_regex_string_hwe_dir, but the order of kv1 and kv2 is exchanged.
916  *
917  * Expected: Devices matching kv1 (and thus, both) get properties
918  * from both, kv1 taking precedence.
919  * Devices matching kv1 only just get props from kv1.
920  */
921 static void test_string_regex_hwe_dir(const struct hwt_state *hwt)
922 {
923         struct path *pp;
924
925         /* foo:bar matches kv2 and kv1 */
926         pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
927         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
928         TEST_PROP(pp->getuid, gui_foo.value);
929         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
930
931         /* foo:baz matches kv1 */
932         pp = mock_path(vnd_foo.value, prd_baz.value);
933         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
934         TEST_PROP(pp->getuid, NULL);
935         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
936
937         /* boo:baz matches kv1 */
938         pp = mock_path(vnd_boo.value, prd_baz.value);
939         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
940         TEST_PROP(pp->getuid, NULL);
941         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
942
943         /* .oo:ba. matches kv1 */
944         pp = mock_path(vnd__oo.value, prd_ba_.value);
945         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
946         TEST_PROP(pp->getuid, NULL);
947         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
948
949         /* .oo:(bar|baz|ba\.)$ doesn't match */
950         pp = mock_path(vnd__oo.value, prd_ba_s.value);
951         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
952         TEST_PROP(pp->getuid, NULL);
953         TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
954 }
955
956 static int setup_string_regex_hwe_dir(void **state)
957 {
958         const struct key_value kv1[] = { vnd_t_oo, prd_ba_s, prio_emc, chk_hp };
959         const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, gui_foo };
960         struct hwt_state *hwt = CHECK_STATE(state);
961
962         WRITE_TWO_DEVICES_W_DIR(hwt, kv2, kv1);
963         SET_TEST_FUNC(hwt, test_string_regex_hwe_dir);
964         return 0;
965 }
966
967 /*
968  * Two identical device entries kv1 and kv2, trival regex ("string").
969  * Both are added to the main config file.
970  * These entries are NOT merged.
971  * This could happen in a large multipath.conf file.
972  *
973  * Expected: matching devices get props from both, kv2 taking precedence.
974  */
975 static void test_2_ident_strings_hwe(const struct hwt_state *hwt)
976 {
977         struct path *pp;
978
979         /* foo:baz doesn't match */
980         pp = mock_path(vnd_foo.value, prd_baz.value);
981         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
982         TEST_PROP(pp->getuid, NULL);
983         TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
984
985         /* foo:bar matches both */
986         pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
987         TEST_PROP(prio_name(&pp->prio), prio_hds.value);
988         TEST_PROP(pp->getuid, gui_foo.value);
989         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
990 }
991
992 static int setup_2_ident_strings_hwe(void **state)
993 {
994         const struct key_value kv1[] = { vnd_foo, prd_bar, prio_emc, chk_hp };
995         const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, gui_foo };
996         struct hwt_state *hwt = CHECK_STATE(state);
997
998         WRITE_TWO_DEVICES(hwt, kv1, kv2);
999         SET_TEST_FUNC(hwt, test_2_ident_strings_hwe);
1000         return 0;
1001 }
1002
1003 /*
1004  * Two identical device entries kv1 and kv2, trival regex ("string").
1005  * Both are added to an extra config file.
1006  * This could happen in a large multipath.conf file.
1007  *
1008  * Expected: matching devices get props from both, kv2 taking precedence.
1009  */
1010 static void test_2_ident_strings_both_dir(const struct hwt_state *hwt)
1011 {
1012         struct path *pp;
1013
1014         /* foo:baz doesn't match */
1015         pp = mock_path(vnd_foo.value, prd_baz.value);
1016         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
1017         TEST_PROP(pp->getuid, NULL);
1018         TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
1019
1020         /* foo:bar matches both */
1021         pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
1022         TEST_PROP(prio_name(&pp->prio), prio_hds.value);
1023         TEST_PROP(pp->getuid, gui_foo.value);
1024         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
1025 }
1026
1027 static int setup_2_ident_strings_both_dir(void **state)
1028 {
1029         const struct key_value kv1[] = { vnd_foo, prd_bar, prio_emc, chk_hp };
1030         const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, gui_foo };
1031         struct hwt_state *hwt = CHECK_STATE(state);
1032
1033         begin_config(hwt);
1034         begin_section_all(hwt, "devices");
1035         write_device(hwt->conf_dir_file[1], ARRAY_SIZE(kv1), kv1);
1036         write_device(hwt->conf_dir_file[1], ARRAY_SIZE(kv2), kv2);
1037         end_section_all(hwt);
1038         finish_config(hwt);
1039         SET_TEST_FUNC(hwt, test_2_ident_strings_both_dir);
1040         return 0;
1041 }
1042
1043 /*
1044  * Two identical device entries kv1 and kv2, trival regex ("string").
1045  * Both are added to an extra config file.
1046  * An empty entry kv0 with the same string exists in the main config file.
1047  *
1048  * Expected: matching devices get props from both, kv2 taking precedence.
1049  */
1050 static void test_2_ident_strings_both_dir_w_prev(const struct hwt_state *hwt)
1051 {
1052         struct path *pp;
1053
1054         /* foo:baz doesn't match */
1055         pp = mock_path(vnd_foo.value, prd_baz.value);
1056         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
1057         TEST_PROP(pp->getuid, NULL);
1058         TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
1059
1060         /* foo:bar matches both */
1061         pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
1062         TEST_PROP(prio_name(&pp->prio), prio_hds.value);
1063         TEST_PROP(pp->getuid, gui_foo.value);
1064         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
1065 }
1066
1067 static int setup_2_ident_strings_both_dir_w_prev(void **state)
1068 {
1069         struct hwt_state *hwt = CHECK_STATE(state);
1070
1071         const struct key_value kv0[] = { vnd_foo, prd_bar };
1072         const struct key_value kv1[] = { vnd_foo, prd_bar, prio_emc, chk_hp };
1073         const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, gui_foo };
1074
1075         begin_config(hwt);
1076         begin_section_all(hwt, "devices");
1077         write_device(hwt->config_file, ARRAY_SIZE(kv0), kv0);
1078         write_device(hwt->conf_dir_file[1], ARRAY_SIZE(kv1), kv1);
1079         write_device(hwt->conf_dir_file[1], ARRAY_SIZE(kv2), kv2);
1080         end_section_all(hwt);
1081         finish_config(hwt);
1082         SET_TEST_FUNC(hwt, test_2_ident_strings_both_dir_w_prev);
1083         return 0;
1084 }
1085
1086 /*
1087  * Two identical device entries kv1 and kv2, trival regex ("string").
1088  * kv1 is added to the main config file, kv2 to a config_dir file.
1089  * These entries are merged.
1090  * This case is more important as you may think, because it's equivalent
1091  * to kv1 being in the built-in hwtable and kv2 in multipath.conf.
1092  *
1093  * Expected: matching devices get props from both, kv2 taking precedence.
1094  */
1095 static void test_2_ident_strings_hwe_dir(const struct hwt_state *hwt)
1096 {
1097         struct path *pp;
1098
1099         /* foo:baz doesn't match */
1100         pp = mock_path(vnd_foo.value, prd_baz.value);
1101         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
1102         TEST_PROP(pp->getuid, NULL);
1103         TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
1104
1105         /* foo:bar matches both */
1106         pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
1107         TEST_PROP(prio_name(&pp->prio), prio_hds.value);
1108         TEST_PROP(pp->getuid, gui_foo.value);
1109         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
1110 }
1111
1112 static int setup_2_ident_strings_hwe_dir(void **state)
1113 {
1114         const struct key_value kv1[] = { vnd_foo, prd_bar, prio_emc, chk_hp };
1115         const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, gui_foo };
1116         struct hwt_state *hwt = CHECK_STATE(state);
1117
1118         WRITE_TWO_DEVICES_W_DIR(hwt, kv1, kv2);
1119         SET_TEST_FUNC(hwt, test_2_ident_strings_hwe_dir);
1120         return 0;
1121 }
1122
1123 /*
1124  * Like test_2_ident_strings_hwe_dir, but this time the config_dir file
1125  * contains an additional, empty entry (kv0).
1126  *
1127  * Expected: matching devices get props from kv1 and kv2, kv2 taking precedence.
1128  */
1129 static void test_3_ident_strings_hwe_dir(const struct hwt_state *hwt)
1130 {
1131         struct path *pp;
1132
1133         /* foo:baz doesn't match */
1134         pp = mock_path(vnd_foo.value, prd_baz.value);
1135         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
1136         TEST_PROP(pp->getuid, NULL);
1137         TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
1138
1139         /* foo:bar matches both */
1140         pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
1141         TEST_PROP(prio_name(&pp->prio), prio_hds.value);
1142         TEST_PROP(pp->getuid, gui_foo.value);
1143         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
1144 }
1145
1146 static int setup_3_ident_strings_hwe_dir(void **state)
1147 {
1148         const struct key_value kv0[] = { vnd_foo, prd_bar };
1149         const struct key_value kv1[] = { vnd_foo, prd_bar, prio_emc, chk_hp };
1150         const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, gui_foo };
1151         struct hwt_state *hwt = CHECK_STATE(state);
1152
1153         begin_config(hwt);
1154         begin_section_all(hwt, "devices");
1155         write_device(hwt->config_file, ARRAY_SIZE(kv1), kv1);
1156         write_device(hwt->conf_dir_file[1], ARRAY_SIZE(kv0), kv0);
1157         write_device(hwt->conf_dir_file[1], ARRAY_SIZE(kv2), kv2);
1158         end_section_all(hwt);
1159         finish_config(hwt);
1160         SET_TEST_FUNC(hwt, test_3_ident_strings_hwe_dir);
1161         return 0;
1162 }
1163
1164 /*
1165  * Two identical device entries kv1 and kv2, non-trival regex that matches
1166  * itself (string ".oo" matches regex ".oo").
1167  * kv1 is added to the main config file, kv2 to a config_dir file.
1168  * This case is more important as you may think, because it's equivalent
1169  * to kv1 being in the built-in hwtable and kv2 in multipath.conf.
1170  *
1171  * Expected: matching devices get props from both, kv2 taking precedence.
1172  */
1173 static void test_2_ident_self_matching_re_hwe_dir(const struct hwt_state *hwt)
1174 {
1175         struct path *pp;
1176
1177         /* foo:baz doesn't match */
1178         pp = mock_path(vnd_foo.value, prd_baz.value);
1179         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
1180         TEST_PROP(pp->getuid, NULL);
1181         TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
1182
1183         /* foo:bar matches both */
1184         pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
1185         TEST_PROP(prio_name(&pp->prio), prio_hds.value);
1186         TEST_PROP(pp->getuid, gui_foo.value);
1187         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
1188 }
1189
1190 static int setup_2_ident_self_matching_re_hwe_dir(void **state)
1191 {
1192         const struct key_value kv1[] = { vnd__oo, prd_bar, prio_emc, chk_hp };
1193         const struct key_value kv2[] = { vnd__oo, prd_bar, prio_hds, gui_foo };
1194         struct hwt_state *hwt = CHECK_STATE(state);
1195
1196         WRITE_TWO_DEVICES_W_DIR(hwt, kv1, kv2);
1197         SET_TEST_FUNC(hwt, test_2_ident_self_matching_re_hwe_dir);
1198         return 0;
1199 }
1200
1201 /*
1202  * Two identical device entries kv1 and kv2, non-trival regex that matches
1203  * itself (string ".oo" matches regex ".oo").
1204  * kv1 and kv2 are added to the main config file.
1205  *
1206  * Expected: matching devices get props from both, kv2 taking precedence.
1207  */
1208 static void test_2_ident_self_matching_re_hwe(const struct hwt_state *hwt)
1209 {
1210         struct path *pp;
1211
1212         /* foo:baz doesn't match */
1213         pp = mock_path(vnd_foo.value, prd_baz.value);
1214         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
1215         TEST_PROP(pp->getuid, NULL);
1216         TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
1217
1218         /* foo:bar matches */
1219         pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
1220         TEST_PROP(prio_name(&pp->prio), prio_hds.value);
1221         TEST_PROP(pp->getuid, gui_foo.value);
1222         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
1223 }
1224
1225 static int setup_2_ident_self_matching_re_hwe(void **state)
1226 {
1227         const struct key_value kv1[] = { vnd__oo, prd_bar, prio_emc, chk_hp };
1228         const struct key_value kv2[] = { vnd__oo, prd_bar, prio_hds, gui_foo };
1229         struct hwt_state *hwt = CHECK_STATE(state);
1230
1231         WRITE_TWO_DEVICES(hwt, kv1, kv2);
1232         SET_TEST_FUNC(hwt, test_2_ident_self_matching_re_hwe);
1233         return 0;
1234 }
1235
1236 /*
1237  * Two identical device entries kv1 and kv2, non-trival regex that doesn't
1238  * match itself (string "^.oo" doesn't match regex "^.oo").
1239  * kv1 is added to the main config file, kv2 to a config_dir file.
1240  * This case is more important as you may think, see above.
1241  *
1242  * Expected: matching devices get props from both, kv2 taking precedence.
1243  */
1244 static void
1245 test_2_ident_not_self_matching_re_hwe_dir(const struct hwt_state *hwt)
1246 {
1247         struct path *pp;
1248
1249         /* foo:baz doesn't match */
1250         pp = mock_path(vnd_foo.value, prd_baz.value);
1251         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
1252         TEST_PROP(pp->getuid, NULL);
1253         TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
1254
1255         /* foo:bar matches both */
1256         pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
1257         TEST_PROP(prio_name(&pp->prio), prio_hds.value);
1258         TEST_PROP(pp->getuid, gui_foo.value);
1259         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
1260 }
1261
1262 static int setup_2_ident_not_self_matching_re_hwe_dir(void **state)
1263 {
1264         const struct key_value kv1[] = { vnd_t_oo, prd_bar, prio_emc, chk_hp };
1265         const struct key_value kv2[] = { vnd_t_oo, prd_bar, prio_hds, gui_foo };
1266         struct hwt_state *hwt = CHECK_STATE(state);
1267
1268         WRITE_TWO_DEVICES_W_DIR(hwt, kv1, kv2);
1269         SET_TEST_FUNC(hwt, test_2_ident_not_self_matching_re_hwe_dir);
1270         return 0;
1271 }
1272
1273 /*
1274  * Two different non-trivial regexes kv1, kv2. The 1st one matches the 2nd, but
1275  * it doesn't match all possible strings matching the second.
1276  * ("ba[zy]" matches regex "ba[[rxy]", but "baz" does not).
1277  *
1278  * Expected: Devices matching both regexes get properties from both, kv2
1279  * taking precedence. Devices matching just one regex get properties from
1280  * that one regex only.
1281  */
1282 static void test_2_matching_res_hwe_dir(const struct hwt_state *hwt)
1283 {
1284         struct path *pp;
1285
1286         /* foo:bar matches k1 only */
1287         pp = mock_path(vnd_foo.value, prd_bar.value);
1288         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
1289         TEST_PROP(pp->getuid, NULL);
1290         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
1291
1292         /* foo:bay matches k1 and k2 */
1293         pp = mock_path_flags(vnd_foo.value, "bay", USE_GETUID);
1294         TEST_PROP(prio_name(&pp->prio), prio_hds.value);
1295         TEST_PROP(pp->getuid, gui_foo.value);
1296         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
1297
1298         /* foo:baz matches k2 only. */
1299         pp = mock_path_flags(vnd_foo.value, prd_baz.value, USE_GETUID);
1300         TEST_PROP(prio_name(&pp->prio), prio_hds.value);
1301         TEST_PROP(pp->getuid, gui_foo.value);
1302         TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
1303 }
1304
1305 static int setup_2_matching_res_hwe_dir(void **state)
1306 {
1307         const struct key_value kv1[] = { vnd_foo, prd_barx, prio_emc, chk_hp };
1308         const struct key_value kv2[] = { vnd_foo, prd_bazy, prio_hds, gui_foo };
1309         struct hwt_state *hwt = CHECK_STATE(state);
1310
1311         WRITE_TWO_DEVICES_W_DIR(hwt, kv1, kv2);
1312         SET_TEST_FUNC(hwt, test_2_matching_res_hwe_dir);
1313         return 0;
1314 }
1315
1316 /*
1317  * Two different non-trivial regexes which match the same set of strings.
1318  * But they don't match each other.
1319  * "baz" matches both regex "ba[zy]" and "ba(z|y)"
1320  *
1321  * Expected: matching devices get properties from both, kv2 taking precedence.
1322  */
1323 static void test_2_nonmatching_res_hwe_dir(const struct hwt_state *hwt)
1324 {
1325         struct path *pp;
1326
1327         /* foo:bar doesn't match */
1328         pp = mock_path(vnd_foo.value, prd_bar.value);
1329         TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
1330         TEST_PROP(pp->getuid, NULL);
1331         TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
1332
1333         pp = mock_path_flags(vnd_foo.value, prd_baz.value, USE_GETUID);
1334         TEST_PROP(prio_name(&pp->prio), prio_hds.value);
1335         TEST_PROP(pp->getuid, gui_foo.value);
1336         TEST_PROP(checker_name(&pp->checker), chk_hp.value);
1337 }
1338
1339 static int setup_2_nonmatching_res_hwe_dir(void **state)
1340 {
1341         const struct key_value kv1[] = { vnd_foo, prd_bazy, prio_emc, chk_hp };
1342         const struct key_value kv2[] = { vnd_foo, prd_bazy1,
1343                                          prio_hds, gui_foo };
1344         struct hwt_state *hwt = CHECK_STATE(state);
1345
1346         WRITE_TWO_DEVICES_W_DIR(hwt, kv1, kv2);
1347         SET_TEST_FUNC(hwt, test_2_nonmatching_res_hwe_dir);
1348         return 0;
1349 }
1350
1351 /*
1352  * Simple blacklist test.
1353  *
1354  * NOTE: test failures in blacklisting tests will manifest as cmocka errors
1355  * "Could not get value to mock function XYZ", because pathinfo() takes
1356  * different code paths for blacklisted devices.
1357  */
1358 static void test_blacklist(const struct hwt_state *hwt)
1359 {
1360         mock_path_flags(vnd_foo.value, prd_bar.value, BL_BY_DEVICE);
1361         mock_path(vnd_foo.value, prd_baz.value);
1362 }
1363
1364 static int setup_blacklist(void **state)
1365 {
1366         const struct key_value kv1[] = { vnd_foo, prd_bar };
1367         struct hwt_state *hwt = CHECK_STATE(state);
1368
1369         begin_config(hwt);
1370         begin_section_all(hwt, "blacklist");
1371         write_device(hwt->config_file, ARRAY_SIZE(kv1), kv1);
1372         end_section_all(hwt);
1373         finish_config(hwt);
1374         SET_TEST_FUNC(hwt, test_blacklist);
1375         return 0;
1376 }
1377
1378 /*
1379  * Simple blacklist test with regex and exception
1380  */
1381 static void test_blacklist_regex(const struct hwt_state *hwt)
1382 {
1383         mock_path(vnd_foo.value, prd_bar.value);
1384         mock_path_flags(vnd_foo.value, prd_baz.value, BL_BY_DEVICE);
1385         mock_path(vnd_foo.value, prd_bam.value);
1386 }
1387
1388 static int setup_blacklist_regex(void **state)
1389 {
1390         const struct key_value kv1[] = { vnd_foo, prd_ba_s };
1391         const struct key_value kv2[] = { vnd_foo, prd_bar };
1392         struct hwt_state *hwt = CHECK_STATE(state);
1393
1394         hwt = CHECK_STATE(state);
1395         begin_config(hwt);
1396         begin_section_all(hwt, "blacklist");
1397         write_device(hwt->config_file, ARRAY_SIZE(kv1), kv1);
1398         end_section_all(hwt);
1399         begin_section_all(hwt, "blacklist_exceptions");
1400         write_device(hwt->conf_dir_file[0], ARRAY_SIZE(kv2), kv2);
1401         end_section_all(hwt);
1402         finish_config(hwt);
1403         SET_TEST_FUNC(hwt, test_blacklist_regex);
1404         return 0;
1405 }
1406
1407 /*
1408  * Simple blacklist test with regex and exception
1409  * config file order inverted wrt test_blacklist_regex
1410  */
1411 static int setup_blacklist_regex_inv(void **state)
1412 {
1413         const struct key_value kv1[] = { vnd_foo, prd_ba_s };
1414         const struct key_value kv2[] = { vnd_foo, prd_bar };
1415         struct hwt_state *hwt = CHECK_STATE(state);
1416
1417         begin_config(hwt);
1418         begin_section_all(hwt, "blacklist");
1419         write_device(hwt->conf_dir_file[0], ARRAY_SIZE(kv1), kv1);
1420         end_section_all(hwt);
1421         begin_section_all(hwt, "blacklist_exceptions");
1422         write_device(hwt->config_file, ARRAY_SIZE(kv2), kv2);
1423         end_section_all(hwt);
1424         finish_config(hwt);
1425         SET_TEST_FUNC(hwt, test_blacklist_regex);
1426         return 0;
1427 }
1428
1429 /*
1430  * Simple blacklist test with regex and exception
1431  * config file order inverted wrt test_blacklist_regex
1432  */
1433 static void test_blacklist_regex_matching(const struct hwt_state *hwt)
1434 {
1435         mock_path_flags(vnd_foo.value, prd_bar.value, BL_BY_DEVICE);
1436         mock_path_flags(vnd_foo.value, prd_baz.value, BL_BY_DEVICE);
1437         mock_path(vnd_foo.value, prd_bam.value);
1438 }
1439
1440 static int setup_blacklist_regex_matching(void **state)
1441 {
1442         const struct key_value kv1[] = { vnd_foo, prd_barx };
1443         const struct key_value kv2[] = { vnd_foo, prd_bazy };
1444         struct hwt_state *hwt = CHECK_STATE(state);
1445
1446         begin_config(hwt);
1447         begin_section_all(hwt, "blacklist");
1448         write_device(hwt->config_file, ARRAY_SIZE(kv1), kv1);
1449         write_device(hwt->conf_dir_file[0], ARRAY_SIZE(kv2), kv2);
1450         end_section_all(hwt);
1451         finish_config(hwt);
1452         SET_TEST_FUNC(hwt, test_blacklist_regex_matching);
1453         return 0;
1454 }
1455
1456 /*
1457  * Test for blacklisting by WWID
1458  *
1459  * Note that default_wwid is a substring of default_wwid_1. Because
1460  * matching is done by regex, both paths are blacklisted.
1461  */
1462 static void test_blacklist_wwid(const struct hwt_state *hwt)
1463 {
1464         mock_path_flags(vnd_foo.value, prd_bar.value, BL_BY_WWID);
1465         mock_path_wwid_flags(vnd_foo.value, prd_baz.value, default_wwid_1,
1466                              BL_BY_WWID);
1467 }
1468
1469 static int setup_blacklist_wwid(void **state)
1470 {
1471         const struct key_value kv[] = { wwid_test };
1472         struct hwt_state *hwt = CHECK_STATE(state);
1473
1474         begin_config(hwt);
1475         write_section(hwt->config_file, "blacklist", ARRAY_SIZE(kv), kv);
1476         finish_config(hwt);
1477         SET_TEST_FUNC(hwt, test_blacklist_wwid);
1478         return 0;
1479 }
1480
1481 /*
1482  * Test for blacklisting by WWID
1483  *
1484  * Here the blacklist contains only default_wwid_1. Thus the path
1485  * with default_wwid is NOT blacklisted.
1486  */
1487 static void test_blacklist_wwid_1(const struct hwt_state *hwt)
1488 {
1489         mock_path(vnd_foo.value, prd_bar.value);
1490         mock_path_wwid_flags(vnd_foo.value, prd_baz.value, default_wwid_1,
1491                              BL_BY_WWID);
1492 }
1493
1494 static int setup_blacklist_wwid_1(void **state)
1495 {
1496         const struct key_value kv[] = { { _wwid, default_wwid_1 }, };
1497         struct hwt_state *hwt = CHECK_STATE(state);
1498
1499         begin_config(hwt);
1500         write_section(hwt->config_file, "blacklist", ARRAY_SIZE(kv), kv);
1501         finish_config(hwt);
1502         SET_TEST_FUNC(hwt, test_blacklist_wwid_1);
1503         return 0;
1504 }
1505
1506 /*
1507  * Test for product_blacklist. Two entries blacklisting each other.
1508  *
1509  * Expected: Both are blacklisted.
1510  */
1511 static void test_product_blacklist(const struct hwt_state *hwt)
1512 {
1513         mock_path_flags(vnd_foo.value, prd_baz.value, BL_BY_DEVICE);
1514         mock_path_flags(vnd_foo.value, prd_bar.value, BL_BY_DEVICE);
1515         mock_path(vnd_foo.value, prd_bam.value);
1516 }
1517
1518 static int setup_product_blacklist(void **state)
1519 {
1520         const struct key_value kv1[] = { vnd_foo, prd_bar, bl_baz };
1521         const struct key_value kv2[] = { vnd_foo, prd_baz, bl_bar };
1522         struct hwt_state *hwt = CHECK_STATE(state);
1523
1524         WRITE_TWO_DEVICES(hwt, kv1, kv2);
1525         SET_TEST_FUNC(hwt, test_product_blacklist);
1526         return 0;
1527 }
1528
1529 /*
1530  * Test for product_blacklist. The second regex "matches" the first.
1531  * This is a pathological example.
1532  *
1533  * Expected: "foo:bar", "foo:baz" are blacklisted.
1534  */
1535 static void test_product_blacklist_matching(const struct hwt_state *hwt)
1536 {
1537         mock_path_flags(vnd_foo.value, prd_bar.value, BL_BY_DEVICE);
1538         mock_path_flags(vnd_foo.value, prd_baz.value, BL_BY_DEVICE);
1539         mock_path(vnd_foo.value, prd_bam.value);
1540 }
1541
1542 static int setup_product_blacklist_matching(void **state)
1543 {
1544         const struct key_value kv1[] = { vnd_foo, prd_bar, bl_barx };
1545         const struct key_value kv2[] = { vnd_foo, prd_baz, bl_bazy };
1546         struct hwt_state *hwt = CHECK_STATE(state);
1547
1548         WRITE_TWO_DEVICES(hwt, kv1, kv2);
1549         SET_TEST_FUNC(hwt, test_product_blacklist_matching);
1550         return 0;
1551 }
1552
1553 /*
1554  * Basic test for multipath-based configuration.
1555  *
1556  * Expected: properties, including pp->prio, are taken from multipath
1557  * section.
1558  */
1559 static void test_multipath_config(const struct hwt_state *hwt)
1560 {
1561         struct path *pp;
1562         struct multipath *mp;
1563
1564         pp = mock_path(vnd_foo.value, prd_bar.value);
1565         mp = mock_multipath(pp);
1566         assert_ptr_not_equal(mp->mpe, NULL);
1567         TEST_PROP(prio_name(&pp->prio), prio_rdac.value);
1568         assert_int_equal(mp->minio, atoi(minio_99.value));
1569         TEST_PROP(pp->uid_attribute, uid_baz.value);
1570
1571         /* test different wwid */
1572         pp = mock_path_wwid(vnd_foo.value, prd_bar.value, default_wwid_1);
1573         mp = mock_multipath(pp);
1574         // assert_ptr_equal(mp->mpe, NULL);
1575         TEST_PROP(prio_name(&pp->prio), prio_emc.value);
1576         assert_int_equal(mp->minio, DEFAULT_MINIO_RQ);
1577         TEST_PROP(pp->uid_attribute, uid_baz.value);
1578 }
1579
1580 static int setup_multipath_config(void **state)
1581 {
1582         struct hwt_state *hwt = CHECK_STATE(state);
1583         const struct key_value kvm[] = { wwid_test, prio_rdac, minio_99 };
1584         const struct key_value kvp[] = { vnd_foo, prd_bar, prio_emc, uid_baz };
1585
1586         begin_config(hwt);
1587         begin_section_all(hwt, "devices");
1588         write_section(hwt->conf_dir_file[0], "device", ARRAY_SIZE(kvp), kvp);
1589         end_section_all(hwt);
1590         begin_section_all(hwt, "multipaths");
1591         write_section(hwt->config_file, "multipath", ARRAY_SIZE(kvm), kvm);
1592         end_section_all(hwt);
1593         finish_config(hwt);
1594         SET_TEST_FUNC(hwt, test_multipath_config);
1595         return 0;
1596 }
1597
1598 /*
1599  * Basic test for multipath-based configuration. Two sections for the same wwid.
1600  *
1601  * Expected: properties are taken from both multipath sections, later taking
1602  * precedence
1603  */
1604 static void test_multipath_config_2(const struct hwt_state *hwt)
1605 {
1606         struct path *pp;
1607         struct multipath *mp;
1608
1609         pp = mock_path(vnd_foo.value, prd_bar.value);
1610         mp = mock_multipath(pp);
1611         assert_ptr_not_equal(mp, NULL);
1612         assert_ptr_not_equal(mp->mpe, NULL);
1613         TEST_PROP(prio_name(&pp->prio), prio_rdac.value);
1614         assert_int_equal(mp->minio, atoi(minio_99.value));
1615         assert_int_equal(mp->no_path_retry, atoi(npr_37.value));
1616 }
1617
1618 static int setup_multipath_config_2(void **state)
1619 {
1620         const struct key_value kv1[] = { wwid_test, prio_rdac, npr_queue };
1621         const struct key_value kv2[] = { wwid_test, minio_99, npr_37 };
1622         struct hwt_state *hwt = CHECK_STATE(state);
1623
1624         begin_config(hwt);
1625         begin_section_all(hwt, "multipaths");
1626         write_section(hwt->config_file, "multipath", ARRAY_SIZE(kv1), kv1);
1627         write_section(hwt->conf_dir_file[1], "multipath", ARRAY_SIZE(kv2), kv2);
1628         end_section_all(hwt);
1629         finish_config(hwt);
1630         SET_TEST_FUNC(hwt, test_multipath_config_2);
1631         return 0;
1632 }
1633
1634 /*
1635  * Same as test_multipath_config_2, both entries in the same config file.
1636  *
1637  * Expected: properties are taken from both multipath sections.
1638  */
1639 static void test_multipath_config_3(const struct hwt_state *hwt)
1640 {
1641         struct path *pp;
1642         struct multipath *mp;
1643
1644         pp = mock_path(vnd_foo.value, prd_bar.value);
1645         mp = mock_multipath(pp);
1646         assert_ptr_not_equal(mp, NULL);
1647         assert_ptr_not_equal(mp->mpe, NULL);
1648         TEST_PROP(prio_name(&pp->prio), prio_rdac.value);
1649         assert_int_equal(mp->minio, atoi(minio_99.value));
1650         assert_int_equal(mp->no_path_retry, atoi(npr_37.value));
1651 }
1652
1653 static int setup_multipath_config_3(void **state)
1654 {
1655         const struct key_value kv1[] = { wwid_test, prio_rdac, npr_queue };
1656         const struct key_value kv2[] = { wwid_test, minio_99, npr_37 };
1657         struct hwt_state *hwt = CHECK_STATE(state);
1658
1659         begin_config(hwt);
1660         begin_section_all(hwt, "multipaths");
1661         write_section(hwt->config_file, "multipath", ARRAY_SIZE(kv1), kv1);
1662         write_section(hwt->config_file, "multipath", ARRAY_SIZE(kv2), kv2);
1663         end_section_all(hwt);
1664         finish_config(hwt);
1665         SET_TEST_FUNC(hwt, test_multipath_config_3);
1666         return 0;
1667 }
1668
1669 /*
1670  * Test for device with "hidden" attribute
1671  */
1672 static void test_hidden(const struct hwt_state *hwt)
1673 {
1674         mock_path_flags("NVME", "NoName", DEV_HIDDEN|BL_MASK);
1675 }
1676
1677 static int setup_hidden(void **state)
1678 {
1679         struct hwt_state *hwt = CHECK_STATE(state);
1680
1681         WRITE_EMPTY_CONF(hwt);
1682         SET_TEST_FUNC(hwt, test_hidden);
1683
1684         return 0;
1685 }
1686
1687 /*
1688  * Create wrapper functions around test_driver() to avoid that cmocka
1689  * always uses the same test name. That makes it easier to read test results.
1690  */
1691
1692 #define define_test(x)                          \
1693         static void run_##x(void **state)       \
1694         {                                       \
1695                 return test_driver(state);      \
1696         }
1697
1698 define_test(string_hwe)
1699 define_test(broken_hwe)
1700 define_test(broken_hwe_dir)
1701 define_test(quoted_hwe)
1702 define_test(internal_nvme)
1703 define_test(regex_hwe)
1704 define_test(regex_string_hwe)
1705 define_test(regex_string_hwe_dir)
1706 define_test(regex_2_strings_hwe_dir)
1707 define_test(string_regex_hwe_dir)
1708 define_test(2_ident_strings_hwe)
1709 define_test(2_ident_strings_both_dir)
1710 define_test(2_ident_strings_both_dir_w_prev)
1711 define_test(2_ident_strings_hwe_dir)
1712 define_test(3_ident_strings_hwe_dir)
1713 define_test(2_ident_self_matching_re_hwe_dir)
1714 define_test(2_ident_self_matching_re_hwe)
1715 define_test(2_ident_not_self_matching_re_hwe_dir)
1716 define_test(2_matching_res_hwe_dir)
1717 define_test(2_nonmatching_res_hwe_dir)
1718 define_test(blacklist)
1719 define_test(blacklist_wwid)
1720 define_test(blacklist_wwid_1)
1721 define_test(blacklist_regex)
1722 define_test(blacklist_regex_inv)
1723 define_test(blacklist_regex_matching)
1724 define_test(product_blacklist)
1725 define_test(product_blacklist_matching)
1726 define_test(multipath_config)
1727 define_test(multipath_config_2)
1728 define_test(multipath_config_3)
1729 define_test(hidden)
1730
1731 #define test_entry(x) \
1732         cmocka_unit_test_setup(run_##x, setup_##x)
1733
1734 static int test_hwtable(void)
1735 {
1736         const struct CMUnitTest tests[] = {
1737                 cmocka_unit_test(test_sanity_globals),
1738                 test_entry(internal_nvme),
1739                 test_entry(string_hwe),
1740                 test_entry(broken_hwe),
1741                 test_entry(broken_hwe_dir),
1742                 test_entry(quoted_hwe),
1743                 test_entry(regex_hwe),
1744                 test_entry(regex_string_hwe),
1745                 test_entry(regex_string_hwe_dir),
1746                 test_entry(regex_2_strings_hwe_dir),
1747                 test_entry(string_regex_hwe_dir),
1748                 test_entry(2_ident_strings_hwe),
1749                 test_entry(2_ident_strings_both_dir),
1750                 test_entry(2_ident_strings_both_dir_w_prev),
1751                 test_entry(2_ident_strings_hwe_dir),
1752                 test_entry(3_ident_strings_hwe_dir),
1753                 test_entry(2_ident_self_matching_re_hwe_dir),
1754                 test_entry(2_ident_self_matching_re_hwe),
1755                 test_entry(2_ident_not_self_matching_re_hwe_dir),
1756                 test_entry(2_matching_res_hwe_dir),
1757                 test_entry(2_nonmatching_res_hwe_dir),
1758                 test_entry(blacklist),
1759                 test_entry(blacklist_wwid),
1760                 test_entry(blacklist_wwid_1),
1761                 test_entry(blacklist_regex),
1762                 test_entry(blacklist_regex_inv),
1763                 test_entry(blacklist_regex_matching),
1764                 test_entry(product_blacklist),
1765                 test_entry(product_blacklist_matching),
1766                 test_entry(multipath_config),
1767                 test_entry(multipath_config_2),
1768                 test_entry(multipath_config_3),
1769                 test_entry(hidden),
1770         };
1771
1772         return cmocka_run_group_tests(tests, setup, teardown);
1773 }
1774
1775 int main(void)
1776 {
1777         int ret = 0;
1778
1779         ret += test_hwtable();
1780         return ret;
1781 }