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