|
Packit Service |
0af388 |
/* Set BROKEN to 1 to treat broken behavior as success */
|
|
Packit Service |
0af388 |
#define BROKEN 1
|
|
Packit Service |
0af388 |
#define VERBOSITY 2
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#include <stdbool.h>
|
|
Packit Service |
0af388 |
#include <stdarg.h>
|
|
Packit Service |
0af388 |
#include <stddef.h>
|
|
Packit Service |
0af388 |
#include <setjmp.h>
|
|
Packit Service |
0af388 |
#include <stdlib.h>
|
|
Packit Service |
0af388 |
#include <cmocka.h>
|
|
Packit Service |
0af388 |
#include <libudev.h>
|
|
Packit Service |
0af388 |
#include <sys/stat.h>
|
|
Packit Service |
0af388 |
#include <fcntl.h>
|
|
Packit Service |
0af388 |
#include <unistd.h>
|
|
Packit Service |
0af388 |
#include <stdio.h>
|
|
Packit Service |
0af388 |
#include <errno.h>
|
|
Packit Service |
0af388 |
#include <limits.h>
|
|
Packit Service |
0af388 |
#include <sys/sysmacros.h>
|
|
Packit Service |
0af388 |
#include "structs.h"
|
|
Packit Service |
0af388 |
#include "structs_vec.h"
|
|
Packit Service |
0af388 |
#include "config.h"
|
|
Packit Service |
0af388 |
#include "debug.h"
|
|
Packit Service |
0af388 |
#include "defaults.h"
|
|
Packit Service |
0af388 |
#include "pgpolicies.h"
|
|
Packit Service |
0af388 |
#include "test-lib.h"
|
|
Packit Service |
0af388 |
#include "print.h"
|
|
Packit Service |
0af388 |
#include "util.h"
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#define N_CONF_FILES 2
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static const char tmplate[] = "/tmp/hwtable-XXXXXX";
|
|
Packit Service |
0af388 |
/* pretend new dm, use minio_rq */
|
|
Packit Service |
0af388 |
static const unsigned int dm_tgt_version[3] = { 1, 1, 1 };
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
struct key_value {
|
|
Packit Service |
0af388 |
const char *key;
|
|
Packit Service |
0af388 |
const char *value;
|
|
Packit Service |
0af388 |
};
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
struct hwt_state {
|
|
Packit Service |
0af388 |
char *tmpname;
|
|
Packit Service |
0af388 |
char *dirname;
|
|
Packit Service |
0af388 |
FILE *config_file;
|
|
Packit Service |
0af388 |
FILE *conf_dir_file[N_CONF_FILES];
|
|
Packit Service |
0af388 |
struct vectors *vecs;
|
|
Packit Service |
0af388 |
void (*test)(const struct hwt_state *);
|
|
Packit Service |
0af388 |
const char *test_name;
|
|
Packit Service |
0af388 |
};
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#define SET_TEST_FUNC(hwt, func) do { \
|
|
Packit Service |
0af388 |
hwt->test = func; \
|
|
Packit Service |
0af388 |
hwt->test_name = #func; \
|
|
Packit Service |
0af388 |
} while (0)
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static struct config *_conf;
|
|
Packit Service |
0af388 |
struct udev *udev;
|
|
Packit Service |
0af388 |
int logsink = -1;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
struct config *get_multipath_config(void)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
return _conf;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
void put_multipath_config(void *arg)
|
|
Packit Service |
0af388 |
{}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
void make_config_file_path(char *buf, int buflen,
|
|
Packit Service |
0af388 |
const struct hwt_state *hwt, int i)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
static const char fn_template[] = "%s/test-%02d.conf";
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
if (i == -1)
|
|
Packit Service |
0af388 |
/* main config file */
|
|
Packit Service |
0af388 |
snprintf(buf, buflen, fn_template, hwt->tmpname, 0);
|
|
Packit Service |
0af388 |
else
|
|
Packit Service |
0af388 |
snprintf(buf, buflen, fn_template, hwt->dirname, i);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static void reset_vecs(struct vectors *vecs)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
remove_maps(vecs);
|
|
Packit Service |
0af388 |
free_pathvec(vecs->pathvec, FREE_PATHS);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
vecs->pathvec = vector_alloc();
|
|
Packit Service |
0af388 |
assert_ptr_not_equal(vecs->pathvec, NULL);
|
|
Packit Service |
0af388 |
vecs->mpvec = vector_alloc();
|
|
Packit Service |
0af388 |
assert_ptr_not_equal(vecs->mpvec, NULL);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static void free_hwt(struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
char buf[PATH_MAX];
|
|
Packit Service |
0af388 |
int i;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
if (hwt->config_file != NULL)
|
|
Packit Service |
0af388 |
fclose(hwt->config_file);
|
|
Packit Service |
0af388 |
for (i = 0; i < N_CONF_FILES; i++) {
|
|
Packit Service |
0af388 |
if (hwt->conf_dir_file[i] != NULL)
|
|
Packit Service |
0af388 |
fclose(hwt->conf_dir_file[i]);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
if (hwt->tmpname != NULL) {
|
|
Packit Service |
0af388 |
make_config_file_path(buf, sizeof(buf), hwt, -1);
|
|
Packit Service |
0af388 |
unlink(buf);
|
|
Packit Service |
0af388 |
rmdir(hwt->tmpname);
|
|
Packit Service |
0af388 |
free(hwt->tmpname);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
if (hwt->dirname != NULL) {
|
|
Packit Service |
0af388 |
for (i = 0; i < N_CONF_FILES; i++) {
|
|
Packit Service |
0af388 |
make_config_file_path(buf, sizeof(buf), hwt, i);
|
|
Packit Service |
0af388 |
unlink(buf);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
rmdir(hwt->dirname);
|
|
Packit Service |
0af388 |
free(hwt->dirname);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
if (hwt->vecs != NULL) {
|
|
Packit Service |
0af388 |
if (hwt->vecs->mpvec != NULL)
|
|
Packit Service |
0af388 |
remove_maps(hwt->vecs);
|
|
Packit Service |
0af388 |
if (hwt->vecs->pathvec != NULL)
|
|
Packit Service |
0af388 |
free_pathvec(hwt->vecs->pathvec, FREE_PATHS);
|
|
Packit Service |
0af388 |
pthread_mutex_destroy(&hwt->vecs->lock.mutex);
|
|
Packit Service |
0af388 |
free(hwt->vecs);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
free(hwt);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct hwt_state *hwt;
|
|
Packit Service |
0af388 |
char buf[PATH_MAX];
|
|
Packit Service |
0af388 |
int i;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
*state = NULL;
|
|
Packit Service |
0af388 |
hwt = calloc(1, sizeof(*hwt));
|
|
Packit Service |
0af388 |
if (hwt == NULL)
|
|
Packit Service |
0af388 |
return -1;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
snprintf(buf, sizeof(buf), "%s", tmplate);
|
|
Packit Service |
0af388 |
if (mkdtemp(buf) == NULL) {
|
|
Packit Service |
0af388 |
condlog(0, "mkdtemp: %s", strerror(errno));
|
|
Packit Service |
0af388 |
goto err;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
hwt->tmpname = strdup(buf);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
snprintf(buf, sizeof(buf), "%s", tmplate);
|
|
Packit Service |
0af388 |
if (mkdtemp(buf) == NULL) {
|
|
Packit Service |
0af388 |
condlog(0, "mkdtemp (2): %s", strerror(errno));
|
|
Packit Service |
0af388 |
goto err;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
hwt->dirname = strdup(buf);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
make_config_file_path(buf, sizeof(buf), hwt, -1);
|
|
Packit Service |
0af388 |
hwt->config_file = fopen(buf, "w+");
|
|
Packit Service |
0af388 |
if (hwt->config_file == NULL)
|
|
Packit Service |
0af388 |
goto err;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
for (i = 0; i < N_CONF_FILES; i++) {
|
|
Packit Service |
0af388 |
make_config_file_path(buf, sizeof(buf), hwt, i);
|
|
Packit Service |
0af388 |
hwt->conf_dir_file[i] = fopen(buf, "w+");
|
|
Packit Service |
0af388 |
if (hwt->conf_dir_file[i] == NULL)
|
|
Packit Service |
0af388 |
goto err;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
hwt->vecs = calloc(1, sizeof(*hwt->vecs));
|
|
Packit Service |
0af388 |
if (hwt->vecs == NULL)
|
|
Packit Service |
0af388 |
goto err;
|
|
Packit Service |
0af388 |
pthread_mutex_init(&hwt->vecs->lock.mutex, NULL);
|
|
Packit Service |
0af388 |
hwt->vecs->pathvec = vector_alloc();
|
|
Packit Service |
0af388 |
hwt->vecs->mpvec = vector_alloc();
|
|
Packit Service |
0af388 |
if (hwt->vecs->pathvec == NULL || hwt->vecs->mpvec == NULL)
|
|
Packit Service |
0af388 |
goto err;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
*state = hwt;
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
err:
|
|
Packit Service |
0af388 |
free_hwt(hwt);
|
|
Packit Service |
0af388 |
return -1;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int teardown(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
if (state == NULL || *state == NULL)
|
|
Packit Service |
0af388 |
return -1;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
free_hwt(*state);
|
|
Packit Service |
0af388 |
*state = NULL;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Helpers for creating the config file(s)
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static void reset_config(FILE *ff)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
if (ff == NULL)
|
|
Packit Service |
0af388 |
return;
|
|
Packit Service |
0af388 |
rewind(ff);
|
|
Packit Service |
0af388 |
if (ftruncate(fileno(ff), 0) == -1)
|
|
Packit Service |
0af388 |
condlog(1, "ftruncate: %s", strerror(errno));
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static void reset_configs(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
int i;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
reset_config(hwt->config_file);
|
|
Packit Service |
0af388 |
for (i = 0; i < N_CONF_FILES; i++)
|
|
Packit Service |
0af388 |
reset_config(hwt->conf_dir_file[i]);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static void write_key_values(FILE *ff, int nkv, const struct key_value *kv)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
int i;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
for (i = 0; i < nkv; i++) {
|
|
Packit Service |
0af388 |
if (strchr(kv[i].value, ' ') == NULL &&
|
|
Packit Service |
0af388 |
strchr(kv[i].value, '\"') == NULL)
|
|
Packit Service |
0af388 |
fprintf(ff, "\t%s %s\n", kv[i].key, kv[i].value);
|
|
Packit Service |
0af388 |
else
|
|
Packit Service |
0af388 |
fprintf(ff, "\t%s \"%s\"\n", kv[i].key, kv[i].value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static void begin_section(FILE *ff, const char *section)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
fprintf(ff, "%s {\n", section);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static void end_section(FILE *ff)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
fprintf(ff, "}\n");
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static void write_section(FILE *ff, const char *section,
|
|
Packit Service |
0af388 |
int nkv, const struct key_value *kv)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
begin_section(ff, section);
|
|
Packit Service |
0af388 |
write_key_values(ff, nkv, kv);
|
|
Packit Service |
0af388 |
end_section(ff);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static void write_defaults(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
static const char bindings_name[] = "bindings";
|
|
Packit Service |
0af388 |
static struct key_value defaults[] = {
|
|
Packit Service |
0af388 |
{ "config_dir", NULL },
|
|
Packit Service |
0af388 |
{ "bindings_file", NULL },
|
|
Packit Service |
0af388 |
{ "multipath_dir", NULL },
|
|
Packit Service |
0af388 |
{ "detect_prio", "no" },
|
|
Packit Service |
0af388 |
{ "detect_checker", "no" },
|
|
Packit Service |
0af388 |
};
|
|
Packit Service |
0af388 |
char buf[sizeof(tmplate) + sizeof(bindings_name)];
|
|
Packit Service |
0af388 |
char dirbuf[PATH_MAX];
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
snprintf(buf, sizeof(buf), "%s/%s", hwt->tmpname, bindings_name);
|
|
Packit Service |
0af388 |
defaults[0].value = hwt->dirname;
|
|
Packit Service |
0af388 |
defaults[1].value = buf;
|
|
Packit Service |
0af388 |
assert_ptr_not_equal(getcwd(dirbuf, sizeof(dirbuf)), NULL);
|
|
Packit Service |
0af388 |
strncat(dirbuf, "/lib", sizeof(dirbuf) - 5);
|
|
Packit Service |
0af388 |
defaults[2].value = dirbuf;
|
|
Packit Service |
0af388 |
write_section(hwt->config_file, "defaults",
|
|
Packit Service |
0af388 |
ARRAY_SIZE(defaults), defaults);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static void begin_config(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
reset_configs(hwt);
|
|
Packit Service |
0af388 |
write_defaults(hwt);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static void begin_section_all(const struct hwt_state *hwt, const char *section)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
int i;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
begin_section(hwt->config_file, section);
|
|
Packit Service |
0af388 |
for (i = 0; i < N_CONF_FILES; i++)
|
|
Packit Service |
0af388 |
begin_section(hwt->conf_dir_file[i], section);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static void end_section_all(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
int i;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
end_section(hwt->config_file);
|
|
Packit Service |
0af388 |
for (i = 0; i < N_CONF_FILES; i++)
|
|
Packit Service |
0af388 |
end_section(hwt->conf_dir_file[i]);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static void finish_config(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
int i;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
fflush(hwt->config_file);
|
|
Packit Service |
0af388 |
for (i = 0; i < N_CONF_FILES; i++) {
|
|
Packit Service |
0af388 |
fflush(hwt->conf_dir_file[i]);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static void write_device(FILE *ff, int nkv, const struct key_value *kv)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
write_section(ff, "device", nkv, kv);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Some macros to avoid boilerplace code
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#define CHECK_STATE(state) ({ \
|
|
Packit Service |
0af388 |
assert_ptr_not_equal(state, NULL); \
|
|
Packit Service |
0af388 |
assert_ptr_not_equal(*(state), NULL); \
|
|
Packit Service |
0af388 |
*state; })
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#define WRITE_EMPTY_CONF(hwt) do { \
|
|
Packit Service |
0af388 |
begin_config(hwt); \
|
|
Packit Service |
0af388 |
finish_config(hwt); \
|
|
Packit Service |
0af388 |
} while (0)
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#define WRITE_ONE_DEVICE(hwt, kv) do { \
|
|
Packit Service |
0af388 |
begin_config(hwt); \
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "devices"); \
|
|
Packit Service |
0af388 |
write_device(hwt->config_file, ARRAY_SIZE(kv), kv); \
|
|
Packit Service |
0af388 |
end_section_all(hwt); \
|
|
Packit Service |
0af388 |
finish_config(hwt); \
|
|
Packit Service |
0af388 |
} while (0)
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#define WRITE_TWO_DEVICES(hwt, kv1, kv2) do { \
|
|
Packit Service |
0af388 |
begin_config(hwt); \
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "devices"); \
|
|
Packit Service |
0af388 |
write_device(hwt->config_file, ARRAY_SIZE(kv1), kv1); \
|
|
Packit Service |
0af388 |
write_device(hwt->config_file, ARRAY_SIZE(kv2), kv2); \
|
|
Packit Service |
0af388 |
end_section_all(hwt); \
|
|
Packit Service |
0af388 |
finish_config(hwt); \
|
|
Packit Service |
0af388 |
} while (0)
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#define WRITE_TWO_DEVICES_W_DIR(hwt, kv1, kv2) do { \
|
|
Packit Service |
0af388 |
begin_config(hwt); \
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "devices"); \
|
|
Packit Service |
0af388 |
write_device(hwt->config_file, ARRAY_SIZE(kv1), kv1); \
|
|
Packit Service |
0af388 |
write_device(hwt->conf_dir_file[0], \
|
|
Packit Service |
0af388 |
ARRAY_SIZE(kv2), kv2); \
|
|
Packit Service |
0af388 |
end_section_all(hwt); \
|
|
Packit Service |
0af388 |
finish_config(hwt); \
|
|
Packit Service |
0af388 |
} while (0)
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#define LOAD_CONFIG(hwt) ({ \
|
|
Packit Service |
0af388 |
char buf[PATH_MAX]; \
|
|
Packit Service |
0af388 |
struct config *__cf; \
|
|
Packit Service |
0af388 |
\
|
|
Packit Service |
0af388 |
make_config_file_path(buf, sizeof(buf), hwt, -1); \
|
|
Packit Service |
0af388 |
__cf = load_config(buf); \
|
|
Packit Service |
0af388 |
assert_ptr_not_equal(__cf, NULL); \
|
|
Packit Service |
0af388 |
assert_ptr_not_equal(__cf->hwtable, NULL); \
|
|
Packit Service |
0af388 |
__cf->verbosity = VERBOSITY; \
|
|
Packit Service |
0af388 |
memcpy(&__cf->version, dm_tgt_version, sizeof(__cf->version)); \
|
|
Packit Service |
0af388 |
__cf; })
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#define FREE_CONFIG(conf) do { \
|
|
Packit Service |
0af388 |
free_config(conf); \
|
|
Packit Service |
0af388 |
conf = NULL; \
|
|
Packit Service |
0af388 |
} while (0)
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static void replace_config(const struct hwt_state *hwt,
|
|
Packit Service |
0af388 |
const char *conf_str)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
FREE_CONFIG(_conf);
|
|
Packit Service |
0af388 |
reset_configs(hwt);
|
|
Packit Service |
0af388 |
fprintf(hwt->config_file, "%s", conf_str);
|
|
Packit Service |
0af388 |
fflush(hwt->config_file);
|
|
Packit Service |
0af388 |
_conf = LOAD_CONFIG(hwt);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#define TEST_PROP(prop, val) do { \
|
|
Packit Service |
0af388 |
if (val == NULL) \
|
|
Packit Service |
0af388 |
assert_ptr_equal(prop, NULL); \
|
|
Packit Service |
0af388 |
else { \
|
|
Packit Service |
0af388 |
assert_ptr_not_equal(prop, NULL); \
|
|
Packit Service |
0af388 |
assert_string_equal(prop, val); \
|
|
Packit Service |
0af388 |
} \
|
|
Packit Service |
0af388 |
} while (0)
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#if BROKEN
|
|
Packit Service |
0af388 |
#define TEST_PROP_BROKEN(name, prop, bad, good) do { \
|
|
Packit Service |
0af388 |
condlog(1, "%s: WARNING: Broken test for %s == \"%s\" on line %d, should be \"%s\"", \
|
|
Packit Service |
0af388 |
__func__, name, bad ? bad : "NULL", \
|
|
Packit Service |
0af388 |
__LINE__, good ? good : "NULL"); \
|
|
Packit Service |
0af388 |
TEST_PROP(prop, bad); \
|
|
Packit Service |
0af388 |
} while (0)
|
|
Packit Service |
0af388 |
#else
|
|
Packit Service |
0af388 |
#define TEST_PROP_BROKEN(name, prop, bad, good) TEST_PROP(prop, good)
|
|
Packit Service |
0af388 |
#endif
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Some predefined key/value pairs
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static const char _wwid[] = "wwid";
|
|
Packit Service |
0af388 |
static const char _vendor[] = "vendor";
|
|
Packit Service |
0af388 |
static const char _product[] = "product";
|
|
Packit Service |
0af388 |
static const char _prio[] = "prio";
|
|
Packit Service |
0af388 |
static const char _checker[] = "path_checker";
|
|
Packit Service |
0af388 |
static const char _getuid[] = "getuid_callout";
|
|
Packit Service |
0af388 |
static const char _uid_attr[] = "uid_attribute";
|
|
Packit Service |
0af388 |
static const char _bl_product[] = "product_blacklist";
|
|
Packit Service |
0af388 |
static const char _minio[] = "rr_min_io_rq";
|
|
Packit Service |
0af388 |
static const char _no_path_retry[] = "no_path_retry";
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* Device identifiers */
|
|
Packit Service |
0af388 |
static const struct key_value vnd_foo = { _vendor, "foo" };
|
|
Packit Service |
0af388 |
static const struct key_value prd_bar = { _product, "bar" };
|
|
Packit Service |
0af388 |
static const struct key_value prd_bam = { _product, "bam" };
|
|
Packit Service |
0af388 |
static const struct key_value prd_baq = { _product, "\"bar\"" };
|
|
Packit Service |
0af388 |
static const struct key_value prd_baqq = { _product, "\"\"bar\"\"" };
|
|
Packit Service |
0af388 |
static const struct key_value prd_barz = { _product, "barz" };
|
|
Packit Service |
0af388 |
static const struct key_value vnd_boo = { _vendor, "boo" };
|
|
Packit Service |
0af388 |
static const struct key_value prd_baz = { _product, "baz" };
|
|
Packit Service |
0af388 |
static const struct key_value wwid_test = { _wwid, default_wwid };
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* Regular expresssions */
|
|
Packit Service |
0af388 |
static const struct key_value vnd__oo = { _vendor, ".oo" };
|
|
Packit Service |
0af388 |
static const struct key_value vnd_t_oo = { _vendor, "^.oo" };
|
|
Packit Service |
0af388 |
static const struct key_value prd_ba_ = { _product, "ba." };
|
|
Packit Service |
0af388 |
static const struct key_value prd_ba_s = { _product, "(bar|baz|ba\\.)$" };
|
|
Packit Service |
0af388 |
/* Pathological cases, see below */
|
|
Packit Service |
0af388 |
static const struct key_value prd_barx = { _product, "ba[[rxy]" };
|
|
Packit Service |
0af388 |
static const struct key_value prd_bazy = { _product, "ba[zy]" };
|
|
Packit Service |
0af388 |
static const struct key_value prd_bazy1 = { _product, "ba(z|y)" };
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* Properties */
|
|
Packit Service |
0af388 |
static const struct key_value prio_emc = { _prio, "emc" };
|
|
Packit Service |
0af388 |
static const struct key_value prio_hds = { _prio, "hds" };
|
|
Packit Service |
0af388 |
static const struct key_value prio_rdac = { _prio, "rdac" };
|
|
Packit Service |
0af388 |
static const struct key_value chk_hp = { _checker, "hp_sw" };
|
|
Packit Service |
0af388 |
static const struct key_value gui_foo = { _getuid, "/tmp/foo" };
|
|
Packit Service |
0af388 |
static const struct key_value uid_baz = { _uid_attr, "BAZ_ATTR" };
|
|
Packit Service |
0af388 |
static const struct key_value bl_bar = { _bl_product, "bar" };
|
|
Packit Service |
0af388 |
static const struct key_value bl_baz = { _bl_product, "baz" };
|
|
Packit Service |
0af388 |
static const struct key_value bl_barx = { _bl_product, "ba[[rxy]" };
|
|
Packit Service |
0af388 |
static const struct key_value bl_bazy = { _bl_product, "ba[zy]" };
|
|
Packit Service |
0af388 |
static const struct key_value minio_99 = { _minio, "99" };
|
|
Packit Service |
0af388 |
static const struct key_value npr_37 = { _no_path_retry, "37" };
|
|
Packit Service |
0af388 |
static const struct key_value npr_queue = { _no_path_retry, "queue" };
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/***** BEGIN TESTS SECTION *****/
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Dump the configuration, subistitute the dumped configuration
|
|
Packit Service |
0af388 |
* for the current one, and verify that the result is identical.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void replicate_config(const struct hwt_state *hwt, bool local)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
char *cfg1, *cfg2;
|
|
Packit Service |
0af388 |
vector hwtable;
|
|
Packit Service |
0af388 |
struct config *conf;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
condlog(3, "--- %s: replicating %s configuration", __func__,
|
|
Packit Service |
0af388 |
local ? "local" : "full");
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
conf = get_multipath_config();
|
|
Packit Service |
0af388 |
if (!local)
|
|
Packit Service |
0af388 |
/* "full" configuration */
|
|
Packit Service |
0af388 |
cfg1 = snprint_config(conf, NULL, NULL, NULL);
|
|
Packit Service |
0af388 |
else {
|
|
Packit Service |
0af388 |
/* "local" configuration */
|
|
Packit Service |
0af388 |
hwtable = get_used_hwes(hwt->vecs->pathvec);
|
|
Packit Service |
0af388 |
cfg1 = snprint_config(conf, NULL, hwtable, hwt->vecs->mpvec);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
assert_non_null(cfg1);
|
|
Packit Service |
0af388 |
put_multipath_config(conf);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
replace_config(hwt, cfg1);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* The local configuration adds multipath entries, and may move device
|
|
Packit Service |
0af388 |
* entries for local devices to the end of the list. Identical config
|
|
Packit Service |
0af388 |
* strings therefore can't be expected in the "local" case.
|
|
Packit Service |
0af388 |
* That doesn't matter. The important thing is that, with the reloaded
|
|
Packit Service |
0af388 |
* configuration, the test case still passes.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
if (local) {
|
|
Packit Service |
0af388 |
free(cfg1);
|
|
Packit Service |
0af388 |
return;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
conf = get_multipath_config();
|
|
Packit Service |
0af388 |
cfg2 = snprint_config(conf, NULL, NULL, NULL);
|
|
Packit Service |
0af388 |
assert_non_null(cfg2);
|
|
Packit Service |
0af388 |
put_multipath_config(conf);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
// #define DBG_CONFIG 1
|
|
Packit Service |
0af388 |
#ifdef DBG_CONFIG
|
|
Packit Service |
0af388 |
#define DUMP_CFG_STR(x) do { \
|
|
Packit Service |
0af388 |
FILE *tmp = fopen("/tmp/hwtable-" #x ".txt", "w"); \
|
|
Packit Service |
0af388 |
fprintf(tmp, "%s", x); \
|
|
Packit Service |
0af388 |
fclose(tmp); \
|
|
Packit Service |
0af388 |
} while (0)
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
DUMP_CFG_STR(cfg1);
|
|
Packit Service |
0af388 |
DUMP_CFG_STR(cfg2);
|
|
Packit Service |
0af388 |
#endif
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
assert_int_equal(strlen(cfg2), strlen(cfg1));
|
|
Packit Service |
0af388 |
assert_string_equal(cfg2, cfg1);
|
|
Packit Service |
0af388 |
free(cfg1);
|
|
Packit Service |
0af388 |
free(cfg2);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Run hwt->test three times; once with the constructed configuration,
|
|
Packit Service |
0af388 |
* once after re-reading the full dumped configuration, and once with the
|
|
Packit Service |
0af388 |
* dumped local configuration.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: test passes every time.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_driver(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct hwt_state *hwt;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
_conf = LOAD_CONFIG(hwt);
|
|
Packit Service |
0af388 |
hwt->test(hwt);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
replicate_config(hwt, false);
|
|
Packit Service |
0af388 |
reset_vecs(hwt->vecs);
|
|
Packit Service |
0af388 |
hwt->test(hwt);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
replicate_config(hwt, true);
|
|
Packit Service |
0af388 |
reset_vecs(hwt->vecs);
|
|
Packit Service |
0af388 |
hwt->test(hwt);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
reset_vecs(hwt->vecs);
|
|
Packit Service |
0af388 |
FREE_CONFIG(_conf);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Sanity check for the test itself, because defaults may be changed
|
|
Packit Service |
0af388 |
* in libmultipath.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Our checking for match or non-match relies on the defaults being
|
|
Packit Service |
0af388 |
* different from what our device sections contain.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_sanity_globals(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
assert_string_not_equal(prio_emc.value, DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
assert_string_not_equal(prio_hds.value, DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
assert_string_not_equal(chk_hp.value, DEFAULT_CHECKER);
|
|
Packit Service |
0af388 |
assert_int_not_equal(MULTIBUS, DEFAULT_PGPOLICY);
|
|
Packit Service |
0af388 |
assert_int_not_equal(NO_PATH_RETRY_QUEUE, DEFAULT_NO_PATH_RETRY);
|
|
Packit Service |
0af388 |
assert_int_not_equal(atoi(minio_99.value), DEFAULT_MINIO_RQ);
|
|
Packit Service |
0af388 |
assert_int_not_equal(atoi(npr_37.value), DEFAULT_NO_PATH_RETRY);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Regression test for internal hwtable. NVME is an example of two entries
|
|
Packit Service |
0af388 |
* in the built-in hwtable, one if which matches a subset of the other.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_internal_nvme(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
struct multipath *mp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Generic NVMe: expect defaults for pgpolicy and no_path_retry
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
pp = mock_path("NVME", "NoName");
|
|
Packit Service |
0af388 |
mp = mock_multipath(pp);
|
|
Packit Service |
0af388 |
assert_ptr_not_equal(mp, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), NONE);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->uid_attribute, DEFAULT_NVME_UID_ATTRIBUTE);
|
|
Packit Service |
0af388 |
assert_int_equal(mp->pgpolicy, DEFAULT_PGPOLICY);
|
|
Packit Service |
0af388 |
assert_int_equal(mp->no_path_retry, DEFAULT_NO_PATH_RETRY);
|
|
Packit Service |
0af388 |
assert_int_equal(mp->retain_hwhandler, RETAIN_HWHANDLER_OFF);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* NetApp NVMe: expect special values for pgpolicy and no_path_retry
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
pp = mock_path_wwid("NVME", "NetApp ONTAP Controller",
|
|
Packit Service |
0af388 |
default_wwid_1);
|
|
Packit Service |
0af388 |
mp = mock_multipath(pp);
|
|
Packit Service |
0af388 |
assert_ptr_not_equal(mp, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), NONE);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->uid_attribute, "ID_WWN");
|
|
Packit Service |
0af388 |
assert_int_equal(mp->pgpolicy, MULTIBUS);
|
|
Packit Service |
0af388 |
assert_int_equal(mp->no_path_retry, NO_PATH_RETRY_QUEUE);
|
|
Packit Service |
0af388 |
assert_int_equal(mp->retain_hwhandler, RETAIN_HWHANDLER_OFF);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_internal_nvme(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_EMPTY_CONF(hwt);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_internal_nvme);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Device section with a simple entry qith double quotes ('foo:"bar"')
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_quoted_hwe(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:"bar" matches */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_baq.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_bar.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_quoted_hwe(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
const struct key_value kv[] = { vnd_foo, prd_baqq, prio_emc };
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_ONE_DEVICE(hwt, kv);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_quoted_hwe);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Device section with a single simple entry ("foo:bar")
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_string_hwe(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar matches */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_bar.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:baz doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* boo:bar doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_boo.value, prd_bar.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_string_hwe(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
const struct key_value kv[] = { vnd_foo, prd_bar, prio_emc };
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_ONE_DEVICE(hwt, kv);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_string_hwe);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Device section with a broken entry (no product)
|
|
Packit Service |
0af388 |
* It should be ignored.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_broken_hwe(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar doesn't match, as hwentry is ignored */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_bar.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* boo:bar doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_boo.value, prd_bar.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_broken_hwe(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
const struct key_value kv[] = { vnd_foo, prio_emc };
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_ONE_DEVICE(hwt, kv);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_broken_hwe);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Like test_broken_hwe, but in config_dir file.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static int setup_broken_hwe_dir(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
const struct key_value kv[] = { vnd_foo, prio_emc };
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
begin_config(hwt);
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "devices");
|
|
Packit Service |
0af388 |
write_device(hwt->conf_dir_file[0], ARRAY_SIZE(kv), kv);
|
|
Packit Service |
0af388 |
end_section_all(hwt);
|
|
Packit Service |
0af388 |
finish_config(hwt);
|
|
Packit Service |
0af388 |
hwt->test = test_broken_hwe;
|
|
Packit Service |
0af388 |
hwt->test_name = "test_broken_hwe_dir";
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Device section with a single regex entry ("^.foo:(bar|baz|ba\.)$")
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_regex_hwe(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar matches */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_bar.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:baz matches */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* boo:baz matches */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_boo.value, prd_bar.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:BAR doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, "BAR");
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* bboo:bar doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path("bboo", prd_bar.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_regex_hwe(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
const struct key_value kv[] = { vnd_t_oo, prd_ba_s, prio_emc };
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_ONE_DEVICE(hwt, kv);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_regex_hwe);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Two device entries, kv1 is a regex match ("^.foo:(bar|baz|ba\.)$"),
|
|
Packit Service |
0af388 |
* kv2 a string match (foo:bar) which matches a subset of the regex.
|
|
Packit Service |
0af388 |
* Both are added to the main config file.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: Devices matching both get properties from both, kv2 taking
|
|
Packit Service |
0af388 |
* precedence. Devices matching kv1 only just get props from kv1.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_regex_string_hwe(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:baz matches kv1 */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* boo:baz matches kv1 */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_boo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* .oo:ba. matches kv1 */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd__oo.value, prd_ba_.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* .foo:(bar|baz|ba\.) doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd__oo.value, prd_ba_s.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar matches kv2 and kv1 */
|
|
Packit Service |
0af388 |
pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_hds.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, gui_foo.value);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_regex_string_hwe(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_t_oo, prd_ba_s, prio_emc, chk_hp };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, gui_foo };
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_TWO_DEVICES(hwt, kv1, kv2);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_regex_string_hwe);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Two device entries, kv1 is a regex match ("^.foo:(bar|baz|ba\.)$"),
|
|
Packit Service |
0af388 |
* kv2 a string match (foo:bar) which matches a subset of the regex.
|
|
Packit Service |
0af388 |
* kv1 is added to the main config file, kv2 to a config_dir file.
|
|
Packit Service |
0af388 |
* This case is more important as you may think, because it's equivalent
|
|
Packit Service |
0af388 |
* to kv1 being in the built-in hwtable and kv2 in multipath.conf.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: Devices matching kv2 (and thus, both) get properties
|
|
Packit Service |
0af388 |
* from both, kv2 taking precedence.
|
|
Packit Service |
0af388 |
* Devices matching kv1 only just get props from kv1.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_regex_string_hwe_dir(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:baz matches kv1 */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* boo:baz matches kv1 */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_boo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* .oo:ba. matches kv1 */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd__oo.value, prd_ba_.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* .oo:(bar|baz|ba\.)$ doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd__oo.value, prd_ba_s.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar matches kv2 */
|
|
Packit Service |
0af388 |
pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
|
|
Packit Service |
0af388 |
/* Later match takes prio */
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_hds.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, gui_foo.value);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_regex_string_hwe_dir(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_t_oo, prd_ba_s, prio_emc, chk_hp };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, gui_foo };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_TWO_DEVICES_W_DIR(hwt, kv1, kv2);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_regex_string_hwe_dir);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Three device entries, kv1 is a regex match and kv2 and kv3 string
|
|
Packit Service |
0af388 |
* matches, where kv3 is a substring of kv2. All in different config
|
|
Packit Service |
0af388 |
* files.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: Devices matching kv3 get props from all, devices matching
|
|
Packit Service |
0af388 |
* kv2 from kv2 and kv1, and devices matching kv1 only just from kv1.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_regex_2_strings_hwe_dir(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:baz matches kv1 */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* boo:baz doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_boo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->uid_attribute, DEFAULT_UID_ATTRIBUTE);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar matches kv2 and kv1 */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_bar.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_hds.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->uid_attribute, uid_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:barz matches kv3 and kv2 and kv1 */
|
|
Packit Service |
0af388 |
pp = mock_path_flags(vnd_foo.value, prd_barz.value, USE_GETUID);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_rdac.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, gui_foo.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->uid_attribute, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_regex_2_strings_hwe_dir(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_foo, prd_ba_, prio_emc, chk_hp };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, uid_baz };
|
|
Packit Service |
0af388 |
const struct key_value kv3[] = { vnd_foo, prd_barz,
|
|
Packit Service |
0af388 |
prio_rdac, gui_foo };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
begin_config(hwt);
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "devices");
|
|
Packit Service |
0af388 |
write_device(hwt->config_file, ARRAY_SIZE(kv1), kv1);
|
|
Packit Service |
0af388 |
write_device(hwt->conf_dir_file[0], ARRAY_SIZE(kv2), kv2);
|
|
Packit Service |
0af388 |
write_device(hwt->conf_dir_file[1], ARRAY_SIZE(kv3), kv3);
|
|
Packit Service |
0af388 |
end_section_all(hwt);
|
|
Packit Service |
0af388 |
finish_config(hwt);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_regex_2_strings_hwe_dir);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Like test_regex_string_hwe_dir, but the order of kv1 and kv2 is exchanged.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: Devices matching kv1 (and thus, both) get properties
|
|
Packit Service |
0af388 |
* from both, kv1 taking precedence.
|
|
Packit Service |
0af388 |
* Devices matching kv1 only just get props from kv1.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_string_regex_hwe_dir(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar matches kv2 and kv1 */
|
|
Packit Service |
0af388 |
pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, gui_foo.value);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:baz matches kv1 */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* boo:baz matches kv1 */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_boo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* .oo:ba. matches kv1 */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd__oo.value, prd_ba_.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* .oo:(bar|baz|ba\.)$ doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd__oo.value, prd_ba_s.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_string_regex_hwe_dir(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_t_oo, prd_ba_s, prio_emc, chk_hp };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, gui_foo };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_TWO_DEVICES_W_DIR(hwt, kv2, kv1);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_string_regex_hwe_dir);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Two identical device entries kv1 and kv2, trival regex ("string").
|
|
Packit Service |
0af388 |
* Both are added to the main config file.
|
|
Packit Service |
0af388 |
* These entries are NOT merged.
|
|
Packit Service |
0af388 |
* This could happen in a large multipath.conf file.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: matching devices get props from both, kv2 taking precedence.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_2_ident_strings_hwe(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:baz doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar matches both */
|
|
Packit Service |
0af388 |
pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_hds.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, gui_foo.value);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_2_ident_strings_hwe(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_foo, prd_bar, prio_emc, chk_hp };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, gui_foo };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_TWO_DEVICES(hwt, kv1, kv2);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_2_ident_strings_hwe);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Two identical device entries kv1 and kv2, trival regex ("string").
|
|
Packit Service |
0af388 |
* Both are added to an extra config file.
|
|
Packit Service |
0af388 |
* This could happen in a large multipath.conf file.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: matching devices get props from both, kv2 taking precedence.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_2_ident_strings_both_dir(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:baz doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar matches both */
|
|
Packit Service |
0af388 |
pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_hds.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, gui_foo.value);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_2_ident_strings_both_dir(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_foo, prd_bar, prio_emc, chk_hp };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, gui_foo };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
begin_config(hwt);
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "devices");
|
|
Packit Service |
0af388 |
write_device(hwt->conf_dir_file[1], ARRAY_SIZE(kv1), kv1);
|
|
Packit Service |
0af388 |
write_device(hwt->conf_dir_file[1], ARRAY_SIZE(kv2), kv2);
|
|
Packit Service |
0af388 |
end_section_all(hwt);
|
|
Packit Service |
0af388 |
finish_config(hwt);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_2_ident_strings_both_dir);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Two identical device entries kv1 and kv2, trival regex ("string").
|
|
Packit Service |
0af388 |
* Both are added to an extra config file.
|
|
Packit Service |
0af388 |
* An empty entry kv0 with the same string exists in the main config file.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: matching devices get props from both, kv2 taking precedence.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_2_ident_strings_both_dir_w_prev(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:baz doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar matches both */
|
|
Packit Service |
0af388 |
pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_hds.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, gui_foo.value);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_2_ident_strings_both_dir_w_prev(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
const struct key_value kv0[] = { vnd_foo, prd_bar };
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_foo, prd_bar, prio_emc, chk_hp };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, gui_foo };
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
begin_config(hwt);
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "devices");
|
|
Packit Service |
0af388 |
write_device(hwt->config_file, ARRAY_SIZE(kv0), kv0);
|
|
Packit Service |
0af388 |
write_device(hwt->conf_dir_file[1], ARRAY_SIZE(kv1), kv1);
|
|
Packit Service |
0af388 |
write_device(hwt->conf_dir_file[1], ARRAY_SIZE(kv2), kv2);
|
|
Packit Service |
0af388 |
end_section_all(hwt);
|
|
Packit Service |
0af388 |
finish_config(hwt);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_2_ident_strings_both_dir_w_prev);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Two identical device entries kv1 and kv2, trival regex ("string").
|
|
Packit Service |
0af388 |
* kv1 is added to the main config file, kv2 to a config_dir file.
|
|
Packit Service |
0af388 |
* These entries are merged.
|
|
Packit Service |
0af388 |
* This case is more important as you may think, because it's equivalent
|
|
Packit Service |
0af388 |
* to kv1 being in the built-in hwtable and kv2 in multipath.conf.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: matching devices get props from both, kv2 taking precedence.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_2_ident_strings_hwe_dir(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:baz doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar matches both */
|
|
Packit Service |
0af388 |
pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_hds.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, gui_foo.value);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_2_ident_strings_hwe_dir(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_foo, prd_bar, prio_emc, chk_hp };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, gui_foo };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_TWO_DEVICES_W_DIR(hwt, kv1, kv2);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_2_ident_strings_hwe_dir);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Like test_2_ident_strings_hwe_dir, but this time the config_dir file
|
|
Packit Service |
0af388 |
* contains an additional, empty entry (kv0).
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: matching devices get props from kv1 and kv2, kv2 taking precedence.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_3_ident_strings_hwe_dir(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:baz doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar matches both */
|
|
Packit Service |
0af388 |
pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_hds.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, gui_foo.value);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_3_ident_strings_hwe_dir(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv0[] = { vnd_foo, prd_bar };
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_foo, prd_bar, prio_emc, chk_hp };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_foo, prd_bar, prio_hds, gui_foo };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
begin_config(hwt);
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "devices");
|
|
Packit Service |
0af388 |
write_device(hwt->config_file, ARRAY_SIZE(kv1), kv1);
|
|
Packit Service |
0af388 |
write_device(hwt->conf_dir_file[1], ARRAY_SIZE(kv0), kv0);
|
|
Packit Service |
0af388 |
write_device(hwt->conf_dir_file[1], ARRAY_SIZE(kv2), kv2);
|
|
Packit Service |
0af388 |
end_section_all(hwt);
|
|
Packit Service |
0af388 |
finish_config(hwt);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_3_ident_strings_hwe_dir);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Two identical device entries kv1 and kv2, non-trival regex that matches
|
|
Packit Service |
0af388 |
* itself (string ".oo" matches regex ".oo").
|
|
Packit Service |
0af388 |
* kv1 is added to the main config file, kv2 to a config_dir file.
|
|
Packit Service |
0af388 |
* This case is more important as you may think, because it's equivalent
|
|
Packit Service |
0af388 |
* to kv1 being in the built-in hwtable and kv2 in multipath.conf.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: matching devices get props from both, kv2 taking precedence.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_2_ident_self_matching_re_hwe_dir(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:baz doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar matches both */
|
|
Packit Service |
0af388 |
pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_hds.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, gui_foo.value);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_2_ident_self_matching_re_hwe_dir(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd__oo, prd_bar, prio_emc, chk_hp };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd__oo, prd_bar, prio_hds, gui_foo };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_TWO_DEVICES_W_DIR(hwt, kv1, kv2);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_2_ident_self_matching_re_hwe_dir);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Two identical device entries kv1 and kv2, non-trival regex that matches
|
|
Packit Service |
0af388 |
* itself (string ".oo" matches regex ".oo").
|
|
Packit Service |
0af388 |
* kv1 and kv2 are added to the main config file.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: matching devices get props from both, kv2 taking precedence.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_2_ident_self_matching_re_hwe(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:baz doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar matches */
|
|
Packit Service |
0af388 |
pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_hds.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, gui_foo.value);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_2_ident_self_matching_re_hwe(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd__oo, prd_bar, prio_emc, chk_hp };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd__oo, prd_bar, prio_hds, gui_foo };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_TWO_DEVICES(hwt, kv1, kv2);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_2_ident_self_matching_re_hwe);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Two identical device entries kv1 and kv2, non-trival regex that doesn't
|
|
Packit Service |
0af388 |
* match itself (string "^.oo" doesn't match regex "^.oo").
|
|
Packit Service |
0af388 |
* kv1 is added to the main config file, kv2 to a config_dir file.
|
|
Packit Service |
0af388 |
* This case is more important as you may think, see above.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: matching devices get props from both, kv2 taking precedence.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void
|
|
Packit Service |
0af388 |
test_2_ident_not_self_matching_re_hwe_dir(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:baz doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar matches both */
|
|
Packit Service |
0af388 |
pp = mock_path_flags(vnd_foo.value, prd_bar.value, USE_GETUID);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_hds.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, gui_foo.value);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_2_ident_not_self_matching_re_hwe_dir(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_t_oo, prd_bar, prio_emc, chk_hp };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_t_oo, prd_bar, prio_hds, gui_foo };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_TWO_DEVICES_W_DIR(hwt, kv1, kv2);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_2_ident_not_self_matching_re_hwe_dir);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Two different non-trivial regexes kv1, kv2. The 1st one matches the 2nd, but
|
|
Packit Service |
0af388 |
* it doesn't match all possible strings matching the second.
|
|
Packit Service |
0af388 |
* ("ba[zy]" matches regex "ba[[rxy]", but "baz" does not).
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: Devices matching both regexes get properties from both, kv2
|
|
Packit Service |
0af388 |
* taking precedence. Devices matching just one regex get properties from
|
|
Packit Service |
0af388 |
* that one regex only.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_2_matching_res_hwe_dir(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar matches k1 only */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_bar.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bay matches k1 and k2 */
|
|
Packit Service |
0af388 |
pp = mock_path_flags(vnd_foo.value, "bay", USE_GETUID);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_hds.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, gui_foo.value);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:baz matches k2 only. */
|
|
Packit Service |
0af388 |
pp = mock_path_flags(vnd_foo.value, prd_baz.value, USE_GETUID);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_hds.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, gui_foo.value);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_2_matching_res_hwe_dir(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_foo, prd_barx, prio_emc, chk_hp };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_foo, prd_bazy, prio_hds, gui_foo };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_TWO_DEVICES_W_DIR(hwt, kv1, kv2);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_2_matching_res_hwe_dir);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Two different non-trivial regexes which match the same set of strings.
|
|
Packit Service |
0af388 |
* But they don't match each other.
|
|
Packit Service |
0af388 |
* "baz" matches both regex "ba[zy]" and "ba(z|y)"
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: matching devices get properties from both, kv2 taking precedence.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_2_nonmatching_res_hwe_dir(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* foo:bar doesn't match */
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_bar.value);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), DEFAULT_PRIO);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), DEFAULT_CHECKER);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
pp = mock_path_flags(vnd_foo.value, prd_baz.value, USE_GETUID);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_hds.value);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->getuid, gui_foo.value);
|
|
Packit Service |
0af388 |
TEST_PROP(checker_name(&pp->checker), chk_hp.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_2_nonmatching_res_hwe_dir(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_foo, prd_bazy, prio_emc, chk_hp };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_foo, prd_bazy1,
|
|
Packit Service |
0af388 |
prio_hds, gui_foo };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_TWO_DEVICES_W_DIR(hwt, kv1, kv2);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_2_nonmatching_res_hwe_dir);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Simple blacklist test.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* NOTE: test failures in blacklisting tests will manifest as cmocka errors
|
|
Packit Service |
0af388 |
* "Could not get value to mock function XYZ", because pathinfo() takes
|
|
Packit Service |
0af388 |
* different code paths for blacklisted devices.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_blacklist(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
mock_path_flags(vnd_foo.value, prd_bar.value, BL_BY_DEVICE);
|
|
Packit Service |
0af388 |
mock_path(vnd_foo.value, prd_baz.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_blacklist(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_foo, prd_bar };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
begin_config(hwt);
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "blacklist");
|
|
Packit Service |
0af388 |
write_device(hwt->config_file, ARRAY_SIZE(kv1), kv1);
|
|
Packit Service |
0af388 |
end_section_all(hwt);
|
|
Packit Service |
0af388 |
finish_config(hwt);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_blacklist);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Simple blacklist test with regex and exception
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_blacklist_regex(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
mock_path(vnd_foo.value, prd_bar.value);
|
|
Packit Service |
0af388 |
mock_path_flags(vnd_foo.value, prd_baz.value, BL_BY_DEVICE);
|
|
Packit Service |
0af388 |
mock_path(vnd_foo.value, prd_bam.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_blacklist_regex(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_foo, prd_ba_s };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_foo, prd_bar };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
begin_config(hwt);
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "blacklist");
|
|
Packit Service |
0af388 |
write_device(hwt->config_file, ARRAY_SIZE(kv1), kv1);
|
|
Packit Service |
0af388 |
end_section_all(hwt);
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "blacklist_exceptions");
|
|
Packit Service |
0af388 |
write_device(hwt->conf_dir_file[0], ARRAY_SIZE(kv2), kv2);
|
|
Packit Service |
0af388 |
end_section_all(hwt);
|
|
Packit Service |
0af388 |
finish_config(hwt);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_blacklist_regex);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Simple blacklist test with regex and exception
|
|
Packit Service |
0af388 |
* config file order inverted wrt test_blacklist_regex
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static int setup_blacklist_regex_inv(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_foo, prd_ba_s };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_foo, prd_bar };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
begin_config(hwt);
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "blacklist");
|
|
Packit Service |
0af388 |
write_device(hwt->conf_dir_file[0], ARRAY_SIZE(kv1), kv1);
|
|
Packit Service |
0af388 |
end_section_all(hwt);
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "blacklist_exceptions");
|
|
Packit Service |
0af388 |
write_device(hwt->config_file, ARRAY_SIZE(kv2), kv2);
|
|
Packit Service |
0af388 |
end_section_all(hwt);
|
|
Packit Service |
0af388 |
finish_config(hwt);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_blacklist_regex);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Simple blacklist test with regex and exception
|
|
Packit Service |
0af388 |
* config file order inverted wrt test_blacklist_regex
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_blacklist_regex_matching(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
mock_path_flags(vnd_foo.value, prd_bar.value, BL_BY_DEVICE);
|
|
Packit Service |
0af388 |
mock_path_flags(vnd_foo.value, prd_baz.value, BL_BY_DEVICE);
|
|
Packit Service |
0af388 |
mock_path(vnd_foo.value, prd_bam.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_blacklist_regex_matching(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_foo, prd_barx };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_foo, prd_bazy };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
begin_config(hwt);
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "blacklist");
|
|
Packit Service |
0af388 |
write_device(hwt->config_file, ARRAY_SIZE(kv1), kv1);
|
|
Packit Service |
0af388 |
write_device(hwt->conf_dir_file[0], ARRAY_SIZE(kv2), kv2);
|
|
Packit Service |
0af388 |
end_section_all(hwt);
|
|
Packit Service |
0af388 |
finish_config(hwt);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_blacklist_regex_matching);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Test for blacklisting by WWID
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Note that default_wwid is a substring of default_wwid_1. Because
|
|
Packit Service |
0af388 |
* matching is done by regex, both paths are blacklisted.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_blacklist_wwid(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
mock_path_flags(vnd_foo.value, prd_bar.value, BL_BY_WWID);
|
|
Packit Service |
0af388 |
mock_path_wwid_flags(vnd_foo.value, prd_baz.value, default_wwid_1,
|
|
Packit Service |
0af388 |
BL_BY_WWID);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_blacklist_wwid(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv[] = { wwid_test };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
begin_config(hwt);
|
|
Packit Service |
0af388 |
write_section(hwt->config_file, "blacklist", ARRAY_SIZE(kv), kv);
|
|
Packit Service |
0af388 |
finish_config(hwt);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_blacklist_wwid);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Test for blacklisting by WWID
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Here the blacklist contains only default_wwid_1. Thus the path
|
|
Packit Service |
0af388 |
* with default_wwid is NOT blacklisted.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_blacklist_wwid_1(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
mock_path(vnd_foo.value, prd_bar.value);
|
|
Packit Service |
0af388 |
mock_path_wwid_flags(vnd_foo.value, prd_baz.value, default_wwid_1,
|
|
Packit Service |
0af388 |
BL_BY_WWID);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_blacklist_wwid_1(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv[] = { { _wwid, default_wwid_1 }, };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
begin_config(hwt);
|
|
Packit Service |
0af388 |
write_section(hwt->config_file, "blacklist", ARRAY_SIZE(kv), kv);
|
|
Packit Service |
0af388 |
finish_config(hwt);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_blacklist_wwid_1);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Test for product_blacklist. Two entries blacklisting each other.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: Both are blacklisted.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_product_blacklist(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
mock_path_flags(vnd_foo.value, prd_baz.value, BL_BY_DEVICE);
|
|
Packit Service |
0af388 |
mock_path_flags(vnd_foo.value, prd_bar.value, BL_BY_DEVICE);
|
|
Packit Service |
0af388 |
mock_path(vnd_foo.value, prd_bam.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_product_blacklist(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_foo, prd_bar, bl_baz };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_foo, prd_baz, bl_bar };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_TWO_DEVICES(hwt, kv1, kv2);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_product_blacklist);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Test for product_blacklist. The second regex "matches" the first.
|
|
Packit Service |
0af388 |
* This is a pathological example.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: "foo:bar", "foo:baz" are blacklisted.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_product_blacklist_matching(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
mock_path_flags(vnd_foo.value, prd_bar.value, BL_BY_DEVICE);
|
|
Packit Service |
0af388 |
mock_path_flags(vnd_foo.value, prd_baz.value, BL_BY_DEVICE);
|
|
Packit Service |
0af388 |
mock_path(vnd_foo.value, prd_bam.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_product_blacklist_matching(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { vnd_foo, prd_bar, bl_barx };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { vnd_foo, prd_baz, bl_bazy };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_TWO_DEVICES(hwt, kv1, kv2);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_product_blacklist_matching);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Basic test for multipath-based configuration.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: properties, including pp->prio, are taken from multipath
|
|
Packit Service |
0af388 |
* section.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_multipath_config(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
struct multipath *mp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_bar.value);
|
|
Packit Service |
0af388 |
mp = mock_multipath(pp);
|
|
Packit Service |
0af388 |
assert_ptr_not_equal(mp->mpe, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_rdac.value);
|
|
Packit Service |
0af388 |
assert_int_equal(mp->minio, atoi(minio_99.value));
|
|
Packit Service |
0af388 |
TEST_PROP(pp->uid_attribute, uid_baz.value);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/* test different wwid */
|
|
Packit Service |
0af388 |
pp = mock_path_wwid(vnd_foo.value, prd_bar.value, default_wwid_1);
|
|
Packit Service |
0af388 |
mp = mock_multipath(pp);
|
|
Packit Service |
0af388 |
// assert_ptr_equal(mp->mpe, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_emc.value);
|
|
Packit Service |
0af388 |
assert_int_equal(mp->minio, DEFAULT_MINIO_RQ);
|
|
Packit Service |
0af388 |
TEST_PROP(pp->uid_attribute, uid_baz.value);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_multipath_config(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
const struct key_value kvm[] = { wwid_test, prio_rdac, minio_99 };
|
|
Packit Service |
0af388 |
const struct key_value kvp[] = { vnd_foo, prd_bar, prio_emc, uid_baz };
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
begin_config(hwt);
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "devices");
|
|
Packit Service |
0af388 |
write_section(hwt->conf_dir_file[0], "device", ARRAY_SIZE(kvp), kvp);
|
|
Packit Service |
0af388 |
end_section_all(hwt);
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "multipaths");
|
|
Packit Service |
0af388 |
write_section(hwt->config_file, "multipath", ARRAY_SIZE(kvm), kvm);
|
|
Packit Service |
0af388 |
end_section_all(hwt);
|
|
Packit Service |
0af388 |
finish_config(hwt);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_multipath_config);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Basic test for multipath-based configuration. Two sections for the same wwid.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: properties are taken from both multipath sections, later taking
|
|
Packit Service |
0af388 |
* precedence
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_multipath_config_2(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
struct multipath *mp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_bar.value);
|
|
Packit Service |
0af388 |
mp = mock_multipath(pp);
|
|
Packit Service |
0af388 |
assert_ptr_not_equal(mp, NULL);
|
|
Packit Service |
0af388 |
assert_ptr_not_equal(mp->mpe, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_rdac.value);
|
|
Packit Service |
0af388 |
assert_int_equal(mp->minio, atoi(minio_99.value));
|
|
Packit Service |
0af388 |
assert_int_equal(mp->no_path_retry, atoi(npr_37.value));
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_multipath_config_2(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { wwid_test, prio_rdac, npr_queue };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { wwid_test, minio_99, npr_37 };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
begin_config(hwt);
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "multipaths");
|
|
Packit Service |
0af388 |
write_section(hwt->config_file, "multipath", ARRAY_SIZE(kv1), kv1);
|
|
Packit Service |
0af388 |
write_section(hwt->conf_dir_file[1], "multipath", ARRAY_SIZE(kv2), kv2);
|
|
Packit Service |
0af388 |
end_section_all(hwt);
|
|
Packit Service |
0af388 |
finish_config(hwt);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_multipath_config_2);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Same as test_multipath_config_2, both entries in the same config file.
|
|
Packit Service |
0af388 |
*
|
|
Packit Service |
0af388 |
* Expected: properties are taken from both multipath sections.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_multipath_config_3(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct path *pp;
|
|
Packit Service |
0af388 |
struct multipath *mp;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
pp = mock_path(vnd_foo.value, prd_bar.value);
|
|
Packit Service |
0af388 |
mp = mock_multipath(pp);
|
|
Packit Service |
0af388 |
assert_ptr_not_equal(mp, NULL);
|
|
Packit Service |
0af388 |
assert_ptr_not_equal(mp->mpe, NULL);
|
|
Packit Service |
0af388 |
TEST_PROP(prio_name(&pp->prio), prio_rdac.value);
|
|
Packit Service |
0af388 |
assert_int_equal(mp->minio, atoi(minio_99.value));
|
|
Packit Service |
0af388 |
assert_int_equal(mp->no_path_retry, atoi(npr_37.value));
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_multipath_config_3(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct key_value kv1[] = { wwid_test, prio_rdac, npr_queue };
|
|
Packit Service |
0af388 |
const struct key_value kv2[] = { wwid_test, minio_99, npr_37 };
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
begin_config(hwt);
|
|
Packit Service |
0af388 |
begin_section_all(hwt, "multipaths");
|
|
Packit Service |
0af388 |
write_section(hwt->config_file, "multipath", ARRAY_SIZE(kv1), kv1);
|
|
Packit Service |
0af388 |
write_section(hwt->config_file, "multipath", ARRAY_SIZE(kv2), kv2);
|
|
Packit Service |
0af388 |
end_section_all(hwt);
|
|
Packit Service |
0af388 |
finish_config(hwt);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_multipath_config_3);
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Test for device with "hidden" attribute
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
static void test_hidden(const struct hwt_state *hwt)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
mock_path_flags("NVME", "NoName", DEV_HIDDEN|BL_MASK);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int setup_hidden(void **state)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
struct hwt_state *hwt = CHECK_STATE(state);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
WRITE_EMPTY_CONF(hwt);
|
|
Packit Service |
0af388 |
SET_TEST_FUNC(hwt, test_hidden);
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
return 0;
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
/*
|
|
Packit Service |
0af388 |
* Create wrapper functions around test_driver() to avoid that cmocka
|
|
Packit Service |
0af388 |
* always uses the same test name. That makes it easier to read test results.
|
|
Packit Service |
0af388 |
*/
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#define define_test(x) \
|
|
Packit Service |
0af388 |
static void run_##x(void **state) \
|
|
Packit Service |
0af388 |
{ \
|
|
Packit Service |
0af388 |
return test_driver(state); \
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
define_test(string_hwe)
|
|
Packit Service |
0af388 |
define_test(broken_hwe)
|
|
Packit Service |
0af388 |
define_test(broken_hwe_dir)
|
|
Packit Service |
0af388 |
define_test(quoted_hwe)
|
|
Packit Service |
0af388 |
define_test(internal_nvme)
|
|
Packit Service |
0af388 |
define_test(regex_hwe)
|
|
Packit Service |
0af388 |
define_test(regex_string_hwe)
|
|
Packit Service |
0af388 |
define_test(regex_string_hwe_dir)
|
|
Packit Service |
0af388 |
define_test(regex_2_strings_hwe_dir)
|
|
Packit Service |
0af388 |
define_test(string_regex_hwe_dir)
|
|
Packit Service |
0af388 |
define_test(2_ident_strings_hwe)
|
|
Packit Service |
0af388 |
define_test(2_ident_strings_both_dir)
|
|
Packit Service |
0af388 |
define_test(2_ident_strings_both_dir_w_prev)
|
|
Packit Service |
0af388 |
define_test(2_ident_strings_hwe_dir)
|
|
Packit Service |
0af388 |
define_test(3_ident_strings_hwe_dir)
|
|
Packit Service |
0af388 |
define_test(2_ident_self_matching_re_hwe_dir)
|
|
Packit Service |
0af388 |
define_test(2_ident_self_matching_re_hwe)
|
|
Packit Service |
0af388 |
define_test(2_ident_not_self_matching_re_hwe_dir)
|
|
Packit Service |
0af388 |
define_test(2_matching_res_hwe_dir)
|
|
Packit Service |
0af388 |
define_test(2_nonmatching_res_hwe_dir)
|
|
Packit Service |
0af388 |
define_test(blacklist)
|
|
Packit Service |
0af388 |
define_test(blacklist_wwid)
|
|
Packit Service |
0af388 |
define_test(blacklist_wwid_1)
|
|
Packit Service |
0af388 |
define_test(blacklist_regex)
|
|
Packit Service |
0af388 |
define_test(blacklist_regex_inv)
|
|
Packit Service |
0af388 |
define_test(blacklist_regex_matching)
|
|
Packit Service |
0af388 |
define_test(product_blacklist)
|
|
Packit Service |
0af388 |
define_test(product_blacklist_matching)
|
|
Packit Service |
0af388 |
define_test(multipath_config)
|
|
Packit Service |
0af388 |
define_test(multipath_config_2)
|
|
Packit Service |
0af388 |
define_test(multipath_config_3)
|
|
Packit Service |
0af388 |
define_test(hidden)
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
#define test_entry(x) \
|
|
Packit Service |
0af388 |
cmocka_unit_test_setup(run_##x, setup_##x)
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
static int test_hwtable(void)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
const struct CMUnitTest tests[] = {
|
|
Packit Service |
0af388 |
cmocka_unit_test(test_sanity_globals),
|
|
Packit Service |
0af388 |
test_entry(internal_nvme),
|
|
Packit Service |
0af388 |
test_entry(string_hwe),
|
|
Packit Service |
0af388 |
test_entry(broken_hwe),
|
|
Packit Service |
0af388 |
test_entry(broken_hwe_dir),
|
|
Packit Service |
0af388 |
test_entry(quoted_hwe),
|
|
Packit Service |
0af388 |
test_entry(regex_hwe),
|
|
Packit Service |
0af388 |
test_entry(regex_string_hwe),
|
|
Packit Service |
0af388 |
test_entry(regex_string_hwe_dir),
|
|
Packit Service |
0af388 |
test_entry(regex_2_strings_hwe_dir),
|
|
Packit Service |
0af388 |
test_entry(string_regex_hwe_dir),
|
|
Packit Service |
0af388 |
test_entry(2_ident_strings_hwe),
|
|
Packit Service |
0af388 |
test_entry(2_ident_strings_both_dir),
|
|
Packit Service |
0af388 |
test_entry(2_ident_strings_both_dir_w_prev),
|
|
Packit Service |
0af388 |
test_entry(2_ident_strings_hwe_dir),
|
|
Packit Service |
0af388 |
test_entry(3_ident_strings_hwe_dir),
|
|
Packit Service |
0af388 |
test_entry(2_ident_self_matching_re_hwe_dir),
|
|
Packit Service |
0af388 |
test_entry(2_ident_self_matching_re_hwe),
|
|
Packit Service |
0af388 |
test_entry(2_ident_not_self_matching_re_hwe_dir),
|
|
Packit Service |
0af388 |
test_entry(2_matching_res_hwe_dir),
|
|
Packit Service |
0af388 |
test_entry(2_nonmatching_res_hwe_dir),
|
|
Packit Service |
0af388 |
test_entry(blacklist),
|
|
Packit Service |
0af388 |
test_entry(blacklist_wwid),
|
|
Packit Service |
0af388 |
test_entry(blacklist_wwid_1),
|
|
Packit Service |
0af388 |
test_entry(blacklist_regex),
|
|
Packit Service |
0af388 |
test_entry(blacklist_regex_inv),
|
|
Packit Service |
0af388 |
test_entry(blacklist_regex_matching),
|
|
Packit Service |
0af388 |
test_entry(product_blacklist),
|
|
Packit Service |
0af388 |
test_entry(product_blacklist_matching),
|
|
Packit Service |
0af388 |
test_entry(multipath_config),
|
|
Packit Service |
0af388 |
test_entry(multipath_config_2),
|
|
Packit Service |
0af388 |
test_entry(multipath_config_3),
|
|
Packit Service |
0af388 |
test_entry(hidden),
|
|
Packit Service |
0af388 |
};
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
return cmocka_run_group_tests(tests, setup, teardown);
|
|
Packit Service |
0af388 |
}
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
int main(void)
|
|
Packit Service |
0af388 |
{
|
|
Packit Service |
0af388 |
int ret = 0;
|
|
Packit Service |
0af388 |
|
|
Packit Service |
0af388 |
ret += test_hwtable();
|
|
Packit Service |
0af388 |
return ret;
|
|
Packit Service |
0af388 |
}
|