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