[dm-devel] [PATCH 2/7] tests: cmocka-based unit test for uevent_get_XXX

Martin Wilck mwilck at suse.com
Wed Jan 17 07:49:34 UTC 2018


This patch starts a simple unit test framework for multipath-tools
based on the cmocka framework (https://cmocka.org/). As a start,
it adds unit tests for the uevent_get_XXX set of functions.

Note that some tests currently fail. This will be fixed by the
following patches.

Signed-off-by: Martin Wilck <mwilck at suse.com>
---
 .gitignore      |   3 +
 Makefile        |   4 +
 tests/Makefile  |  23 ++++++
 tests/globals.c |  17 ++++
 tests/uevent.c  | 241 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 288 insertions(+)
 create mode 100644 tests/Makefile
 create mode 100644 tests/globals.c
 create mode 100644 tests/uevent.c

diff --git a/.gitignore b/.gitignore
index 57cf7e6a31a5..371b8758c0a1 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,3 +18,6 @@ libdmmp/docs/man/*.3.gz
 libdmmp/*.so.*
 libdmmp/test/libdmmp_test
 libdmmp/test/libdmmp_speed_test
+tests/*-test
+tests/*.out
+
diff --git a/Makefile b/Makefile
index bfb168fb172c..11c46eb4dbc9 100644
--- a/Makefile
+++ b/Makefile
@@ -27,6 +27,7 @@ recurse_clean:
 	@for dir in $(BUILDDIRS); do \
 	$(MAKE) -C $$dir clean || exit $?; \
 	done
+	$(MAKE) -C tests clean
 
 recurse_install:
 	@for dir in $(BUILDDIRS); do \
@@ -44,6 +45,9 @@ install: recurse_install
 
 uninstall: recurse_uninstall
 
+test:	all
+	$(MAKE) -C tests
+
 .PHONY:	TAGS
 TAGS:
 	etags -a libmultipath/*.c
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644
index 000000000000..ff58cb8bb207
--- /dev/null
+++ b/tests/Makefile
@@ -0,0 +1,23 @@
+include ../Makefile.inc
+
+CFLAGS += $(BIN_CFLAGS) -I$(multipathdir) -I$(mpathcmddir)
+LIBDEPS += -L$(multipathdir) -lmultipath -lcmocka
+
+TESTS := uevent
+
+.SILENT: $(TESTS:%=%.o)
+.PRECIOUS: $(TESTS:%=%-test)
+
+%-test:	%.o globals.c $(multipathdir)/libmultipath.so
+	@$(CC) -o $@ $< $(LDFLAGS) $(LIBDEPS)
+
+%.out:	%-test
+	@echo == running $< ==
+	@LD_LIBRARY_PATH=$(multipathdir):$(mpathcmddir) ./$< >$@
+
+all:	$(TESTS:%=%.out)
+
+clean:
+	rm -f $(TESTS:%=%-test) $(TESTS:%=%.out) $(TESTS:%=%.o)
+
+
diff --git a/tests/globals.c b/tests/globals.c
new file mode 100644
index 000000000000..96a56515fd09
--- /dev/null
+++ b/tests/globals.c
@@ -0,0 +1,17 @@
+#include "structs.h"
+#include "config.h"
+
+/* Required globals */
+struct udev *udev;
+int logsink = 0;
+struct config conf = {
+	.uid_attrs = "sd:ID_BOGUS",
+};
+
+struct config *get_multipath_config(void)
+{
+	return &conf;
+}
+
+void put_multipath_config(struct config* c)
+{}
diff --git a/tests/uevent.c b/tests/uevent.c
new file mode 100644
index 000000000000..a8edd710f653
--- /dev/null
+++ b/tests/uevent.c
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2018 SUSE Linux GmbH
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ *
+ */
+
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <stdlib.h>
+#include <cmocka.h>
+#include "list.h"
+#include "uevent.h"
+
+#include "globals.c"
+
+/* Private prototypes missing in uevent.h */
+struct uevent * alloc_uevent(void);
+void uevent_get_wwid(struct uevent *uev);
+
+/* Stringify helpers */
+#define _str_(x) #x
+#define str(x) _str_(x)
+
+#define MAJOR 17
+#define MINOR 217
+#define DISK_RO 0
+#define DM_NAME "spam"
+#define WWID "foo"
+
+static int setup_uev(void **state)
+{
+	struct uevent *uev = alloc_uevent();
+
+	if (uev == NULL)
+		return -1;
+
+	*state = uev;
+	uev->kernel = "sdo";
+	uev->envp[0] = "MAJOR=" str(MAJOR);
+	uev->envp[1] = "ID_BOGUS=" WWID;
+	uev->envp[2] = "MINOR=" str(MINOR);
+	uev->envp[3] = "DM_NAME=" DM_NAME;
+	uev->envp[4] = "DISK_RO=" str(DISK_RO);
+	uev->envp[5] = NULL;
+	return 0;
+}
+
+static int teardown(void **state)
+{
+	free(*state);
+	return 0;
+}
+
+static void test_major_good(void **state)
+{
+	struct uevent *uev = *state;
+
+	assert_int_equal(uevent_get_major(uev), MAJOR);
+}
+
+static void test_minor_good(void **state)
+{
+	struct uevent *uev = *state;
+
+	assert_int_equal(uevent_get_minor(uev), MINOR);
+}
+
+static void test_ro_good(void **state)
+{
+	struct uevent *uev = *state;
+
+	assert_int_equal(uevent_get_disk_ro(uev), DISK_RO);
+}
+
+static void test_wwid(void **state)
+{
+	struct uevent *uev = *state;
+	uevent_get_wwid(uev);
+
+	assert_string_equal(uev->wwid, WWID);
+}
+
+static void test_major_bad_0(void **state)
+{
+	struct uevent *uev = *state;
+
+	uev->envp[0] = "MAJOR" str(MAJOR);
+	assert_int_equal(uevent_get_major(uev), -1);
+}
+
+static void test_major_bad_1(void **state)
+{
+	struct uevent *uev = *state;
+
+	uev->envp[0] = "MAJOr=" str(MAJOR);
+	assert_int_equal(uevent_get_major(uev), -1);
+}
+
+static void test_major_bad_2(void **state)
+{
+	struct uevent *uev = *state;
+
+	uev->envp[0] = "MAJORIE=" str(MAJOR);
+	assert_int_equal(uevent_get_major(uev), -1);
+}
+
+static void test_major_bad_3(void **state)
+{
+	struct uevent *uev = *state;
+
+	uev->envp[0] = "MAJOR=max";
+	assert_int_equal(uevent_get_major(uev), -1);
+}
+
+static void test_major_bad_4(void **state)
+{
+	struct uevent *uev = *state;
+
+	uev->envp[0] = "MAJOR=0x10";
+	assert_int_equal(uevent_get_major(uev), -1);
+}
+
+static void test_major_bad_5(void **state)
+{
+	struct uevent *uev = *state;
+
+	uev->envp[0] = "MAJO=" str(MAJOR);
+	assert_int_equal(uevent_get_major(uev), -1);
+}
+
+static void test_major_bad_6(void **state)
+{
+	struct uevent *uev = *state;
+
+	uev->envp[0] = "MAJOR=" str(-MAJOR);
+	assert_int_equal(uevent_get_major(uev), -1);
+}
+
+static void test_major_bad_7(void **state)
+{
+	struct uevent *uev = *state;
+
+	uev->envp[0] = "MAJOR=";
+	assert_int_equal(uevent_get_major(uev), -1);
+}
+
+static void test_major_bad_8(void **state)
+{
+	struct uevent *uev = *state;
+
+	uev->envp[0] = "MAJOR";
+	assert_int_equal(uevent_get_major(uev), -1);
+}
+
+static void test_dm_name_good(void **state)
+{
+	struct uevent *uev = *state;
+	const char *name = uevent_get_dm_name(uev);
+
+	assert_string_equal(name, DM_NAME);
+	free((void*)name);
+}
+
+static void test_dm_name_bad_0(void **state)
+{
+	struct uevent *uev = *state;
+	const char *name;
+
+	uev->envp[3] = "DM_NAME" DM_NAME;
+	name = uevent_get_dm_name(uev);
+	assert_ptr_equal(name, NULL);
+	free((void*)name);
+}
+
+static void test_dm_name_bad_1(void **state)
+{
+	struct uevent *uev = *state;
+	const char *name;
+
+	uev->envp[3] = "DM_NAMES=" DM_NAME;
+	name = uevent_get_dm_name(uev);
+	assert_ptr_equal(name, NULL);
+	free((void*)name);
+}
+
+static void test_dm_name_good_1(void **state)
+{
+	struct uevent *uev = *state;
+	const char *name;
+
+	/* Note we change index 2 here */
+	uev->envp[2] = "DM_NAME=" DM_NAME;
+	name = uevent_get_dm_name(uev);
+	assert_string_equal(name, DM_NAME);
+	free((void*)name);
+}
+
+int test_uevent_get_XXX(void)
+{
+	const struct CMUnitTest tests[] = {
+		cmocka_unit_test(test_major_good),
+		cmocka_unit_test(test_minor_good),
+		cmocka_unit_test(test_ro_good),
+		cmocka_unit_test(test_dm_name_good),
+		cmocka_unit_test(test_wwid),
+		cmocka_unit_test(test_major_bad_0),
+		cmocka_unit_test(test_major_bad_1),
+		cmocka_unit_test(test_major_bad_2),
+		cmocka_unit_test(test_major_bad_3),
+		cmocka_unit_test(test_major_bad_4),
+		cmocka_unit_test(test_major_bad_5),
+		cmocka_unit_test(test_major_bad_6),
+		cmocka_unit_test(test_major_bad_7),
+		cmocka_unit_test(test_major_bad_8),
+		cmocka_unit_test(test_dm_name_bad_0),
+		cmocka_unit_test(test_dm_name_bad_1),
+		cmocka_unit_test(test_dm_name_good_1),
+	};
+	return cmocka_run_group_tests(tests, setup_uev, teardown);
+}
+
+int main(void)
+{
+	int ret = 0;
+
+	ret += test_uevent_get_XXX();
+	return ret;
+}
-- 
2.15.1




More information about the dm-devel mailing list