Sfoglia il codice sorgente

libdpkg: Switch test suite to use TAP

This has the following benefits. It stops using assert() for the test
framework, it prints a more descriptive message, it performs all test
cases even if one fails. It allows to skip specific cases, or mark as
todo.

This also switches the build system to use the automake TAP driver.
Guillem Jover 12 anni fa
parent
commit
d9833ac0b6

+ 1 - 0
configure.ac

@@ -7,6 +7,7 @@ AC_INIT([dpkg], m4_esyscmd([./get-version]), [debian-dpkg@lists.debian.org])
 AC_CONFIG_SRCDIR([lib/dpkg/dpkg.h])
 AC_CONFIG_MACRO_DIR([m4])
 AC_CONFIG_AUX_DIR([build-aux])
+AC_REQUIRE_AUX_FILE([tap-driver.pl])
 
 AC_USE_SYSTEM_EXTENSIONS
 

+ 1 - 0
debian/changelog

@@ -78,6 +78,7 @@ dpkg (1.17.7) UNRELEASED; urgency=low
     - Do not unnecessarily shut up stdout in t-subproc.
     - Test command_exec() exit code.
     - Test allocations with new test_alloc() instead of pass/fail macros.
+    - Switch C test suite to use TAP.
 
   [ Updated dpkg translations ]
   * German (Sven Joachim).

+ 54 - 10
lib/dpkg/test.h

@@ -2,7 +2,7 @@
  * libdpkg - Debian packaging suite library routines
  * test.h - test suite support
  *
- * Copyright © 2009-2012 Guillem Jover <guillem@debian.org>
+ * Copyright © 2009-2014 Guillem Jover <guillem@debian.org>
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -21,17 +21,14 @@
 #ifndef LIBDPKG_TEST_H
 #define LIBDPKG_TEST_H
 
-#include <assert.h>
 #include <string.h>
+#include <stdlib.h>
 #include <stdio.h>
 
 #ifndef TEST_MAIN_PROVIDED
 #include <dpkg/ehandle.h>
 #endif
 
-/* Make sure NDEBUG is never defined, as we rely on the assert() macro. */
-#undef NDEBUG
-
 /**
  * @defgroup dpkg_test Test suite support
  * @ingroup dpkg-internal
@@ -41,7 +38,7 @@
 #define test_bail(reason) \
 	do { \
 		printf("Bail out! %s\n", (reason)); \
-		exit(99); \
+		exit(255); \
 	} while (0)
 
 #define test_xstringify(str) \
@@ -60,10 +57,55 @@ test_alloc(void *ptr, const char *reason)
 #define test_alloc(ptr) \
 	test_alloc((ptr), "cannot allocate memory for " #ptr " in " __FILE__ ":" test_stringify(__LINE__))
 
-#define test_pass(a)			assert((a))
-#define test_fail(a)			assert(!(a))
-#define test_str(a, op, b)		assert(strcmp((a), (b)) op 0)
-#define test_mem(a, op, b, size)	assert(memcmp((a), (b), (size)) op 0)
+static int test_id = 1;
+static int test_skip_code;
+static const char *test_skip_prefix;
+static const char *test_skip_reason;
+
+#define test_plan(n) \
+	printf("1..%d\n", n);
+
+#define test_skip_all(reason) \
+	do { \
+		printf("1..0 # SKIP %s\n", (reason)); \
+		exit(0); \
+	} while (0)
+#define test_skip(reason) \
+	printf("ok %d # SKIP %s\n", test_id++, (reason))
+#define test_skip_block(cond) \
+	for (test_skip_prefix = " # SKIP ", \
+	     test_skip_reason = cond ? #cond : NULL, \
+	     test_skip_code = 1; \
+	     test_skip_prefix; \
+	     test_skip_prefix = test_skip_reason = NULL, test_skip_code = 0)
+
+#define test_todo(a, reason, desc) \
+	do { \
+		test_skip_prefix = " # TODO "; \
+		test_skip_reason = reason; \
+		test_case(a, "%s", desc); \
+		test_skip_prefix = test_skip_reason = NULL; \
+	} while(0)
+#define test_todo_block(reason) \
+	for (test_skip_prefix = " # TODO ", test_skip_reason = reason; \
+	     test_skip_prefix; \
+	     test_skip_prefix = test_skip_reason = NULL)
+
+#define test_case(a, fmt, ...) \
+	printf("%sok %d - " fmt "%s%s\n", \
+	       test_skip_code || (a) ? "" : "not ", \
+	       test_id++, __VA_ARGS__, \
+	       test_skip_reason ? test_skip_prefix : "", \
+	       test_skip_reason ? test_skip_reason : "")
+
+#define test_pass(a) \
+	test_case((a), "pass %s", #a)
+#define test_fail(a) \
+	test_case(!(a), "fail %s", #a)
+#define test_str(a, op, b) \
+	test_case(strcmp((a), (b)) op 0, "strcmp '%s' %s '%s'", a, #op, b)
+#define test_mem(a, op, b, size) \
+	test_case(memcmp((a), (b), (size)) op 0, "memcmp %p %s %p", a, #op, b)
 
 /** @} */
 
