From: Martin Wilck <mwilck@xxxxxxxx> Some of these tests fail with the current code base. Signed-off-by: Martin Wilck <mwilck@xxxxxxxx> --- tests/Makefile | 3 +- tests/alias.c | 590 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 592 insertions(+), 1 deletion(-) create mode 100644 tests/alias.c diff --git a/tests/Makefile b/tests/Makefile index fb3c067b..0ce318c6 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -3,7 +3,7 @@ include ../Makefile.inc CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir) LIBDEPS += -L$(multipathdir) -lmultipath -lcmocka -TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy +TESTS := uevent parser util dmevents hwtable blacklist unaligned vpd pgpolicy alias .SILENT: $(TESTS:%=%.o) .PRECIOUS: $(TESTS:%=%-test) @@ -28,6 +28,7 @@ blacklist-test_OBJDEPS := ../libmultipath/blacklist.o blacklist-test_LIBDEPS := -ludev vpd-test_OBJDEPS := ../libmultipath/discovery.o vpd-test_LIBDEPS := -ludev -lpthread -ldl +alias-test_TESTDEPS := test-log.o lib/libchecktur.so: mkdir lib diff --git a/tests/alias.c b/tests/alias.c new file mode 100644 index 00000000..32fdc697 --- /dev/null +++ b/tests/alias.c @@ -0,0 +1,590 @@ +#include <stdint.h> +#include <setjmp.h> +#include <stdio.h> +#include <cmocka.h> +#include "util.h" +#include "alias.h" +#include "test-log.h" + +#include "globals.c" +#include "../libmultipath/alias.c" + +#if INT_MAX == 0x7fffffff +/* user_friendly_name for map #INT_MAX */ +#define MPATH_ID_INT_MAX "fxshrxw" +/* ... and one less */ +#define MPATH_ID_INT_MAX_m1 "fxshrxv" +/* ... and one more */ +#define MPATH_ID_INT_MAX_p1 "fxshrxx" +#endif + +void __wrap_rewind(FILE *stream) +{} + +char *__wrap_fgets(char *buf, int n, FILE *stream) +{ + char *val = mock_ptr_type(char *); + if (!val) + return NULL; + strlcpy(buf, val, n); + return buf; +} + +static void fd_mpatha(void **state) +{ + char buf[32]; + int rc; + + rc = format_devname(buf, 1, sizeof(buf), "FOO"); + assert_int_equal(rc, 4); + assert_string_equal(buf, "FOOa"); +} + +static void fd_mpathz(void **state) +{ + /* This also tests a "short" buffer, see fd_mpath_short1 */ + char buf[5]; + int rc; + + rc = format_devname(buf, 26, sizeof(buf), "FOO"); + assert_int_equal(rc, 4); + assert_string_equal(buf, "FOOz"); +} + +static void fd_mpathaa(void **state) +{ + char buf[32]; + int rc; + + rc = format_devname(buf, 26 + 1, sizeof(buf), "FOO"); + assert_int_equal(rc, 5); + assert_string_equal(buf, "FOOaa"); +} + +static void fd_mpathzz(void **state) +{ + char buf[32]; + int rc; + + rc = format_devname(buf, 26*26 + 26, sizeof(buf), "FOO"); + assert_int_equal(rc, 5); + assert_string_equal(buf, "FOOzz"); +} + +static void fd_mpathaaa(void **state) +{ + char buf[32]; + int rc; + + rc = format_devname(buf, 26*26 + 27, sizeof(buf), "FOO"); + assert_int_equal(rc, 6); + assert_string_equal(buf, "FOOaaa"); +} + +static void fd_mpathzzz(void **state) +{ + char buf[32]; + int rc; + + rc = format_devname(buf, 26*26*26 + 26*26 + 26, sizeof(buf), "FOO"); + assert_int_equal(rc, 6); + assert_string_equal(buf, "FOOzzz"); +} + +static void fd_mpathaaaa(void **state) +{ + char buf[32]; + int rc; + + rc = format_devname(buf, 26*26*26 + 26*26 + 27, sizeof(buf), "FOO"); + assert_int_equal(rc, 7); + assert_string_equal(buf, "FOOaaaa"); +} + +static void fd_mpathzzzz(void **state) +{ + char buf[32]; + int rc; + + rc = format_devname(buf, 26*26*26*26 + 26*26*26 + 26*26 + 26, + sizeof(buf), "FOO"); + assert_int_equal(rc, 7); + assert_string_equal(buf, "FOOzzzz"); +} + +#ifdef MPATH_ID_INT_MAX +static void fd_mpath_max(void **state) +{ + char buf[32]; + int rc; + + rc = format_devname(buf, INT_MAX, sizeof(buf), ""); + assert_int_equal(rc, strlen(MPATH_ID_INT_MAX)); + assert_string_equal(buf, MPATH_ID_INT_MAX); +} +#endif + +static void fd_mpath_max1(void **state) +{ + char buf[32]; + int rc; + + rc = format_devname(buf, INT_MIN, sizeof(buf), ""); + assert_int_equal(rc, -1); +} + +static void fd_mpath_short(void **state) +{ + char buf[4]; + int rc; + + rc = format_devname(buf, 1, sizeof(buf), "FOO"); + assert_int_equal(rc, -1); +} + +static void fd_mpath_short1(void **state) +{ + char buf[5]; + int rc; + + rc = format_devname(buf, 27, sizeof(buf), "FOO"); + assert_int_equal(rc, -1); +} + +static int test_format_devname(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(fd_mpatha), + cmocka_unit_test(fd_mpathz), + cmocka_unit_test(fd_mpathaa), + cmocka_unit_test(fd_mpathzz), + cmocka_unit_test(fd_mpathaaa), + cmocka_unit_test(fd_mpathzzz), + cmocka_unit_test(fd_mpathaaaa), + cmocka_unit_test(fd_mpathzzzz), +#ifdef MPATH_ID_INT_MAX + cmocka_unit_test(fd_mpath_max), +#endif + cmocka_unit_test(fd_mpath_max1), + cmocka_unit_test(fd_mpath_short), + cmocka_unit_test(fd_mpath_short1), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} + +static void sd_mpatha(void **state) +{ + int rc = scan_devname("MPATHa", "MPATH"); + + assert_int_equal(rc, 1); +} + +/* + * Text after whitespace is ignored. But an overlong input + * errors out, even if it's just whitespace. + * It's kind of strange that scan_devname() treats whitespace + * like this. But I'm not sure if some corner case depends + * on this behavior. + */ +static void sd_mpatha_spc(void **state) +{ + int rc = scan_devname("MPATHa 00", "MPATH"); + + assert_int_equal(rc, 1); +} + +static void sd_mpatha_tab(void **state) +{ + int rc = scan_devname("MPATHa\t00", "MPATH"); + + assert_int_equal(rc, 1); +} + +static void sd_overlong(void **state) +{ + int rc = scan_devname("MPATHa ", "MPATH"); + + assert_int_equal(rc, -1); +} + +static void sd_overlong1(void **state) +{ + int rc = scan_devname("MPATHabcdefgh", "MPATH"); + + assert_int_equal(rc, -1); +} + +static void sd_noprefix(void **state) +{ + int rc = scan_devname("MPATHa", NULL); + + assert_int_equal(rc, -1); +} + +static void sd_nomatchprefix(void **state) +{ + int rc = scan_devname("MPATHa", "mpath"); + + assert_int_equal(rc, -1); +} + +static void sd_eq_prefix(void **state) +{ + int rc = scan_devname("MPATH", "MPATH"); + + assert_int_equal(rc, -1); +} + +static void sd_bad_1(void **state) +{ + int rc = scan_devname("MPATH0", "MPATH"); + + assert_int_equal(rc, -1); +} + +static void sd_bad_2(void **state) +{ + int rc = scan_devname("MPATHa0c", "MPATH"); + + assert_int_equal(rc, -1); +} + +#ifdef MPATH_ID_INT_MAX +static void sd_max(void **state) +{ + int rc = scan_devname("MPATH" MPATH_ID_INT_MAX, "MPATH"); + + assert_int_equal(rc, INT_MAX); +} + +static void sd_max_p1(void **state) +{ + int rc = scan_devname("MPATH" MPATH_ID_INT_MAX_p1, "MPATH"); + + assert_int_equal(rc, -1); +} +#endif + +static int test_scan_devname(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(sd_mpatha), + cmocka_unit_test(sd_mpatha_spc), + cmocka_unit_test(sd_mpatha_tab), + cmocka_unit_test(sd_overlong), + cmocka_unit_test(sd_overlong1), + cmocka_unit_test(sd_noprefix), + cmocka_unit_test(sd_nomatchprefix), + cmocka_unit_test(sd_eq_prefix), + cmocka_unit_test(sd_bad_1), + cmocka_unit_test(sd_bad_2), +#ifdef MPATH_ID_INT_MAX + cmocka_unit_test(sd_max), + cmocka_unit_test(sd_max_p1), +#endif + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} + +static void lb_empty(void **state) +{ + int rc; + char *alias; + + will_return(__wrap_fgets, NULL); + expect_condlog(3, "No matching wwid [WWID0] in bindings file.\n"); + rc = lookup_binding(NULL, "WWID0", &alias, NULL); + assert_int_equal(rc, 1); + assert_ptr_equal(alias, NULL); +} + +static void lb_match_a(void **state) +{ + int rc; + char *alias; + + will_return(__wrap_fgets, "MPATHa WWID0\n"); + expect_condlog(3, "Found matching wwid [WWID0] in bindings file." + " Setting alias to MPATHa\n"); + rc = lookup_binding(NULL, "WWID0", &alias, "MPATH"); + assert_int_equal(rc, 0); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHa"); + free(alias); +} + +static void lb_nomatch_a(void **state) +{ + int rc; + char *alias; + + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "No matching wwid [WWID1] in bindings file.\n"); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH"); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +} + +static void lb_match_c(void **state) +{ + int rc; + char *alias; + + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHc WWID1\n"); + expect_condlog(3, "Found matching wwid [WWID1] in bindings file." + " Setting alias to MPATHc\n"); + rc = lookup_binding(NULL, "WWID1", &alias, "MPATH"); + assert_int_equal(rc, 0); + assert_ptr_not_equal(alias, NULL); + assert_string_equal(alias, "MPATHc"); + free(alias); +} + +static void lb_nomatch_a_c(void **state) +{ + int rc; + char *alias; + + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHc WWID1\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +} + +static void lb_nomatch_c_a(void **state) +{ + int rc; + char *alias; + + will_return(__wrap_fgets, "MPATHc WWID1\n"); + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); + assert_int_equal(rc, 2); + assert_ptr_equal(alias, NULL); +} + +static void lb_nomatch_a_b(void **state) +{ + int rc; + char *alias; + + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHz WWID26\n"); + will_return(__wrap_fgets, "MPATHb WWID1\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); + assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); +} + +static void lb_nomatch_a_b_bad(void **state) +{ + int rc; + char *alias; + + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHz WWID26\n"); + will_return(__wrap_fgets, "MPATHb\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "Ignoring malformed line 3 in bindings file\n"); + expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); + assert_int_equal(rc, 3); + assert_ptr_equal(alias, NULL); +} + +static void lb_nomatch_b_a(void **state) +{ + int rc; + char *alias; + + will_return(__wrap_fgets, "MPATHb WWID1\n"); + will_return(__wrap_fgets, "MPATHz WWID26\n"); + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); + assert_int_equal(rc, 27); + assert_ptr_equal(alias, NULL); +} + +#ifdef MPATH_ID_INT_MAX +static void lb_nomatch_int_max(void **state) +{ + int rc; + char *alias; + + will_return(__wrap_fgets, "MPATHb WWID1\n"); + will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX " WWIDMAX\n"); + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(0, "no more available user_friendly_names\n"); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); + assert_int_equal(rc, -1); + assert_ptr_equal(alias, NULL); +} + +static void lb_nomatch_int_max_m1(void **state) +{ + int rc; + char *alias; + + will_return(__wrap_fgets, "MPATHb WWID1\n"); + will_return(__wrap_fgets, "MPATH" MPATH_ID_INT_MAX_m1 " WWIDMAX\n"); + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "No matching wwid [WWID2] in bindings file.\n"); + rc = lookup_binding(NULL, "WWID2", &alias, "MPATH"); + assert_int_equal(rc, INT_MAX); + assert_ptr_equal(alias, NULL); +} +#endif + +static int test_lookup_binding(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(lb_empty), + cmocka_unit_test(lb_match_a), + cmocka_unit_test(lb_nomatch_a), + cmocka_unit_test(lb_match_c), + cmocka_unit_test(lb_nomatch_a_c), + cmocka_unit_test(lb_nomatch_c_a), + cmocka_unit_test(lb_nomatch_a_b), + cmocka_unit_test(lb_nomatch_a_b_bad), + cmocka_unit_test(lb_nomatch_b_a), +#ifdef MPATH_ID_INT_MAX + cmocka_unit_test(lb_nomatch_int_max), + cmocka_unit_test(lb_nomatch_int_max_m1), +#endif + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} + +static void rl_empty(void **state) +{ + int rc; + char buf[WWID_SIZE]; + + buf[0] = '\0'; + will_return(__wrap_fgets, NULL); + expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n"); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); + assert_string_equal(buf, ""); +} + +static void rl_match_a(void **state) +{ + int rc; + char buf[WWID_SIZE]; + + buf[0] = '\0'; + will_return(__wrap_fgets, "MPATHa WWID0\n"); + expect_condlog(3, "Found matching alias [MPATHa] in bindings file.\n" + "Setting wwid to WWID0\n"); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, 0); + assert_string_equal(buf, "WWID0"); +} + +static void rl_nomatch_a(void **state) +{ + int rc; + char buf[WWID_SIZE]; + + buf[0] = '\0'; + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "No matching alias [MPATHb] in bindings file.\n"); + rc = rlookup_binding(NULL, buf, "MPATHb"); + assert_int_equal(rc, -1); + assert_string_equal(buf, ""); +} + +static void rl_malformed_a(void **state) +{ + int rc; + char buf[WWID_SIZE]; + + buf[0] = '\0'; + will_return(__wrap_fgets, "MPATHa \n"); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "Ignoring malformed line 1 in bindings file\n"); + expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n"); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); + assert_string_equal(buf, ""); +} + +static void rl_overlong_a(void **state) +{ + int rc; + char buf[WWID_SIZE]; + char line[WWID_SIZE + 10]; + + snprintf(line, sizeof(line), "MPATHa "); + memset(line + strlen(line), 'W', sizeof(line) - 2 - strlen(line)); + snprintf(line + sizeof(line) - 2, 2, "\n"); + + buf[0] = '\0'; + will_return(__wrap_fgets, line); + will_return(__wrap_fgets, NULL); + expect_condlog(3, "Ignoring too large wwid at 1 in bindings file\n"); + expect_condlog(3, "No matching alias [MPATHa] in bindings file.\n"); + rc = rlookup_binding(NULL, buf, "MPATHa"); + assert_int_equal(rc, -1); + assert_string_equal(buf, ""); +} + +static void rl_match_b(void **state) +{ + int rc; + char buf[WWID_SIZE]; + + buf[0] = '\0'; + will_return(__wrap_fgets, "MPATHa WWID0\n"); + will_return(__wrap_fgets, "MPATHz WWID26\n"); + will_return(__wrap_fgets, "MPATHb WWID2\n"); + expect_condlog(3, "Found matching alias [MPATHb] in bindings file.\n" + "Setting wwid to WWID2\n"); + rc = rlookup_binding(NULL, buf, "MPATHb"); + assert_int_equal(rc, 0); + assert_string_equal(buf, "WWID2"); +} + +static int test_rlookup_binding(void) +{ + const struct CMUnitTest tests[] = { + cmocka_unit_test(rl_empty), + cmocka_unit_test(rl_match_a), + cmocka_unit_test(rl_nomatch_a), + cmocka_unit_test(rl_malformed_a), + cmocka_unit_test(rl_overlong_a), + cmocka_unit_test(rl_match_b), + }; + + return cmocka_run_group_tests(tests, NULL, NULL); +} + +int main(void) +{ + int ret = 0; + + ret += test_format_devname(); + ret += test_scan_devname(); + ret += test_lookup_binding(); + ret += test_rlookup_binding(); + + return ret; +} -- 2.23.0 -- dm-devel mailing list dm-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/dm-devel