Add 0067-kpartx-hold-device-open-until-partitions-have-been-c.patch * Fixes bz #2141860 Add 0068-libmultipath-cleanup-remove_feature.patch Add 0069-libmultipath-cleanup-add_feature.patch Add 0070-multipath-tests-tests-for-adding-and-removing-featur.patch Add 0071-libmultipath-fix-queue_mode-feature-handling.patch Add 0072-multipath-tests-tests-for-reconcile_features_with_qu.patch Add 0073-libmultipath-prepare-proto_id-for-use-by-non-scsi-de.patch Add 0074-libmultipath-get-nvme-path-transport-protocol.patch Add 0075-libmultipath-enforce-queue_mode-bio-for-nmve-tcp-pat.patch * Fixes bz #2033080 Resolves: bz #2033080, #2141860
		
			
				
	
	
		
			292 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			292 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
 | |
| From: Benjamin Marzinski <bmarzins@redhat.com>
 | |
| Date: Fri, 7 Oct 2022 12:35:41 -0500
 | |
| Subject: [PATCH] multipath tests: tests for reconcile_features_with_queue_mode
 | |
| 
 | |
| Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
 | |
| Reviewed-by: Martin Wilck <mwilck@suse.com>
 | |
| ---
 | |
|  tests/Makefile   |   2 +
 | |
|  tests/features.c | 232 ++++++++++++++++++++++++++++++++++++++++++++++-
 | |
|  2 files changed, 233 insertions(+), 1 deletion(-)
 | |
| 
 | |
| diff --git a/tests/Makefile b/tests/Makefile
 | |
| index 972a5e04..27e3ffa9 100644
 | |
| --- a/tests/Makefile
 | |
| +++ b/tests/Makefile
 | |
| @@ -33,6 +33,7 @@ ifneq ($(DIO_TEST_DEV),)
 | |
|  directio-test_FLAGS := -DDIO_TEST_DEV=\"$(DIO_TEST_DEV)\"
 | |
|  endif
 | |
|  mpathvalid-test_FLAGS := -I$(mpathvaliddir)
 | |
| +features-test_FLAGS := -I$(multipathdir)/nvme
 | |
|  
 | |
|  # test-specific linker flags
 | |
|  # XYZ-test_TESTDEPS: test libraries containing __wrap_xyz functions
 | |
| @@ -64,6 +65,7 @@ ifneq ($(DIO_TEST_DEV),)
 | |
|  directio-test_LIBDEPS := -laio
 | |
|  endif
 | |
|  strbuf-test_OBJDEPS := ../libmultipath/strbuf.o
 | |
| +features-test_LIBDEPS := -ludev -lpthread
 | |
|  
 | |
|  %.o: %.c
 | |
|  	$(CC) $(CFLAGS) $($*-test_FLAGS) -c -o $@ $<
 | |
| diff --git a/tests/features.c b/tests/features.c
 | |
| index 4d8f0860..31f978fd 100644
 | |
| --- a/tests/features.c
 | |
| +++ b/tests/features.c
 | |
| @@ -1,9 +1,10 @@
 | |
| +#define _GNU_SOURCE
 | |
|  #include <stddef.h>
 | |
|  #include <stdarg.h>
 | |
|  #include <setjmp.h>
 | |
|  #include <cmocka.h>
 | |
|  
 | |
| -#include "structs.h"
 | |
| +#include "../libmultipath/propsel.c"
 | |
|  #include "globals.c"
 | |
|  
 | |
|  static void test_af_null_features_ptr(void **state)
 | |
| @@ -307,6 +308,234 @@ static int test_remove_features(void)
 | |
|  	return cmocka_run_group_tests(tests, NULL, NULL);
 | |
|  }
 | |
|  
 | |
| +static void test_cf_null_features(void **state)
 | |
| +{
 | |
| +	struct multipath mp = {
 | |
| +			.alias = "test",
 | |
| +	};
 | |
| +	reconcile_features_with_queue_mode(&mp);
 | |
| +	assert_null(mp.features);
 | |
| +}
 | |
| +
 | |
| +static void cf_helper(const char *features_start, const char *features_end,
 | |
| +		      int queue_mode_start, int queue_mode_end)
 | |