@@ -73,6 +115,8 @@ static void test(void);
 int
 main(int argc, char **argv)
 {
+	setvbuf(stdout, NULL, _IOLBF, 0);
+
 	push_error_context();
 
 	test();

+ 1 - 0
lib/dpkg/test/.gitignore

@@ -13,6 +13,7 @@ t-progname
 t-string
 t-subproc
 t-test
+t-test-skip
 t-trigger
 t-varbuf
 t-version

+ 2 - 0
lib/dpkg/test/Makefile.am

@@ -14,6 +14,7 @@ LDADD = \
 # The tests are sorted in order of increasing complexity.
 check_PROGRAMS = \
 	t-test \
+	t-test-skip \
 	t-macros \
 	t-string \
 	t-buffer \
@@ -32,4 +33,5 @@ check_PROGRAMS = \
 	t-trigger \
 	t-mod-db
 
+LOG_DRIVER = $(PERL) $(top_srcdir)/build-aux/tap-driver.pl
 TESTS = $(check_PROGRAMS)

+ 2 - 0
lib/dpkg/test/t-ar.c

@@ -41,5 +41,7 @@ test_ar_normalize_name(void)
 static void
 test(void)
 {
+	test_plan(2);
+
 	test_ar_normalize_name();
 }

+ 2 - 0
lib/dpkg/test/t-arch.c

@@ -191,6 +191,8 @@ test_dpkg_arch_varbuf_archqual(void)
 void
 test(void)
 {
+	test_plan(55);
+
 	test_dpkg_arch_name_is_illegal();
 	test_dpkg_arch_get_list();
 	test_dpkg_arch_find();

+ 2 - 0
lib/dpkg/test/t-buffer.c

@@ -74,6 +74,8 @@ test_fdio_hash(void)
 static void
 test(void)
 {
+	test_plan(10);
+
 	test_buffer_hash();
 	test_fdio_hash();
 }

+ 2 - 0
lib/dpkg/test/t-command.c

@@ -185,6 +185,8 @@ test_command_shell(void)
 static void
 test(void)
 {
+	test_plan(44);
+
 	test_command_init();
 	test_command_add_arg();
 	test_command_add_argl();

+ 2 - 0
lib/dpkg/test/t-deb-version.c

@@ -65,5 +65,7 @@ test_deb_version_parse(void)
 static void
 test(void)
 {
+	test_plan(21);
+
 	test_deb_version_parse();
 }

+ 2 - 0
lib/dpkg/test/t-macros.c

@@ -27,6 +27,8 @@
 static void
 test(void)
 {
+	test_plan(12);
+
 	test_pass(min(10, 30) == 10);
 	test_pass(min(30, 10) == 10);
 	test_pass(min(0, 10) == 0);

+ 2 - 0
lib/dpkg/test/t-mod-db.c

@@ -52,5 +52,7 @@ test_db_dir(void)
 static void
 test(void)
 {
+	test_plan(5);
+
 	test_db_dir();
 }

+ 2 - 0
lib/dpkg/test/t-path.c

@@ -172,6 +172,8 @@ test_path_quote(void)
 static void
 test(void)
 {
+	test_plan(41);
+
 	test_path_trim();
 	test_path_skip();
 	test_path_basename();

+ 2 - 0
lib/dpkg/test/t-pkg-list.c

@@ -84,6 +84,8 @@ test_pkg_list_prepend(void)
 static void
 test(void)
 {
+	test_plan(14);
+
 	test_pkg_list_new();
 	test_pkg_list_prepend();
 }

+ 2 - 0
lib/dpkg/test/t-pkg-queue.c

@@ -110,6 +110,8 @@ test_pkg_queue_push_pop(void)
 static void
 test(void)
 {
+	test_plan(38);
+
 	test_pkg_queue_init();
 	test_pkg_queue_push_pop();
 }

+ 2 - 0
lib/dpkg/test/t-pkginfo.c

@@ -144,6 +144,8 @@ test_pkginfo_instance_tracking(void)
 static void
 test(void)
 {
+	test_plan(28);
+
 	test_pkginfo_informative();
 	test_pkginfo_eflags();
 	test_pkginfo_instance_tracking();

+ 2 - 0
lib/dpkg/test/t-progname.c

@@ -42,5 +42,7 @@ test_progname(void)
 static void
 test(void)
 {
+	test_plan(3);
+
 	test_progname();
 }

+ 2 - 0
lib/dpkg/test/t-string.c

@@ -127,6 +127,8 @@ test_str_strip_quotes(void)
 static void
 test(void)
 {
+	test_plan(18);
+
 	test_str_escape_fmt();
 	test_str_quote_meta();
 	test_str_strip_quotes();

+ 4 - 1
lib/dpkg/test/t-subproc.c

@@ -81,9 +81,12 @@ test(void)
 {
 	int fd;
 
+	test_plan(6);
+
 	/* XXX: Shut up stderr, we don't want the error output. */
 	fd = open("/dev/null", O_RDWR);
-	test_pass(fd >= 0);
+	if (fd < 0)
+		test_bail("cannot open /dev/null");
 	dup2(fd, 2);
 
 	test_subproc_fork();

+ 32 - 0
lib/dpkg/test/t-test-skip.c

@@ -0,0 +1,32 @@
+/*
+ * libdpkg - Debian packaging suite library routines
+ * t-test-skip.c - test suite self tests, skip all
+ *
+ * Copyright © 2014 Guillem Jover <guillem@debian.org>
+ *
+ * This 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 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, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <compat.h>
+
+#include <dpkg/test.h>
+
+static void
+test(void)
+{
+	test_skip_all("ignore all tests");
+
+	test_fail(1);
+}

+ 17 - 1
lib/dpkg/test/t-test.c

@@ -2,7 +2,7 @@
  * libdpkg - Debian packaging suite library routines
  * t-test.c - test suite self tests
  *
- * Copyright © 2009 Guillem Jover <guillem@debian.org>
+ * Copyright © 2009, 2014 Guillem Jover <guillem@debian.org>
  *
  * This is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,9 +26,25 @@
 static void
 test(void)
 {
+	test_plan(20);
+
 	test_pass(1);
 	test_fail(0);
 
+	test_skip("ignore test");
+
+	test_skip_block(1) {
+		test_pass(0);
+		test_pass(1);
+	}
+
+	test_todo(0, "unimplemented test", "failing test");
+
+	test_todo_block("unimplemented block") {
+		test_pass(0);
+		test_fail(1);
+	}
+
 	test_str("aaa", ==, "aaa");
 	test_str("aaa", <, "bbb");
 	test_str("ccc", >, "bbb");

+ 2 - 0
lib/dpkg/test/t-trigger.c

@@ -44,5 +44,7 @@ test_trig_name_is_illegal(void)
 void
 test(void)
 {
+	test_plan(9);
+
 	test_trig_name_is_illegal();
 }

+ 2 - 0
lib/dpkg/test/t-varbuf.c

@@ -291,6 +291,8 @@ test_varbuf_detach(void)
 static void
 test(void)
 {
+	test_plan(99);
+
 	test_varbuf_init();
 	test_varbuf_prealloc();
 	test_varbuf_grow();

+ 2 - 0
lib/dpkg/test/t-version.c

@@ -283,6 +283,8 @@ test_version_parse(void)
 static void
 test(void)
 {
+	test_plan(178);
+
 	test_version_blank();
 	test_version_is_informative();
 	test_version_compare();