All of lore.kernel.org
 help / color / mirror / Atom feed
From: Martin Wilck <mwilck@suse.com>
To: Christophe Varoqui <christophe.varoqui@opensvc.com>
Cc: dm-devel@redhat.com, Martin Wilck <mwilck@suse.com>
Subject: [PATCH v2 1/5] tests: add unit tests for config file parser
Date: Thu,  8 Mar 2018 00:26:16 +0100	[thread overview]
Message-ID: <20180307232620.15746-2-mwilck@suse.com> (raw)
In-Reply-To: <20180307232620.15746-1-mwilck@suse.com>

Add test cases for parsing the config file.

Some of these tests currently fail. The patches that follow fix them.

Signed-off-by: Martin Wilck <mwilck@suse.com>
---
 tests/Makefile  |   2 +-
 tests/globals.c |   1 +
 tests/parser.c  | 479 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 481 insertions(+), 1 deletion(-)
 create mode 100644 tests/parser.c

diff --git a/tests/Makefile b/tests/Makefile
index 7ae6b9012b5a..81f5518b05d0 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
+TESTS := uevent parser
 
 .SILENT: $(TESTS:%=%.o)
 .PRECIOUS: $(TESTS:%=%-test)
diff --git a/tests/globals.c b/tests/globals.c
index 96a56515fd09..80f57bd3639a 100644
--- a/tests/globals.c
+++ b/tests/globals.c
@@ -6,6 +6,7 @@ struct udev *udev;
 int logsink = 0;
 struct config conf = {
 	.uid_attrs = "sd:ID_BOGUS",
+	.verbosity = 4,
 };
 
 struct config *get_multipath_config(void)