| +{
 | |
| +	struct multipath mp = {
 | |
| +			.alias = "test",
 | |
| +			.features = strdup(features_start),
 | |
| +			.queue_mode = queue_mode_start,
 | |
| +	};
 | |
| +	char *orig = mp.features;
 | |
| +
 | |
| +	assert_non_null(orig);
 | |
| +	reconcile_features_with_queue_mode(&mp);
 | |
| +	if (!features_end)
 | |
| +		assert_ptr_equal(orig, mp.features);
 | |
| +	else
 | |
| +		assert_string_equal(mp.features, features_end);
 | |
| +	free(mp.features);
 | |
| +	assert_int_equal(mp.queue_mode, queue_mode_end);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_unset_unset1(void **state)
 | |
| +{
 | |
| +	cf_helper("0", NULL, QUEUE_MODE_UNDEF, QUEUE_MODE_UNDEF);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_unset_unset2(void **state)
 | |
| +{
 | |
| +	cf_helper("1 queue_mode", NULL, QUEUE_MODE_UNDEF, QUEUE_MODE_UNDEF);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_unset_unset3(void **state)
 | |
| +{
 | |
| +	cf_helper("queue_mode", NULL, QUEUE_MODE_UNDEF, QUEUE_MODE_UNDEF);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_unset_unset4(void **state)
 | |
| +{
 | |
| +	cf_helper("2 queue_model bio", NULL, QUEUE_MODE_UNDEF,
 | |
| +		  QUEUE_MODE_UNDEF);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_unset_unset5(void **state)
 | |
| +{
 | |
| +	cf_helper("1 queue_if_no_path", NULL, QUEUE_MODE_UNDEF,
 | |
| +		  QUEUE_MODE_UNDEF);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_invalid_unset1(void **state)
 | |
| +{
 | |
| +	cf_helper("2 queue_mode biop", "0", QUEUE_MODE_UNDEF, QUEUE_MODE_UNDEF);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_invalid_unset2(void **state)
 | |
| +{
 | |
| +	cf_helper("3 queue_mode rqs queue_if_no_path", "1 queue_if_no_path",
 | |
| +		  QUEUE_MODE_UNDEF, QUEUE_MODE_UNDEF);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_rq_unset1(void **state)
 | |
| +{
 | |
| +	cf_helper("2 queue_mode rq", NULL, QUEUE_MODE_UNDEF, QUEUE_MODE_RQ);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_rq_unset2(void **state)
 | |
| +{
 | |
| +	cf_helper("2 queue_mode mq", NULL, QUEUE_MODE_UNDEF, QUEUE_MODE_RQ);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_bio_unset(void **state)
 | |
| +{
 | |
| +	cf_helper("2 queue_mode bio", NULL, QUEUE_MODE_UNDEF, QUEUE_MODE_BIO);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_unset_bio1(void **state)
 | |
| +{
 | |
| +	cf_helper("1 queue_if_no_path", "3 queue_if_no_path queue_mode bio",
 | |
| +		  QUEUE_MODE_BIO, QUEUE_MODE_BIO);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_unset_bio2(void **state)
 | |
| +{
 | |
| +	cf_helper("0", "2 queue_mode bio", QUEUE_MODE_BIO, QUEUE_MODE_BIO);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_unset_bio3(void **state)
 | |
| +{
 | |
| +	cf_helper("2 pg_init_retries 50", "4 pg_init_retries 50 queue_mode bio",
 | |
| +		  QUEUE_MODE_BIO, QUEUE_MODE_BIO);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_invalid_bio1(void **state)
 | |
| +{
 | |
| +	cf_helper("2 queue_mode bad", "2 queue_mode bio",
 | |
| +		  QUEUE_MODE_BIO, QUEUE_MODE_BIO);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_invalid_bio2(void **state)
 | |
| +{
 | |
| +	cf_helper("3 queue_if_no_path queue_mode\tbad", "3 queue_if_no_path queue_mode bio",
 | |
| +		  QUEUE_MODE_BIO, QUEUE_MODE_BIO);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_bio_bio1(void **state)
 | |
| +{
 | |
| +	cf_helper("2 queue_mode bio", NULL, QUEUE_MODE_BIO, QUEUE_MODE_BIO);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_bio_bio2(void **state)
 | |
| +{
 | |
| +	cf_helper("3 queue_if_no_path queue_mode bio", NULL, QUEUE_MODE_BIO, QUEUE_MODE_BIO);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_bio_bio3(void **state)
 | |
| +{
 | |
| +	cf_helper("3 queue_mode\nbio queue_if_no_path", NULL, QUEUE_MODE_BIO, QUEUE_MODE_BIO);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_bio_rq1(void **state)
 | |
| +{
 | |
| +	cf_helper("2\nqueue_mode\tbio", "0", QUEUE_MODE_RQ, QUEUE_MODE_RQ);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_bio_rq2(void **state)
 | |
| +{
 | |
| +	cf_helper("3 queue_if_no_path\nqueue_mode bio", "1 queue_if_no_path",
 | |
| +		  QUEUE_MODE_RQ, QUEUE_MODE_RQ);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_bio_rq3(void **state)
 | |
| +{
 | |
| +	cf_helper("4 queue_mode bio pg_init_retries 20", "2 pg_init_retries 20",
 | |
| +		  QUEUE_MODE_RQ, QUEUE_MODE_RQ);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_unset_rq1(void **state)
 | |
| +{
 | |
| +	cf_helper("0", NULL, QUEUE_MODE_RQ, QUEUE_MODE_RQ);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_unset_rq2(void **state)
 | |
| +{
 | |
| +	cf_helper("2 pg_init_retries 15", NULL, QUEUE_MODE_RQ, QUEUE_MODE_RQ);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_invalid_rq1(void **state)
 | |
| +{
 | |
| +	cf_helper("2 queue_mode bionic", "0", QUEUE_MODE_RQ, QUEUE_MODE_RQ);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_invalid_rq2(void **state)
 | |
| +{
 | |
| +	cf_helper("3 queue_mode b\nqueue_if_no_path", "1 queue_if_no_path",
 | |
| +		  QUEUE_MODE_RQ, QUEUE_MODE_RQ);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_rq_rq1(void **state)
 | |
| +{
 | |
| +	cf_helper("2 queue_mode rq", NULL, QUEUE_MODE_RQ, QUEUE_MODE_RQ);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_rq_rq2(void **state)
 | |
| +{
 | |
| +	cf_helper("3 queue_mode\t \trq\nqueue_if_no_path", NULL, QUEUE_MODE_RQ, QUEUE_MODE_RQ);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_rq_bio1(void **state)
 | |
| +{
 | |
| +	cf_helper("2 queue_mode rq", "2 queue_mode bio", QUEUE_MODE_BIO,
 | |
| +		  QUEUE_MODE_BIO);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_rq_bio2(void **state)
 | |
| +{
 | |
| +	cf_helper("3 queue_if_no_path\nqueue_mode rq", "3 queue_if_no_path queue_mode bio", QUEUE_MODE_BIO, QUEUE_MODE_BIO);
 | |
| +}
 | |
| +
 | |
| +static void test_cf_rq_bio3(void **state)
 | |
| +{
 | |
| +	cf_helper("3 queue_mode rq\nqueue_if_no_path", "3 queue_if_no_path queue_mode bio", QUEUE_MODE_BIO, QUEUE_MODE_BIO);
 | |
| +}
 | |
| +
 | |
| +static int test_reconcile_features(void)
 | |
| +{
 | |
| +	const struct CMUnitTest tests[] = {
 | |
| +		cmocka_unit_test(test_cf_null_features),
 | |
| +		cmocka_unit_test(test_cf_unset_unset1),
 | |
| +		cmocka_unit_test(test_cf_unset_unset2),
 | |
| +		cmocka_unit_test(test_cf_unset_unset3),
 | |
| +		cmocka_unit_test(test_cf_unset_unset4),
 | |
| +		cmocka_unit_test(test_cf_unset_unset5),
 | |
| +		cmocka_unit_test(test_cf_invalid_unset1),
 | |
| +		cmocka_unit_test(test_cf_invalid_unset2),
 | |
| +		cmocka_unit_test(test_cf_rq_unset1),
 | |
| +		cmocka_unit_test(test_cf_rq_unset2),
 | |
| +		cmocka_unit_test(test_cf_bio_unset),
 | |
| +		cmocka_unit_test(test_cf_unset_bio1),
 | |
| +		cmocka_unit_test(test_cf_unset_bio2),
 | |
| +		cmocka_unit_test(test_cf_unset_bio3),
 | |
| +		cmocka_unit_test(test_cf_invalid_bio1),
 | |
| +		cmocka_unit_test(test_cf_invalid_bio2),
 | |
| +		cmocka_unit_test(test_cf_bio_bio1),
 | |
| +		cmocka_unit_test(test_cf_bio_bio2),
 | |
| +		cmocka_unit_test(test_cf_bio_bio3),
 | |
| +		cmocka_unit_test(test_cf_bio_rq1),
 | |
| +		cmocka_unit_test(test_cf_bio_rq2),
 | |
| +		cmocka_unit_test(test_cf_bio_rq3),
 | |
| +		cmocka_unit_test(test_cf_unset_rq1),
 | |
| +		cmocka_unit_test(test_cf_unset_rq2),
 | |
| +		cmocka_unit_test(test_cf_invalid_rq1),
 | |
| +		cmocka_unit_test(test_cf_invalid_rq2),
 | |
| +		cmocka_unit_test(test_cf_rq_rq1),
 | |
| +		cmocka_unit_test(test_cf_rq_rq2),
 | |
| +		cmocka_unit_test(test_cf_rq_bio1),
 | |
| +		cmocka_unit_test(test_cf_rq_bio2),
 | |
| +		cmocka_unit_test(test_cf_rq_bio3),
 | |
| +	};
 | |
| +	return cmocka_run_group_tests(tests, NULL, NULL);
 | |
| +}
 | |
| +
 | |
|  int main(void)
 | |
|  {
 | |
|  	int ret = 0;
 | |
| @@ -314,6 +543,7 @@ int main(void)
 | |
|  	init_test_verbosity(-1);
 | |
|  	ret += test_add_features();
 | |
|  	ret += test_remove_features();
 | |
| +	ret += test_reconcile_features();
 | |
|  
 | |
|  	return ret;
 | |
|  }
 |