diff --git a/tests/parser.c b/tests/parser.c
new file mode 100644
index 000000000000..8e73cebd878a
--- /dev/null
+++ b/tests/parser.c
@@ -0,0 +1,479 @@
+/*
+ * 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 <stdbool.h>
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <stdlib.h>
+#include <cmocka.h>
+// #include "list.h"
+#include "parser.h"
+#include "vector.h"
+
+#include "globals.c"
+
+/* Set these to 1 to get success for current broken behavior */
+/* Strip leading whitespace between quotes */
+#define LSTRIP_QUOTED_WSP 0
+/* Stop parsing at 2nd quote */
+#define TWO_QUOTES_ONLY 0
+
+static bool is_quote(const char *s)
+{
+	return *s == '"';
+}
+
+static char *test_file = "test.conf";
+
+/* Missing declaration */
+int validate_config_strvec(vector strvec, char *file);
+
+/* Stringify helpers */
+#define _str_(x) #x
+#define str(x) _str_(x)
+
+static int setup(void **state)
+{
+	return 0;
+}
+
+static int teardown(void **state)
+{
+	return 0;
+}
+
+static void test01(void **state)
+{
+	vector v = alloc_strvec("keyword value");
+	char *val;
+
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 2);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_string_equal(VECTOR_SLOT(v, 1), "value");
+
+	val = set_value(v);
+	assert_string_equal(val, "value");
+
+	free(val);
+	free_strvec(v);
+}
+
+static void test02(void **state)
+{
+	vector v = alloc_strvec("keyword \"value\"");
+	char *val;
+
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 4);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_true(is_quote(VECTOR_SLOT(v, 1)));;
+	assert_string_equal(VECTOR_SLOT(v, 2), "value");
+	assert_true(is_quote(VECTOR_SLOT(v, 3)));;
+
+	val = set_value(v);
+	assert_string_equal(val, "value");
+
+	free(val);
+	free_strvec(v);
+}
+
+static void test03(void **state)
+{
+	vector v = alloc_strvec("keyword value\n");
+	char *val;
+
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 2);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_string_equal(VECTOR_SLOT(v, 1), "value");
+
+	val = set_value(v);
+	assert_string_equal(val, "value");
+
+	free(val);
+	free_strvec(v);
+}
+
+static void test04(void **state)
+{
+	vector v = alloc_strvec("keyword \t   value   \t \n   ");
+	char *val;
+
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 2);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_string_equal(VECTOR_SLOT(v, 1), "value");
+
+	val = set_value(v);
+	assert_string_equal(val, "value");
+
+	free(val);
+	free_strvec(v);
+}
+
+static void test05(void **state)
+{
+	vector v = alloc_strvec("keyword \t   value   \t ! comment  ");
+	char *val;
+
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 2);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_string_equal(VECTOR_SLOT(v, 1), "value");
+
+	val = set_value(v);
+	assert_string_equal(val, "value");
+
+	free(val);
+	free_strvec(v);
+}
+
+static void test06(void **state)
+{
+	vector v = alloc_strvec("keyword \t   value   # \n comment  ");
+	char *val;
+
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 2);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_string_equal(VECTOR_SLOT(v, 1), "value");
+
+	val = set_value(v);
+	assert_string_equal(val, "value");
+
+	free(val);
+	free_strvec(v);
+}
+
+static void test07(void **state)
+{
+	vector v = alloc_strvec("keyword \t   value   more  ");
+	char *val;
+
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 3);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_string_equal(VECTOR_SLOT(v, 1), "value");
+	assert_string_equal(VECTOR_SLOT(v, 2), "more");
+
+	val = set_value(v);
+	assert_string_equal(val, "value");
+
+	free(val);
+	free_strvec(v);
+}
+
+static void test08(void **state)
+{
+#define QUOTED08 "  value   more  "
+#define QUOTED08B "value   more  "
+	vector v = alloc_strvec("keyword \t \"" QUOTED08 "\"");
+	char *val;
+
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 4);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_true(is_quote(VECTOR_SLOT(v, 1)));;
+#if LSTRIP_QUOTED_WSP
+	assert_string_equal(VECTOR_SLOT(v, 2), QUOTED08B);
+#else
+	assert_string_equal(VECTOR_SLOT(v, 2), QUOTED08);
+#endif
+	assert_true(is_quote(VECTOR_SLOT(v, 3)));;
+
+	val = set_value(v);
+#if LSTRIP_QUOTED_WSP
+	assert_string_equal(val, QUOTED08B);
+#else
+	assert_string_equal(val, QUOTED08);
+#endif
+	free(val);
+	free_strvec(v);
+}
+
+static void test09(void **state)
+{
+#define QUOTED09 "value # more"
+	vector v = alloc_strvec("keyword \"" QUOTED09 "\"");
+	char *val;
+
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 4);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_true(is_quote(VECTOR_SLOT(v, 1)));;
+	assert_string_equal(VECTOR_SLOT(v, 2), QUOTED09);
+	assert_true(is_quote(VECTOR_SLOT(v, 3)));;
+
+	val = set_value(v);
+	assert_string_equal(val, QUOTED09);
+
+	free(val);
+	free_strvec(v);
+}
+
+static void test10(void **state)
+{
+#define QUOTED10 "value ! more"
+	vector v = alloc_strvec("keyword \"" QUOTED10 "\"");
+	char *val;
+
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 4);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_true(is_quote(VECTOR_SLOT(v, 1)));;
+	assert_string_equal(VECTOR_SLOT(v, 2), QUOTED10);
+	assert_true(is_quote(VECTOR_SLOT(v, 3)));;
+
+	val = set_value(v);
+	assert_string_equal(val, QUOTED10);
+
+	free(val);
+	free_strvec(v);
+}
+
+static void test11(void **state)
+{
+#define QUOTED11 "value comment"
+	vector v = alloc_strvec("keyword\"" QUOTED11 "\"");
+	char *val;
+
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 4);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_true(is_quote(VECTOR_SLOT(v, 1)));;
+	assert_string_equal(VECTOR_SLOT(v, 2), QUOTED11);
+	assert_true(is_quote(VECTOR_SLOT(v, 3)));;
+
+	val = set_value(v);
+	assert_string_equal(val, QUOTED11);
+
+	free(val);
+	free_strvec(v);
+}
+
+static void test12(void **state)
+{
+	vector v = alloc_strvec("key\"word\"");
+	char *val;
+
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 4);
+	assert_string_equal(VECTOR_SLOT(v, 0), "key");
+	assert_true(is_quote(VECTOR_SLOT(v, 1)));;
+	assert_string_equal(VECTOR_SLOT(v, 2), "word");
+	assert_true(is_quote(VECTOR_SLOT(v, 3)));;
+
+	val = set_value(v);
+	assert_string_equal(val, "word");
+
+	free(val);
+	free_strvec(v);
+}
+
+static void test13(void **state)
+{
+	vector v = alloc_strvec("keyword value \"quoted\"");
+	char *val;
+
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 5);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_string_equal(VECTOR_SLOT(v, 1), "value");
+	assert_true(is_quote(VECTOR_SLOT(v, 2)));;
+	assert_string_equal(VECTOR_SLOT(v, 3), "quoted");
+	assert_true(is_quote(VECTOR_SLOT(v, 4)));;
+
+	val = set_value(v);
+	assert_string_equal(val, "value");
+
+	free(val);
+	free_strvec(v);
+}
+
+static void test14(void **state)
+{
+	vector v = alloc_strvec("keyword \"value \"  comment\"\"");
+	char *val;
+
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 7);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_true(is_quote(VECTOR_SLOT(v, 1)));;
+	assert_string_equal(VECTOR_SLOT(v, 2), "value ");
+	assert_true(is_quote(VECTOR_SLOT(v, 3)));;
+	assert_string_equal(VECTOR_SLOT(v, 4), "comment");
+	assert_true(is_quote(VECTOR_SLOT(v, 5)));;
+	assert_true(is_quote(VECTOR_SLOT(v, 6)));;
+
+	val = set_value(v);
+	assert_string_equal(val, "value ");
+
+	free(val);
+	free_strvec(v);
+}
+
+static void test15(void **state)
+{
+#define QUOTED15 "word  value\n  comment"
+	vector v = alloc_strvec("key\"" QUOTED15 "\"");
+	char *val;
+
+	assert_int_equal(VECTOR_SIZE(v), 4);
+	assert_string_equal(VECTOR_SLOT(v, 0), "key");
+	assert_true(is_quote(VECTOR_SLOT(v, 1)));;
+	assert_string_equal(VECTOR_SLOT(v, 2), QUOTED15);
+	assert_true(is_quote(VECTOR_SLOT(v, 3)));;
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+
+	val = set_value(v);
+	assert_string_equal(val, QUOTED15);
+
+	free(val);
+	free_strvec(v);
+}
+
+static void test16(void **state)
+{
+	vector v = alloc_strvec("keyword \"2.5\"\" SSD\"");
+	char *val;
+
+#if TWO_QUOTES_ONLY
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 6);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_true(is_quote(VECTOR_SLOT(v, 1)));;
+	assert_string_equal(VECTOR_SLOT(v, 2), "2.5");
+	assert_true(is_quote(VECTOR_SLOT(v, 3)));;
+	assert_string_equal(VECTOR_SLOT(v, 4), "SSD");
+	assert_true(is_quote(VECTOR_SLOT(v, 5)));;
+
+	val = set_value(v);
+	assert_string_equal(val, "2.5");
+#else
+	assert_int_equal(VECTOR_SIZE(v), 4);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_true(is_quote(VECTOR_SLOT(v, 1)));;
+	assert_string_equal(VECTOR_SLOT(v, 2), "2.5\" SSD");
+	assert_true(is_quote(VECTOR_SLOT(v, 3)));;
+
+	val = set_value(v);
+	assert_string_equal(val, "2.5\" SSD");
+#endif
+	free(val);
+	free_strvec(v);
+}
+
+static void test17(void **state)
+{
+	vector v = alloc_strvec("keyword \"\"\"\"\" is empty\"");
+ 	char *val;
+#if TWO_QUOTES_ONLY
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 6);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_true(is_quote(VECTOR_SLOT(v, 1)));;
+	assert_true(is_quote(VECTOR_SLOT(v, 2)));;
+	assert_true(is_quote(VECTOR_SLOT(v, 3)));;
+#if LSTRIP_QUOTED_WSP
+	assert_string_equal(VECTOR_SLOT(v, 4), "is empty");
+#else
+	assert_string_equal(VECTOR_SLOT(v, 4), " is empty");
+#endif
+	assert_true(is_quote(VECTOR_SLOT(v, 5)));;
+
+	val = set_value(v);
+	assert_string_equal(val, "");
+#else
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 4);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_true(is_quote(VECTOR_SLOT(v, 1)));;
+	assert_string_equal(VECTOR_SLOT(v, 2), "\"\" is empty");
+	assert_true(is_quote(VECTOR_SLOT(v, 3)));;
+
+	val = set_value(v);
+	assert_string_equal(val, "\"\" is empty");
+#endif
+	free(val);
+	free_strvec(v);
+}
+
+static void test18(void **state)
+{
+	vector v = alloc_strvec("keyword \"\"\"\"");
+ 	char *val;
+#if TWO_QUOTES_ONLY
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 5);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_true(is_quote(VECTOR_SLOT(v, 1)));;
+	assert_true(is_quote(VECTOR_SLOT(v, 2)));;
+	assert_true(is_quote(VECTOR_SLOT(v, 3)));;
+	assert_true(is_quote(VECTOR_SLOT(v, 4)));;
+
+	val = set_value(v);
+	assert_string_equal(val, "");
+#else
+	assert_int_equal(validate_config_strvec(v, test_file), 0);
+	assert_int_equal(VECTOR_SIZE(v), 4);
+	assert_string_equal(VECTOR_SLOT(v, 0), "keyword");
+	assert_true(is_quote(VECTOR_SLOT(v, 1)));;
+	assert_string_equal(VECTOR_SLOT(v, 2), "\"");
+	assert_true(is_quote(VECTOR_SLOT(v, 3)));;
+
+	val = set_value(v);
+	assert_string_equal(val, "\"");
+#endif
+	free(val);
+	free_strvec(v);
+}
+
+int test_config_parser(void)
+{
+	const struct CMUnitTest tests[] = {
+		cmocka_unit_test(test01),
+		cmocka_unit_test(test02),
+		cmocka_unit_test(test03),
+		cmocka_unit_test(test04),
+		cmocka_unit_test(test05),
+		cmocka_unit_test(test06),
+		cmocka_unit_test(test07),
+		cmocka_unit_test(test08),
+		cmocka_unit_test(test09),
+		cmocka_unit_test(test10),
+		cmocka_unit_test(test11),
+		cmocka_unit_test(test12),
+		cmocka_unit_test(test13),
+		cmocka_unit_test(test14),
+		cmocka_unit_test(test15),
+		cmocka_unit_test(test16),
+		cmocka_unit_test(test17),
+		cmocka_unit_test(test18),
+	};
+	return cmocka_run_group_tests(tests, setup, teardown);
+}
+
+int main(void)
+{
+	int ret = 0;
+
+	ret += test_config_parser();
+	return ret;
+}
-- 
2.16.1

  reply	other threads:[~2018-03-07 23:26 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-07 23:26 [PATCH v2 0/5] Fixes for config file parsing Martin Wilck
2018-03-07 23:26 ` Martin Wilck [this message]
2018-03-07 23:26 ` [PATCH v2 2/5] libmultipath: config parser: don't strip whitepace between quotes Martin Wilck
2018-03-07 23:26 ` [PATCH v2 3/5] libmultipath: config parser: Allow '"' in strings Martin Wilck
2018-03-23 16:59   ` Xose Vazquez Perez
2018-03-23 17:40     ` Martin Wilck
2018-03-07 23:26 ` [PATCH v2 4/5] libmultipath: config parser: fix corner case for double quotes Martin Wilck
2018-03-07 23:26 ` [PATCH v2 5/5] multipath.conf(5): improve syntax documentation Martin Wilck
2018-03-14 17:41 ` [PATCH v2 0/5] Fixes for config file parsing Benjamin Marzinski

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180307232620.15746-2-mwilck@suse.com \
    --to=mwilck@suse.com \
    --cc=christophe.varoqui@opensvc.com \
    --cc=dm-devel@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.