netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2, libnftnl] tests: Consolidate printing error utilities
@ 2016-08-11 13:25 Carlos Falgueras García
  2016-08-11 13:25 ` [PATCH 2/2, libnftnl] Use libnftnl comparators in all tests Carlos Falgueras García
  2016-08-11 23:26 ` [PATCH 1/2, libnftnl] tests: Consolidate printing error utilities Pablo Neira Ayuso
  0 siblings, 2 replies; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-11 13:25 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

Created libtest.[hc] in order to consolidate code that is repeated in all
tests.

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 .gitignore                      |  1 +
 tests/Makefile.am               | 52 +++++++++++++++++++++--------------------
 tests/libtest.c                 | 49 ++++++++++++++++++++++++++++++++++++++
 tests/libtest.h                 |  9 +++++++
 tests/nft-chain-test.c          | 16 +++----------
 tests/nft-expr_bitwise-test.c   | 22 +++++------------
 tests/nft-expr_byteorder-test.c | 22 +++++------------
 tests/nft-expr_cmp-test.c       | 22 +++++------------
 tests/nft-expr_counter-test.c   | 20 +++++-----------
 tests/nft-expr_ct-test.c        | 21 +++++------------
 tests/nft-expr_dup-test.c       | 21 +++++------------
 tests/nft-expr_exthdr-test.c    | 21 +++++------------
 tests/nft-expr_fwd-test.c       | 21 +++++------------
 tests/nft-expr_immediate-test.c | 26 +++++++--------------
 tests/nft-expr_limit-test.c     | 22 +++++------------
 tests/nft-expr_log-test.c       | 22 +++++------------
 tests/nft-expr_lookup-test.c    | 23 +++++-------------
 tests/nft-expr_masq-test.c      | 22 +++++------------
 tests/nft-expr_match-test.c     | 31 +++++++-----------------
 tests/nft-expr_meta-test.c      | 22 +++++------------
 tests/nft-expr_nat-test.c       | 22 +++++------------
 tests/nft-expr_payload-test.c   | 22 +++++------------
 tests/nft-expr_queue-test.c     | 22 +++++------------
 tests/nft-expr_redir-test.c     | 22 +++++------------
 tests/nft-expr_reject-test.c    | 22 +++++------------
 tests/nft-expr_target-test.c    | 30 +++++++-----------------
 tests/nft-rule-test.c           | 17 ++++----------
 tests/nft-set-test.c            | 16 +++----------
 tests/nft-table-test.c          | 15 +++---------
 29 files changed, 231 insertions(+), 422 deletions(-)
 create mode 100644 tests/libtest.c
 create mode 100644 tests/libtest.h

diff --git a/.gitignore b/.gitignore
index 1650e58..5a781db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,4 +28,5 @@ examples/*
 !examples/Makefile.am
 tests/*
 !tests/*.c
+!tests/*.h
 !tests/Makefile.am
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0377081..b55aeba 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -4,6 +4,8 @@ EXTRA_DIST =		test-script.sh			\
 			jsonfiles			\
 			xmlfiles
 
+LIBTEST =		libtest.c
+
 check_PROGRAMS = 	nft-parsing-test		\
 			nft-table-test			\
 			nft-chain-test			\
@@ -34,77 +36,77 @@ check_PROGRAMS = 	nft-parsing-test		\
 nft_parsing_test_SOURCES = nft-parsing-test.c
 nft_parsing_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} ${LIBXML_LIBS} ${LIBJSON_LIBS}
 
-nft_table_test_SOURCES = nft-table-test.c
+nft_table_test_SOURCES = nft-table-test.c ${LIBTEST}
 nft_table_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_chain_test_SOURCES = nft-chain-test.c
+nft_chain_test_SOURCES = nft-chain-test.c ${LIBTEST}
 nft_chain_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_rule_test_SOURCES = nft-rule-test.c
+nft_rule_test_SOURCES = nft-rule-test.c ${LIBTEST}
 nft_rule_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_set_test_SOURCES = nft-set-test.c
+nft_set_test_SOURCES = nft-set-test.c ${LIBTEST}
 nft_set_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_bitwise_test_SOURCES = nft-expr_bitwise-test.c
+nft_expr_bitwise_test_SOURCES = nft-expr_bitwise-test.c ${LIBTEST}
 nft_expr_bitwise_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_byteorder_test_SOURCES = nft-expr_byteorder-test.c
+nft_expr_byteorder_test_SOURCES = nft-expr_byteorder-test.c ${LIBTEST}
 nft_expr_byteorder_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_cmp_test_SOURCES = nft-expr_cmp-test.c
+nft_expr_cmp_test_SOURCES = nft-expr_cmp-test.c ${LIBTEST}
 nft_expr_cmp_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_counter_test_SOURCES = nft-expr_counter-test.c
+nft_expr_counter_test_SOURCES = nft-expr_counter-test.c ${LIBTEST}
 nft_expr_counter_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_exthdr_test_SOURCES = nft-expr_exthdr-test.c
+nft_expr_exthdr_test_SOURCES = nft-expr_exthdr-test.c ${LIBTEST}
 nft_expr_exthdr_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_ct_test_SOURCES = nft-expr_ct-test.c
+nft_expr_ct_test_SOURCES = nft-expr_ct-test.c ${LIBTEST}
 nft_expr_ct_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_dup_test_SOURCES = nft-expr_dup-test.c
+nft_expr_dup_test_SOURCES = nft-expr_dup-test.c ${LIBTEST}
 nft_expr_dup_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_fwd_test_SOURCES = nft-expr_fwd-test.c
+nft_expr_fwd_test_SOURCES = nft-expr_fwd-test.c ${LIBTEST}
 nft_expr_fwd_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_immediate_test_SOURCES = nft-expr_immediate-test.c
+nft_expr_immediate_test_SOURCES = nft-expr_immediate-test.c ${LIBTEST}
 nft_expr_immediate_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_limit_test_SOURCES = nft-expr_limit-test.c
+nft_expr_limit_test_SOURCES = nft-expr_limit-test.c ${LIBTEST}
 nft_expr_limit_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_lookup_test_SOURCES = nft-expr_lookup-test.c
+nft_expr_lookup_test_SOURCES = nft-expr_lookup-test.c ${LIBTEST}
 nft_expr_lookup_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_log_test_SOURCES = nft-expr_log-test.c
+nft_expr_log_test_SOURCES = nft-expr_log-test.c ${LIBTEST}
 nft_expr_log_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_match_test_SOURCES = nft-expr_match-test.c
+nft_expr_match_test_SOURCES = nft-expr_match-test.c ${LIBTEST}
 nft_expr_match_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_masq_test_SOURCES = nft-expr_masq-test.c
+nft_expr_masq_test_SOURCES = nft-expr_masq-test.c ${LIBTEST}
 nft_expr_masq_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_meta_test_SOURCES = nft-expr_meta-test.c
+nft_expr_meta_test_SOURCES = nft-expr_meta-test.c ${LIBTEST}
 nft_expr_meta_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_nat_test_SOURCES = nft-expr_nat-test.c
+nft_expr_nat_test_SOURCES = nft-expr_nat-test.c ${LIBTEST}
 nft_expr_nat_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_payload_test_SOURCES = nft-expr_payload-test.c
+nft_expr_payload_test_SOURCES = nft-expr_payload-test.c ${LIBTEST}
 nft_expr_payload_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_queue_test_SOURCES = nft-expr_queue-test.c
+nft_expr_queue_test_SOURCES = nft-expr_queue-test.c ${LIBTEST}
 nft_expr_queue_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_reject_test_SOURCES = nft-expr_reject-test.c
+nft_expr_reject_test_SOURCES = nft-expr_reject-test.c ${LIBTEST}
 nft_expr_reject_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_redir_test_SOURCES = nft-expr_redir-test.c
+nft_expr_redir_test_SOURCES = nft-expr_redir-test.c ${LIBTEST}
 nft_expr_redir_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_target_test_SOURCES = nft-expr_target-test.c
+nft_expr_target_test_SOURCES = nft-expr_target-test.c ${LIBTEST}
 nft_expr_target_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
diff --git a/tests/libtest.c b/tests/libtest.c
new file mode 100644
index 0000000..91f2d5e
--- /dev/null
+++ b/tests/libtest.c
@@ -0,0 +1,49 @@
+#include <libtest.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#define COLOR_RED     "\x1b[31m"
+#define COLOR_GREEN   "\x1b[32m"
+#define COLOR_RESET   "\x1b[0m"
+
+static bool test_ok = true;
+
+void __oom(const char *prog, const char *file, int line)
+{
+	fprintf(stderr,
+		COLOR_RED "OOM" COLOR_RESET " at %s:%d\n\t%s\n", file, line,
+		strerror(errno));
+
+	test_ok = false;
+	test_exit(prog);
+	exit(EXIT_FAILURE);
+}
+
+void print_err(const char *fmt, ...)
+{
+	va_list args;
+
+	fprintf(stderr, COLOR_RED "ERROR: " COLOR_RESET);
+	va_start(args, fmt);
+	vfprintf(stderr, fmt, args);
+	va_end(args);
+	fprintf(stderr, "\n");
+
+	test_ok = false;
+}
+
+int test_exit(const char *prog)
+{
+	if (test_ok) {
+		printf("%s: " COLOR_GREEN "OK\n" COLOR_RESET, prog);
+		return EXIT_SUCCESS;
+	} else {
+		printf("%s: " COLOR_RED "FAIL\n" COLOR_RESET, prog);
+		return EXIT_FAILURE;
+	}
+}
diff --git a/tests/libtest.h b/tests/libtest.h
new file mode 100644
index 0000000..810bd82
--- /dev/null
+++ b/tests/libtest.h
@@ -0,0 +1,9 @@
+#ifndef _TESTS_UTILS_H
+#define _TESTS_UTILS_H
+
+#define oom(prog) __oom(prog, __FILE__, __LINE__)
+void __oom(const char *prog, const char *file, int line);
+void print_err(const char *fmt, ...);
+int test_exit(const char *prog);
+
+#endif
diff --git a/tests/nft-chain-test.c b/tests/nft-chain-test.c
index d678d46..82431c2 100644
--- a/tests/nft-chain-test.c
+++ b/tests/nft-chain-test.c
@@ -15,13 +15,7 @@
 #include <linux/netfilter/nf_tables.h>
 #include <libnftnl/chain.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_chain(struct nftnl_chain *a, struct nftnl_chain *b)
 {
@@ -73,7 +67,7 @@ int main(int argc, char *argv[])
 	a = nftnl_chain_alloc();
 	b = nftnl_chain_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_chain_set_str(a, NFTNL_CHAIN_NAME, "test");
 	nftnl_chain_set_u32(a, NFTNL_CHAIN_FAMILY, AF_INET);
@@ -101,10 +95,6 @@ int main(int argc, char *argv[])
 	nftnl_chain_free(a);
 	nftnl_chain_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 
 }
diff --git a/tests/nft-expr_bitwise-test.c b/tests/nft-expr_bitwise-test.c
index 64c1446..bf76cb2 100644
--- a/tests/nft-expr_bitwise-test.c
+++ b/tests/nft-expr_bitwise-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -66,10 +60,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("bitwise");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_SREG, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_DREG, 0x78123456);
@@ -88,12 +82,12 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
@@ -107,9 +101,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_byteorder-test.c b/tests/nft-expr_byteorder-test.c
index 5994e5b..cbdd1d7 100644
--- a/tests/nft-expr_byteorder-test.c
+++ b/tests/nft-expr_byteorder-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -59,10 +53,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("byteorder");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BYTEORDER_SREG, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BYTEORDER_DREG, 0x12345678);
@@ -81,12 +75,12 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a,rule_b);
 
@@ -99,9 +93,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_cmp-test.c b/tests/nft-expr_cmp-test.c
index ec00bb9..5c1917d 100644
--- a/tests/nft-expr_cmp-test.c
+++ b/tests/nft-expr_cmp-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -57,10 +51,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("cmp");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set(ex, NFTNL_EXPR_CMP_DATA, &data_len, sizeof(data_len));
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_CMP_SREG, 0x12345678);
@@ -77,11 +71,11 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -94,9 +88,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_counter-test.c b/tests/nft-expr_counter-test.c
index 519bc1f..5bbaf68 100644
--- a/tests/nft-expr_counter-test.c
+++ b/tests/nft-expr_counter-test.c
@@ -19,13 +19,8 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
+#include <libtest.h>
 
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -50,11 +45,11 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	ex = nftnl_expr_alloc("counter");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u64(ex, NFTNL_EXPR_CTR_BYTES, 0x123456789abcdef0);
 	nftnl_expr_set_u64(ex, NFTNL_EXPR_CTR_PACKETS, 0xf0123456789abcde);
@@ -69,11 +64,11 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -86,8 +81,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_ct-test.c b/tests/nft-expr_ct-test.c
index e98fbab..0a19513 100644
--- a/tests/nft-expr_ct-test.c
+++ b/tests/nft-expr_ct-test.c
@@ -19,12 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -51,10 +46,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("ct");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_CT_KEY, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_CT_DIR, 0x12);
@@ -71,12 +66,12 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -89,9 +84,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_dup-test.c b/tests/nft-expr_dup-test.c
index 3c37d4a..11acd14 100644
--- a/tests/nft-expr_dup-test.c
+++ b/tests/nft-expr_dup-test.c
@@ -19,12 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -49,10 +44,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("dup");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_DUP_SREG_ADDR, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_DUP_SREG_DEV,  0x78123456);
@@ -68,12 +63,12 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -86,9 +81,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_exthdr-test.c b/tests/nft-expr_exthdr-test.c
index fef2dd0..1418bb5 100644
--- a/tests/nft-expr_exthdr-test.c
+++ b/tests/nft-expr_exthdr-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -56,10 +50,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("exthdr");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_EXTHDR_DREG, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_EXTHDR_TYPE, 0x12);
@@ -76,12 +70,12 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -93,9 +87,6 @@ int main(int argc, char *argv[])
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
-	if (!test_ok)
-		exit(EXIT_FAILURE);
 
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_fwd-test.c b/tests/nft-expr_fwd-test.c
index 4fdf53d..70a72c3 100644
--- a/tests/nft-expr_fwd-test.c
+++ b/tests/nft-expr_fwd-test.c
@@ -19,12 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -46,10 +41,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("dup");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_FWD_SREG_DEV,  0x78123456);
 
@@ -64,12 +59,12 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -82,9 +77,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_immediate-test.c b/tests/nft-expr_immediate-test.c
index e07092f..088987f 100644
--- a/tests/nft-expr_immediate-test.c
+++ b/tests/nft-expr_immediate-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr_verdict(struct nftnl_expr *rule_a,
 				   struct nftnl_expr *rule_b)
@@ -77,11 +71,11 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex_val = nftnl_expr_alloc("immediate");
 	ex_ver = nftnl_expr_alloc("immediate");
 	if (!ex_val || !ex_ver)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u32(ex_val, NFTNL_EXPR_IMM_DREG, 0x1234568);
 	nftnl_expr_set(ex_val,     NFTNL_EXPR_IMM_DATA, data, sizeof(data));
@@ -97,24 +91,24 @@ int main(int argc, char *argv[])
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
 	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+		oom(argv[0]);
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr_value(rule_a, rule_b);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr_verdict(rule_a, rule_b);
 
@@ -127,9 +121,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_limit-test.c b/tests/nft-expr_limit-test.c
index 2838941..fc57775 100644
--- a/tests/nft-expr_limit-test.c
+++ b/tests/nft-expr_limit-test.c
@@ -20,13 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -60,10 +54,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("limit");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u64(ex, NFTNL_EXPR_LIMIT_RATE, 0x123456789abcdef0);
 	nftnl_expr_set_u64(ex, NFTNL_EXPR_LIMIT_UNIT, 0xf0123456789abcde);
@@ -82,12 +76,12 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -100,9 +94,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_log-test.c b/tests/nft-expr_log-test.c
index b7aa302..1ddad82 100644
--- a/tests/nft-expr_log-test.c
+++ b/tests/nft-expr_log-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-	test_ok = 0;
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -56,10 +50,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("log");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_LOG_SNAPLEN, 0x12345678);
 	nftnl_expr_set_u16(ex, NFTNL_EXPR_LOG_GROUP, 0x1234);
@@ -76,11 +70,11 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -93,9 +87,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_lookup-test.c b/tests/nft-expr_lookup-test.c
index d1f017b..68643f2 100644
--- a/tests/nft-expr_lookup-test.c
+++ b/tests/nft-expr_lookup-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -64,10 +58,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("lookup");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_LOOKUP_SREG, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_LOOKUP_DREG, 0x78123456);
@@ -85,11 +79,11 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -102,10 +96,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_masq-test.c b/tests/nft-expr_masq-test.c
index f0302e2..2727f37 100644
--- a/tests/nft-expr_masq-test.c
+++ b/tests/nft-expr_masq-test.c
@@ -17,13 +17,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -51,10 +45,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("nat");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_MASQ_FLAGS, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_MASQ_REG_PROTO_MIN, 0x5432178);
@@ -71,12 +65,12 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -89,9 +83,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_match-test.c b/tests/nft-expr_match-test.c
index 39a49d8..14c32ab 100644
--- a/tests/nft-expr_match-test.c
+++ b/tests/nft-expr_match-test.c
@@ -20,19 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
-
-static void print_err2(const char *msg, uint32_t a, uint32_t b)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s size a: %d b: %d \n", msg, a, b);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -48,7 +36,8 @@ static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 	nftnl_expr_get(rule_a, NFTNL_EXPR_MT_INFO, &lena);
 	nftnl_expr_get(rule_b, NFTNL_EXPR_MT_INFO, &lenb);
 	if (lena != lenb)
-		print_err2("Expr NFTNL_EXPR_MT_INFO size mismatches", lena, lenb);
+		print_err("Expr NFTNL_EXPR_MT_INFO size mismatches: %d != %d",
+			  lena, lenb);
 }
 
 int main(int argc, char *argv[])
@@ -64,10 +53,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("match");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_str(ex, NFTNL_EXPR_MT_NAME, "Tests");
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_MT_REV, 0x12345678);
@@ -82,12 +71,12 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -100,9 +89,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_meta-test.c b/tests/nft-expr_meta-test.c
index 8fb7873..72bfd1e 100644
--- a/tests/nft-expr_meta-test.c
+++ b/tests/nft-expr_meta-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -50,10 +44,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("meta");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_META_KEY, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_META_DREG, 0x78123456);
@@ -68,12 +62,12 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -86,9 +80,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_nat-test.c b/tests/nft-expr_nat-test.c
index fd3a488..5829d1d 100644
--- a/tests/nft-expr_nat-test.c
+++ b/tests/nft-expr_nat-test.c
@@ -20,13 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -66,10 +60,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("nat");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_NAT_TYPE, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_NAT_FAMILY, 0x3456721);
@@ -90,12 +84,12 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -108,9 +102,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_payload-test.c b/tests/nft-expr_payload-test.c
index 371372c..f452f96 100644
--- a/tests/nft-expr_payload-test.c
+++ b/tests/nft-expr_payload-test.c
@@ -20,13 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -57,10 +51,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("payload");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_PAYLOAD_DREG, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_PAYLOAD_BASE, 0x78123456);
@@ -77,12 +71,12 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -95,9 +89,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_queue-test.c b/tests/nft-expr_queue-test.c
index 1cc39aa..b3c6848 100644
--- a/tests/nft-expr_queue-test.c
+++ b/tests/nft-expr_queue-test.c
@@ -22,13 +22,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -53,10 +47,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("queue");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u16(ex, NFTNL_EXPR_QUEUE_NUM, 0x01010);
 	nftnl_expr_set_u16(ex, NFTNL_EXPR_QUEUE_TOTAL, 0x1234);
@@ -73,12 +67,12 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -91,9 +85,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_redir-test.c b/tests/nft-expr_redir-test.c
index 6c8caec..ce21dca 100644
--- a/tests/nft-expr_redir-test.c
+++ b/tests/nft-expr_redir-test.c
@@ -17,13 +17,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -51,10 +45,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("redir");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_REDIR_REG_PROTO_MIN, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_REDIR_REG_PROTO_MAX, 0x56781234);
@@ -71,12 +65,12 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -89,9 +83,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_reject-test.c b/tests/nft-expr_reject-test.c
index d8189ea..cafd4ba 100644
--- a/tests/nft-expr_reject-test.c
+++ b/tests/nft-expr_reject-test.c
@@ -20,13 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -51,10 +45,10 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 	ex = nftnl_expr_alloc("reject");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_REJECT_TYPE, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_REJECT_CODE, 0x45681234);
@@ -70,12 +64,12 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -88,9 +82,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-expr_target-test.c b/tests/nft-expr_target-test.c
index ba56b27..77d877c 100644
--- a/tests/nft-expr_target-test.c
+++ b/tests/nft-expr_target-test.c
@@ -19,19 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
-
-static void print_err2(const char *msg, uint32_t a, uint32_t b)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s size a: %d b: %d \n",msg, a, b);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -47,7 +35,8 @@ static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 	nftnl_expr_get(rule_a, NFTNL_EXPR_TG_INFO, &lena);
 	nftnl_expr_get(rule_b, NFTNL_EXPR_TG_INFO, &lenb);
 	if (lena != lenb)
-		print_err2("Expr NFTNL_EXPR_TG_INFO size mismatches", lena, lenb);
+		print_err("Expr NFTNL_EXPR_TG_INFO size mismatches: %d != %d",
+			  lena, lenb);
 }
 
 int main(int argc, char *argv[])
@@ -63,11 +52,11 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	ex = nftnl_expr_alloc("target");
 	if (ex == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_expr_set(ex, NFTNL_EXPR_TG_NAME, "test", strlen("test"));
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_TG_REV, 0x56781234);
@@ -83,12 +72,12 @@ int main(int argc, char *argv[])
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -101,8 +90,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-rule-test.c b/tests/nft-rule-test.c
index dee3530..5c1b52d 100644
--- a/tests/nft-rule-test.c
+++ b/tests/nft-rule-test.c
@@ -17,13 +17,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/udata.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_rule(struct nftnl_rule *a, struct nftnl_rule *b)
 {
@@ -69,11 +63,11 @@ int main(int argc, char *argv[])
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	udata = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
 	if (!udata)
-		print_err("OOM");
+		oom(argv[0]);
 
 	if (!nftnl_udata_put_strz(udata, 0, "hello world"))
 		print_err("User data too big");
@@ -100,9 +94,6 @@ int main(int argc, char *argv[])
 
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
-	if (!test_ok)
-		exit(EXIT_FAILURE);
 
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-set-test.c b/tests/nft-set-test.c
index 173c17f..e55c9c0 100644
--- a/tests/nft-set-test.c
+++ b/tests/nft-set-test.c
@@ -16,13 +16,7 @@
 
 #include <libnftnl/set.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_set(struct nftnl_set *a, struct nftnl_set *b)
 {
@@ -61,7 +55,7 @@ int main(int argc, char *argv[])
 	a = nftnl_set_alloc();
 	b = nftnl_set_alloc();
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_set_set_str(a, NFTNL_SET_TABLE, "test-table");
 	nftnl_set_set_str(a, NFTNL_SET_NAME, "test-name");
@@ -84,9 +78,5 @@ int main(int argc, char *argv[])
 
 	nftnl_set_free(a); nftnl_set_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
diff --git a/tests/nft-table-test.c b/tests/nft-table-test.c
index 1031ffe..134bd40 100644
--- a/tests/nft-table-test.c
+++ b/tests/nft-table-test.c
@@ -16,13 +16,7 @@
 #include <linux/netfilter/nf_tables.h>
 #include <libnftnl/table.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include <libtest.h>
 
 static void cmp_nftnl_table(struct nftnl_table *a, struct nftnl_table *b)
 {
@@ -48,7 +42,7 @@ int main(int argc, char *argv[])
 	b = nftnl_table_alloc();
 
 	if (a == NULL || b == NULL)
-		print_err("OOM");
+		oom(argv[0]);
 
 	nftnl_table_set_str(a, NFTNL_TABLE_NAME, "test");
 	nftnl_table_set_u32(a, NFTNL_TABLE_FAMILY, AF_INET);
@@ -66,9 +60,6 @@ int main(int argc, char *argv[])
 
 	nftnl_table_free(a);
 	nftnl_table_free(b);
-	if (!test_ok)
-		exit(EXIT_FAILURE);
 
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_exit(argv[0]);
 }
-- 
2.8.3


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 2/2, libnftnl] Use libnftnl comparators in all tests
  2016-08-11 13:25 [PATCH 1/2, libnftnl] tests: Consolidate printing error utilities Carlos Falgueras García
@ 2016-08-11 13:25 ` Carlos Falgueras García
  2016-08-11 23:32   ` Pablo Neira Ayuso
  2016-08-11 23:26 ` [PATCH 1/2, libnftnl] tests: Consolidate printing error utilities Pablo Neira Ayuso
  1 sibling, 1 reply; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-11 13:25 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

Use 'nftnl_expr_cmp' and 'nftnl_rule_cmp' in all tests instead of custom
comparator for each one. If objects differ both are printed.

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 tests/libtest.c                 | 22 +++++++++++++++++++++
 tests/libtest.h                 |  9 +++++++++
 tests/nft-expr_bitwise-test.c   | 29 +++------------------------
 tests/nft-expr_byteorder-test.c | 24 +++-------------------
 tests/nft-expr_cmp-test.c       | 21 +++-----------------
 tests/nft-expr_counter-test.c   | 15 +++-----------
 tests/nft-expr_ct-test.c        | 17 +++-------------
 tests/nft-expr_dup-test.c       | 15 +++-----------
 tests/nft-expr_exthdr-test.c    | 21 +++-----------------
 tests/nft-expr_fwd-test.c       | 12 +++--------
 tests/nft-expr_immediate-test.c | 44 ++++++-----------------------------------
 tests/nft-expr_limit-test.c     | 24 +++-------------------
 tests/nft-expr_log-test.c       | 21 +++-----------------
 tests/nft-expr_lookup-test.c    | 27 +++----------------------
 tests/nft-expr_masq-test.c      | 18 +++--------------
 tests/nft-expr_match-test.c     | 22 +++------------------
 tests/nft-expr_meta-test.c      | 15 +++-----------
 tests/nft-expr_nat-test.c       | 30 +++-------------------------
 tests/nft-expr_payload-test.c   | 21 +++-----------------
 tests/nft-expr_queue-test.c     | 15 +++-----------
 tests/nft-expr_redir-test.c     | 18 +++--------------
 tests/nft-expr_reject-test.c    | 15 +++-----------
 tests/nft-expr_target-test.c    | 22 +++------------------
 tests/nft-rule-test.c           | 38 +++--------------------------------
 24 files changed, 100 insertions(+), 415 deletions(-)

diff --git a/tests/libtest.c b/tests/libtest.c
index 91f2d5e..9ce38ff 100644
--- a/tests/libtest.c
+++ b/tests/libtest.c
@@ -11,6 +11,8 @@
 #define COLOR_GREEN   "\x1b[32m"
 #define COLOR_RESET   "\x1b[0m"
 
+#define SNPRINTF_BUFF_LEN 1024
+
 static bool test_ok = true;
 
 void __oom(const char *prog, const char *file, int line)
@@ -47,3 +49,23 @@ int test_exit(const char *prog)
 		return EXIT_FAILURE;
 	}
 }
+
+const char *rule2str(const struct nftnl_rule *r)
+{
+	static char buff[SNPRINTF_BUFF_LEN];
+
+	nftnl_rule_snprintf(buff, SNPRINTF_BUFF_LEN, r,
+			    NFTNL_OUTPUT_DEFAULT, 0);
+
+	return buff;
+}
+
+const char *expr2str(const struct nftnl_expr *e)
+{
+	static char buff[SNPRINTF_BUFF_LEN];
+
+	nftnl_expr_snprintf(buff, SNPRINTF_BUFF_LEN, e,
+			    NFTNL_OUTPUT_DEFAULT, 0);
+
+	return buff;
+}
diff --git a/tests/libtest.h b/tests/libtest.h
index 810bd82..af469ce 100644
--- a/tests/libtest.h
+++ b/tests/libtest.h
@@ -1,9 +1,18 @@
 #ifndef _TESTS_UTILS_H
 #define _TESTS_UTILS_H
 
+#include <stdbool.h>
+#include <libmnl/libmnl.h>
+#include <libnftnl/common.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
+
 #define oom(prog) __oom(prog, __FILE__, __LINE__)
 void __oom(const char *prog, const char *file, int line);
 void print_err(const char *fmt, ...);
 int test_exit(const char *prog);
 
+const char *rule2str(const struct nftnl_rule *r);
+const char *expr2str(const struct nftnl_expr *e);
+
 #endif
diff --git a/tests/nft-expr_bitwise-test.c b/tests/nft-expr_bitwise-test.c
index bf76cb2..a661be6 100644
--- a/tests/nft-expr_bitwise-test.c
+++ b/tests/nft-expr_bitwise-test.c
@@ -21,31 +21,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	uint32_t maska, maskb;
-	uint32_t xora, xorb;
-
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_DREG))
-		print_err("Expr BITWISE_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_SREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_SREG))
-		print_err("Expr BITWISE_SREG mismatches");
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_BITWISE_LEN) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_BITWISE_LEN))
-		print_err("Expr BITWISE_DREG mismatches");
-	nftnl_expr_get(rule_a, NFTNL_EXPR_BITWISE_MASK, &maska);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_BITWISE_MASK, &maskb);
-	if (maska != maskb)
-		print_err("Size of BITWISE_MASK mismatches");
-	nftnl_expr_get(rule_a, NFTNL_EXPR_BITWISE_XOR, &xora);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_BITWISE_XOR, &xorb);
-	if (xora != xorb)
-		print_err("Size of BITWISE_XOR mismatches");
-
-}
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b = NULL;
@@ -96,7 +71,9 @@ int main(int argc, char *argv[])
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 
-	cmp_nftnl_expr(rule_a,rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
diff --git a/tests/nft-expr_byteorder-test.c b/tests/nft-expr_byteorder-test.c
index cbdd1d7..46bfd44 100644
--- a/tests/nft-expr_byteorder-test.c
+++ b/tests/nft-expr_byteorder-test.c
@@ -21,26 +21,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_DREG))
-		print_err("Expr NFTNL_EXPR_BYTEORDER_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_SREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_SREG))
-		print_err("Expr NFTNL_EXPR_BYTEORDER_SREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_OP) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_OP))
-		print_err("Expr NFTNL_EXPR_BYTEORDER_OP mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_LEN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_LEN))
-		print_err("Expr NFTNL_EXPR_BYTEORDER_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_SIZE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_SIZE))
-		print_err("Expr NFTNL_EXPR_BITWISE_SIZE mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -82,7 +62,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a,rule_b);
+	if (!nftnl_expr_cmp(rule_a,rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_cmp-test.c b/tests/nft-expr_cmp-test.c
index 5c1917d..ffa4e9a 100644
--- a/tests/nft-expr_cmp-test.c
+++ b/tests/nft-expr_cmp-test.c
@@ -21,23 +21,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	uint32_t data_lena, data_lenb;
-
-	nftnl_expr_get(rule_a, NFTNL_EXPR_CMP_DATA, &data_lena);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_CMP_DATA, &data_lenb);
-	if (data_lena != data_lenb)
-		print_err("Size of NFTNL_EXPR_CMP_DATA mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CMP_SREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CMP_SREG))
-		print_err("Expr NFTNL_EXPR_CMP_SREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CMP_OP) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CMP_OP))
-		print_err("Expr NFTNL_EXPR_CMP_OP mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -77,7 +60,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_counter-test.c b/tests/nft-expr_counter-test.c
index 5bbaf68..8b592b1 100644
--- a/tests/nft-expr_counter-test.c
+++ b/tests/nft-expr_counter-test.c
@@ -22,17 +22,6 @@
 #include <libtest.h>
 
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_CTR_BYTES) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_CTR_BYTES))
-		print_err("Expr NFTNL_EXPR_CTR_BYTES mismatches");
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_CTR_PACKETS) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_CTR_PACKETS))
-		print_err("Expr NFTNL_EXPR_CTR_PACKETS mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -70,7 +59,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_ct-test.c b/tests/nft-expr_ct-test.c
index 0a19513..327b25e 100644
--- a/tests/nft-expr_ct-test.c
+++ b/tests/nft-expr_ct-test.c
@@ -21,19 +21,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CT_KEY) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CT_KEY))
-		print_err("Expr CT_KEY mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CT_DIR) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CT_DIR))
-		print_err("Expr CT_DIR mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CT_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CT_DREG))
-		print_err("Expr CT_DREG mismatches");
-}
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -73,7 +60,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_dup-test.c b/tests/nft-expr_dup-test.c
index 11acd14..85702b7 100644
--- a/tests/nft-expr_dup-test.c
+++ b/tests/nft-expr_dup-test.c
@@ -21,17 +21,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_DUP_SREG_ADDR) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_DUP_SREG_ADDR))
-		print_err("Expr SREG_TO mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_DUP_SREG_DEV) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_DUP_SREG_DEV))
-		print_err("Expr SREG_OIF mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -70,7 +59,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_exthdr-test.c b/tests/nft-expr_exthdr-test.c
index 1418bb5..562275c 100644
--- a/tests/nft-expr_exthdr-test.c
+++ b/tests/nft-expr_exthdr-test.c
@@ -21,23 +21,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_EXTHDR_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_EXTHDR_DREG))
-		print_err("Expr NFTNL_EXPR_EXTHDR_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_EXTHDR_TYPE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_EXTHDR_TYPE))
-		print_err("Expr NFTNL_EXPR_EXTHDR_TYPE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_EXTHDR_OFFSET) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_EXTHDR_OFFSET))
-		print_err("Expr NFTNL_EXPR_EXTHDR_OFFSET mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_EXTHDR_LEN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_EXTHDR_LEN))
-		print_err("Expr NFTNL_EXPR_EXTHDR_LEN mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -77,7 +60,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_fwd-test.c b/tests/nft-expr_fwd-test.c
index 70a72c3..4b5c739 100644
--- a/tests/nft-expr_fwd-test.c
+++ b/tests/nft-expr_fwd-test.c
@@ -21,14 +21,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_FWD_SREG_DEV) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_FWD_SREG_DEV))
-		print_err("Expr SREG_OIF mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -66,7 +58,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_immediate-test.c b/tests/nft-expr_immediate-test.c
index 088987f..731ba40 100644
--- a/tests/nft-expr_immediate-test.c
+++ b/tests/nft-expr_immediate-test.c
@@ -21,42 +21,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr_verdict(struct nftnl_expr *rule_a,
-				   struct nftnl_expr *rule_b)
-{
-	uint32_t len_a, len_b;
-	const char *chain_a, *chain_b;
-
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_IMM_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_IMM_DREG))
-		print_err("Expr NFTNL_EXPR_IMM_DREG mismatches");
-
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_IMM_VERDICT) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_IMM_VERDICT))
-		print_err("Expr NFTNL_EXPR_IMM_VERDICT mismatches");
-
-	chain_a = nftnl_expr_get(rule_a, NFTNL_EXPR_IMM_CHAIN, &len_a);
-	chain_b = nftnl_expr_get(rule_b, NFTNL_EXPR_IMM_CHAIN, &len_b);
-	if (len_a != len_b || strncmp(chain_a, chain_b, len_a))
-		print_err("Expr NFTNL_EXPR_IMM_CHAIN mismatches");
-}
-
-static void cmp_nftnl_expr_value(struct nftnl_expr *rule_a,
-				 struct nftnl_expr *rule_b)
-{
-	const uint32_t *data_a, *data_b;
-	uint32_t len_a, len_b;
-
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_IMM_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_IMM_DREG))
-		print_err("Expr NFTNL_EXPR_IMM_DREG mismatches");
-
-	data_a = nftnl_expr_get(rule_a, NFTNL_EXPR_IMM_DATA, &len_a);
-	data_b = nftnl_expr_get(rule_b, NFTNL_EXPR_IMM_DATA, &len_b);
-	if (len_a != len_b || memcmp(data_a, data_b, len_a))
-		print_err("Expr NFTNL_EXPR_IMM_DATA mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -103,14 +67,18 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr_value(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr_verdict(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_limit-test.c b/tests/nft-expr_limit-test.c
index fc57775..197fb04 100644
--- a/tests/nft-expr_limit-test.c
+++ b/tests/nft-expr_limit-test.c
@@ -22,26 +22,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_RATE) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_RATE))
-		print_err("Expr CTR_BYTES mismatches");
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_UNIT) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_UNIT))
-		print_err("Expr CTR_PACKET mismatches");
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_BURST) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_BURST))
-		print_err("Expr CTR_PACKET mismatches");
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_TYPE) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_TYPE))
-		print_err("Expr TYPE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LIMIT_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LIMIT_FLAGS))
-		print_err("Expr FLAGS mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -83,7 +63,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_log-test.c b/tests/nft-expr_log-test.c
index 1ddad82..12bba13 100644
--- a/tests/nft-expr_log-test.c
+++ b/tests/nft-expr_log-test.c
@@ -21,23 +21,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOG_SNAPLEN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOG_SNAPLEN))
-		print_err("Expr NFTNL_EXPR_LOG_SNAPLEN mismatches");
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_LOG_GROUP) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_LOG_GROUP))
-		print_err("Expr NFTNL_EXPR_LOG_GROUP mismatches");
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_LOG_QTHRESHOLD) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_LOG_QTHRESHOLD))
-		print_err("Expr NFTNL_EXPR_LOG_QTHRESHOLD mismatches");
-	if(strcmp(nftnl_expr_get_str(rule_a, NFTNL_EXPR_LOG_PREFIX),
-		  nftnl_expr_get_str(rule_b, NFTNL_EXPR_LOG_PREFIX)) != 0)
-		print_err("Expr NFTNL_EXPR_LOG_PREFIX mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -76,7 +59,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_lookup-test.c b/tests/nft-expr_lookup-test.c
index 68643f2..49a54ff 100644
--- a/tests/nft-expr_lookup-test.c
+++ b/tests/nft-expr_lookup-test.c
@@ -21,29 +21,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_SREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_SREG))
-		print_err("Expr NFTNL_EXPR_LOOKUP_SREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_DREG))
-		print_err("Expr NFTNL_EXPR_LOOKUP_DREG mismatches");
-	if (strcmp(nftnl_expr_get_str(rule_a, NFTNL_EXPR_LOOKUP_SET),
-		   nftnl_expr_get_str(rule_b, NFTNL_EXPR_LOOKUP_SET)))
-		print_err("Expr NFTNL_EXPR_LOOKUP_SET mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_SET_ID) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_SET_ID))
-		print_err("Expr NFTNL_EXPR_LOOKUP_SET_ID mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_FLAGS)) {
-		print_err("Expr NFTNL_EXPR_LOOKUP_FLAGS mismatches");
-		printf("%X %X\n",
-			nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_FLAGS),
-			nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_FLAGS));
-	}
-}
 
 int main(int argc, char *argv[])
 {
@@ -85,7 +62,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_masq-test.c b/tests/nft-expr_masq-test.c
index 2727f37..a81f54c 100644
--- a/tests/nft-expr_masq-test.c
+++ b/tests/nft-expr_masq-test.c
@@ -19,20 +19,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_MASQ_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_MASQ_FLAGS))
-		print_err("Expr NFTNL_EXPR_MASQ_FLAGS mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_MASQ_REG_PROTO_MIN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_MASQ_REG_PROTO_MIN))
-		print_err("Expr NFTNL_EXPR_MASQ_REG_PROTO_MIN mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_MASQ_REG_PROTO_MAX) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_MASQ_REG_PROTO_MAX))
-		print_err("Expr NFTNL_EXPR_MASQ_REG_PROTO_MAX mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -72,7 +58,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_match-test.c b/tests/nft-expr_match-test.c
index 14c32ab..700b6ff 100644
--- a/tests/nft-expr_match-test.c
+++ b/tests/nft-expr_match-test.c
@@ -22,24 +22,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	uint32_t lena, lenb;
-
-	if (strcmp(nftnl_expr_get_str(rule_a, NFTNL_EXPR_MT_NAME),
-		   nftnl_expr_get_str(rule_b, NFTNL_EXPR_MT_NAME)) != 0)
-		print_err("Expr NFTNL_EXPR_MT_NAME mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_MT_REV) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_MT_REV))
-		print_err("Expr NFTNL_EXPR_MT_REV mismatches");
-	nftnl_expr_get(rule_a, NFTNL_EXPR_MT_INFO, &lena);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_MT_INFO, &lenb);
-	if (lena != lenb)
-		print_err("Expr NFTNL_EXPR_MT_INFO size mismatches: %d != %d",
-			  lena, lenb);
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -78,7 +60,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_meta-test.c b/tests/nft-expr_meta-test.c
index 72bfd1e..943ead2 100644
--- a/tests/nft-expr_meta-test.c
+++ b/tests/nft-expr_meta-test.c
@@ -21,17 +21,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_META_KEY) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_META_KEY))
-		print_err("Expr NFTNL_EXPR_META_KEY mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_META_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_META_DREG))
-		print_err("Expr NFTNL_EXPR_META_DREG mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -69,7 +58,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_nat-test.c b/tests/nft-expr_nat-test.c
index 5829d1d..fe20bcd 100644
--- a/tests/nft-expr_nat-test.c
+++ b/tests/nft-expr_nat-test.c
@@ -22,32 +22,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_TYPE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_TYPE))
-		print_err("Expr NFTNL_EXPR_NAT_TYPE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_FAMILY) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_FAMILY))
-		print_err("Expr NFTNL_EXPR_NAT_FAMILY mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_REG_ADDR_MIN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_REG_ADDR_MIN))
-		print_err("Expr NFTNL_EXPR_NAT_REG_ADDR_MIN mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_REG_ADDR_MAX) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_REG_ADDR_MAX))
-		print_err("Expr NFTNL_EXPR_NAT_REG_ADDR_MAX mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_REG_PROTO_MIN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_REG_PROTO_MIN))
-		print_err("Expr NFTNL_EXPR_NAT_REG_PROTO_MIN mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_REG_PROTO_MAX) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_REG_PROTO_MAX))
-		print_err("Expr NFTNL_EXPR_NAT_REG_PROTO_MAX mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_FLAGS))
-		print_err("Expr NFTNL_EXPR_NAT_FLAGS mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -91,7 +65,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_payload-test.c b/tests/nft-expr_payload-test.c
index f452f96..0999941 100644
--- a/tests/nft-expr_payload-test.c
+++ b/tests/nft-expr_payload-test.c
@@ -22,23 +22,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_PAYLOAD_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_PAYLOAD_DREG))
-		print_err("Expr NFTNL_EXPR_PAYLOAD_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_PAYLOAD_BASE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_PAYLOAD_BASE))
-		print_err("Expr NFTNL_EXPR_PAYLOAD_BASE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_PAYLOAD_OFFSET) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_PAYLOAD_OFFSET))
-		print_err("Expr NFTNL_EXPR_PAYLOAD_OFFSET mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_PAYLOAD_LEN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_PAYLOAD_LEN))
-		print_err("Expr NFTNL_EXPR_PAYLOAD_LEN mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -78,7 +61,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_queue-test.c b/tests/nft-expr_queue-test.c
index b3c6848..210143e 100644
--- a/tests/nft-expr_queue-test.c
+++ b/tests/nft-expr_queue-test.c
@@ -24,17 +24,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_QUEUE_NUM) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_QUEUE_NUM))
-		print_err("Expr NFTNL_EXPR_QUEUE_NUM mismatches");
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_QUEUE_TOTAL) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_QUEUE_TOTAL))
-		print_err("Expr NFTNL_EXPR_QUEUE_TOTAL mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -74,7 +63,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_redir-test.c b/tests/nft-expr_redir-test.c
index ce21dca..3948921 100644
--- a/tests/nft-expr_redir-test.c
+++ b/tests/nft-expr_redir-test.c
@@ -19,20 +19,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REDIR_REG_PROTO_MIN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REDIR_REG_PROTO_MIN))
-		print_err("Expr NFTNL_EXPR_REDIR_REG_PROTO_MIN mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REDIR_REG_PROTO_MAX) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REDIR_REG_PROTO_MAX))
-		print_err("Expr NFTNL_EXPR_REDIR_REG_PROTO_MAX mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REDIR_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REDIR_FLAGS))
-		print_err("Expr NFTNL_EXPR_REDIR_FLAGS mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -72,7 +58,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_reject-test.c b/tests/nft-expr_reject-test.c
index cafd4ba..d92d4e0 100644
--- a/tests/nft-expr_reject-test.c
+++ b/tests/nft-expr_reject-test.c
@@ -22,17 +22,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REJECT_TYPE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REJECT_TYPE))
-		print_err("Expr NFTNL_EXPR_REJECT_TYPE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REJECT_CODE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REJECT_CODE))
-		print_err("Expr NFTNL_EXPR_REJECT_CODE mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -71,7 +60,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_target-test.c b/tests/nft-expr_target-test.c
index 77d877c..c8611f3 100644
--- a/tests/nft-expr_target-test.c
+++ b/tests/nft-expr_target-test.c
@@ -21,24 +21,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	uint32_t lena, lenb;
-
-	if (strcmp(nftnl_expr_get_str(rule_a, NFTNL_EXPR_TG_NAME),
-		   nftnl_expr_get_str(rule_b, NFTNL_EXPR_TG_NAME)) != 0)
-		print_err("Expr NFTNL_EXPR_TG_NAME mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_TG_REV) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_TG_REV))
-		print_err("Expr NFTNL_EXPR_TG_REV mismatches");
-	nftnl_expr_get(rule_a, NFTNL_EXPR_TG_INFO, &lena);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_TG_INFO, &lenb);
-	if (lena != lenb)
-		print_err("Expr NFTNL_EXPR_TG_INFO size mismatches: %d != %d",
-			  lena, lenb);
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -79,7 +61,9 @@ int main(int argc, char *argv[])
 	if (rule_a == NULL || rule_b == NULL)
 		oom(argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	if (!nftnl_expr_cmp(rule_a, rule_b))
+		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(rule_a), expr2str(rule_b));
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-rule-test.c b/tests/nft-rule-test.c
index 5c1b52d..57f5bb4 100644
--- a/tests/nft-rule-test.c
+++ b/tests/nft-rule-test.c
@@ -19,40 +19,6 @@
 
 #include <libtest.h>
 
-static void cmp_nftnl_rule(struct nftnl_rule *a, struct nftnl_rule *b)
-{
-	const void *udata_a, *udata_b;
-	uint32_t len_a, len_b;
-
-	if (nftnl_rule_get_u32(a, NFTNL_RULE_FAMILY) !=
-	    nftnl_rule_get_u32(b, NFTNL_RULE_FAMILY))
-		print_err("Rule family mismatches");
-	if (strcmp(nftnl_rule_get_str(a, NFTNL_RULE_TABLE),
-		   nftnl_rule_get_str(b, NFTNL_RULE_TABLE)) != 0)
-		print_err("Rule table mismatches");
-	if (strcmp(nftnl_rule_get_str(a, NFTNL_RULE_CHAIN),
-		   nftnl_rule_get_str(b, NFTNL_RULE_CHAIN)) != 0)
-		print_err("Rule table mismatches");
-	if (nftnl_rule_get_u64(a, NFTNL_RULE_HANDLE) !=
-	    nftnl_rule_get_u64(b, NFTNL_RULE_HANDLE))
-		print_err("Rule handle mismatches");
-	if (nftnl_rule_get_u32(a, NFTNL_RULE_COMPAT_PROTO) !=
-	    nftnl_rule_get_u32(b, NFTNL_RULE_COMPAT_PROTO))
-		print_err("Rule compat_proto mismatches");
-	if (nftnl_rule_get_u32(a, NFTNL_RULE_COMPAT_FLAGS) !=
-	    nftnl_rule_get_u32(b, NFTNL_RULE_COMPAT_FLAGS))
-		print_err("Rule compat_flags mismatches");
-	if (nftnl_rule_get_u64(a, NFTNL_RULE_POSITION) !=
-	    nftnl_rule_get_u64(b, NFTNL_RULE_POSITION))
-		print_err("Rule compat_position mismatches");
-
-	udata_a = nftnl_rule_get_data(a, NFTNL_RULE_USERDATA, &len_a);
-	udata_b = nftnl_rule_get_data(b, NFTNL_RULE_USERDATA, &len_b);
-
-	if (len_a != len_b || memcmp(udata_a, udata_b, len_a) != 0)
-		print_err("Rule userdata mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_udata_buf *udata;
@@ -90,7 +56,9 @@ int main(int argc, char *argv[])
 	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
 		print_err("parsing problems");
 
-	cmp_nftnl_rule(a,b);
+	if (!nftnl_rule_cmp(a, b))
+		print_err("rules mismatches:\nRULE 1:\n%s\nRULE 2:\n%s",
+			  rule2str(a), rule2str(b));
 
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
-- 
2.8.3


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/2, libnftnl] tests: Consolidate printing error utilities
  2016-08-11 13:25 [PATCH 1/2, libnftnl] tests: Consolidate printing error utilities Carlos Falgueras García
  2016-08-11 13:25 ` [PATCH 2/2, libnftnl] Use libnftnl comparators in all tests Carlos Falgueras García
@ 2016-08-11 23:26 ` Pablo Neira Ayuso
  2016-08-12 20:16   ` Carlos Falgueras García
  1 sibling, 1 reply; 31+ messages in thread
From: Pablo Neira Ayuso @ 2016-08-11 23:26 UTC (permalink / raw)
  To: Carlos Falgueras García; +Cc: netfilter-devel

On Thu, Aug 11, 2016 at 03:25:06PM +0200, Carlos Falgueras García wrote:
> Created libtest.[hc] in order to consolidate code that is repeated in all
> tests.

Please, use present tense, eg.

This patch adds libtest.c and libtest.h to reduce test code and
consolidate it.

> diff --git a/tests/libtest.c b/tests/libtest.c
> new file mode 100644
> index 0000000..91f2d5e
> --- /dev/null
> +++ b/tests/libtest.c
> @@ -0,0 +1,49 @@
> +#include <libtest.h>
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <stdarg.h>
> +#include <string.h>
> +#include <errno.h>
> +#include <stdbool.h>
> +
> +#define COLOR_RED     "\x1b[31m"
> +#define COLOR_GREEN   "\x1b[32m"
> +#define COLOR_RESET   "\x1b[0m"
> +
> +static bool test_ok = true;

I don't like this internal test_ok.

> +void __oom(const char *prog, const char *file, int line)
> +{
> +	fprintf(stderr,
> +		COLOR_RED "OOM" COLOR_RESET " at %s:%d\n\t%s\n", file, line,
> +		strerror(errno));
> +
> +	test_ok = false;
> +	test_exit(prog);
> +	exit(EXIT_FAILURE);
> +}
> +
> +void print_err(const char *fmt, ...)
> +{
> +	va_list args;
> +
> +	fprintf(stderr, COLOR_RED "ERROR: " COLOR_RESET);
> +	va_start(args, fmt);
> +	vfprintf(stderr, fmt, args);
> +	va_end(args);
> +	fprintf(stderr, "\n");
> +
> +	test_ok = false;
> +}
> +
> +int test_exit(const char *prog)
> +{
> +	if (test_ok) {
> +		printf("%s: " COLOR_GREEN "OK\n" COLOR_RESET, prog);
> +		return EXIT_SUCCESS;
> +	} else {
> +		printf("%s: " COLOR_RED "FAIL\n" COLOR_RESET, prog);
> +		return EXIT_FAILURE;
> +	}

Looks better like this?

	switch (test_ok) {
        case true:
		printf("%s: " COLOR_GREEN "OK\n" COLOR_RESET, prog);
		return EXIT_SUCCESS;
        case false:
        	printf("%s: " COLOR_RED "FAIL\n" COLOR_RESET, prog);
               	return EXIT_FAILURE;
        }

> +}
> diff --git a/tests/libtest.h b/tests/libtest.h
> new file mode 100644
> index 0000000..810bd82
> --- /dev/null
> +++ b/tests/libtest.h
> @@ -0,0 +1,9 @@
> +#ifndef _TESTS_UTILS_H
> +#define _TESTS_UTILS_H
> +
> +#define oom(prog) __oom(prog, __FILE__, __LINE__)
> +void __oom(const char *prog, const char *file, int line);
> +void print_err(const char *fmt, ...);
> +int test_exit(const char *prog);
> +
> +#endif
> diff --git a/tests/nft-chain-test.c b/tests/nft-chain-test.c
> index d678d46..82431c2 100644
> --- a/tests/nft-chain-test.c
> +++ b/tests/nft-chain-test.c
> @@ -15,13 +15,7 @@
>  #include <linux/netfilter/nf_tables.h>
>  #include <libnftnl/chain.h>
>  
> -static int test_ok = 1;
> -
> -static void print_err(const char *msg)
> -{
> -	test_ok = 0;
> -	printf("\033[31mERROR:\e[0m %s\n", msg);
> -}
> +#include <libtest.h>

Please, use:

#include "libtest.h" instead, I prefer it so we know this is locally
declare it.

>  static void cmp_nftnl_chain(struct nftnl_chain *a, struct nftnl_chain *b)
>  {
> @@ -73,7 +67,7 @@ int main(int argc, char *argv[])
>  	a = nftnl_chain_alloc();
>  	b = nftnl_chain_alloc();
>  	if (a == NULL || b == NULL)
> -		print_err("OOM");
> +		oom(argv[0]);

You can replace this above by:

        test_assert(a != NULL);
        test_assert(b != NULL);

>  	nftnl_chain_set_str(a, NFTNL_CHAIN_NAME, "test");
>  	nftnl_chain_set_u32(a, NFTNL_CHAIN_FAMILY, AF_INET);
> @@ -101,10 +95,6 @@ int main(int argc, char *argv[])
>  	nftnl_chain_free(a);
>  	nftnl_chain_free(b);
>  
> -	if (!test_ok)
> -		exit(EXIT_FAILURE);
> -
> -	printf("%s: \033[32mOK\e[0m\n", argv[0]);
> -	return EXIT_SUCCESS;
> +	return test_exit(argv[0]);

Better name, instead of test_exit:

        return test_report(argv[0]);

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/2, libnftnl] Use libnftnl comparators in all tests
  2016-08-11 13:25 ` [PATCH 2/2, libnftnl] Use libnftnl comparators in all tests Carlos Falgueras García
@ 2016-08-11 23:32   ` Pablo Neira Ayuso
  2016-08-12 20:16     ` Carlos Falgueras García
  2016-08-12 20:17     ` [PATCH 1/4, V2, libnftnl] tests: Fix segfaults due outbound access Carlos Falgueras García
  0 siblings, 2 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2016-08-11 23:32 UTC (permalink / raw)
  To: Carlos Falgueras García; +Cc: netfilter-devel

On Thu, Aug 11, 2016 at 03:25:07PM +0200, Carlos Falgueras García wrote:
> Use 'nftnl_expr_cmp' and 'nftnl_rule_cmp' in all tests instead of custom
> comparator for each one. If objects differ both are printed.
> 
> Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
> ---
>  tests/libtest.c                 | 22 +++++++++++++++++++++
>  tests/libtest.h                 |  9 +++++++++
>  tests/nft-expr_bitwise-test.c   | 29 +++------------------------
>  tests/nft-expr_byteorder-test.c | 24 +++-------------------
>  tests/nft-expr_cmp-test.c       | 21 +++-----------------
>  tests/nft-expr_counter-test.c   | 15 +++-----------
>  tests/nft-expr_ct-test.c        | 17 +++-------------
>  tests/nft-expr_dup-test.c       | 15 +++-----------
>  tests/nft-expr_exthdr-test.c    | 21 +++-----------------
>  tests/nft-expr_fwd-test.c       | 12 +++--------
>  tests/nft-expr_immediate-test.c | 44 ++++++-----------------------------------
>  tests/nft-expr_limit-test.c     | 24 +++-------------------
>  tests/nft-expr_log-test.c       | 21 +++-----------------
>  tests/nft-expr_lookup-test.c    | 27 +++----------------------
>  tests/nft-expr_masq-test.c      | 18 +++--------------
>  tests/nft-expr_match-test.c     | 22 +++------------------
>  tests/nft-expr_meta-test.c      | 15 +++-----------
>  tests/nft-expr_nat-test.c       | 30 +++-------------------------
>  tests/nft-expr_payload-test.c   | 21 +++-----------------
>  tests/nft-expr_queue-test.c     | 15 +++-----------
>  tests/nft-expr_redir-test.c     | 18 +++--------------
>  tests/nft-expr_reject-test.c    | 15 +++-----------
>  tests/nft-expr_target-test.c    | 22 +++------------------
>  tests/nft-rule-test.c           | 38 +++--------------------------------
>  24 files changed, 100 insertions(+), 415 deletions(-)
> 
> diff --git a/tests/libtest.c b/tests/libtest.c
> index 91f2d5e..9ce38ff 100644
> --- a/tests/libtest.c
> +++ b/tests/libtest.c
> @@ -11,6 +11,8 @@
>  #define COLOR_GREEN   "\x1b[32m"
>  #define COLOR_RESET   "\x1b[0m"
>  
> +#define SNPRINTF_BUFF_LEN 1024
> +
>  static bool test_ok = true;
>  
>  void __oom(const char *prog, const char *file, int line)
> @@ -47,3 +49,23 @@ int test_exit(const char *prog)
>  		return EXIT_FAILURE;
>  	}
>  }

Better place the definition here, close to where it is used and
meaningful.

> +const char *rule2str(const struct nftnl_rule *r)
> +{
> +	static char buff[SNPRINTF_BUFF_LEN];
> +
> +	nftnl_rule_snprintf(buff, SNPRINTF_BUFF_LEN, r,
> +			    NFTNL_OUTPUT_DEFAULT, 0);

This fits into one line:

	nftnl_rule_snprintf(buf, sizeof(buf), r, NFTNL_OUTPUT_DEFAULT, 0);

> +
> +	return buff;
> +}
> +
> +const char *expr2str(const struct nftnl_expr *e)
> +{
> +	static char buff[SNPRINTF_BUFF_LEN];
> +
> +	nftnl_expr_snprintf(buff, SNPRINTF_BUFF_LEN, e,
> +			    NFTNL_OUTPUT_DEFAULT, 0);
> +
> +	return buff;
> +}
> diff --git a/tests/libtest.h b/tests/libtest.h
> index 810bd82..af469ce 100644
> --- a/tests/libtest.h
> +++ b/tests/libtest.h
> @@ -1,9 +1,18 @@
>  #ifndef _TESTS_UTILS_H
>  #define _TESTS_UTILS_H
>  
> +#include <stdbool.h>
> +#include <libmnl/libmnl.h>
> +#include <libnftnl/common.h>
> +#include <libnftnl/rule.h>
> +#include <libnftnl/expr.h>
> +
>  #define oom(prog) __oom(prog, __FILE__, __LINE__)
>  void __oom(const char *prog, const char *file, int line);
>  void print_err(const char *fmt, ...);
>  int test_exit(const char *prog);
>  
> +const char *rule2str(const struct nftnl_rule *r);
> +const char *expr2str(const struct nftnl_expr *e);
> +
>  #endif
> diff --git a/tests/nft-expr_bitwise-test.c b/tests/nft-expr_bitwise-test.c
> index bf76cb2..a661be6 100644
> --- a/tests/nft-expr_bitwise-test.c
> +++ b/tests/nft-expr_bitwise-test.c
> @@ -21,31 +21,6 @@
>  
>  #include <libtest.h>
>  
> -static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
> -			      struct nftnl_expr *rule_b)
> -{
> -	uint32_t maska, maskb;
> -	uint32_t xora, xorb;
> -
> -	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_DREG) !=
> -	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_DREG))
> -		print_err("Expr BITWISE_DREG mismatches");
> -	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_SREG) !=
> -	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_SREG))
> -		print_err("Expr BITWISE_SREG mismatches");
> -	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_BITWISE_LEN) !=
> -	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_BITWISE_LEN))
> -		print_err("Expr BITWISE_DREG mismatches");
> -	nftnl_expr_get(rule_a, NFTNL_EXPR_BITWISE_MASK, &maska);
> -	nftnl_expr_get(rule_b, NFTNL_EXPR_BITWISE_MASK, &maskb);
> -	if (maska != maskb)
> -		print_err("Size of BITWISE_MASK mismatches");
> -	nftnl_expr_get(rule_a, NFTNL_EXPR_BITWISE_XOR, &xora);
> -	nftnl_expr_get(rule_b, NFTNL_EXPR_BITWISE_XOR, &xorb);
> -	if (xora != xorb)
> -		print_err("Size of BITWISE_XOR mismatches");
> -
> -}
>  int main(int argc, char *argv[])
>  {
>  	struct nftnl_rule *a, *b = NULL;
> @@ -96,7 +71,9 @@ int main(int argc, char *argv[])
>  	nftnl_expr_iter_destroy(iter_a);
>  	nftnl_expr_iter_destroy(iter_b);
>  
> -	cmp_nftnl_expr(rule_a,rule_b);
> +	if (!nftnl_expr_cmp(rule_a, rule_b))
> +		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
> +			  expr2str(rule_a), expr2str(rule_b));

Better, add something like

                print_expr_mismatch(rule_a, rule_b);

This should be "expressions mismatch" instead of "expressions
mismatches".

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/2, libnftnl] tests: Consolidate printing error utilities
  2016-08-11 23:26 ` [PATCH 1/2, libnftnl] tests: Consolidate printing error utilities Pablo Neira Ayuso
@ 2016-08-12 20:16   ` Carlos Falgueras García
  0 siblings, 0 replies; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-12 20:16 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

On 08/12/2016 01:26 AM, Pablo Neira Ayuso wrote:
> On Thu, Aug 11, 2016 at 03:25:06PM +0200, Carlos Falgueras García wrote:
>> diff --git a/tests/libtest.c b/tests/libtest.c
>> new file mode 100644
>> index 0000000..91f2d5e
>> --- /dev/null
>> +++ b/tests/libtest.c
>> @@ -0,0 +1,49 @@
>> +#include <libtest.h>
>> +
>> +#include <stdio.h>
>> +#include <stdlib.h>
>> +#include <stdarg.h>
>> +#include <string.h>
>> +#include <errno.h>
>> +#include <stdbool.h>
>> +
>> +#define COLOR_RED     "\x1b[31m"
>> +#define COLOR_GREEN   "\x1b[32m"
>> +#define COLOR_RESET   "\x1b[0m"
>> +
>> +static bool test_ok = true;
>
> I don't like this internal test_ok.

I will get rid of this at the next patch. Doing it here means change a 
lot of code that I will delete in the next patch.

>>  static void cmp_nftnl_chain(struct nftnl_chain *a, struct nftnl_chain *b)
>>  {
>> @@ -73,7 +67,7 @@ int main(int argc, char *argv[])
>>  	a = nftnl_chain_alloc();
>>  	b = nftnl_chain_alloc();
>>  	if (a == NULL || b == NULL)
>> -		print_err("OOM");
>> +		oom(argv[0]);
>
> You can replace this above by:
>
>         test_assert(a != NULL);
>         test_assert(b != NULL);

I have changed this to 'oom_assert()' to distinguish it from a future 
'test_assert' that will replace current 'print_err'.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/2, libnftnl] Use libnftnl comparators in all tests
  2016-08-11 23:32   ` Pablo Neira Ayuso
@ 2016-08-12 20:16     ` Carlos Falgueras García
  2016-08-15 12:23       ` [PATCH 1/2 v2 libnftnl] tests: Consolidate printing error utilities Carlos Falgueras García
  2016-08-12 20:17     ` [PATCH 1/4, V2, libnftnl] tests: Fix segfaults due outbound access Carlos Falgueras García
  1 sibling, 1 reply; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-12 20:16 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

On 08/12/2016 01:32 AM, Pablo Neira Ayuso wrote:
> On Thu, Aug 11, 2016 at 03:25:07PM +0200, Carlos Falgueras García wrote:
>> -	cmp_nftnl_expr(rule_a,rule_b);
>> +	if (!nftnl_expr_cmp(rule_a, rule_b))
>> +		print_err("expressions mismatches:\n\texpr 1: %s\n\texpr 2: %s",
>> +			  expr2str(rule_a), expr2str(rule_b));
>
> Better, add something like
>
>                 print_expr_mismatch(rule_a, rule_b);

I have called this 'test_assert_{expr,rule}()' for consistency with 
'test_assert()'.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 1/4, V2, libnftnl] tests: Fix segfaults due outbound access
  2016-08-11 23:32   ` Pablo Neira Ayuso
  2016-08-12 20:16     ` Carlos Falgueras García
@ 2016-08-12 20:17     ` Carlos Falgueras García
  2016-08-12 20:17       ` [PATCH 2/4, V2, libnftnl] tests: Fix wrong expression creation Carlos Falgueras García
                         ` (3 more replies)
  1 sibling, 4 replies; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-12 20:17 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

Changes random values for macros because the conversion to string of these
values are performed by accessing to an array of strings.

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 tests/nft-expr_cmp-test.c | 2 +-
 tests/nft-expr_nat-test.c | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/tests/nft-expr_cmp-test.c b/tests/nft-expr_cmp-test.c
index ec00bb9..4271940 100644
--- a/tests/nft-expr_cmp-test.c
+++ b/tests/nft-expr_cmp-test.c
@@ -64,7 +64,7 @@ int main(int argc, char *argv[])
 
 	nftnl_expr_set(ex, NFTNL_EXPR_CMP_DATA, &data_len, sizeof(data_len));
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_CMP_SREG, 0x12345678);
-	nftnl_expr_set_u32(ex, NFTNL_EXPR_CMP_OP, 0x78123456);
+	nftnl_expr_set_u32(ex, NFTNL_EXPR_CMP_OP, NFT_CMP_LT);
 
 	nftnl_rule_add_expr(a, ex);
 
diff --git a/tests/nft-expr_nat-test.c b/tests/nft-expr_nat-test.c
index fd3a488..9c15a0a 100644
--- a/tests/nft-expr_nat-test.c
+++ b/tests/nft-expr_nat-test.c
@@ -71,8 +71,8 @@ int main(int argc, char *argv[])
 	if (ex == NULL)
 		print_err("OOM");
 
-	nftnl_expr_set_u32(ex, NFTNL_EXPR_NAT_TYPE, 0x1234568);
-	nftnl_expr_set_u32(ex, NFTNL_EXPR_NAT_FAMILY, 0x3456721);
+	nftnl_expr_set_u32(ex, NFTNL_EXPR_NAT_TYPE, NFT_NAT_SNAT);
+	nftnl_expr_set_u32(ex, NFTNL_EXPR_NAT_FAMILY, NFPROTO_INET);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_NAT_REG_ADDR_MIN, 0x1452638);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_NAT_REG_ADDR_MAX, 0x5134682);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_NAT_REG_PROTO_MIN, 0x6124385);
-- 
2.8.3


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 2/4, V2, libnftnl] tests: Fix wrong expression creation
  2016-08-12 20:17     ` [PATCH 1/4, V2, libnftnl] tests: Fix segfaults due outbound access Carlos Falgueras García
@ 2016-08-12 20:17       ` Carlos Falgueras García
  2016-08-13 10:25         ` Pablo Neira Ayuso
  2016-08-12 20:17       ` [PATCH 3/4, V2, libnftnl] tests: Consolidate printing error utilities Carlos Falgueras García
                         ` (2 subsequent siblings)
  3 siblings, 1 reply; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-12 20:17 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 tests/nft-expr_masq-test.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/nft-expr_masq-test.c b/tests/nft-expr_masq-test.c
index f0302e2..3f9903d 100644
--- a/tests/nft-expr_masq-test.c
+++ b/tests/nft-expr_masq-test.c
@@ -52,7 +52,7 @@ int main(int argc, char *argv[])
 	b = nftnl_rule_alloc();
 	if (a == NULL || b == NULL)
 		print_err("OOM");
-	ex = nftnl_expr_alloc("nat");
+	ex = nftnl_expr_alloc("masq");
 	if (ex == NULL)
 		print_err("OOM");
 
-- 
2.8.3


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 3/4, V2, libnftnl] tests: Consolidate printing error utilities
  2016-08-12 20:17     ` [PATCH 1/4, V2, libnftnl] tests: Fix segfaults due outbound access Carlos Falgueras García
  2016-08-12 20:17       ` [PATCH 2/4, V2, libnftnl] tests: Fix wrong expression creation Carlos Falgueras García
@ 2016-08-12 20:17       ` Carlos Falgueras García
  2016-08-12 20:17       ` [PATCH 4/4, V2, libnftnl] tests: Use libnftnl comparators in all tests Carlos Falgueras García
  2016-08-13 10:12       ` [PATCH 1/4, V2, libnftnl] tests: Fix segfaults due outbound access Pablo Neira Ayuso
  3 siblings, 0 replies; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-12 20:17 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

This patch adds libtest.c and libtest.h to reduce test code and
consolidate it.

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 .gitignore                      |  1 +
 tests/Makefile.am               | 52 +++++++++++++++++++++-------------------
 tests/libtest.c                 | 53 +++++++++++++++++++++++++++++++++++++++++
 tests/libtest.h                 | 11 +++++++++
 tests/nft-chain-test.c          | 18 ++++----------
 tests/nft-expr_bitwise-test.c   | 29 +++++++---------------
 tests/nft-expr_byteorder-test.c | 29 +++++++---------------
 tests/nft-expr_cmp-test.c       | 29 +++++++---------------
 tests/nft-expr_counter-test.c   | 27 +++++++--------------
 tests/nft-expr_ct-test.c        | 28 +++++++---------------
 tests/nft-expr_dup-test.c       | 28 +++++++---------------
 tests/nft-expr_exthdr-test.c    | 28 +++++++---------------
 tests/nft-expr_fwd-test.c       | 28 +++++++---------------
 tests/nft-expr_immediate-test.c | 34 ++++++++++----------------
 tests/nft-expr_limit-test.c     | 29 +++++++---------------
 tests/nft-expr_log-test.c       | 29 +++++++---------------
 tests/nft-expr_lookup-test.c    | 30 +++++++----------------
 tests/nft-expr_masq-test.c      | 29 +++++++---------------
 tests/nft-expr_match-test.c     | 38 +++++++++--------------------
 tests/nft-expr_meta-test.c      | 29 +++++++---------------
 tests/nft-expr_nat-test.c       | 29 +++++++---------------
 tests/nft-expr_payload-test.c   | 29 +++++++---------------
 tests/nft-expr_queue-test.c     | 29 +++++++---------------
 tests/nft-expr_redir-test.c     | 29 +++++++---------------
 tests/nft-expr_reject-test.c    | 29 +++++++---------------
 tests/nft-expr_target-test.c    | 37 +++++++++-------------------
 tests/nft-rule-test.c           | 20 ++++------------
 tests/nft-set-test.c            | 18 ++++----------
 tests/nft-table-test.c          | 17 ++++---------
 29 files changed, 305 insertions(+), 511 deletions(-)
 create mode 100644 tests/libtest.c
 create mode 100644 tests/libtest.h

diff --git a/.gitignore b/.gitignore
index 1650e58..5a781db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,4 +28,5 @@ examples/*
 !examples/Makefile.am
 tests/*
 !tests/*.c
+!tests/*.h
 !tests/Makefile.am
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0377081..b55aeba 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -4,6 +4,8 @@ EXTRA_DIST =		test-script.sh			\
 			jsonfiles			\
 			xmlfiles
 
+LIBTEST =		libtest.c
+
 check_PROGRAMS = 	nft-parsing-test		\
 			nft-table-test			\
 			nft-chain-test			\
@@ -34,77 +36,77 @@ check_PROGRAMS = 	nft-parsing-test		\
 nft_parsing_test_SOURCES = nft-parsing-test.c
 nft_parsing_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} ${LIBXML_LIBS} ${LIBJSON_LIBS}
 
-nft_table_test_SOURCES = nft-table-test.c
+nft_table_test_SOURCES = nft-table-test.c ${LIBTEST}
 nft_table_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_chain_test_SOURCES = nft-chain-test.c
+nft_chain_test_SOURCES = nft-chain-test.c ${LIBTEST}
 nft_chain_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_rule_test_SOURCES = nft-rule-test.c
+nft_rule_test_SOURCES = nft-rule-test.c ${LIBTEST}
 nft_rule_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_set_test_SOURCES = nft-set-test.c
+nft_set_test_SOURCES = nft-set-test.c ${LIBTEST}
 nft_set_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_bitwise_test_SOURCES = nft-expr_bitwise-test.c
+nft_expr_bitwise_test_SOURCES = nft-expr_bitwise-test.c ${LIBTEST}
 nft_expr_bitwise_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_byteorder_test_SOURCES = nft-expr_byteorder-test.c
+nft_expr_byteorder_test_SOURCES = nft-expr_byteorder-test.c ${LIBTEST}
 nft_expr_byteorder_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_cmp_test_SOURCES = nft-expr_cmp-test.c
+nft_expr_cmp_test_SOURCES = nft-expr_cmp-test.c ${LIBTEST}
 nft_expr_cmp_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_counter_test_SOURCES = nft-expr_counter-test.c
+nft_expr_counter_test_SOURCES = nft-expr_counter-test.c ${LIBTEST}
 nft_expr_counter_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_exthdr_test_SOURCES = nft-expr_exthdr-test.c
+nft_expr_exthdr_test_SOURCES = nft-expr_exthdr-test.c ${LIBTEST}
 nft_expr_exthdr_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_ct_test_SOURCES = nft-expr_ct-test.c
+nft_expr_ct_test_SOURCES = nft-expr_ct-test.c ${LIBTEST}
 nft_expr_ct_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_dup_test_SOURCES = nft-expr_dup-test.c
+nft_expr_dup_test_SOURCES = nft-expr_dup-test.c ${LIBTEST}
 nft_expr_dup_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_fwd_test_SOURCES = nft-expr_fwd-test.c
+nft_expr_fwd_test_SOURCES = nft-expr_fwd-test.c ${LIBTEST}
 nft_expr_fwd_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_immediate_test_SOURCES = nft-expr_immediate-test.c
+nft_expr_immediate_test_SOURCES = nft-expr_immediate-test.c ${LIBTEST}
 nft_expr_immediate_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_limit_test_SOURCES = nft-expr_limit-test.c
+nft_expr_limit_test_SOURCES = nft-expr_limit-test.c ${LIBTEST}
 nft_expr_limit_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_lookup_test_SOURCES = nft-expr_lookup-test.c
+nft_expr_lookup_test_SOURCES = nft-expr_lookup-test.c ${LIBTEST}
 nft_expr_lookup_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_log_test_SOURCES = nft-expr_log-test.c
+nft_expr_log_test_SOURCES = nft-expr_log-test.c ${LIBTEST}
 nft_expr_log_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_match_test_SOURCES = nft-expr_match-test.c
+nft_expr_match_test_SOURCES = nft-expr_match-test.c ${LIBTEST}
 nft_expr_match_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_masq_test_SOURCES = nft-expr_masq-test.c
+nft_expr_masq_test_SOURCES = nft-expr_masq-test.c ${LIBTEST}
 nft_expr_masq_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_meta_test_SOURCES = nft-expr_meta-test.c
+nft_expr_meta_test_SOURCES = nft-expr_meta-test.c ${LIBTEST}
 nft_expr_meta_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_nat_test_SOURCES = nft-expr_nat-test.c
+nft_expr_nat_test_SOURCES = nft-expr_nat-test.c ${LIBTEST}
 nft_expr_nat_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_payload_test_SOURCES = nft-expr_payload-test.c
+nft_expr_payload_test_SOURCES = nft-expr_payload-test.c ${LIBTEST}
 nft_expr_payload_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_queue_test_SOURCES = nft-expr_queue-test.c
+nft_expr_queue_test_SOURCES = nft-expr_queue-test.c ${LIBTEST}
 nft_expr_queue_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_reject_test_SOURCES = nft-expr_reject-test.c
+nft_expr_reject_test_SOURCES = nft-expr_reject-test.c ${LIBTEST}
 nft_expr_reject_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_redir_test_SOURCES = nft-expr_redir-test.c
+nft_expr_redir_test_SOURCES = nft-expr_redir-test.c ${LIBTEST}
 nft_expr_redir_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_target_test_SOURCES = nft-expr_target-test.c
+nft_expr_target_test_SOURCES = nft-expr_target-test.c ${LIBTEST}
 nft_expr_target_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
diff --git a/tests/libtest.c b/tests/libtest.c
new file mode 100644
index 0000000..ed7eafa
--- /dev/null
+++ b/tests/libtest.c
@@ -0,0 +1,53 @@
+#include <libtest.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#define COLOR_RED     "\x1b[31m"
+#define COLOR_GREEN   "\x1b[32m"
+#define COLOR_RESET   "\x1b[0m"
+
+static bool test_ok = true;
+
+void __oom_assert(bool cond, const char *prog, const char *file, int line)
+{
+	if (cond)
+		return;
+
+	fprintf(stderr,
+		COLOR_RED "OOM" COLOR_RESET " at %s:%d\n\t%s\n", file, line,
+		strerror(errno));
+
+	test_ok = false;
+	test_report(prog);
+	exit(EXIT_FAILURE);
+}
+
+void print_err(const char *fmt, ...)
+{
+	va_list args;
+
+	fprintf(stderr, COLOR_RED "ERROR: " COLOR_RESET);
+	va_start(args, fmt);
+	vfprintf(stderr, fmt, args);
+	va_end(args);
+	fprintf(stderr, "\n");
+
+	test_ok = false;
+}
+
+int test_report(const char *prog)
+{
+	switch (test_ok) {
+	case true:
+		printf("%s: " COLOR_GREEN "OK\n" COLOR_RESET, prog);
+		return EXIT_SUCCESS;
+	case false:
+		printf("%s: " COLOR_RED "FAIL\n" COLOR_RESET, prog);
+		return EXIT_FAILURE;
+	}
+}
diff --git a/tests/libtest.h b/tests/libtest.h
new file mode 100644
index 0000000..f570057
--- /dev/null
+++ b/tests/libtest.h
@@ -0,0 +1,11 @@
+#ifndef _TESTS_UTILS_H
+#define _TESTS_UTILS_H
+
+#include <stdbool.h>
+
+#define oom_assert(cond, prog) __oom_assert(cond, prog, __FILE__, __LINE__)
+void __oom_assert(bool cond, const char *prog, const char *file, int line);
+void print_err(const char *fmt, ...);
+int test_report(const char *prog);
+
+#endif
diff --git a/tests/nft-chain-test.c b/tests/nft-chain-test.c
index d678d46..b42fb86 100644
--- a/tests/nft-chain-test.c
+++ b/tests/nft-chain-test.c
@@ -15,13 +15,7 @@
 #include <linux/netfilter/nf_tables.h>
 #include <libnftnl/chain.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_chain(struct nftnl_chain *a, struct nftnl_chain *b)
 {
@@ -72,8 +66,8 @@ int main(int argc, char *argv[])
 
 	a = nftnl_chain_alloc();
 	b = nftnl_chain_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	nftnl_chain_set_str(a, NFTNL_CHAIN_NAME, "test");
 	nftnl_chain_set_u32(a, NFTNL_CHAIN_FAMILY, AF_INET);
@@ -101,10 +95,6 @@ int main(int argc, char *argv[])
 	nftnl_chain_free(a);
 	nftnl_chain_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 
 }
diff --git a/tests/nft-expr_bitwise-test.c b/tests/nft-expr_bitwise-test.c
index 64c1446..42e9bb2 100644
--- a/tests/nft-expr_bitwise-test.c
+++ b/tests/nft-expr_bitwise-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -65,11 +59,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("bitwise");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_SREG, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_DREG, 0x78123456);
@@ -87,13 +80,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
@@ -107,9 +100,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_byteorder-test.c b/tests/nft-expr_byteorder-test.c
index 5994e5b..9a25667 100644
--- a/tests/nft-expr_byteorder-test.c
+++ b/tests/nft-expr_byteorder-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -58,11 +52,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("byteorder");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BYTEORDER_SREG, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BYTEORDER_DREG, 0x12345678);
@@ -80,13 +73,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a,rule_b);
 
@@ -99,9 +92,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_cmp-test.c b/tests/nft-expr_cmp-test.c
index 4271940..a8d6eb1 100644
--- a/tests/nft-expr_cmp-test.c
+++ b/tests/nft-expr_cmp-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -56,11 +50,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("cmp");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set(ex, NFTNL_EXPR_CMP_DATA, &data_len, sizeof(data_len));
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_CMP_SREG, 0x12345678);
@@ -76,12 +69,12 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -94,9 +87,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_counter-test.c b/tests/nft-expr_counter-test.c
index 519bc1f..7066c26 100644
--- a/tests/nft-expr_counter-test.c
+++ b/tests/nft-expr_counter-test.c
@@ -19,13 +19,8 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
+#include "libtest.h"
 
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -49,12 +44,11 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	ex = nftnl_expr_alloc("counter");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u64(ex, NFTNL_EXPR_CTR_BYTES, 0x123456789abcdef0);
 	nftnl_expr_set_u64(ex, NFTNL_EXPR_CTR_PACKETS, 0xf0123456789abcde);
@@ -68,12 +62,12 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -86,8 +80,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_ct-test.c b/tests/nft-expr_ct-test.c
index e98fbab..cfbe0d6 100644
--- a/tests/nft-expr_ct-test.c
+++ b/tests/nft-expr_ct-test.c
@@ -19,12 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -50,11 +45,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("ct");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_CT_KEY, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_CT_DIR, 0x12);
@@ -70,13 +64,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -89,9 +83,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_dup-test.c b/tests/nft-expr_dup-test.c
index 3c37d4a..4ae112d 100644
--- a/tests/nft-expr_dup-test.c
+++ b/tests/nft-expr_dup-test.c
@@ -19,12 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -48,11 +43,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("dup");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_DUP_SREG_ADDR, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_DUP_SREG_DEV,  0x78123456);
@@ -67,13 +61,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -86,9 +80,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_exthdr-test.c b/tests/nft-expr_exthdr-test.c
index fef2dd0..56652b5 100644
--- a/tests/nft-expr_exthdr-test.c
+++ b/tests/nft-expr_exthdr-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -55,11 +49,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("exthdr");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_EXTHDR_DREG, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_EXTHDR_TYPE, 0x12);
@@ -75,13 +68,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -93,9 +86,6 @@ int main(int argc, char *argv[])
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
-	if (!test_ok)
-		exit(EXIT_FAILURE);
 
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_fwd-test.c b/tests/nft-expr_fwd-test.c
index 4fdf53d..7a27299 100644
--- a/tests/nft-expr_fwd-test.c
+++ b/tests/nft-expr_fwd-test.c
@@ -19,12 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -45,11 +40,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("dup");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_FWD_SREG_DEV,  0x78123456);
 
@@ -63,13 +57,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -82,9 +76,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_immediate-test.c b/tests/nft-expr_immediate-test.c
index e07092f..ecc1b5d 100644
--- a/tests/nft-expr_immediate-test.c
+++ b/tests/nft-expr_immediate-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr_verdict(struct nftnl_expr *rule_a,
 				   struct nftnl_expr *rule_b)
@@ -76,12 +70,12 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex_val = nftnl_expr_alloc("immediate");
 	ex_ver = nftnl_expr_alloc("immediate");
-	if (!ex_val || !ex_ver)
-		print_err("OOM");
+	oom_assert(ex_val, argv[0]);
+	oom_assert(ex_ver, argv[0]);
 
 	nftnl_expr_set_u32(ex_val, NFTNL_EXPR_IMM_DREG, 0x1234568);
 	nftnl_expr_set(ex_val,     NFTNL_EXPR_IMM_DATA, data, sizeof(data));
@@ -101,20 +95,20 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr_value(rule_a, rule_b);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr_verdict(rule_a, rule_b);
 
@@ -127,9 +121,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_limit-test.c b/tests/nft-expr_limit-test.c
index 2838941..7848e29 100644
--- a/tests/nft-expr_limit-test.c
+++ b/tests/nft-expr_limit-test.c
@@ -20,13 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -59,11 +53,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("limit");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u64(ex, NFTNL_EXPR_LIMIT_RATE, 0x123456789abcdef0);
 	nftnl_expr_set_u64(ex, NFTNL_EXPR_LIMIT_UNIT, 0xf0123456789abcde);
@@ -81,13 +74,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -100,9 +93,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_log-test.c b/tests/nft-expr_log-test.c
index b7aa302..a2c1f1d 100644
--- a/tests/nft-expr_log-test.c
+++ b/tests/nft-expr_log-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-	test_ok = 0;
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -55,11 +49,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("log");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_LOG_SNAPLEN, 0x12345678);
 	nftnl_expr_set_u16(ex, NFTNL_EXPR_LOG_GROUP, 0x1234);
@@ -75,12 +68,12 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -93,9 +86,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_lookup-test.c b/tests/nft-expr_lookup-test.c
index d1f017b..f7bb7f4 100644
--- a/tests/nft-expr_lookup-test.c
+++ b/tests/nft-expr_lookup-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -63,11 +57,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("lookup");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_LOOKUP_SREG, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_LOOKUP_DREG, 0x78123456);
@@ -84,12 +77,12 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -102,10 +95,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_masq-test.c b/tests/nft-expr_masq-test.c
index 3f9903d..fdfbf03 100644
--- a/tests/nft-expr_masq-test.c
+++ b/tests/nft-expr_masq-test.c
@@ -17,13 +17,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -50,11 +44,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("masq");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_MASQ_FLAGS, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_MASQ_REG_PROTO_MIN, 0x5432178);
@@ -70,13 +63,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -89,9 +82,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_match-test.c b/tests/nft-expr_match-test.c
index 39a49d8..9902d2f 100644
--- a/tests/nft-expr_match-test.c
+++ b/tests/nft-expr_match-test.c
@@ -20,19 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
-
-static void print_err2(const char *msg, uint32_t a, uint32_t b)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s size a: %d b: %d \n", msg, a, b);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -48,7 +36,8 @@ static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 	nftnl_expr_get(rule_a, NFTNL_EXPR_MT_INFO, &lena);
 	nftnl_expr_get(rule_b, NFTNL_EXPR_MT_INFO, &lenb);
 	if (lena != lenb)
-		print_err2("Expr NFTNL_EXPR_MT_INFO size mismatches", lena, lenb);
+		print_err("Expr NFTNL_EXPR_MT_INFO size mismatches: %d != %d",
+			  lena, lenb);
 }
 
 int main(int argc, char *argv[])
@@ -63,11 +52,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("match");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_str(ex, NFTNL_EXPR_MT_NAME, "Tests");
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_MT_REV, 0x12345678);
@@ -81,13 +69,13 @@ int main(int argc, char *argv[])
 		print_err("parsing problems");
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -100,9 +88,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_meta-test.c b/tests/nft-expr_meta-test.c
index 8fb7873..e528631 100644
--- a/tests/nft-expr_meta-test.c
+++ b/tests/nft-expr_meta-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -49,11 +43,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("meta");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_META_KEY, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_META_DREG, 0x78123456);
@@ -67,13 +60,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -86,9 +79,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_nat-test.c b/tests/nft-expr_nat-test.c
index 9c15a0a..fdd91ba 100644
--- a/tests/nft-expr_nat-test.c
+++ b/tests/nft-expr_nat-test.c
@@ -20,13 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -65,11 +59,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("nat");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_NAT_TYPE, NFT_NAT_SNAT);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_NAT_FAMILY, NFPROTO_INET);
@@ -89,13 +82,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -108,9 +101,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_payload-test.c b/tests/nft-expr_payload-test.c
index 371372c..0812d6d 100644
--- a/tests/nft-expr_payload-test.c
+++ b/tests/nft-expr_payload-test.c
@@ -20,13 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -56,11 +50,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("payload");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_PAYLOAD_DREG, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_PAYLOAD_BASE, 0x78123456);
@@ -76,13 +69,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -95,9 +88,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_queue-test.c b/tests/nft-expr_queue-test.c
index 1cc39aa..327e8fd 100644
--- a/tests/nft-expr_queue-test.c
+++ b/tests/nft-expr_queue-test.c
@@ -22,13 +22,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -52,11 +46,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("queue");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u16(ex, NFTNL_EXPR_QUEUE_NUM, 0x01010);
 	nftnl_expr_set_u16(ex, NFTNL_EXPR_QUEUE_TOTAL, 0x1234);
@@ -72,13 +65,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -91,9 +84,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_redir-test.c b/tests/nft-expr_redir-test.c
index 6c8caec..ce97928 100644
--- a/tests/nft-expr_redir-test.c
+++ b/tests/nft-expr_redir-test.c
@@ -17,13 +17,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -50,11 +44,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("redir");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_REDIR_REG_PROTO_MIN, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_REDIR_REG_PROTO_MAX, 0x56781234);
@@ -70,13 +63,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -89,9 +82,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_reject-test.c b/tests/nft-expr_reject-test.c
index d8189ea..426f9e9 100644
--- a/tests/nft-expr_reject-test.c
+++ b/tests/nft-expr_reject-test.c
@@ -20,13 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -50,11 +44,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("reject");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_REJECT_TYPE, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_REJECT_CODE, 0x45681234);
@@ -69,13 +62,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -88,9 +81,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_target-test.c b/tests/nft-expr_target-test.c
index ba56b27..82a4a9f 100644
--- a/tests/nft-expr_target-test.c
+++ b/tests/nft-expr_target-test.c
@@ -19,19 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
-
-static void print_err2(const char *msg, uint32_t a, uint32_t b)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s size a: %d b: %d \n",msg, a, b);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -47,7 +35,8 @@ static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 	nftnl_expr_get(rule_a, NFTNL_EXPR_TG_INFO, &lena);
 	nftnl_expr_get(rule_b, NFTNL_EXPR_TG_INFO, &lenb);
 	if (lena != lenb)
-		print_err2("Expr NFTNL_EXPR_TG_INFO size mismatches", lena, lenb);
+		print_err("Expr NFTNL_EXPR_TG_INFO size mismatches: %d != %d",
+			  lena, lenb);
 }
 
 int main(int argc, char *argv[])
@@ -62,12 +51,11 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	ex = nftnl_expr_alloc("target");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set(ex, NFTNL_EXPR_TG_NAME, "test", strlen("test"));
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_TG_REV, 0x56781234);
@@ -82,13 +70,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -101,8 +89,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-rule-test.c b/tests/nft-rule-test.c
index dee3530..c6ba719 100644
--- a/tests/nft-rule-test.c
+++ b/tests/nft-rule-test.c
@@ -17,13 +17,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/udata.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_rule(struct nftnl_rule *a, struct nftnl_rule *b)
 {
@@ -68,12 +62,11 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	udata = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
-	if (!udata)
-		print_err("OOM");
+	oom_assert(udata, argv[0]);
 
 	if (!nftnl_udata_put_strz(udata, 0, "hello world"))
 		print_err("User data too big");
@@ -100,9 +93,6 @@ int main(int argc, char *argv[])
 
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
-	if (!test_ok)
-		exit(EXIT_FAILURE);
 
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-set-test.c b/tests/nft-set-test.c
index 173c17f..6f9b03d 100644
--- a/tests/nft-set-test.c
+++ b/tests/nft-set-test.c
@@ -16,13 +16,7 @@
 
 #include <libnftnl/set.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_set(struct nftnl_set *a, struct nftnl_set *b)
 {
@@ -60,8 +54,8 @@ int main(int argc, char *argv[])
 
 	a = nftnl_set_alloc();
 	b = nftnl_set_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	nftnl_set_set_str(a, NFTNL_SET_TABLE, "test-table");
 	nftnl_set_set_str(a, NFTNL_SET_NAME, "test-name");
@@ -84,9 +78,5 @@ int main(int argc, char *argv[])
 
 	nftnl_set_free(a); nftnl_set_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-table-test.c b/tests/nft-table-test.c
index 1031ffe..6b0418f 100644
--- a/tests/nft-table-test.c
+++ b/tests/nft-table-test.c
@@ -16,13 +16,7 @@
 #include <linux/netfilter/nf_tables.h>
 #include <libnftnl/table.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_table(struct nftnl_table *a, struct nftnl_table *b)
 {
@@ -47,8 +41,8 @@ int main(int argc, char *argv[])
 	a = nftnl_table_alloc();
 	b = nftnl_table_alloc();
 
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	nftnl_table_set_str(a, NFTNL_TABLE_NAME, "test");
 	nftnl_table_set_u32(a, NFTNL_TABLE_FAMILY, AF_INET);
@@ -66,9 +60,6 @@ int main(int argc, char *argv[])
 
 	nftnl_table_free(a);
 	nftnl_table_free(b);
-	if (!test_ok)
-		exit(EXIT_FAILURE);
 
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
-- 
2.8.3


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 4/4, V2, libnftnl] tests: Use libnftnl comparators in all tests
  2016-08-12 20:17     ` [PATCH 1/4, V2, libnftnl] tests: Fix segfaults due outbound access Carlos Falgueras García
  2016-08-12 20:17       ` [PATCH 2/4, V2, libnftnl] tests: Fix wrong expression creation Carlos Falgueras García
  2016-08-12 20:17       ` [PATCH 3/4, V2, libnftnl] tests: Consolidate printing error utilities Carlos Falgueras García
@ 2016-08-12 20:17       ` Carlos Falgueras García
  2016-08-13 10:12       ` [PATCH 1/4, V2, libnftnl] tests: Fix segfaults due outbound access Pablo Neira Ayuso
  3 siblings, 0 replies; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-12 20:17 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

Use 'nftnl_expr_cmp' and 'nftnl_rule_cmp' in all tests instead of custom
comparator for each one. If objects differ both are printed.

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 tests/libtest.c                 | 44 +++++++++++++++----
 tests/libtest.h                 | 15 ++++++-
 tests/nft-chain-test.c          | 93 ++++++++++++++++++++++++-----------------
 tests/nft-expr_bitwise-test.c   | 40 ++++--------------
 tests/nft-expr_byteorder-test.c | 35 ++++------------
 tests/nft-expr_cmp-test.c       | 32 ++++----------
 tests/nft-expr_counter-test.c   | 26 ++++--------
 tests/nft-expr_ct-test.c        | 28 ++++---------
 tests/nft-expr_dup-test.c       | 26 ++++--------
 tests/nft-expr_exthdr-test.c    | 32 ++++----------
 tests/nft-expr_fwd-test.c       | 23 ++++------
 tests/nft-expr_immediate-test.c | 53 ++++-------------------
 tests/nft-expr_limit-test.c     | 35 ++++------------
 tests/nft-expr_log-test.c       | 32 ++++----------
 tests/nft-expr_lookup-test.c    | 38 ++++-------------
 tests/nft-expr_masq-test.c      | 29 ++++---------
 tests/nft-expr_match-test.c     | 33 ++++-----------
 tests/nft-expr_meta-test.c      | 26 ++++--------
 tests/nft-expr_nat-test.c       | 41 ++++--------------
 tests/nft-expr_payload-test.c   | 32 ++++----------
 tests/nft-expr_queue-test.c     | 26 ++++--------
 tests/nft-expr_redir-test.c     | 29 ++++---------
 tests/nft-expr_reject-test.c    | 26 ++++--------
 tests/nft-expr_target-test.c    | 33 ++++-----------
 tests/nft-rule-test.c           | 48 ++++-----------------
 tests/nft-set-test.c            | 72 ++++++++++++++++++-------------
 tests/nft-table-test.c          | 38 ++++++++++-------
 27 files changed, 348 insertions(+), 637 deletions(-)

diff --git a/tests/libtest.c b/tests/libtest.c
index ed7eafa..4b36f55 100644
--- a/tests/libtest.c
+++ b/tests/libtest.c
@@ -11,8 +11,6 @@
 #define COLOR_GREEN   "\x1b[32m"
 #define COLOR_RESET   "\x1b[0m"
 
-static bool test_ok = true;
-
 void __oom_assert(bool cond, const char *prog, const char *file, int line)
 {
 	if (cond)
@@ -22,25 +20,27 @@ void __oom_assert(bool cond, const char *prog, const char *file, int line)
 		COLOR_RED "OOM" COLOR_RESET " at %s:%d\n\t%s\n", file, line,
 		strerror(errno));
 
-	test_ok = false;
-	test_report(prog);
+	test_report(false, prog);
 	exit(EXIT_FAILURE);
 }
 
-void print_err(const char *fmt, ...)
+bool test_assert(bool cond, const char *fmt, ...)
 {
 	va_list args;
 
+	if (cond)
+		return true;
+
 	fprintf(stderr, COLOR_RED "ERROR: " COLOR_RESET);
 	va_start(args, fmt);
 	vfprintf(stderr, fmt, args);
 	va_end(args);
 	fprintf(stderr, "\n");
 
-	test_ok = false;
+	return false;
 }
 
-int test_report(const char *prog)
+int test_report(bool test_ok, const char *prog)
 {
 	switch (test_ok) {
 	case true:
@@ -51,3 +51,33 @@ int test_report(const char *prog)
 		return EXIT_FAILURE;
 	}
 }
+
+#define SNPRINTF_BUFF_LEN 1024
+
+static const char *rule2str(const struct nftnl_rule *r)
+{
+	static char buff[SNPRINTF_BUFF_LEN];
+	nftnl_rule_snprintf(buff, SNPRINTF_BUFF_LEN, r, NFTNL_OUTPUT_DEFAULT, 0);
+	return buff;
+}
+
+static const char *expr2str(const struct nftnl_expr *e)
+{
+	static char buff[SNPRINTF_BUFF_LEN];
+	nftnl_expr_snprintf(buff, SNPRINTF_BUFF_LEN, e, NFTNL_OUTPUT_DEFAULT, 0);
+	return buff;
+}
+
+bool test_assert_expr(const struct nftnl_expr *e1, const struct nftnl_expr *e2)
+{
+	return test_assert(nftnl_expr_cmp(e1, e2),
+			   "expressions mismatch:\n\texpr 1: %s\n\texpr 2: %s",
+			   expr2str(e1), expr2str(e2));
+}
+
+bool test_assert_rule(const struct nftnl_rule *r1, const struct nftnl_rule *r2)
+{
+	return test_assert(nftnl_rule_cmp(r1, r2),
+			   "rules mismatch:\nRULE 1:\n%s\nRULE 2:\n%s",
+			   rule2str(r1), rule2str(r2));
+}
diff --git a/tests/libtest.h b/tests/libtest.h
index f570057..0f5aa9f 100644
--- a/tests/libtest.h
+++ b/tests/libtest.h
@@ -2,10 +2,21 @@
 #define _TESTS_UTILS_H
 
 #include <stdbool.h>
+#include <libmnl/libmnl.h>
+#include <libnftnl/common.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
 
 #define oom_assert(cond, prog) __oom_assert(cond, prog, __FILE__, __LINE__)
 void __oom_assert(bool cond, const char *prog, const char *file, int line);
-void print_err(const char *fmt, ...);
-int test_report(const char *prog);
+bool test_assert(bool cond, const char *fmt, ...);
+int test_report(bool test_ok, const char *prog);
+bool test_assert_expr(const struct nftnl_expr *e1, const struct nftnl_expr *e2);
+bool test_assert_rule(const struct nftnl_rule *r1, const struct nftnl_rule *r2);
+
+/*
+ * const char *rule2str(const struct nftnl_rule *r);
+ * const char *expr2str(const struct nftnl_expr *e);
+ */
 
 #endif
diff --git a/tests/nft-chain-test.c b/tests/nft-chain-test.c
index b42fb86..1b6672a 100644
--- a/tests/nft-chain-test.c
+++ b/tests/nft-chain-test.c
@@ -19,43 +19,56 @@
 
 static void cmp_nftnl_chain(struct nftnl_chain *a, struct nftnl_chain *b)
 {
+	bool test_ok = true;
+	bool ret;
 
-	if (strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_NAME),
-		   nftnl_chain_get_str(b, NFTNL_CHAIN_NAME)) != 0)
-		print_err("Chain name mismatches");
-	if (strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_TABLE),
-		   nftnl_chain_get_str(b, NFTNL_CHAIN_TABLE)) != 0)
-		print_err("Chain table mismatches");
-	if (nftnl_chain_get_u32(a, NFTNL_CHAIN_FAMILY) !=
-	    nftnl_chain_get_u32(b, NFTNL_CHAIN_FAMILY))
-		print_err("Chain family mismatches");
-	if (nftnl_chain_get_u32(a, NFTNL_CHAIN_POLICY) !=
-	    nftnl_chain_get_u32(b, NFTNL_CHAIN_POLICY))
-		print_err("Chain policy mismatches");
-	if (nftnl_chain_get_u32(a, NFTNL_CHAIN_HOOKNUM) !=
-	    nftnl_chain_get_u32(b, NFTNL_CHAIN_HOOKNUM))
-		print_err("Chain hooknum mismatches");
-	if (nftnl_chain_get_s32(a, NFTNL_CHAIN_PRIO) !=
-	    nftnl_chain_get_s32(b, NFTNL_CHAIN_PRIO))
-		print_err("Chain Prio mismatches");
-	if (nftnl_chain_get_u32(a, NFTNL_CHAIN_USE) !=
-	    nftnl_chain_get_u32(b, NFTNL_CHAIN_USE))
-		print_err("Chain use mismatches");
-	if (nftnl_chain_get_u64(a, NFTNL_CHAIN_PACKETS) !=
-	    nftnl_chain_get_u64(b, NFTNL_CHAIN_PACKETS))
-		print_err("Chain packets mismatches");
-	if (nftnl_chain_get_u64(a, NFTNL_CHAIN_BYTES) !=
-	    nftnl_chain_get_u64(b, NFTNL_CHAIN_BYTES))
-		print_err("Chain bytes mismatches");
-	if (nftnl_chain_get_u64(a, NFTNL_CHAIN_HANDLE) !=
-	    nftnl_chain_get_u64(b, NFTNL_CHAIN_HANDLE))
-		print_err("Chain handle mismatches");
-	if (strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_TYPE),
-		   nftnl_chain_get_str(b, NFTNL_CHAIN_TYPE)) != 0)
-		print_err("Chain type mismatches");
-	if (strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_DEV),
-		   nftnl_chain_get_str(b, NFTNL_CHAIN_DEV)) != 0)
-		print_err("Chain device mismatches");
+	ret = !strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_NAME),
+		      nftnl_chain_get_str(b, NFTNL_CHAIN_NAME));
+	test_ok &= test_assert(ret, "Chain name mismatches");
+
+	ret = !strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_TABLE),
+		      nftnl_chain_get_str(b, NFTNL_CHAIN_TABLE));
+	test_ok &= test_assert(ret, "Chain table mismatches");
+
+	ret = nftnl_chain_get_u32(a, NFTNL_CHAIN_FAMILY) ==
+	      nftnl_chain_get_u32(b, NFTNL_CHAIN_FAMILY);
+	test_ok &= test_assert(ret, "Chain family mismatches");
+
+	ret = nftnl_chain_get_u32(a, NFTNL_CHAIN_POLICY) ==
+	      nftnl_chain_get_u32(b, NFTNL_CHAIN_POLICY);
+	test_ok &= test_assert(ret, "Chain policy mismatches");
+
+	ret = nftnl_chain_get_u32(a, NFTNL_CHAIN_HOOKNUM) ==
+	      nftnl_chain_get_u32(b, NFTNL_CHAIN_HOOKNUM);
+	test_ok &= test_assert(ret, "Chain hooknum mismatches");
+
+	ret = nftnl_chain_get_s32(a, NFTNL_CHAIN_PRIO) ==
+	      nftnl_chain_get_s32(b, NFTNL_CHAIN_PRIO);
+	test_ok &= test_assert(ret, "Chain Prio mismatches");
+
+	ret = nftnl_chain_get_u32(a, NFTNL_CHAIN_USE) ==
+	      nftnl_chain_get_u32(b, NFTNL_CHAIN_USE);
+	test_ok &= test_assert(ret, "Chain use mismatches");
+
+	ret = nftnl_chain_get_u64(a, NFTNL_CHAIN_PACKETS) ==
+	      nftnl_chain_get_u64(b, NFTNL_CHAIN_PACKETS);
+	test_ok &= test_assert(ret, "Chain packets mismatches");
+
+	ret = nftnl_chain_get_u64(a, NFTNL_CHAIN_BYTES) ==
+	      nftnl_chain_get_u64(b, NFTNL_CHAIN_BYTES);
+	test_ok &= test_assert(ret, "Chain bytes mismatches");
+
+	ret = nftnl_chain_get_u64(a, NFTNL_CHAIN_HANDLE) ==
+	      nftnl_chain_get_u64(b, NFTNL_CHAIN_HANDLE);
+	test_ok &= test_assert(ret, "Chain handle mismatches");
+
+	ret = !strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_TYPE),
+		      nftnl_chain_get_str(b, NFTNL_CHAIN_TYPE));
+	test_ok &= test_assert(ret, "Chain type mismatches");
+
+	ret = !strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_DEV),
+		      nftnl_chain_get_str(b, NFTNL_CHAIN_DEV));
+	test_ok &= test_assert(ret, "Chain device mismatches");
 }
 
 int main(int argc, char *argv[])
@@ -63,6 +76,8 @@ int main(int argc, char *argv[])
 	struct nftnl_chain *a, *b;
 	char buf[4096];
 	struct nlmsghdr *nlh;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_chain_alloc();
 	b = nftnl_chain_alloc();
@@ -87,14 +102,14 @@ int main(int argc, char *argv[])
 					0, 1234);
 	nftnl_chain_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_chain_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_chain_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	cmp_nftnl_chain(a, b);
 
 	nftnl_chain_free(a);
 	nftnl_chain_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 
 }
diff --git a/tests/nft-expr_bitwise-test.c b/tests/nft-expr_bitwise-test.c
index 42e9bb2..8f6781f 100644
--- a/tests/nft-expr_bitwise-test.c
+++ b/tests/nft-expr_bitwise-test.c
@@ -21,31 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	uint32_t maska, maskb;
-	uint32_t xora, xorb;
-
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_DREG))
-		print_err("Expr BITWISE_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_SREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_SREG))
-		print_err("Expr BITWISE_SREG mismatches");
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_BITWISE_LEN) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_BITWISE_LEN))
-		print_err("Expr BITWISE_DREG mismatches");
-	nftnl_expr_get(rule_a, NFTNL_EXPR_BITWISE_MASK, &maska);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_BITWISE_MASK, &maskb);
-	if (maska != maskb)
-		print_err("Size of BITWISE_MASK mismatches");
-	nftnl_expr_get(rule_a, NFTNL_EXPR_BITWISE_XOR, &xora);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_BITWISE_XOR, &xorb);
-	if (xora != xorb)
-		print_err("Size of BITWISE_XOR mismatches");
-
-}
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b = NULL;
@@ -56,6 +31,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr *rule_a, *rule_b = NULL;
 	uint32_t mask = 0x01010101;
 	uint32_t xor = 0x12345678;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -75,8 +52,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -88,17 +65,16 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 
-	cmp_nftnl_expr(rule_a,rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_byteorder-test.c b/tests/nft-expr_byteorder-test.c
index 9a25667..29df7a6 100644
--- a/tests/nft-expr_byteorder-test.c
+++ b/tests/nft-expr_byteorder-test.c
@@ -21,26 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_DREG))
-		print_err("Expr NFTNL_EXPR_BYTEORDER_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_SREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_SREG))
-		print_err("Expr NFTNL_EXPR_BYTEORDER_SREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_OP) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_OP))
-		print_err("Expr NFTNL_EXPR_BYTEORDER_OP mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_LEN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_LEN))
-		print_err("Expr NFTNL_EXPR_BYTEORDER_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_SIZE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_SIZE))
-		print_err("Expr NFTNL_EXPR_BITWISE_SIZE mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -49,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -68,8 +50,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -81,16 +63,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a,rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_cmp-test.c b/tests/nft-expr_cmp-test.c
index a8d6eb1..6c0d550 100644
--- a/tests/nft-expr_cmp-test.c
+++ b/tests/nft-expr_cmp-test.c
@@ -21,23 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	uint32_t data_lena, data_lenb;
-
-	nftnl_expr_get(rule_a, NFTNL_EXPR_CMP_DATA, &data_lena);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_CMP_DATA, &data_lenb);
-	if (data_lena != data_lenb)
-		print_err("Size of NFTNL_EXPR_CMP_DATA mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CMP_SREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CMP_SREG))
-		print_err("Expr NFTNL_EXPR_CMP_SREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CMP_OP) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CMP_OP))
-		print_err("Expr NFTNL_EXPR_CMP_OP mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -47,6 +30,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
 	uint32_t data_len = 0x01010101;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -64,8 +49,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -76,16 +61,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_counter-test.c b/tests/nft-expr_counter-test.c
index 7066c26..a6cb95d 100644
--- a/tests/nft-expr_counter-test.c
+++ b/tests/nft-expr_counter-test.c
@@ -22,17 +22,6 @@
 #include "libtest.h"
 
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_CTR_BYTES) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_CTR_BYTES))
-		print_err("Expr NFTNL_EXPR_CTR_BYTES mismatches");
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_CTR_PACKETS) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_CTR_PACKETS))
-		print_err("Expr NFTNL_EXPR_CTR_PACKETS mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -41,6 +30,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -57,8 +48,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -69,16 +60,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_ct-test.c b/tests/nft-expr_ct-test.c
index cfbe0d6..55f6d52 100644
--- a/tests/nft-expr_ct-test.c
+++ b/tests/nft-expr_ct-test.c
@@ -21,19 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CT_KEY) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CT_KEY))
-		print_err("Expr CT_KEY mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CT_DIR) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CT_DIR))
-		print_err("Expr CT_DIR mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CT_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CT_DREG))
-		print_err("Expr CT_DREG mismatches");
-}
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -42,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -59,8 +48,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -72,16 +61,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_dup-test.c b/tests/nft-expr_dup-test.c
index 4ae112d..4c90b41 100644
--- a/tests/nft-expr_dup-test.c
+++ b/tests/nft-expr_dup-test.c
@@ -21,17 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_DUP_SREG_ADDR) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_DUP_SREG_ADDR))
-		print_err("Expr SREG_TO mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_DUP_SREG_DEV) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_DUP_SREG_DEV))
-		print_err("Expr SREG_OIF mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -40,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -56,8 +47,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -69,16 +60,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_exthdr-test.c b/tests/nft-expr_exthdr-test.c
index 56652b5..26642c3 100644
--- a/tests/nft-expr_exthdr-test.c
+++ b/tests/nft-expr_exthdr-test.c
@@ -21,23 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_EXTHDR_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_EXTHDR_DREG))
-		print_err("Expr NFTNL_EXPR_EXTHDR_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_EXTHDR_TYPE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_EXTHDR_TYPE))
-		print_err("Expr NFTNL_EXPR_EXTHDR_TYPE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_EXTHDR_OFFSET) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_EXTHDR_OFFSET))
-		print_err("Expr NFTNL_EXPR_EXTHDR_OFFSET mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_EXTHDR_LEN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_EXTHDR_LEN))
-		print_err("Expr NFTNL_EXPR_EXTHDR_LEN mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -46,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -63,8 +48,8 @@ int main(int argc, char *argv[])
 
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -76,16 +61,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_fwd-test.c b/tests/nft-expr_fwd-test.c
index 7a27299..385ca8e 100644
--- a/tests/nft-expr_fwd-test.c
+++ b/tests/nft-expr_fwd-test.c
@@ -21,14 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_FWD_SREG_DEV) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_FWD_SREG_DEV))
-		print_err("Expr SREG_OIF mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -37,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -52,8 +46,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -65,16 +59,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_immediate-test.c b/tests/nft-expr_immediate-test.c
index ecc1b5d..fba84f1 100644
--- a/tests/nft-expr_immediate-test.c
+++ b/tests/nft-expr_immediate-test.c
@@ -21,42 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr_verdict(struct nftnl_expr *rule_a,
-				   struct nftnl_expr *rule_b)
-{
-	uint32_t len_a, len_b;
-	const char *chain_a, *chain_b;
-
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_IMM_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_IMM_DREG))
-		print_err("Expr NFTNL_EXPR_IMM_DREG mismatches");
-
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_IMM_VERDICT) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_IMM_VERDICT))
-		print_err("Expr NFTNL_EXPR_IMM_VERDICT mismatches");
-
-	chain_a = nftnl_expr_get(rule_a, NFTNL_EXPR_IMM_CHAIN, &len_a);
-	chain_b = nftnl_expr_get(rule_b, NFTNL_EXPR_IMM_CHAIN, &len_b);
-	if (len_a != len_b || strncmp(chain_a, chain_b, len_a))
-		print_err("Expr NFTNL_EXPR_IMM_CHAIN mismatches");
-}
-
-static void cmp_nftnl_expr_value(struct nftnl_expr *rule_a,
-				 struct nftnl_expr *rule_b)
-{
-	const uint32_t *data_a, *data_b;
-	uint32_t len_a, len_b;
-
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_IMM_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_IMM_DREG))
-		print_err("Expr NFTNL_EXPR_IMM_DREG mismatches");
-
-	data_a = nftnl_expr_get(rule_a, NFTNL_EXPR_IMM_DATA, &len_a);
-	data_b = nftnl_expr_get(rule_b, NFTNL_EXPR_IMM_DATA, &len_b);
-	if (len_a != len_b || memcmp(data_a, data_b, len_a))
-		print_err("Expr NFTNL_EXPR_IMM_DATA mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -67,6 +31,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr *rule_a, *rule_b;
 	char chain[] = "tests_chain01234";
 	char data[] = "test_data_01234";
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -90,8 +56,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -103,23 +69,22 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr_value(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr_verdict(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 2 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 2 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_limit-test.c b/tests/nft-expr_limit-test.c
index 7848e29..a5cb137 100644
--- a/tests/nft-expr_limit-test.c
+++ b/tests/nft-expr_limit-test.c
@@ -22,26 +22,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_RATE) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_RATE))
-		print_err("Expr CTR_BYTES mismatches");
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_UNIT) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_UNIT))
-		print_err("Expr CTR_PACKET mismatches");
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_BURST) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_BURST))
-		print_err("Expr CTR_PACKET mismatches");
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_TYPE) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_TYPE))
-		print_err("Expr TYPE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LIMIT_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LIMIT_FLAGS))
-		print_err("Expr FLAGS mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -50,6 +30,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -69,8 +51,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -82,16 +64,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_log-test.c b/tests/nft-expr_log-test.c
index a2c1f1d..7dbbf34 100644
--- a/tests/nft-expr_log-test.c
+++ b/tests/nft-expr_log-test.c
@@ -21,23 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOG_SNAPLEN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOG_SNAPLEN))
-		print_err("Expr NFTNL_EXPR_LOG_SNAPLEN mismatches");
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_LOG_GROUP) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_LOG_GROUP))
-		print_err("Expr NFTNL_EXPR_LOG_GROUP mismatches");
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_LOG_QTHRESHOLD) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_LOG_QTHRESHOLD))
-		print_err("Expr NFTNL_EXPR_LOG_QTHRESHOLD mismatches");
-	if(strcmp(nftnl_expr_get_str(rule_a, NFTNL_EXPR_LOG_PREFIX),
-		  nftnl_expr_get_str(rule_b, NFTNL_EXPR_LOG_PREFIX)) != 0)
-		print_err("Expr NFTNL_EXPR_LOG_PREFIX mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -46,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -63,8 +48,8 @@ int main(int argc, char *argv[])
 
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -75,16 +60,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_lookup-test.c b/tests/nft-expr_lookup-test.c
index f7bb7f4..8301a11 100644
--- a/tests/nft-expr_lookup-test.c
+++ b/tests/nft-expr_lookup-test.c
@@ -21,29 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_SREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_SREG))
-		print_err("Expr NFTNL_EXPR_LOOKUP_SREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_DREG))
-		print_err("Expr NFTNL_EXPR_LOOKUP_DREG mismatches");
-	if (strcmp(nftnl_expr_get_str(rule_a, NFTNL_EXPR_LOOKUP_SET),
-		   nftnl_expr_get_str(rule_b, NFTNL_EXPR_LOOKUP_SET)))
-		print_err("Expr NFTNL_EXPR_LOOKUP_SET mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_SET_ID) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_SET_ID))
-		print_err("Expr NFTNL_EXPR_LOOKUP_SET_ID mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_FLAGS)) {
-		print_err("Expr NFTNL_EXPR_LOOKUP_FLAGS mismatches");
-		printf("%X %X\n",
-			nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_FLAGS),
-			nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_FLAGS));
-	}
-}
 
 int main(int argc, char *argv[])
 {
@@ -54,6 +31,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
 	char lookup_set[] = "test_set_01243";
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -72,8 +51,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -84,16 +63,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_masq-test.c b/tests/nft-expr_masq-test.c
index fdfbf03..b93fc27 100644
--- a/tests/nft-expr_masq-test.c
+++ b/tests/nft-expr_masq-test.c
@@ -19,20 +19,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_MASQ_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_MASQ_FLAGS))
-		print_err("Expr NFTNL_EXPR_MASQ_FLAGS mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_MASQ_REG_PROTO_MIN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_MASQ_REG_PROTO_MIN))
-		print_err("Expr NFTNL_EXPR_MASQ_REG_PROTO_MIN mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_MASQ_REG_PROTO_MAX) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_MASQ_REG_PROTO_MAX))
-		print_err("Expr NFTNL_EXPR_MASQ_REG_PROTO_MAX mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -41,6 +27,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -58,8 +46,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -71,16 +59,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_match-test.c b/tests/nft-expr_match-test.c
index 9902d2f..78868bf 100644
--- a/tests/nft-expr_match-test.c
+++ b/tests/nft-expr_match-test.c
@@ -22,24 +22,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	uint32_t lena, lenb;
-
-	if (strcmp(nftnl_expr_get_str(rule_a, NFTNL_EXPR_MT_NAME),
-		   nftnl_expr_get_str(rule_b, NFTNL_EXPR_MT_NAME)) != 0)
-		print_err("Expr NFTNL_EXPR_MT_NAME mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_MT_REV) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_MT_REV))
-		print_err("Expr NFTNL_EXPR_MT_REV mismatches");
-	nftnl_expr_get(rule_a, NFTNL_EXPR_MT_INFO, &lena);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_MT_INFO, &lenb);
-	if (lena != lenb)
-		print_err("Expr NFTNL_EXPR_MT_INFO size mismatches: %d != %d",
-			  lena, lenb);
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -49,6 +31,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
 	char data[16] = "0123456789abcdef";
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -65,8 +49,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	oom_assert(iter_a, argv[0]);
@@ -77,16 +61,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_meta-test.c b/tests/nft-expr_meta-test.c
index e528631..44fa022 100644
--- a/tests/nft-expr_meta-test.c
+++ b/tests/nft-expr_meta-test.c
@@ -21,17 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_META_KEY) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_META_KEY))
-		print_err("Expr NFTNL_EXPR_META_KEY mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_META_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_META_DREG))
-		print_err("Expr NFTNL_EXPR_META_DREG mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -40,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -55,8 +46,8 @@ int main(int argc, char *argv[])
 
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -68,16 +59,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_nat-test.c b/tests/nft-expr_nat-test.c
index fdd91ba..9e8447a 100644
--- a/tests/nft-expr_nat-test.c
+++ b/tests/nft-expr_nat-test.c
@@ -22,32 +22,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_TYPE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_TYPE))
-		print_err("Expr NFTNL_EXPR_NAT_TYPE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_FAMILY) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_FAMILY))
-		print_err("Expr NFTNL_EXPR_NAT_FAMILY mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_REG_ADDR_MIN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_REG_ADDR_MIN))
-		print_err("Expr NFTNL_EXPR_NAT_REG_ADDR_MIN mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_REG_ADDR_MAX) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_REG_ADDR_MAX))
-		print_err("Expr NFTNL_EXPR_NAT_REG_ADDR_MAX mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_REG_PROTO_MIN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_REG_PROTO_MIN))
-		print_err("Expr NFTNL_EXPR_NAT_REG_PROTO_MIN mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_REG_PROTO_MAX) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_REG_PROTO_MAX))
-		print_err("Expr NFTNL_EXPR_NAT_REG_PROTO_MAX mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_FLAGS))
-		print_err("Expr NFTNL_EXPR_NAT_FLAGS mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -56,6 +30,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -77,8 +53,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -90,16 +66,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_payload-test.c b/tests/nft-expr_payload-test.c
index 0812d6d..dc52916 100644
--- a/tests/nft-expr_payload-test.c
+++ b/tests/nft-expr_payload-test.c
@@ -22,23 +22,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_PAYLOAD_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_PAYLOAD_DREG))
-		print_err("Expr NFTNL_EXPR_PAYLOAD_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_PAYLOAD_BASE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_PAYLOAD_BASE))
-		print_err("Expr NFTNL_EXPR_PAYLOAD_BASE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_PAYLOAD_OFFSET) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_PAYLOAD_OFFSET))
-		print_err("Expr NFTNL_EXPR_PAYLOAD_OFFSET mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_PAYLOAD_LEN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_PAYLOAD_LEN))
-		print_err("Expr NFTNL_EXPR_PAYLOAD_LEN mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -47,6 +30,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -64,8 +49,8 @@ int main(int argc, char *argv[])
 
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -77,16 +62,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_queue-test.c b/tests/nft-expr_queue-test.c
index 327e8fd..d266882 100644
--- a/tests/nft-expr_queue-test.c
+++ b/tests/nft-expr_queue-test.c
@@ -24,17 +24,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_QUEUE_NUM) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_QUEUE_NUM))
-		print_err("Expr NFTNL_EXPR_QUEUE_NUM mismatches");
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_QUEUE_TOTAL) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_QUEUE_TOTAL))
-		print_err("Expr NFTNL_EXPR_QUEUE_TOTAL mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -43,6 +32,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -60,8 +51,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -73,16 +64,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_redir-test.c b/tests/nft-expr_redir-test.c
index ce97928..ed3ff65 100644
--- a/tests/nft-expr_redir-test.c
+++ b/tests/nft-expr_redir-test.c
@@ -19,20 +19,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REDIR_REG_PROTO_MIN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REDIR_REG_PROTO_MIN))
-		print_err("Expr NFTNL_EXPR_REDIR_REG_PROTO_MIN mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REDIR_REG_PROTO_MAX) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REDIR_REG_PROTO_MAX))
-		print_err("Expr NFTNL_EXPR_REDIR_REG_PROTO_MAX mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REDIR_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REDIR_FLAGS))
-		print_err("Expr NFTNL_EXPR_REDIR_FLAGS mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -41,6 +27,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -58,8 +46,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("Parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "Parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -71,16 +59,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More than 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More than 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_reject-test.c b/tests/nft-expr_reject-test.c
index 426f9e9..8edc240 100644
--- a/tests/nft-expr_reject-test.c
+++ b/tests/nft-expr_reject-test.c
@@ -22,17 +22,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REJECT_TYPE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REJECT_TYPE))
-		print_err("Expr NFTNL_EXPR_REJECT_TYPE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REJECT_CODE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REJECT_CODE))
-		print_err("Expr NFTNL_EXPR_REJECT_CODE mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -41,6 +30,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -57,8 +48,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -70,16 +61,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_target-test.c b/tests/nft-expr_target-test.c
index 82a4a9f..00a3c0d 100644
--- a/tests/nft-expr_target-test.c
+++ b/tests/nft-expr_target-test.c
@@ -21,24 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	uint32_t lena, lenb;
-
-	if (strcmp(nftnl_expr_get_str(rule_a, NFTNL_EXPR_TG_NAME),
-		   nftnl_expr_get_str(rule_b, NFTNL_EXPR_TG_NAME)) != 0)
-		print_err("Expr NFTNL_EXPR_TG_NAME mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_TG_REV) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_TG_REV))
-		print_err("Expr NFTNL_EXPR_TG_REV mismatches");
-	nftnl_expr_get(rule_a, NFTNL_EXPR_TG_INFO, &lena);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_TG_INFO, &lenb);
-	if (lena != lenb)
-		print_err("Expr NFTNL_EXPR_TG_INFO size mismatches: %d != %d",
-			  lena, lenb);
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -48,6 +30,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
 	char data[16] = "0123456789abcdef";
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -65,8 +49,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -78,16 +62,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-rule-test.c b/tests/nft-rule-test.c
index c6ba719..2479cc3 100644
--- a/tests/nft-rule-test.c
+++ b/tests/nft-rule-test.c
@@ -19,46 +19,14 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_rule(struct nftnl_rule *a, struct nftnl_rule *b)
-{
-	const void *udata_a, *udata_b;
-	uint32_t len_a, len_b;
-
-	if (nftnl_rule_get_u32(a, NFTNL_RULE_FAMILY) !=
-	    nftnl_rule_get_u32(b, NFTNL_RULE_FAMILY))
-		print_err("Rule family mismatches");
-	if (strcmp(nftnl_rule_get_str(a, NFTNL_RULE_TABLE),
-		   nftnl_rule_get_str(b, NFTNL_RULE_TABLE)) != 0)
-		print_err("Rule table mismatches");
-	if (strcmp(nftnl_rule_get_str(a, NFTNL_RULE_CHAIN),
-		   nftnl_rule_get_str(b, NFTNL_RULE_CHAIN)) != 0)
-		print_err("Rule table mismatches");
-	if (nftnl_rule_get_u64(a, NFTNL_RULE_HANDLE) !=
-	    nftnl_rule_get_u64(b, NFTNL_RULE_HANDLE))
-		print_err("Rule handle mismatches");
-	if (nftnl_rule_get_u32(a, NFTNL_RULE_COMPAT_PROTO) !=
-	    nftnl_rule_get_u32(b, NFTNL_RULE_COMPAT_PROTO))
-		print_err("Rule compat_proto mismatches");
-	if (nftnl_rule_get_u32(a, NFTNL_RULE_COMPAT_FLAGS) !=
-	    nftnl_rule_get_u32(b, NFTNL_RULE_COMPAT_FLAGS))
-		print_err("Rule compat_flags mismatches");
-	if (nftnl_rule_get_u64(a, NFTNL_RULE_POSITION) !=
-	    nftnl_rule_get_u64(b, NFTNL_RULE_POSITION))
-		print_err("Rule compat_position mismatches");
-
-	udata_a = nftnl_rule_get_data(a, NFTNL_RULE_USERDATA, &len_a);
-	udata_b = nftnl_rule_get_data(b, NFTNL_RULE_USERDATA, &len_b);
-
-	if (len_a != len_b || memcmp(udata_a, udata_b, len_a) != 0)
-		print_err("Rule userdata mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_udata_buf *udata;
 	struct nftnl_rule *a, *b;
 	char buf[4096];
 	struct nlmsghdr *nlh;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -68,8 +36,8 @@ int main(int argc, char *argv[])
 	udata = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
 	oom_assert(udata, argv[0]);
 
-	if (!nftnl_udata_put_strz(udata, 0, "hello world"))
-		print_err("User data too big");
+	ret = nftnl_udata_put_strz(udata, 0, "hello world");
+	test_ok &= test_assert(ret, "User data too big");
 
 	nftnl_rule_set_u32(a, NFTNL_RULE_FAMILY, AF_INET);
 	nftnl_rule_set_str(a, NFTNL_RULE_TABLE, "table");
@@ -86,13 +54,13 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
-	cmp_nftnl_rule(a,b);
+	test_ok &= test_assert_rule(a, b);
 
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-set-test.c b/tests/nft-set-test.c
index 6f9b03d..24e1c62 100644
--- a/tests/nft-set-test.c
+++ b/tests/nft-set-test.c
@@ -18,32 +18,44 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_set(struct nftnl_set *a, struct nftnl_set *b)
+static bool cmp_nftnl_set(struct nftnl_set *a, struct nftnl_set *b)
 {
-	if (strcmp(nftnl_set_get_str(a, NFTNL_SET_TABLE),
-		   nftnl_set_get_str(b, NFTNL_SET_TABLE)) != 0)
-		print_err("Set table mismatches");
-	if (strcmp(nftnl_set_get_str(a, NFTNL_SET_NAME),
-		   nftnl_set_get_str(b, NFTNL_SET_NAME)) != 0)
-		print_err("Set name mismatches");
-	if (nftnl_set_get_u32(a, NFTNL_SET_FLAGS) !=
-	    nftnl_set_get_u32(b, NFTNL_SET_FLAGS))
-		print_err("Set flags mismatches");
-	if (nftnl_set_get_u32(a, NFTNL_SET_KEY_TYPE) !=
-	    nftnl_set_get_u32(b, NFTNL_SET_KEY_TYPE))
-		print_err("Set key-type mismatches");
-	if (nftnl_set_get_u32(a, NFTNL_SET_KEY_LEN) !=
-	    nftnl_set_get_u32(b, NFTNL_SET_KEY_LEN))
-		print_err("Set key-len mismatches");
-	if (nftnl_set_get_u32(a, NFTNL_SET_DATA_TYPE) !=
-	    nftnl_set_get_u32(b, NFTNL_SET_DATA_TYPE))
-		print_err("Set data-type mismatches");
-	if (nftnl_set_get_u32(a, NFTNL_SET_DATA_LEN) !=
-	    nftnl_set_get_u32(b, NFTNL_SET_DATA_LEN))
-		print_err("Set data-len mismatches");
-	if (strcmp(nftnl_set_get_str(a, NFTNL_SET_USERDATA),
-		   nftnl_set_get_str(b, NFTNL_SET_USERDATA)) != 0)
-		print_err("Set userdata mismatches");
+	bool test_ok = true;
+	bool ret;
+
+	ret = !strcmp(nftnl_set_get_str(a, NFTNL_SET_TABLE),
+		      nftnl_set_get_str(b, NFTNL_SET_TABLE));
+	test_ok &= test_assert(ret, "Set table mismatches");
+
+	ret = !strcmp(nftnl_set_get_str(a, NFTNL_SET_NAME),
+		      nftnl_set_get_str(b, NFTNL_SET_NAME));
+	test_ok &= test_assert(ret, "Set name mismatches");
+
+	ret = nftnl_set_get_u32(a, NFTNL_SET_FLAGS) ==
+	      nftnl_set_get_u32(b, NFTNL_SET_FLAGS);
+	test_ok &= test_assert(ret, "Set flags mismatches");
+
+	ret = nftnl_set_get_u32(a, NFTNL_SET_KEY_TYPE) ==
+	      nftnl_set_get_u32(b, NFTNL_SET_KEY_TYPE);
+	test_ok &= test_assert(ret, "Set key-type mismatches");
+
+	ret = nftnl_set_get_u32(a, NFTNL_SET_KEY_LEN) ==
+	      nftnl_set_get_u32(b, NFTNL_SET_KEY_LEN);
+	test_ok &= test_assert(ret, "Set key-len mismatches");
+
+	ret = nftnl_set_get_u32(a, NFTNL_SET_DATA_TYPE) ==
+	      nftnl_set_get_u32(b, NFTNL_SET_DATA_TYPE);
+	test_ok &= test_assert(ret, "Set data-type mismatches");
+
+	ret = nftnl_set_get_u32(a, NFTNL_SET_DATA_LEN) ==
+	      nftnl_set_get_u32(b, NFTNL_SET_DATA_LEN);
+	test_ok &= test_assert(ret, "Set data-len mismatches");
+
+	ret = !strcmp(nftnl_set_get_str(a, NFTNL_SET_USERDATA),
+		    nftnl_set_get_str(b, NFTNL_SET_USERDATA));
+	test_ok &= test_assert(ret, "Set userdata mismatches");
+
+	return test_ok;
 }
 
 int main(int argc, char *argv[])
@@ -51,6 +63,8 @@ int main(int argc, char *argv[])
 	struct nftnl_set *a, *b = NULL;
 	char buf[4096];
 	struct nlmsghdr *nlh;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_set_alloc();
 	b = nftnl_set_alloc();
@@ -71,12 +85,12 @@ int main(int argc, char *argv[])
 	nlh = nftnl_set_nlmsg_build_hdr(buf, NFT_MSG_NEWSET, AF_INET, 0, 1234);
 	nftnl_set_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_set_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_set_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
-	cmp_nftnl_set(a,b);
+	test_ok &= cmp_nftnl_set(a,b);
 
 	nftnl_set_free(a); nftnl_set_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-table-test.c b/tests/nft-table-test.c
index 6b0418f..d53541a 100644
--- a/tests/nft-table-test.c
+++ b/tests/nft-table-test.c
@@ -18,17 +18,24 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_table(struct nftnl_table *a, struct nftnl_table *b)
+static bool cmp_nftnl_table(struct nftnl_table *a, struct nftnl_table *b)
 {
-	if (strcmp(nftnl_table_get_str(a, NFTNL_TABLE_NAME),
-		   nftnl_table_get_str(b, NFTNL_TABLE_NAME)) != 0)
-		print_err("table name mismatches");
-	if (nftnl_table_get_u32(a, NFTNL_TABLE_FLAGS) !=
-	    nftnl_table_get_u32(b, NFTNL_TABLE_FLAGS))
-		print_err("table flags mismatches");
-	if (nftnl_table_get_u32(a, NFTNL_TABLE_FAMILY) !=
-	    nftnl_table_get_u32(b, NFTNL_TABLE_FAMILY))
-		print_err("tabke family mismatches");
+	bool test_ok = true;
+	bool ret;
+
+	ret = !strcmp(nftnl_table_get_str(a, NFTNL_TABLE_NAME),
+		      nftnl_table_get_str(b, NFTNL_TABLE_NAME));
+	test_ok &= test_assert(ret, "table name mismatches");
+
+	ret = nftnl_table_get_u32(a, NFTNL_TABLE_FLAGS) ==
+	      nftnl_table_get_u32(b, NFTNL_TABLE_FLAGS);
+	test_ok &= test_assert(ret, "table flags mismatches");
+
+	ret = nftnl_table_get_u32(a, NFTNL_TABLE_FAMILY) ==
+	      nftnl_table_get_u32(b, NFTNL_TABLE_FAMILY);
+	test_ok &= test_assert(ret, "table family mismatches");
+
+	return test_ok;
 }
 
 int main(int argc, char *argv[])
@@ -38,6 +45,9 @@ int main(int argc, char *argv[])
 
 	struct nftnl_table *a = NULL;
 	struct nftnl_table *b = NULL;
+	bool test_ok = true;
+	bool ret;
+
 	a = nftnl_table_alloc();
 	b = nftnl_table_alloc();
 
@@ -53,13 +63,13 @@ int main(int argc, char *argv[])
 					1234);
 	nftnl_table_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_table_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_table_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
-	cmp_nftnl_table(a,b);
+	test_ok &= cmp_nftnl_table(a,b);
 
 	nftnl_table_free(a);
 	nftnl_table_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
-- 
2.8.3


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/4, V2, libnftnl] tests: Fix segfaults due outbound access
  2016-08-12 20:17     ` [PATCH 1/4, V2, libnftnl] tests: Fix segfaults due outbound access Carlos Falgueras García
                         ` (2 preceding siblings ...)
  2016-08-12 20:17       ` [PATCH 4/4, V2, libnftnl] tests: Use libnftnl comparators in all tests Carlos Falgueras García
@ 2016-08-13 10:12       ` Pablo Neira Ayuso
  2016-08-13 15:25         ` Carlos Falgueras García
  3 siblings, 1 reply; 31+ messages in thread
From: Pablo Neira Ayuso @ 2016-08-13 10:12 UTC (permalink / raw)
  To: Carlos Falgueras García; +Cc: netfilter-devel

On Fri, Aug 12, 2016 at 10:17:19PM +0200, Carlos Falgueras García wrote:
> Changes random values for macros because the conversion to string of these
> values are performed by accessing to an array of strings.

Then, we should fix the functions to return "unknown" for out of bound
access of the array.

I think you have to fix this in the library, not the test.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/4, V2, libnftnl] tests: Fix wrong expression creation
  2016-08-12 20:17       ` [PATCH 2/4, V2, libnftnl] tests: Fix wrong expression creation Carlos Falgueras García
@ 2016-08-13 10:25         ` Pablo Neira Ayuso
  0 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2016-08-13 10:25 UTC (permalink / raw)
  To: Carlos Falgueras García; +Cc: netfilter-devel

Applied, thanks.

On Fri, Aug 12, 2016 at 10:17:20PM +0200, Carlos Falgueras García wrote:
> Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
> ---
>  tests/nft-expr_masq-test.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/tests/nft-expr_masq-test.c b/tests/nft-expr_masq-test.c
> index f0302e2..3f9903d 100644
> --- a/tests/nft-expr_masq-test.c
> +++ b/tests/nft-expr_masq-test.c
> @@ -52,7 +52,7 @@ int main(int argc, char *argv[])
>  	b = nftnl_rule_alloc();
>  	if (a == NULL || b == NULL)
>  		print_err("OOM");
> -	ex = nftnl_expr_alloc("nat");
> +	ex = nftnl_expr_alloc("masq");
>  	if (ex == NULL)
>  		print_err("OOM");
>  
> -- 
> 2.8.3
> 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/4, V2, libnftnl] tests: Fix segfaults due outbound access
  2016-08-13 10:12       ` [PATCH 1/4, V2, libnftnl] tests: Fix segfaults due outbound access Pablo Neira Ayuso
@ 2016-08-13 15:25         ` Carlos Falgueras García
  2016-08-15  9:12           ` Pablo Neira Ayuso
  0 siblings, 1 reply; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-13 15:25 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

On 08/13/2016 12:12 PM, Pablo Neira Ayuso wrote:
> On Fri, Aug 12, 2016 at 10:17:19PM +0200, Carlos Falgueras García wrote:
>> Changes random values for macros because the conversion to string of these
>> values are performed by accessing to an array of strings.
>
> Then, we should fix the functions to return "unknown" for out of bound
> access of the array.
>
> I think you have to fix this in the library, not the test.

The most common structure we have is this:

	static const char *element2str_array[MAX_ELEMENTS] {
		[ELEMENT_1]	= "element 1",
		...
		[ELEMENT_N]	= "element N",
	};

	static const char *element2str(uint32_t element) {
		if (element < MAX_ELEMENT)
			return "unkown";
		return element2str_array[element];
	}

I think it is better if we change it to a switch-case statement. I think 
a switch-case have the same performance and it is more robust due cases 
like this:

netfilter.h:
	enum {
		NFPROTO_UNSPEC =  0,
		NFPROTO_INET   =  1,
		NFPROTO_IPV4   =  2,
		NFPROTO_ARP    =  3,
		NFPROTO_NETDEV =  5,
		NFPROTO_BRIDGE =  7,
		NFPROTO_IPV6   = 10,
		NFPROTO_DECNET = 12,
		NFPROTO_NUMPROTO,
	};

utils.c:
	static const char *const nftnl_family_str[NFPROTO_NUMPROTO] = {
		[NFPROTO_INET]		= "inet",
		[NFPROTO_IPV4]		= "ip",
		[NFPROTO_ARP]		= "arp",
		[NFPROTO_NETDEV]	= "netdev",
		[NFPROTO_BRIDGE]	= "bridge",
		[NFPROTO_IPV6]		= "ip6",
	};

We do not have all element in the translation table and elements have 
unconsecutives values.

Another possible solution is something like this:

	  static const char *element2str(uint32_t element) {
	- 	if (element < MAX_ELEMENT)
	+ 	if (element < MAX_ELEMENT || !element2str_array[element])
	  		return "unkown";
	  	return element2str_array[element];
	  }

What do you think?

Thanks.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/4, V2, libnftnl] tests: Fix segfaults due outbound access
  2016-08-13 15:25         ` Carlos Falgueras García
@ 2016-08-15  9:12           ` Pablo Neira Ayuso
  2016-08-15 10:27             ` [PATCH 1/2 libnftnl] expr: Improve bound checking in stringification functions Carlos Falgueras García
  0 siblings, 1 reply; 31+ messages in thread
From: Pablo Neira Ayuso @ 2016-08-15  9:12 UTC (permalink / raw)
  To: Carlos Falgueras García; +Cc: netfilter-devel

On Sat, Aug 13, 2016 at 05:25:19PM +0200, Carlos Falgueras García wrote:
> Another possible solution is something like this:
> 
> 	  static const char *element2str(uint32_t element) {
> 	- 	if (element < MAX_ELEMENT)
> 	+ 	if (element < MAX_ELEMENT || !element2str_array[element])
> 	  		return "unkown";
> 	  	return element2str_array[element];
> 	  }
> 
> What do you think?

This only requires a oneliner patch and a very simple solution, please
do this.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 1/2 libnftnl] expr: Improve bound checking in stringification functions
  2016-08-15  9:12           ` Pablo Neira Ayuso
@ 2016-08-15 10:27             ` Carlos Falgueras García
  2016-08-15 10:27               ` [PATCH 2/2 libnftnl] expr: cmp: Use cmp2str() instead of directly access to array Carlos Falgueras García
  2016-08-15 10:32               ` [PATCH 1/2 libnftnl] expr: Improve bound checking in stringification functions Pablo Neira Ayuso
  0 siblings, 2 replies; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-15 10:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

In stringification functions that uses string tables it is convenient to
check the array bounds and if the element is not null. Due use of
designated initializers string tables can have gaps set to null.

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 src/expr/byteorder.c | 2 +-
 src/expr/cmp.c       | 2 +-
 src/expr/ct.c        | 2 +-
 src/expr/dynset.c    | 2 +-
 src/expr/meta.c      | 2 +-
 src/utils.c          | 3 ++-
 6 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/expr/byteorder.c b/src/expr/byteorder.c
index ca697cf..020d876 100644
--- a/src/expr/byteorder.c
+++ b/src/expr/byteorder.c
@@ -179,7 +179,7 @@ static char *expr_byteorder_str[] = {
 
 static const char *bo2str(uint32_t type)
 {
-	if (type > NFT_BYTEORDER_HTON)
+	if (type > NFT_BYTEORDER_HTON || !expr_byteorder_str[type])
 		return "unknown";
 
 	return expr_byteorder_str[type];
diff --git a/src/expr/cmp.c b/src/expr/cmp.c
index f3dd62c..92c7364 100644
--- a/src/expr/cmp.c
+++ b/src/expr/cmp.c
@@ -150,7 +150,7 @@ static char *expr_cmp_str[] = {
 
 static const char *cmp2str(uint32_t op)
 {
-	if (op > NFT_CMP_GTE)
+	if (op > NFT_CMP_GTE || !expr_cmp_str[op])
 		return "unknown";
 
 	return expr_cmp_str[op];
diff --git a/src/expr/ct.c b/src/expr/ct.c
index 1a53b49..d515302 100644
--- a/src/expr/ct.c
+++ b/src/expr/ct.c
@@ -173,7 +173,7 @@ static const char *ctkey2str_array[NFT_CT_MAX] = {
 
 static const char *ctkey2str(uint32_t ctkey)
 {
-	if (ctkey >= NFT_CT_MAX)
+	if (ctkey >= NFT_CT_MAX || !ctkey2str_array[ctkey])
 		return "unknown";
 
 	return ctkey2str_array[ctkey];
diff --git a/src/expr/dynset.c b/src/expr/dynset.c
index 6fc5bc1..90737a2 100644
--- a/src/expr/dynset.c
+++ b/src/expr/dynset.c
@@ -302,7 +302,7 @@ static char *op2str_array[] = {
 
 static const char *op2str(enum nft_dynset_ops op)
 {
-	if (op > NFT_DYNSET_OP_UPDATE)
+	if (op > NFT_DYNSET_OP_UPDATE || !op2str_array[op])
 		return "unknown";
 	return op2str_array[op];
 }
diff --git a/src/expr/meta.c b/src/expr/meta.c
index a478a89..e6b9b06 100644
--- a/src/expr/meta.c
+++ b/src/expr/meta.c
@@ -162,7 +162,7 @@ static const char *meta_key2str_array[NFT_META_MAX] = {
 
 static const char *meta_key2str(uint8_t key)
 {
-	if (key < NFT_META_MAX)
+	if (key < NFT_META_MAX && meta_key2str_array[key])
 		return meta_key2str_array[key];
 
 	return "unknown";
diff --git a/src/utils.c b/src/utils.c
index e2715a2..7264d1f 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -23,6 +23,7 @@
 #include <linux/netfilter/nf_tables.h>
 
 static const char *const nftnl_family_str[NFPROTO_NUMPROTO] = {
+	[NFPROTO_UNSPEC]	= "unknown",
 	[NFPROTO_INET]		= "inet",
 	[NFPROTO_IPV4]		= "ip",
 	[NFPROTO_ARP]		= "arp",
@@ -33,7 +34,7 @@ static const char *const nftnl_family_str[NFPROTO_NUMPROTO] = {
 
 const char *nftnl_family2str(uint32_t family)
 {
-	if (nftnl_family_str[family] == NULL)
+	if (family >= NFPROTO_NUMPROTO || !nftnl_family_str[family])
 		return "unknown";
 
 	return nftnl_family_str[family];
-- 
2.8.3


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 2/2 libnftnl] expr: cmp: Use cmp2str() instead of directly access to array
  2016-08-15 10:27             ` [PATCH 1/2 libnftnl] expr: Improve bound checking in stringification functions Carlos Falgueras García
@ 2016-08-15 10:27               ` Carlos Falgueras García
  2016-08-15 10:32                 ` Pablo Neira Ayuso
  2016-08-15 10:32               ` [PATCH 1/2 libnftnl] expr: Improve bound checking in stringification functions Pablo Neira Ayuso
  1 sibling, 1 reply; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-15 10:27 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 src/expr/cmp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/expr/cmp.c b/src/expr/cmp.c
index 92c7364..b647b01 100644
--- a/src/expr/cmp.c
+++ b/src/expr/cmp.c
@@ -267,7 +267,7 @@ static int nftnl_expr_cmp_snprintf_default(char *buf, size_t size,
 	int len = size, offset = 0, ret;
 
 	ret = snprintf(buf, len, "%s reg %u ",
-		       expr_cmp_str[cmp->op], cmp->sreg);
+		       cmp2str(cmp->op), cmp->sreg);
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
 	ret = nftnl_data_reg_snprintf(buf+offset, len, &cmp->data,
-- 
2.8.3


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/2 libnftnl] expr: Improve bound checking in stringification functions
  2016-08-15 10:27             ` [PATCH 1/2 libnftnl] expr: Improve bound checking in stringification functions Carlos Falgueras García
  2016-08-15 10:27               ` [PATCH 2/2 libnftnl] expr: cmp: Use cmp2str() instead of directly access to array Carlos Falgueras García
@ 2016-08-15 10:32               ` Pablo Neira Ayuso
  1 sibling, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2016-08-15 10:32 UTC (permalink / raw)
  To: Carlos Falgueras García; +Cc: netfilter-devel

On Mon, Aug 15, 2016 at 12:27:36PM +0200, Carlos Falgueras García wrote:
> --- a/src/utils.c
> +++ b/src/utils.c
> @@ -23,6 +23,7 @@
>  #include <linux/netfilter/nf_tables.h>
>  
>  static const char *const nftnl_family_str[NFPROTO_NUMPROTO] = {
> +	[NFPROTO_UNSPEC]	= "unknown",
>  	[NFPROTO_INET]		= "inet",
>  	[NFPROTO_IPV4]		= "ip",
>  	[NFPROTO_ARP]		= "arp",
> @@ -33,7 +34,7 @@ static const char *const nftnl_family_str[NFPROTO_NUMPROTO] = {
>  
>  const char *nftnl_family2str(uint32_t family)
>  {
> -	if (nftnl_family_str[family] == NULL)
> +	if (family >= NFPROTO_NUMPROTO || !nftnl_family_str[family])
>  		return "unknown";
>  
>  	return nftnl_family_str[family];

You only need this chunk.

Other spots have continuous enums, so there is no problem.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/2 libnftnl] expr: cmp: Use cmp2str() instead of directly access to array
  2016-08-15 10:27               ` [PATCH 2/2 libnftnl] expr: cmp: Use cmp2str() instead of directly access to array Carlos Falgueras García
@ 2016-08-15 10:32                 ` Pablo Neira Ayuso
  2016-08-15 10:51                   ` [PATCH 1/2 libnftnl] utils: Fix out of bound access in nftnl_family2str Carlos Falgueras García
  0 siblings, 1 reply; 31+ messages in thread
From: Pablo Neira Ayuso @ 2016-08-15 10:32 UTC (permalink / raw)
  To: Carlos Falgueras García; +Cc: netfilter-devel

On Mon, Aug 15, 2016 at 12:27:37PM +0200, Carlos Falgueras García wrote:

Please always add a description to your patches, even if it is only
one line to explain why we need this.

Thanks.

> Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
> ---
>  src/expr/cmp.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/src/expr/cmp.c b/src/expr/cmp.c
> index 92c7364..b647b01 100644
> --- a/src/expr/cmp.c
> +++ b/src/expr/cmp.c
> @@ -267,7 +267,7 @@ static int nftnl_expr_cmp_snprintf_default(char *buf, size_t size,
>  	int len = size, offset = 0, ret;
>  
>  	ret = snprintf(buf, len, "%s reg %u ",
> -		       expr_cmp_str[cmp->op], cmp->sreg);
> +		       cmp2str(cmp->op), cmp->sreg);
>  	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
>  
>  	ret = nftnl_data_reg_snprintf(buf+offset, len, &cmp->data,
> -- 
> 2.8.3
> 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 1/2 libnftnl] utils: Fix out of bound access in nftnl_family2str
  2016-08-15 10:32                 ` Pablo Neira Ayuso
@ 2016-08-15 10:51                   ` Carlos Falgueras García
  2016-08-15 10:51                     ` [PATCH 2/2 libnfntl] expr: cmp: Use cmp2str() instead of directly access to array Carlos Falgueras García
  2016-08-15 11:03                     ` [PATCH 1/2 libnftnl] utils: Fix out of bound access in nftnl_family2str Pablo Neira Ayuso
  0 siblings, 2 replies; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-15 10:51 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

Checks array limits before access it and adds a missed translation.

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 src/utils.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/utils.c b/src/utils.c
index e2715a2..7264d1f 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -23,6 +23,7 @@
 #include <linux/netfilter/nf_tables.h>
 
 static const char *const nftnl_family_str[NFPROTO_NUMPROTO] = {
+	[NFPROTO_UNSPEC]	= "unknown",
 	[NFPROTO_INET]		= "inet",
 	[NFPROTO_IPV4]		= "ip",
 	[NFPROTO_ARP]		= "arp",
@@ -33,7 +34,7 @@ static const char *const nftnl_family_str[NFPROTO_NUMPROTO] = {
 
 const char *nftnl_family2str(uint32_t family)
 {
-	if (nftnl_family_str[family] == NULL)
+	if (family >= NFPROTO_NUMPROTO || !nftnl_family_str[family])
 		return "unknown";
 
 	return nftnl_family_str[family];
-- 
2.8.3


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 2/2 libnfntl] expr: cmp: Use cmp2str() instead of directly access to array
  2016-08-15 10:51                   ` [PATCH 1/2 libnftnl] utils: Fix out of bound access in nftnl_family2str Carlos Falgueras García
@ 2016-08-15 10:51                     ` Carlos Falgueras García
  2016-08-15 11:49                       ` Pablo Neira Ayuso
  2016-08-15 11:03                     ` [PATCH 1/2 libnftnl] utils: Fix out of bound access in nftnl_family2str Pablo Neira Ayuso
  1 sibling, 1 reply; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-15 10:51 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

Uses cmp2str() which checks array bounds.

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 src/expr/cmp.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/expr/cmp.c b/src/expr/cmp.c
index f3dd62c..5d51958 100644
--- a/src/expr/cmp.c
+++ b/src/expr/cmp.c
@@ -267,7 +267,7 @@ static int nftnl_expr_cmp_snprintf_default(char *buf, size_t size,
 	int len = size, offset = 0, ret;
 
 	ret = snprintf(buf, len, "%s reg %u ",
-		       expr_cmp_str[cmp->op], cmp->sreg);
+		       cmp2str(cmp->op), cmp->sreg);
 	SNPRINTF_BUFFER_SIZE(ret, size, len, offset);
 
 	ret = nftnl_data_reg_snprintf(buf+offset, len, &cmp->data,
-- 
2.8.3


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/2 libnftnl] utils: Fix out of bound access in nftnl_family2str
  2016-08-15 10:51                   ` [PATCH 1/2 libnftnl] utils: Fix out of bound access in nftnl_family2str Carlos Falgueras García
  2016-08-15 10:51                     ` [PATCH 2/2 libnfntl] expr: cmp: Use cmp2str() instead of directly access to array Carlos Falgueras García
@ 2016-08-15 11:03                     ` Pablo Neira Ayuso
  2016-08-15 11:45                       ` Carlos Falgueras García
  1 sibling, 1 reply; 31+ messages in thread
From: Pablo Neira Ayuso @ 2016-08-15 11:03 UTC (permalink / raw)
  To: Carlos Falgueras García; +Cc: netfilter-devel

On Mon, Aug 15, 2016 at 12:51:02PM +0200, Carlos Falgueras García wrote:
> Checks array limits before access it and adds a missed translation.
> 
> Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
> ---
>  src/utils.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/src/utils.c b/src/utils.c
> index e2715a2..7264d1f 100644
> --- a/src/utils.c
> +++ b/src/utils.c
> @@ -23,6 +23,7 @@
>  #include <linux/netfilter/nf_tables.h>
>  
>  static const char *const nftnl_family_str[NFPROTO_NUMPROTO] = {
> +	[NFPROTO_UNSPEC]	= "unknown",

You don't need this line above, right? I can mangle the patch here
before applying it.

>  	[NFPROTO_INET]		= "inet",
>  	[NFPROTO_IPV4]		= "ip",
>  	[NFPROTO_ARP]		= "arp",
> @@ -33,7 +34,7 @@ static const char *const nftnl_family_str[NFPROTO_NUMPROTO] = {
>  
>  const char *nftnl_family2str(uint32_t family)
>  {
> -	if (nftnl_family_str[family] == NULL)
> +	if (family >= NFPROTO_NUMPROTO || !nftnl_family_str[family])
>  		return "unknown";
>  
>  	return nftnl_family_str[family];
> -- 
> 2.8.3
> 

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/2 libnftnl] utils: Fix out of bound access in nftnl_family2str
  2016-08-15 11:03                     ` [PATCH 1/2 libnftnl] utils: Fix out of bound access in nftnl_family2str Pablo Neira Ayuso
@ 2016-08-15 11:45                       ` Carlos Falgueras García
  2016-08-15 11:46                         ` Pablo Neira Ayuso
  0 siblings, 1 reply; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-15 11:45 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

On 08/15/2016 01:03 PM, Pablo Neira Ayuso wrote:
> On Mon, Aug 15, 2016 at 12:51:02PM +0200, Carlos Falgueras García wrote:
>> Checks array limits before access it and adds a missed translation.
>>
>> Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
>> ---
>>  src/utils.c | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>>
>> diff --git a/src/utils.c b/src/utils.c
>> index e2715a2..7264d1f 100644
>> --- a/src/utils.c
>> +++ b/src/utils.c
>> @@ -23,6 +23,7 @@
>>  #include <linux/netfilter/nf_tables.h>
>>
>>  static const char *const nftnl_family_str[NFPROTO_NUMPROTO] = {
>> +	[NFPROTO_UNSPEC]	= "unknown",
>
> You don't need this line above, right? I can mangle the patch here
> before applying it.

Yes, sorry. Do you get rid of it or must I send another version?

>>  	[NFPROTO_INET]		= "inet",
>>  	[NFPROTO_IPV4]		= "ip",
>>  	[NFPROTO_ARP]		= "arp",
>> @@ -33,7 +34,7 @@ static const char *const nftnl_family_str[NFPROTO_NUMPROTO] = {
>>
>>  const char *nftnl_family2str(uint32_t family)
>>  {
>> -	if (nftnl_family_str[family] == NULL)
>> +	if (family >= NFPROTO_NUMPROTO || !nftnl_family_str[family])
>>  		return "unknown";
>>
>>  	return nftnl_family_str[family];
>> --
>> 2.8.3
>>

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 1/2 libnftnl] utils: Fix out of bound access in nftnl_family2str
  2016-08-15 11:45                       ` Carlos Falgueras García
@ 2016-08-15 11:46                         ` Pablo Neira Ayuso
  0 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2016-08-15 11:46 UTC (permalink / raw)
  To: Carlos Falgueras García; +Cc: netfilter-devel

On Mon, Aug 15, 2016 at 01:45:55PM +0200, Carlos Falgueras García wrote:
> On 08/15/2016 01:03 PM, Pablo Neira Ayuso wrote:
> >On Mon, Aug 15, 2016 at 12:51:02PM +0200, Carlos Falgueras García wrote:
> >>Checks array limits before access it and adds a missed translation.
> >>
> >>Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
> >>---
> >> src/utils.c | 3 ++-
> >> 1 file changed, 2 insertions(+), 1 deletion(-)
> >>
> >>diff --git a/src/utils.c b/src/utils.c
> >>index e2715a2..7264d1f 100644
> >>--- a/src/utils.c
> >>+++ b/src/utils.c
> >>@@ -23,6 +23,7 @@
> >> #include <linux/netfilter/nf_tables.h>
> >>
> >> static const char *const nftnl_family_str[NFPROTO_NUMPROTO] = {
> >>+	[NFPROTO_UNSPEC]	= "unknown",
> >
> >You don't need this line above, right? I can mangle the patch here
> >before applying it.
> 
> Yes, sorry. Do you get rid of it or must I send another version?

I just edit this here, no problem.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/2 libnfntl] expr: cmp: Use cmp2str() instead of directly access to array
  2016-08-15 10:51                     ` [PATCH 2/2 libnfntl] expr: cmp: Use cmp2str() instead of directly access to array Carlos Falgueras García
@ 2016-08-15 11:49                       ` Pablo Neira Ayuso
  0 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2016-08-15 11:49 UTC (permalink / raw)
  To: Carlos Falgueras García; +Cc: netfilter-devel

On Mon, Aug 15, 2016 at 12:51:03PM +0200, Carlos Falgueras García wrote:
> Uses cmp2str() which checks array bounds.

Applied, thanks.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 1/2 v2 libnftnl] tests: Consolidate printing error utilities
  2016-08-12 20:16     ` Carlos Falgueras García
@ 2016-08-15 12:23       ` Carlos Falgueras García
  2016-08-15 12:23         ` [PATCH 2/2 v2 libnftnl] test: Use libnftnl comparators in all tests Carlos Falgueras García
  0 siblings, 1 reply; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-15 12:23 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

This patch adds libtest.c and libtest.h to reduce test code and
consolidate it.

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 .gitignore                      |  1 +
 tests/Makefile.am               | 52 +++++++++++++++++++++-------------------
 tests/libtest.c                 | 53 +++++++++++++++++++++++++++++++++++++++++
 tests/libtest.h                 | 11 +++++++++
 tests/nft-chain-test.c          | 18 ++++----------
 tests/nft-expr_bitwise-test.c   | 29 +++++++---------------
 tests/nft-expr_byteorder-test.c | 29 +++++++---------------
 tests/nft-expr_cmp-test.c       | 29 +++++++---------------
 tests/nft-expr_counter-test.c   | 27 +++++++--------------
 tests/nft-expr_ct-test.c        | 28 +++++++---------------
 tests/nft-expr_dup-test.c       | 28 +++++++---------------
 tests/nft-expr_exthdr-test.c    | 28 +++++++---------------
 tests/nft-expr_fwd-test.c       | 28 +++++++---------------
 tests/nft-expr_immediate-test.c | 34 ++++++++++----------------
 tests/nft-expr_limit-test.c     | 29 +++++++---------------
 tests/nft-expr_log-test.c       | 29 +++++++---------------
 tests/nft-expr_lookup-test.c    | 30 +++++++----------------
 tests/nft-expr_masq-test.c      | 29 +++++++---------------
 tests/nft-expr_match-test.c     | 38 +++++++++--------------------
 tests/nft-expr_meta-test.c      | 29 +++++++---------------
 tests/nft-expr_nat-test.c       | 29 +++++++---------------
 tests/nft-expr_payload-test.c   | 29 +++++++---------------
 tests/nft-expr_queue-test.c     | 29 +++++++---------------
 tests/nft-expr_redir-test.c     | 29 +++++++---------------
 tests/nft-expr_reject-test.c    | 29 +++++++---------------
 tests/nft-expr_target-test.c    | 37 +++++++++-------------------
 tests/nft-rule-test.c           | 20 ++++------------
 tests/nft-set-test.c            | 18 ++++----------
 tests/nft-table-test.c          | 17 ++++---------
 29 files changed, 305 insertions(+), 511 deletions(-)
 create mode 100644 tests/libtest.c
 create mode 100644 tests/libtest.h

diff --git a/.gitignore b/.gitignore
index 1650e58..5a781db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,4 +28,5 @@ examples/*
 !examples/Makefile.am
 tests/*
 !tests/*.c
+!tests/*.h
 !tests/Makefile.am
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0377081..b55aeba 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -4,6 +4,8 @@ EXTRA_DIST =		test-script.sh			\
 			jsonfiles			\
 			xmlfiles
 
+LIBTEST =		libtest.c
+
 check_PROGRAMS = 	nft-parsing-test		\
 			nft-table-test			\
 			nft-chain-test			\
@@ -34,77 +36,77 @@ check_PROGRAMS = 	nft-parsing-test		\
 nft_parsing_test_SOURCES = nft-parsing-test.c
 nft_parsing_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} ${LIBXML_LIBS} ${LIBJSON_LIBS}
 
-nft_table_test_SOURCES = nft-table-test.c
+nft_table_test_SOURCES = nft-table-test.c ${LIBTEST}
 nft_table_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_chain_test_SOURCES = nft-chain-test.c
+nft_chain_test_SOURCES = nft-chain-test.c ${LIBTEST}
 nft_chain_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_rule_test_SOURCES = nft-rule-test.c
+nft_rule_test_SOURCES = nft-rule-test.c ${LIBTEST}
 nft_rule_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_set_test_SOURCES = nft-set-test.c
+nft_set_test_SOURCES = nft-set-test.c ${LIBTEST}
 nft_set_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_bitwise_test_SOURCES = nft-expr_bitwise-test.c
+nft_expr_bitwise_test_SOURCES = nft-expr_bitwise-test.c ${LIBTEST}
 nft_expr_bitwise_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_byteorder_test_SOURCES = nft-expr_byteorder-test.c
+nft_expr_byteorder_test_SOURCES = nft-expr_byteorder-test.c ${LIBTEST}
 nft_expr_byteorder_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_cmp_test_SOURCES = nft-expr_cmp-test.c
+nft_expr_cmp_test_SOURCES = nft-expr_cmp-test.c ${LIBTEST}
 nft_expr_cmp_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_counter_test_SOURCES = nft-expr_counter-test.c
+nft_expr_counter_test_SOURCES = nft-expr_counter-test.c ${LIBTEST}
 nft_expr_counter_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_exthdr_test_SOURCES = nft-expr_exthdr-test.c
+nft_expr_exthdr_test_SOURCES = nft-expr_exthdr-test.c ${LIBTEST}
 nft_expr_exthdr_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_ct_test_SOURCES = nft-expr_ct-test.c
+nft_expr_ct_test_SOURCES = nft-expr_ct-test.c ${LIBTEST}
 nft_expr_ct_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_dup_test_SOURCES = nft-expr_dup-test.c
+nft_expr_dup_test_SOURCES = nft-expr_dup-test.c ${LIBTEST}
 nft_expr_dup_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_fwd_test_SOURCES = nft-expr_fwd-test.c
+nft_expr_fwd_test_SOURCES = nft-expr_fwd-test.c ${LIBTEST}
 nft_expr_fwd_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_immediate_test_SOURCES = nft-expr_immediate-test.c
+nft_expr_immediate_test_SOURCES = nft-expr_immediate-test.c ${LIBTEST}
 nft_expr_immediate_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_limit_test_SOURCES = nft-expr_limit-test.c
+nft_expr_limit_test_SOURCES = nft-expr_limit-test.c ${LIBTEST}
 nft_expr_limit_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_lookup_test_SOURCES = nft-expr_lookup-test.c
+nft_expr_lookup_test_SOURCES = nft-expr_lookup-test.c ${LIBTEST}
 nft_expr_lookup_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_log_test_SOURCES = nft-expr_log-test.c
+nft_expr_log_test_SOURCES = nft-expr_log-test.c ${LIBTEST}
 nft_expr_log_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_match_test_SOURCES = nft-expr_match-test.c
+nft_expr_match_test_SOURCES = nft-expr_match-test.c ${LIBTEST}
 nft_expr_match_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_masq_test_SOURCES = nft-expr_masq-test.c
+nft_expr_masq_test_SOURCES = nft-expr_masq-test.c ${LIBTEST}
 nft_expr_masq_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_meta_test_SOURCES = nft-expr_meta-test.c
+nft_expr_meta_test_SOURCES = nft-expr_meta-test.c ${LIBTEST}
 nft_expr_meta_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_nat_test_SOURCES = nft-expr_nat-test.c
+nft_expr_nat_test_SOURCES = nft-expr_nat-test.c ${LIBTEST}
 nft_expr_nat_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_payload_test_SOURCES = nft-expr_payload-test.c
+nft_expr_payload_test_SOURCES = nft-expr_payload-test.c ${LIBTEST}
 nft_expr_payload_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_queue_test_SOURCES = nft-expr_queue-test.c
+nft_expr_queue_test_SOURCES = nft-expr_queue-test.c ${LIBTEST}
 nft_expr_queue_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_reject_test_SOURCES = nft-expr_reject-test.c
+nft_expr_reject_test_SOURCES = nft-expr_reject-test.c ${LIBTEST}
 nft_expr_reject_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_redir_test_SOURCES = nft-expr_redir-test.c
+nft_expr_redir_test_SOURCES = nft-expr_redir-test.c ${LIBTEST}
 nft_expr_redir_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_target_test_SOURCES = nft-expr_target-test.c
+nft_expr_target_test_SOURCES = nft-expr_target-test.c ${LIBTEST}
 nft_expr_target_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
diff --git a/tests/libtest.c b/tests/libtest.c
new file mode 100644
index 0000000..ed7eafa
--- /dev/null
+++ b/tests/libtest.c
@@ -0,0 +1,53 @@
+#include <libtest.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#define COLOR_RED     "\x1b[31m"
+#define COLOR_GREEN   "\x1b[32m"
+#define COLOR_RESET   "\x1b[0m"
+
+static bool test_ok = true;
+
+void __oom_assert(bool cond, const char *prog, const char *file, int line)
+{
+	if (cond)
+		return;
+
+	fprintf(stderr,
+		COLOR_RED "OOM" COLOR_RESET " at %s:%d\n\t%s\n", file, line,
+		strerror(errno));
+
+	test_ok = false;
+	test_report(prog);
+	exit(EXIT_FAILURE);
+}
+
+void print_err(const char *fmt, ...)
+{
+	va_list args;
+
+	fprintf(stderr, COLOR_RED "ERROR: " COLOR_RESET);
+	va_start(args, fmt);
+	vfprintf(stderr, fmt, args);
+	va_end(args);
+	fprintf(stderr, "\n");
+
+	test_ok = false;
+}
+
+int test_report(const char *prog)
+{
+	switch (test_ok) {
+	case true:
+		printf("%s: " COLOR_GREEN "OK\n" COLOR_RESET, prog);
+		return EXIT_SUCCESS;
+	case false:
+		printf("%s: " COLOR_RED "FAIL\n" COLOR_RESET, prog);
+		return EXIT_FAILURE;
+	}
+}
diff --git a/tests/libtest.h b/tests/libtest.h
new file mode 100644
index 0000000..f570057
--- /dev/null
+++ b/tests/libtest.h
@@ -0,0 +1,11 @@
+#ifndef _TESTS_UTILS_H
+#define _TESTS_UTILS_H
+
+#include <stdbool.h>
+
+#define oom_assert(cond, prog) __oom_assert(cond, prog, __FILE__, __LINE__)
+void __oom_assert(bool cond, const char *prog, const char *file, int line);
+void print_err(const char *fmt, ...);
+int test_report(const char *prog);
+
+#endif
diff --git a/tests/nft-chain-test.c b/tests/nft-chain-test.c
index d678d46..b42fb86 100644
--- a/tests/nft-chain-test.c
+++ b/tests/nft-chain-test.c
@@ -15,13 +15,7 @@
 #include <linux/netfilter/nf_tables.h>
 #include <libnftnl/chain.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_chain(struct nftnl_chain *a, struct nftnl_chain *b)
 {
@@ -72,8 +66,8 @@ int main(int argc, char *argv[])
 
 	a = nftnl_chain_alloc();
 	b = nftnl_chain_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	nftnl_chain_set_str(a, NFTNL_CHAIN_NAME, "test");
 	nftnl_chain_set_u32(a, NFTNL_CHAIN_FAMILY, AF_INET);
@@ -101,10 +95,6 @@ int main(int argc, char *argv[])
 	nftnl_chain_free(a);
 	nftnl_chain_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 
 }
diff --git a/tests/nft-expr_bitwise-test.c b/tests/nft-expr_bitwise-test.c
index 64c1446..42e9bb2 100644
--- a/tests/nft-expr_bitwise-test.c
+++ b/tests/nft-expr_bitwise-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -65,11 +59,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("bitwise");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_SREG, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_DREG, 0x78123456);
@@ -87,13 +80,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
@@ -107,9 +100,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_byteorder-test.c b/tests/nft-expr_byteorder-test.c
index 5994e5b..9a25667 100644
--- a/tests/nft-expr_byteorder-test.c
+++ b/tests/nft-expr_byteorder-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -58,11 +52,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("byteorder");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BYTEORDER_SREG, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BYTEORDER_DREG, 0x12345678);
@@ -80,13 +73,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a,rule_b);
 
@@ -99,9 +92,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_cmp-test.c b/tests/nft-expr_cmp-test.c
index ec00bb9..570db2c 100644
--- a/tests/nft-expr_cmp-test.c
+++ b/tests/nft-expr_cmp-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -56,11 +50,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("cmp");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set(ex, NFTNL_EXPR_CMP_DATA, &data_len, sizeof(data_len));
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_CMP_SREG, 0x12345678);
@@ -76,12 +69,12 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -94,9 +87,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_counter-test.c b/tests/nft-expr_counter-test.c
index 519bc1f..7066c26 100644
--- a/tests/nft-expr_counter-test.c
+++ b/tests/nft-expr_counter-test.c
@@ -19,13 +19,8 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
+#include "libtest.h"
 
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -49,12 +44,11 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	ex = nftnl_expr_alloc("counter");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u64(ex, NFTNL_EXPR_CTR_BYTES, 0x123456789abcdef0);
 	nftnl_expr_set_u64(ex, NFTNL_EXPR_CTR_PACKETS, 0xf0123456789abcde);
@@ -68,12 +62,12 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -86,8 +80,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_ct-test.c b/tests/nft-expr_ct-test.c
index e98fbab..cfbe0d6 100644
--- a/tests/nft-expr_ct-test.c
+++ b/tests/nft-expr_ct-test.c
@@ -19,12 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -50,11 +45,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("ct");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_CT_KEY, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_CT_DIR, 0x12);
@@ -70,13 +64,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -89,9 +83,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_dup-test.c b/tests/nft-expr_dup-test.c
index 3c37d4a..4ae112d 100644
--- a/tests/nft-expr_dup-test.c
+++ b/tests/nft-expr_dup-test.c
@@ -19,12 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -48,11 +43,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("dup");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_DUP_SREG_ADDR, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_DUP_SREG_DEV,  0x78123456);
@@ -67,13 +61,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -86,9 +80,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_exthdr-test.c b/tests/nft-expr_exthdr-test.c
index fef2dd0..56652b5 100644
--- a/tests/nft-expr_exthdr-test.c
+++ b/tests/nft-expr_exthdr-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -55,11 +49,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("exthdr");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_EXTHDR_DREG, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_EXTHDR_TYPE, 0x12);
@@ -75,13 +68,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -93,9 +86,6 @@ int main(int argc, char *argv[])
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
-	if (!test_ok)
-		exit(EXIT_FAILURE);
 
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_fwd-test.c b/tests/nft-expr_fwd-test.c
index 4fdf53d..7a27299 100644
--- a/tests/nft-expr_fwd-test.c
+++ b/tests/nft-expr_fwd-test.c
@@ -19,12 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -45,11 +40,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("dup");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_FWD_SREG_DEV,  0x78123456);
 
@@ -63,13 +57,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -82,9 +76,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_immediate-test.c b/tests/nft-expr_immediate-test.c
index 60a1450..1e9749f 100644
--- a/tests/nft-expr_immediate-test.c
+++ b/tests/nft-expr_immediate-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr_verdict(struct nftnl_expr *rule_a,
 				   struct nftnl_expr *rule_b)
@@ -76,12 +70,12 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex_val = nftnl_expr_alloc("immediate");
 	ex_ver = nftnl_expr_alloc("immediate");
-	if (!ex_val || !ex_ver)
-		print_err("OOM");
+	oom_assert(ex_val, argv[0]);
+	oom_assert(ex_ver, argv[0]);
 
 	nftnl_expr_set_u32(ex_val, NFTNL_EXPR_IMM_DREG, 0x1234568);
 	nftnl_expr_set(ex_val,     NFTNL_EXPR_IMM_DATA, data, sizeof(data));
@@ -101,20 +95,20 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr_value(rule_a, rule_b);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr_verdict(rule_a, rule_b);
 
@@ -127,9 +121,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_limit-test.c b/tests/nft-expr_limit-test.c
index 2838941..7848e29 100644
--- a/tests/nft-expr_limit-test.c
+++ b/tests/nft-expr_limit-test.c
@@ -20,13 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -59,11 +53,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("limit");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u64(ex, NFTNL_EXPR_LIMIT_RATE, 0x123456789abcdef0);
 	nftnl_expr_set_u64(ex, NFTNL_EXPR_LIMIT_UNIT, 0xf0123456789abcde);
@@ -81,13 +74,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -100,9 +93,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_log-test.c b/tests/nft-expr_log-test.c
index b7aa302..a2c1f1d 100644
--- a/tests/nft-expr_log-test.c
+++ b/tests/nft-expr_log-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-	test_ok = 0;
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -55,11 +49,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("log");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_LOG_SNAPLEN, 0x12345678);
 	nftnl_expr_set_u16(ex, NFTNL_EXPR_LOG_GROUP, 0x1234);
@@ -75,12 +68,12 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -93,9 +86,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_lookup-test.c b/tests/nft-expr_lookup-test.c
index 28c1204..34dffdf 100644
--- a/tests/nft-expr_lookup-test.c
+++ b/tests/nft-expr_lookup-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -63,11 +57,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("lookup");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_LOOKUP_SREG, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_LOOKUP_DREG, 0x78123456);
@@ -84,12 +77,12 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -102,10 +95,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_masq-test.c b/tests/nft-expr_masq-test.c
index 3f9903d..fdfbf03 100644
--- a/tests/nft-expr_masq-test.c
+++ b/tests/nft-expr_masq-test.c
@@ -17,13 +17,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -50,11 +44,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("masq");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_MASQ_FLAGS, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_MASQ_REG_PROTO_MIN, 0x5432178);
@@ -70,13 +63,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -89,9 +82,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_match-test.c b/tests/nft-expr_match-test.c
index 39a49d8..9902d2f 100644
--- a/tests/nft-expr_match-test.c
+++ b/tests/nft-expr_match-test.c
@@ -20,19 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
-
-static void print_err2(const char *msg, uint32_t a, uint32_t b)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s size a: %d b: %d \n", msg, a, b);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -48,7 +36,8 @@ static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 	nftnl_expr_get(rule_a, NFTNL_EXPR_MT_INFO, &lena);
 	nftnl_expr_get(rule_b, NFTNL_EXPR_MT_INFO, &lenb);
 	if (lena != lenb)
-		print_err2("Expr NFTNL_EXPR_MT_INFO size mismatches", lena, lenb);
+		print_err("Expr NFTNL_EXPR_MT_INFO size mismatches: %d != %d",
+			  lena, lenb);
 }
 
 int main(int argc, char *argv[])
@@ -63,11 +52,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("match");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_str(ex, NFTNL_EXPR_MT_NAME, "Tests");
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_MT_REV, 0x12345678);
@@ -81,13 +69,13 @@ int main(int argc, char *argv[])
 		print_err("parsing problems");
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -100,9 +88,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_meta-test.c b/tests/nft-expr_meta-test.c
index 8fb7873..e528631 100644
--- a/tests/nft-expr_meta-test.c
+++ b/tests/nft-expr_meta-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -49,11 +43,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("meta");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_META_KEY, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_META_DREG, 0x78123456);
@@ -67,13 +60,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -86,9 +79,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_nat-test.c b/tests/nft-expr_nat-test.c
index fd3a488..d1cc0b1 100644
--- a/tests/nft-expr_nat-test.c
+++ b/tests/nft-expr_nat-test.c
@@ -20,13 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -65,11 +59,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("nat");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_NAT_TYPE, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_NAT_FAMILY, 0x3456721);
@@ -89,13 +82,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -108,9 +101,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_payload-test.c b/tests/nft-expr_payload-test.c
index 371372c..0812d6d 100644
--- a/tests/nft-expr_payload-test.c
+++ b/tests/nft-expr_payload-test.c
@@ -20,13 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -56,11 +50,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("payload");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_PAYLOAD_DREG, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_PAYLOAD_BASE, 0x78123456);
@@ -76,13 +69,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -95,9 +88,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_queue-test.c b/tests/nft-expr_queue-test.c
index 1cc39aa..327e8fd 100644
--- a/tests/nft-expr_queue-test.c
+++ b/tests/nft-expr_queue-test.c
@@ -22,13 +22,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -52,11 +46,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("queue");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u16(ex, NFTNL_EXPR_QUEUE_NUM, 0x01010);
 	nftnl_expr_set_u16(ex, NFTNL_EXPR_QUEUE_TOTAL, 0x1234);
@@ -72,13 +65,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -91,9 +84,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_redir-test.c b/tests/nft-expr_redir-test.c
index 6c8caec..ce97928 100644
--- a/tests/nft-expr_redir-test.c
+++ b/tests/nft-expr_redir-test.c
@@ -17,13 +17,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -50,11 +44,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("redir");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_REDIR_REG_PROTO_MIN, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_REDIR_REG_PROTO_MAX, 0x56781234);
@@ -70,13 +63,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -89,9 +82,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_reject-test.c b/tests/nft-expr_reject-test.c
index d8189ea..426f9e9 100644
--- a/tests/nft-expr_reject-test.c
+++ b/tests/nft-expr_reject-test.c
@@ -20,13 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -50,11 +44,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("reject");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_REJECT_TYPE, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_REJECT_CODE, 0x45681234);
@@ -69,13 +62,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -88,9 +81,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_target-test.c b/tests/nft-expr_target-test.c
index ba56b27..82a4a9f 100644
--- a/tests/nft-expr_target-test.c
+++ b/tests/nft-expr_target-test.c
@@ -19,19 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
-
-static void print_err2(const char *msg, uint32_t a, uint32_t b)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s size a: %d b: %d \n",msg, a, b);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -47,7 +35,8 @@ static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 	nftnl_expr_get(rule_a, NFTNL_EXPR_TG_INFO, &lena);
 	nftnl_expr_get(rule_b, NFTNL_EXPR_TG_INFO, &lenb);
 	if (lena != lenb)
-		print_err2("Expr NFTNL_EXPR_TG_INFO size mismatches", lena, lenb);
+		print_err("Expr NFTNL_EXPR_TG_INFO size mismatches: %d != %d",
+			  lena, lenb);
 }
 
 int main(int argc, char *argv[])
@@ -62,12 +51,11 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	ex = nftnl_expr_alloc("target");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set(ex, NFTNL_EXPR_TG_NAME, "test", strlen("test"));
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_TG_REV, 0x56781234);
@@ -82,13 +70,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -101,8 +89,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-rule-test.c b/tests/nft-rule-test.c
index dee3530..c6ba719 100644
--- a/tests/nft-rule-test.c
+++ b/tests/nft-rule-test.c
@@ -17,13 +17,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/udata.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_rule(struct nftnl_rule *a, struct nftnl_rule *b)
 {
@@ -68,12 +62,11 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	udata = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
-	if (!udata)
-		print_err("OOM");
+	oom_assert(udata, argv[0]);
 
 	if (!nftnl_udata_put_strz(udata, 0, "hello world"))
 		print_err("User data too big");
@@ -100,9 +93,6 @@ int main(int argc, char *argv[])
 
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
-	if (!test_ok)
-		exit(EXIT_FAILURE);
 
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-set-test.c b/tests/nft-set-test.c
index 173c17f..6f9b03d 100644
--- a/tests/nft-set-test.c
+++ b/tests/nft-set-test.c
@@ -16,13 +16,7 @@
 
 #include <libnftnl/set.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_set(struct nftnl_set *a, struct nftnl_set *b)
 {
@@ -60,8 +54,8 @@ int main(int argc, char *argv[])
 
 	a = nftnl_set_alloc();
 	b = nftnl_set_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	nftnl_set_set_str(a, NFTNL_SET_TABLE, "test-table");
 	nftnl_set_set_str(a, NFTNL_SET_NAME, "test-name");
@@ -84,9 +78,5 @@ int main(int argc, char *argv[])
 
 	nftnl_set_free(a); nftnl_set_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-table-test.c b/tests/nft-table-test.c
index 1031ffe..6b0418f 100644
--- a/tests/nft-table-test.c
+++ b/tests/nft-table-test.c
@@ -16,13 +16,7 @@
 #include <linux/netfilter/nf_tables.h>
 #include <libnftnl/table.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_table(struct nftnl_table *a, struct nftnl_table *b)
 {
@@ -47,8 +41,8 @@ int main(int argc, char *argv[])
 	a = nftnl_table_alloc();
 	b = nftnl_table_alloc();
 
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	nftnl_table_set_str(a, NFTNL_TABLE_NAME, "test");
 	nftnl_table_set_u32(a, NFTNL_TABLE_FAMILY, AF_INET);
@@ -66,9 +60,6 @@ int main(int argc, char *argv[])
 
 	nftnl_table_free(a);
 	nftnl_table_free(b);
-	if (!test_ok)
-		exit(EXIT_FAILURE);
 
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
-- 
2.8.3


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 2/2 v2 libnftnl] test: Use libnftnl comparators in all tests
  2016-08-15 12:23       ` [PATCH 1/2 v2 libnftnl] tests: Consolidate printing error utilities Carlos Falgueras García
@ 2016-08-15 12:23         ` Carlos Falgueras García
  2016-08-15 12:27           ` Pablo Neira Ayuso
  0 siblings, 1 reply; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-15 12:23 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

Use 'nftnl_expr_cmp' and 'nftnl_rule_cmp' in all tests instead of custom
comparator for each one. If objects differ both are printed.

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 tests/libtest.c                 | 44 +++++++++++++++----
 tests/libtest.h                 | 15 ++++++-
 tests/nft-chain-test.c          | 93 ++++++++++++++++++++++++-----------------
 tests/nft-expr_bitwise-test.c   | 40 ++++--------------
 tests/nft-expr_byteorder-test.c | 35 ++++------------
 tests/nft-expr_cmp-test.c       | 32 ++++----------
 tests/nft-expr_counter-test.c   | 26 ++++--------
 tests/nft-expr_ct-test.c        | 28 ++++---------
 tests/nft-expr_dup-test.c       | 26 ++++--------
 tests/nft-expr_exthdr-test.c    | 32 ++++----------
 tests/nft-expr_fwd-test.c       | 23 ++++------
 tests/nft-expr_immediate-test.c | 53 ++++-------------------
 tests/nft-expr_limit-test.c     | 35 ++++------------
 tests/nft-expr_log-test.c       | 32 ++++----------
 tests/nft-expr_lookup-test.c    | 38 ++++-------------
 tests/nft-expr_masq-test.c      | 29 ++++---------
 tests/nft-expr_match-test.c     | 33 ++++-----------
 tests/nft-expr_meta-test.c      | 26 ++++--------
 tests/nft-expr_nat-test.c       | 41 ++++--------------
 tests/nft-expr_payload-test.c   | 32 ++++----------
 tests/nft-expr_queue-test.c     | 26 ++++--------
 tests/nft-expr_redir-test.c     | 29 ++++---------
 tests/nft-expr_reject-test.c    | 26 ++++--------
 tests/nft-expr_target-test.c    | 33 ++++-----------
 tests/nft-rule-test.c           | 48 ++++-----------------
 tests/nft-set-test.c            | 72 ++++++++++++++++++-------------
 tests/nft-table-test.c          | 38 ++++++++++-------
 27 files changed, 348 insertions(+), 637 deletions(-)

diff --git a/tests/libtest.c b/tests/libtest.c
index ed7eafa..4b36f55 100644
--- a/tests/libtest.c
+++ b/tests/libtest.c
@@ -11,8 +11,6 @@
 #define COLOR_GREEN   "\x1b[32m"
 #define COLOR_RESET   "\x1b[0m"
 
-static bool test_ok = true;
-
 void __oom_assert(bool cond, const char *prog, const char *file, int line)
 {
 	if (cond)
@@ -22,25 +20,27 @@ void __oom_assert(bool cond, const char *prog, const char *file, int line)
 		COLOR_RED "OOM" COLOR_RESET " at %s:%d\n\t%s\n", file, line,
 		strerror(errno));
 
-	test_ok = false;
-	test_report(prog);
+	test_report(false, prog);
 	exit(EXIT_FAILURE);
 }
 
-void print_err(const char *fmt, ...)
+bool test_assert(bool cond, const char *fmt, ...)
 {
 	va_list args;
 
+	if (cond)
+		return true;
+
 	fprintf(stderr, COLOR_RED "ERROR: " COLOR_RESET);
 	va_start(args, fmt);
 	vfprintf(stderr, fmt, args);
 	va_end(args);
 	fprintf(stderr, "\n");
 
-	test_ok = false;
+	return false;
 }
 
-int test_report(const char *prog)
+int test_report(bool test_ok, const char *prog)
 {
 	switch (test_ok) {
 	case true:
@@ -51,3 +51,33 @@ int test_report(const char *prog)
 		return EXIT_FAILURE;
 	}
 }
+
+#define SNPRINTF_BUFF_LEN 1024
+
+static const char *rule2str(const struct nftnl_rule *r)
+{
+	static char buff[SNPRINTF_BUFF_LEN];
+	nftnl_rule_snprintf(buff, SNPRINTF_BUFF_LEN, r, NFTNL_OUTPUT_DEFAULT, 0);
+	return buff;
+}
+
+static const char *expr2str(const struct nftnl_expr *e)
+{
+	static char buff[SNPRINTF_BUFF_LEN];
+	nftnl_expr_snprintf(buff, SNPRINTF_BUFF_LEN, e, NFTNL_OUTPUT_DEFAULT, 0);
+	return buff;
+}
+
+bool test_assert_expr(const struct nftnl_expr *e1, const struct nftnl_expr *e2)
+{
+	return test_assert(nftnl_expr_cmp(e1, e2),
+			   "expressions mismatch:\n\texpr 1: %s\n\texpr 2: %s",
+			   expr2str(e1), expr2str(e2));
+}
+
+bool test_assert_rule(const struct nftnl_rule *r1, const struct nftnl_rule *r2)
+{
+	return test_assert(nftnl_rule_cmp(r1, r2),
+			   "rules mismatch:\nRULE 1:\n%s\nRULE 2:\n%s",
+			   rule2str(r1), rule2str(r2));
+}
diff --git a/tests/libtest.h b/tests/libtest.h
index f570057..0f5aa9f 100644
--- a/tests/libtest.h
+++ b/tests/libtest.h
@@ -2,10 +2,21 @@
 #define _TESTS_UTILS_H
 
 #include <stdbool.h>
+#include <libmnl/libmnl.h>
+#include <libnftnl/common.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
 
 #define oom_assert(cond, prog) __oom_assert(cond, prog, __FILE__, __LINE__)
 void __oom_assert(bool cond, const char *prog, const char *file, int line);
-void print_err(const char *fmt, ...);
-int test_report(const char *prog);
+bool test_assert(bool cond, const char *fmt, ...);
+int test_report(bool test_ok, const char *prog);
+bool test_assert_expr(const struct nftnl_expr *e1, const struct nftnl_expr *e2);
+bool test_assert_rule(const struct nftnl_rule *r1, const struct nftnl_rule *r2);
+
+/*
+ * const char *rule2str(const struct nftnl_rule *r);
+ * const char *expr2str(const struct nftnl_expr *e);
+ */
 
 #endif
diff --git a/tests/nft-chain-test.c b/tests/nft-chain-test.c
index b42fb86..1b6672a 100644
--- a/tests/nft-chain-test.c
+++ b/tests/nft-chain-test.c
@@ -19,43 +19,56 @@
 
 static void cmp_nftnl_chain(struct nftnl_chain *a, struct nftnl_chain *b)
 {
+	bool test_ok = true;
+	bool ret;
 
-	if (strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_NAME),
-		   nftnl_chain_get_str(b, NFTNL_CHAIN_NAME)) != 0)
-		print_err("Chain name mismatches");
-	if (strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_TABLE),
-		   nftnl_chain_get_str(b, NFTNL_CHAIN_TABLE)) != 0)
-		print_err("Chain table mismatches");
-	if (nftnl_chain_get_u32(a, NFTNL_CHAIN_FAMILY) !=
-	    nftnl_chain_get_u32(b, NFTNL_CHAIN_FAMILY))
-		print_err("Chain family mismatches");
-	if (nftnl_chain_get_u32(a, NFTNL_CHAIN_POLICY) !=
-	    nftnl_chain_get_u32(b, NFTNL_CHAIN_POLICY))
-		print_err("Chain policy mismatches");
-	if (nftnl_chain_get_u32(a, NFTNL_CHAIN_HOOKNUM) !=
-	    nftnl_chain_get_u32(b, NFTNL_CHAIN_HOOKNUM))
-		print_err("Chain hooknum mismatches");
-	if (nftnl_chain_get_s32(a, NFTNL_CHAIN_PRIO) !=
-	    nftnl_chain_get_s32(b, NFTNL_CHAIN_PRIO))
-		print_err("Chain Prio mismatches");
-	if (nftnl_chain_get_u32(a, NFTNL_CHAIN_USE) !=
-	    nftnl_chain_get_u32(b, NFTNL_CHAIN_USE))
-		print_err("Chain use mismatches");
-	if (nftnl_chain_get_u64(a, NFTNL_CHAIN_PACKETS) !=
-	    nftnl_chain_get_u64(b, NFTNL_CHAIN_PACKETS))
-		print_err("Chain packets mismatches");
-	if (nftnl_chain_get_u64(a, NFTNL_CHAIN_BYTES) !=
-	    nftnl_chain_get_u64(b, NFTNL_CHAIN_BYTES))
-		print_err("Chain bytes mismatches");
-	if (nftnl_chain_get_u64(a, NFTNL_CHAIN_HANDLE) !=
-	    nftnl_chain_get_u64(b, NFTNL_CHAIN_HANDLE))
-		print_err("Chain handle mismatches");
-	if (strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_TYPE),
-		   nftnl_chain_get_str(b, NFTNL_CHAIN_TYPE)) != 0)
-		print_err("Chain type mismatches");
-	if (strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_DEV),
-		   nftnl_chain_get_str(b, NFTNL_CHAIN_DEV)) != 0)
-		print_err("Chain device mismatches");
+	ret = !strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_NAME),
+		      nftnl_chain_get_str(b, NFTNL_CHAIN_NAME));
+	test_ok &= test_assert(ret, "Chain name mismatches");
+
+	ret = !strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_TABLE),
+		      nftnl_chain_get_str(b, NFTNL_CHAIN_TABLE));
+	test_ok &= test_assert(ret, "Chain table mismatches");
+
+	ret = nftnl_chain_get_u32(a, NFTNL_CHAIN_FAMILY) ==
+	      nftnl_chain_get_u32(b, NFTNL_CHAIN_FAMILY);
+	test_ok &= test_assert(ret, "Chain family mismatches");
+
+	ret = nftnl_chain_get_u32(a, NFTNL_CHAIN_POLICY) ==
+	      nftnl_chain_get_u32(b, NFTNL_CHAIN_POLICY);
+	test_ok &= test_assert(ret, "Chain policy mismatches");
+
+	ret = nftnl_chain_get_u32(a, NFTNL_CHAIN_HOOKNUM) ==
+	      nftnl_chain_get_u32(b, NFTNL_CHAIN_HOOKNUM);
+	test_ok &= test_assert(ret, "Chain hooknum mismatches");
+
+	ret = nftnl_chain_get_s32(a, NFTNL_CHAIN_PRIO) ==
+	      nftnl_chain_get_s32(b, NFTNL_CHAIN_PRIO);
+	test_ok &= test_assert(ret, "Chain Prio mismatches");
+
+	ret = nftnl_chain_get_u32(a, NFTNL_CHAIN_USE) ==
+	      nftnl_chain_get_u32(b, NFTNL_CHAIN_USE);
+	test_ok &= test_assert(ret, "Chain use mismatches");
+
+	ret = nftnl_chain_get_u64(a, NFTNL_CHAIN_PACKETS) ==
+	      nftnl_chain_get_u64(b, NFTNL_CHAIN_PACKETS);
+	test_ok &= test_assert(ret, "Chain packets mismatches");
+
+	ret = nftnl_chain_get_u64(a, NFTNL_CHAIN_BYTES) ==
+	      nftnl_chain_get_u64(b, NFTNL_CHAIN_BYTES);
+	test_ok &= test_assert(ret, "Chain bytes mismatches");
+
+	ret = nftnl_chain_get_u64(a, NFTNL_CHAIN_HANDLE) ==
+	      nftnl_chain_get_u64(b, NFTNL_CHAIN_HANDLE);
+	test_ok &= test_assert(ret, "Chain handle mismatches");
+
+	ret = !strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_TYPE),
+		      nftnl_chain_get_str(b, NFTNL_CHAIN_TYPE));
+	test_ok &= test_assert(ret, "Chain type mismatches");
+
+	ret = !strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_DEV),
+		      nftnl_chain_get_str(b, NFTNL_CHAIN_DEV));
+	test_ok &= test_assert(ret, "Chain device mismatches");
 }
 
 int main(int argc, char *argv[])
@@ -63,6 +76,8 @@ int main(int argc, char *argv[])
 	struct nftnl_chain *a, *b;
 	char buf[4096];
 	struct nlmsghdr *nlh;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_chain_alloc();
 	b = nftnl_chain_alloc();
@@ -87,14 +102,14 @@ int main(int argc, char *argv[])
 					0, 1234);
 	nftnl_chain_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_chain_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_chain_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	cmp_nftnl_chain(a, b);
 
 	nftnl_chain_free(a);
 	nftnl_chain_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 
 }
diff --git a/tests/nft-expr_bitwise-test.c b/tests/nft-expr_bitwise-test.c
index 42e9bb2..8f6781f 100644
--- a/tests/nft-expr_bitwise-test.c
+++ b/tests/nft-expr_bitwise-test.c
@@ -21,31 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	uint32_t maska, maskb;
-	uint32_t xora, xorb;
-
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_DREG))
-		print_err("Expr BITWISE_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_SREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_SREG))
-		print_err("Expr BITWISE_SREG mismatches");
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_BITWISE_LEN) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_BITWISE_LEN))
-		print_err("Expr BITWISE_DREG mismatches");
-	nftnl_expr_get(rule_a, NFTNL_EXPR_BITWISE_MASK, &maska);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_BITWISE_MASK, &maskb);
-	if (maska != maskb)
-		print_err("Size of BITWISE_MASK mismatches");
-	nftnl_expr_get(rule_a, NFTNL_EXPR_BITWISE_XOR, &xora);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_BITWISE_XOR, &xorb);
-	if (xora != xorb)
-		print_err("Size of BITWISE_XOR mismatches");
-
-}
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b = NULL;
@@ -56,6 +31,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr *rule_a, *rule_b = NULL;
 	uint32_t mask = 0x01010101;
 	uint32_t xor = 0x12345678;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -75,8 +52,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -88,17 +65,16 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 
-	cmp_nftnl_expr(rule_a,rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_byteorder-test.c b/tests/nft-expr_byteorder-test.c
index 9a25667..29df7a6 100644
--- a/tests/nft-expr_byteorder-test.c
+++ b/tests/nft-expr_byteorder-test.c
@@ -21,26 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_DREG))
-		print_err("Expr NFTNL_EXPR_BYTEORDER_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_SREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_SREG))
-		print_err("Expr NFTNL_EXPR_BYTEORDER_SREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_OP) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_OP))
-		print_err("Expr NFTNL_EXPR_BYTEORDER_OP mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_LEN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_LEN))
-		print_err("Expr NFTNL_EXPR_BYTEORDER_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_SIZE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_SIZE))
-		print_err("Expr NFTNL_EXPR_BITWISE_SIZE mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -49,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -68,8 +50,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -81,16 +63,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a,rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_cmp-test.c b/tests/nft-expr_cmp-test.c
index 570db2c..e8cd90b 100644
--- a/tests/nft-expr_cmp-test.c
+++ b/tests/nft-expr_cmp-test.c
@@ -21,23 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	uint32_t data_lena, data_lenb;
-
-	nftnl_expr_get(rule_a, NFTNL_EXPR_CMP_DATA, &data_lena);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_CMP_DATA, &data_lenb);
-	if (data_lena != data_lenb)
-		print_err("Size of NFTNL_EXPR_CMP_DATA mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CMP_SREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CMP_SREG))
-		print_err("Expr NFTNL_EXPR_CMP_SREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CMP_OP) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CMP_OP))
-		print_err("Expr NFTNL_EXPR_CMP_OP mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -47,6 +30,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
 	uint32_t data_len = 0x01010101;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -64,8 +49,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -76,16 +61,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_counter-test.c b/tests/nft-expr_counter-test.c
index 7066c26..a6cb95d 100644
--- a/tests/nft-expr_counter-test.c
+++ b/tests/nft-expr_counter-test.c
@@ -22,17 +22,6 @@
 #include "libtest.h"
 
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_CTR_BYTES) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_CTR_BYTES))
-		print_err("Expr NFTNL_EXPR_CTR_BYTES mismatches");
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_CTR_PACKETS) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_CTR_PACKETS))
-		print_err("Expr NFTNL_EXPR_CTR_PACKETS mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -41,6 +30,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -57,8 +48,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -69,16 +60,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_ct-test.c b/tests/nft-expr_ct-test.c
index cfbe0d6..55f6d52 100644
--- a/tests/nft-expr_ct-test.c
+++ b/tests/nft-expr_ct-test.c
@@ -21,19 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CT_KEY) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CT_KEY))
-		print_err("Expr CT_KEY mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CT_DIR) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CT_DIR))
-		print_err("Expr CT_DIR mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CT_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CT_DREG))
-		print_err("Expr CT_DREG mismatches");
-}
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -42,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -59,8 +48,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -72,16 +61,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_dup-test.c b/tests/nft-expr_dup-test.c
index 4ae112d..4c90b41 100644
--- a/tests/nft-expr_dup-test.c
+++ b/tests/nft-expr_dup-test.c
@@ -21,17 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_DUP_SREG_ADDR) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_DUP_SREG_ADDR))
-		print_err("Expr SREG_TO mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_DUP_SREG_DEV) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_DUP_SREG_DEV))
-		print_err("Expr SREG_OIF mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -40,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -56,8 +47,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -69,16 +60,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_exthdr-test.c b/tests/nft-expr_exthdr-test.c
index 56652b5..26642c3 100644
--- a/tests/nft-expr_exthdr-test.c
+++ b/tests/nft-expr_exthdr-test.c
@@ -21,23 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_EXTHDR_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_EXTHDR_DREG))
-		print_err("Expr NFTNL_EXPR_EXTHDR_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_EXTHDR_TYPE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_EXTHDR_TYPE))
-		print_err("Expr NFTNL_EXPR_EXTHDR_TYPE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_EXTHDR_OFFSET) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_EXTHDR_OFFSET))
-		print_err("Expr NFTNL_EXPR_EXTHDR_OFFSET mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_EXTHDR_LEN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_EXTHDR_LEN))
-		print_err("Expr NFTNL_EXPR_EXTHDR_LEN mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -46,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -63,8 +48,8 @@ int main(int argc, char *argv[])
 
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -76,16 +61,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_fwd-test.c b/tests/nft-expr_fwd-test.c
index 7a27299..385ca8e 100644
--- a/tests/nft-expr_fwd-test.c
+++ b/tests/nft-expr_fwd-test.c
@@ -21,14 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_FWD_SREG_DEV) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_FWD_SREG_DEV))
-		print_err("Expr SREG_OIF mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -37,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -52,8 +46,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -65,16 +59,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_immediate-test.c b/tests/nft-expr_immediate-test.c
index 1e9749f..8987677 100644
--- a/tests/nft-expr_immediate-test.c
+++ b/tests/nft-expr_immediate-test.c
@@ -21,42 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr_verdict(struct nftnl_expr *rule_a,
-				   struct nftnl_expr *rule_b)
-{
-	const char *chain_a, *chain_b;
-	uint32_t len_a, len_b;
-
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_IMM_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_IMM_DREG))
-		print_err("Expr NFTNL_EXPR_IMM_DREG mismatches");
-
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_IMM_VERDICT) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_IMM_VERDICT))
-		print_err("Expr NFTNL_EXPR_IMM_VERDICT mismatches");
-
-	chain_a = nftnl_expr_get(rule_a, NFTNL_EXPR_IMM_CHAIN, &len_a);
-	chain_b = nftnl_expr_get(rule_b, NFTNL_EXPR_IMM_CHAIN, &len_b);
-	if (len_a != len_b || strncmp(chain_a, chain_b, len_a))
-		print_err("Expr NFTNL_EXPR_IMM_CHAIN mismatches");
-}
-
-static void cmp_nftnl_expr_value(struct nftnl_expr *rule_a,
-				 struct nftnl_expr *rule_b)
-{
-	const uint32_t *data_a, *data_b;
-	uint32_t len_a, len_b;
-
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_IMM_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_IMM_DREG))
-		print_err("Expr NFTNL_EXPR_IMM_DREG mismatches");
-
-	data_a = nftnl_expr_get(rule_a, NFTNL_EXPR_IMM_DATA, &len_a);
-	data_b = nftnl_expr_get(rule_b, NFTNL_EXPR_IMM_DATA, &len_b);
-	if (len_a != len_b || memcmp(data_a, data_b, len_a))
-		print_err("Expr NFTNL_EXPR_IMM_DATA mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -67,6 +31,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr *rule_a, *rule_b;
 	char *chain = "tests_chain01234";
 	char *data = "test_data_01234";
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -90,8 +56,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -103,23 +69,22 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr_value(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr_verdict(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 2 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 2 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_limit-test.c b/tests/nft-expr_limit-test.c
index 7848e29..a5cb137 100644
--- a/tests/nft-expr_limit-test.c
+++ b/tests/nft-expr_limit-test.c
@@ -22,26 +22,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_RATE) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_RATE))
-		print_err("Expr CTR_BYTES mismatches");
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_UNIT) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_UNIT))
-		print_err("Expr CTR_PACKET mismatches");
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_BURST) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_BURST))
-		print_err("Expr CTR_PACKET mismatches");
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_TYPE) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_TYPE))
-		print_err("Expr TYPE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LIMIT_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LIMIT_FLAGS))
-		print_err("Expr FLAGS mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -50,6 +30,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -69,8 +51,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -82,16 +64,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_log-test.c b/tests/nft-expr_log-test.c
index a2c1f1d..7dbbf34 100644
--- a/tests/nft-expr_log-test.c
+++ b/tests/nft-expr_log-test.c
@@ -21,23 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOG_SNAPLEN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOG_SNAPLEN))
-		print_err("Expr NFTNL_EXPR_LOG_SNAPLEN mismatches");
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_LOG_GROUP) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_LOG_GROUP))
-		print_err("Expr NFTNL_EXPR_LOG_GROUP mismatches");
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_LOG_QTHRESHOLD) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_LOG_QTHRESHOLD))
-		print_err("Expr NFTNL_EXPR_LOG_QTHRESHOLD mismatches");
-	if(strcmp(nftnl_expr_get_str(rule_a, NFTNL_EXPR_LOG_PREFIX),
-		  nftnl_expr_get_str(rule_b, NFTNL_EXPR_LOG_PREFIX)) != 0)
-		print_err("Expr NFTNL_EXPR_LOG_PREFIX mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -46,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -63,8 +48,8 @@ int main(int argc, char *argv[])
 
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -75,16 +60,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_lookup-test.c b/tests/nft-expr_lookup-test.c
index 34dffdf..537adfd 100644
--- a/tests/nft-expr_lookup-test.c
+++ b/tests/nft-expr_lookup-test.c
@@ -21,29 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_SREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_SREG))
-		print_err("Expr NFTNL_EXPR_LOOKUP_SREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_DREG))
-		print_err("Expr NFTNL_EXPR_LOOKUP_DREG mismatches");
-	if (strcmp(nftnl_expr_get_str(rule_a, NFTNL_EXPR_LOOKUP_SET),
-		   nftnl_expr_get_str(rule_b, NFTNL_EXPR_LOOKUP_SET)))
-		print_err("Expr NFTNL_EXPR_LOOKUP_SET mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_SET_ID) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_SET_ID))
-		print_err("Expr NFTNL_EXPR_LOOKUP_SET_ID mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_FLAGS)) {
-		print_err("Expr NFTNL_EXPR_LOOKUP_FLAGS mismatches");
-		printf("%X %X\n",
-			nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_FLAGS),
-			nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_FLAGS));
-	}
-}
 
 int main(int argc, char *argv[])
 {
@@ -54,6 +31,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
 	char *lookup_set = "test_set_01243";
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -72,8 +51,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -84,16 +63,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_masq-test.c b/tests/nft-expr_masq-test.c
index fdfbf03..b93fc27 100644
--- a/tests/nft-expr_masq-test.c
+++ b/tests/nft-expr_masq-test.c
@@ -19,20 +19,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_MASQ_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_MASQ_FLAGS))
-		print_err("Expr NFTNL_EXPR_MASQ_FLAGS mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_MASQ_REG_PROTO_MIN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_MASQ_REG_PROTO_MIN))
-		print_err("Expr NFTNL_EXPR_MASQ_REG_PROTO_MIN mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_MASQ_REG_PROTO_MAX) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_MASQ_REG_PROTO_MAX))
-		print_err("Expr NFTNL_EXPR_MASQ_REG_PROTO_MAX mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -41,6 +27,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -58,8 +46,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -71,16 +59,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_match-test.c b/tests/nft-expr_match-test.c
index 9902d2f..78868bf 100644
--- a/tests/nft-expr_match-test.c
+++ b/tests/nft-expr_match-test.c
@@ -22,24 +22,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	uint32_t lena, lenb;
-
-	if (strcmp(nftnl_expr_get_str(rule_a, NFTNL_EXPR_MT_NAME),
-		   nftnl_expr_get_str(rule_b, NFTNL_EXPR_MT_NAME)) != 0)
-		print_err("Expr NFTNL_EXPR_MT_NAME mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_MT_REV) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_MT_REV))
-		print_err("Expr NFTNL_EXPR_MT_REV mismatches");
-	nftnl_expr_get(rule_a, NFTNL_EXPR_MT_INFO, &lena);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_MT_INFO, &lenb);
-	if (lena != lenb)
-		print_err("Expr NFTNL_EXPR_MT_INFO size mismatches: %d != %d",
-			  lena, lenb);
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -49,6 +31,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
 	char data[16] = "0123456789abcdef";
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -65,8 +49,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	oom_assert(iter_a, argv[0]);
@@ -77,16 +61,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_meta-test.c b/tests/nft-expr_meta-test.c
index e528631..44fa022 100644
--- a/tests/nft-expr_meta-test.c
+++ b/tests/nft-expr_meta-test.c
@@ -21,17 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_META_KEY) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_META_KEY))
-		print_err("Expr NFTNL_EXPR_META_KEY mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_META_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_META_DREG))
-		print_err("Expr NFTNL_EXPR_META_DREG mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -40,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -55,8 +46,8 @@ int main(int argc, char *argv[])
 
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -68,16 +59,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_nat-test.c b/tests/nft-expr_nat-test.c
index d1cc0b1..ea26e7c 100644
--- a/tests/nft-expr_nat-test.c
+++ b/tests/nft-expr_nat-test.c
@@ -22,32 +22,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_TYPE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_TYPE))
-		print_err("Expr NFTNL_EXPR_NAT_TYPE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_FAMILY) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_FAMILY))
-		print_err("Expr NFTNL_EXPR_NAT_FAMILY mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_REG_ADDR_MIN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_REG_ADDR_MIN))
-		print_err("Expr NFTNL_EXPR_NAT_REG_ADDR_MIN mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_REG_ADDR_MAX) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_REG_ADDR_MAX))
-		print_err("Expr NFTNL_EXPR_NAT_REG_ADDR_MAX mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_REG_PROTO_MIN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_REG_PROTO_MIN))
-		print_err("Expr NFTNL_EXPR_NAT_REG_PROTO_MIN mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_REG_PROTO_MAX) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_REG_PROTO_MAX))
-		print_err("Expr NFTNL_EXPR_NAT_REG_PROTO_MAX mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_FLAGS))
-		print_err("Expr NFTNL_EXPR_NAT_FLAGS mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -56,6 +30,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -77,8 +53,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -90,16 +66,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_payload-test.c b/tests/nft-expr_payload-test.c
index 0812d6d..dc52916 100644
--- a/tests/nft-expr_payload-test.c
+++ b/tests/nft-expr_payload-test.c
@@ -22,23 +22,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_PAYLOAD_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_PAYLOAD_DREG))
-		print_err("Expr NFTNL_EXPR_PAYLOAD_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_PAYLOAD_BASE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_PAYLOAD_BASE))
-		print_err("Expr NFTNL_EXPR_PAYLOAD_BASE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_PAYLOAD_OFFSET) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_PAYLOAD_OFFSET))
-		print_err("Expr NFTNL_EXPR_PAYLOAD_OFFSET mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_PAYLOAD_LEN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_PAYLOAD_LEN))
-		print_err("Expr NFTNL_EXPR_PAYLOAD_LEN mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -47,6 +30,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -64,8 +49,8 @@ int main(int argc, char *argv[])
 
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -77,16 +62,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_queue-test.c b/tests/nft-expr_queue-test.c
index 327e8fd..d266882 100644
--- a/tests/nft-expr_queue-test.c
+++ b/tests/nft-expr_queue-test.c
@@ -24,17 +24,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_QUEUE_NUM) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_QUEUE_NUM))
-		print_err("Expr NFTNL_EXPR_QUEUE_NUM mismatches");
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_QUEUE_TOTAL) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_QUEUE_TOTAL))
-		print_err("Expr NFTNL_EXPR_QUEUE_TOTAL mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -43,6 +32,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -60,8 +51,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -73,16 +64,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_redir-test.c b/tests/nft-expr_redir-test.c
index ce97928..ed3ff65 100644
--- a/tests/nft-expr_redir-test.c
+++ b/tests/nft-expr_redir-test.c
@@ -19,20 +19,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REDIR_REG_PROTO_MIN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REDIR_REG_PROTO_MIN))
-		print_err("Expr NFTNL_EXPR_REDIR_REG_PROTO_MIN mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REDIR_REG_PROTO_MAX) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REDIR_REG_PROTO_MAX))
-		print_err("Expr NFTNL_EXPR_REDIR_REG_PROTO_MAX mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REDIR_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REDIR_FLAGS))
-		print_err("Expr NFTNL_EXPR_REDIR_FLAGS mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -41,6 +27,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -58,8 +46,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("Parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "Parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -71,16 +59,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More than 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More than 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_reject-test.c b/tests/nft-expr_reject-test.c
index 426f9e9..8edc240 100644
--- a/tests/nft-expr_reject-test.c
+++ b/tests/nft-expr_reject-test.c
@@ -22,17 +22,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REJECT_TYPE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REJECT_TYPE))
-		print_err("Expr NFTNL_EXPR_REJECT_TYPE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REJECT_CODE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REJECT_CODE))
-		print_err("Expr NFTNL_EXPR_REJECT_CODE mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -41,6 +30,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -57,8 +48,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -70,16 +61,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_target-test.c b/tests/nft-expr_target-test.c
index 82a4a9f..00a3c0d 100644
--- a/tests/nft-expr_target-test.c
+++ b/tests/nft-expr_target-test.c
@@ -21,24 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	uint32_t lena, lenb;
-
-	if (strcmp(nftnl_expr_get_str(rule_a, NFTNL_EXPR_TG_NAME),
-		   nftnl_expr_get_str(rule_b, NFTNL_EXPR_TG_NAME)) != 0)
-		print_err("Expr NFTNL_EXPR_TG_NAME mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_TG_REV) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_TG_REV))
-		print_err("Expr NFTNL_EXPR_TG_REV mismatches");
-	nftnl_expr_get(rule_a, NFTNL_EXPR_TG_INFO, &lena);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_TG_INFO, &lenb);
-	if (lena != lenb)
-		print_err("Expr NFTNL_EXPR_TG_INFO size mismatches: %d != %d",
-			  lena, lenb);
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -48,6 +30,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
 	char data[16] = "0123456789abcdef";
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -65,8 +49,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -78,16 +62,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-rule-test.c b/tests/nft-rule-test.c
index c6ba719..2479cc3 100644
--- a/tests/nft-rule-test.c
+++ b/tests/nft-rule-test.c
@@ -19,46 +19,14 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_rule(struct nftnl_rule *a, struct nftnl_rule *b)
-{
-	const void *udata_a, *udata_b;
-	uint32_t len_a, len_b;
-
-	if (nftnl_rule_get_u32(a, NFTNL_RULE_FAMILY) !=
-	    nftnl_rule_get_u32(b, NFTNL_RULE_FAMILY))
-		print_err("Rule family mismatches");
-	if (strcmp(nftnl_rule_get_str(a, NFTNL_RULE_TABLE),
-		   nftnl_rule_get_str(b, NFTNL_RULE_TABLE)) != 0)
-		print_err("Rule table mismatches");
-	if (strcmp(nftnl_rule_get_str(a, NFTNL_RULE_CHAIN),
-		   nftnl_rule_get_str(b, NFTNL_RULE_CHAIN)) != 0)
-		print_err("Rule table mismatches");
-	if (nftnl_rule_get_u64(a, NFTNL_RULE_HANDLE) !=
-	    nftnl_rule_get_u64(b, NFTNL_RULE_HANDLE))
-		print_err("Rule handle mismatches");
-	if (nftnl_rule_get_u32(a, NFTNL_RULE_COMPAT_PROTO) !=
-	    nftnl_rule_get_u32(b, NFTNL_RULE_COMPAT_PROTO))
-		print_err("Rule compat_proto mismatches");
-	if (nftnl_rule_get_u32(a, NFTNL_RULE_COMPAT_FLAGS) !=
-	    nftnl_rule_get_u32(b, NFTNL_RULE_COMPAT_FLAGS))
-		print_err("Rule compat_flags mismatches");
-	if (nftnl_rule_get_u64(a, NFTNL_RULE_POSITION) !=
-	    nftnl_rule_get_u64(b, NFTNL_RULE_POSITION))
-		print_err("Rule compat_position mismatches");
-
-	udata_a = nftnl_rule_get_data(a, NFTNL_RULE_USERDATA, &len_a);
-	udata_b = nftnl_rule_get_data(b, NFTNL_RULE_USERDATA, &len_b);
-
-	if (len_a != len_b || memcmp(udata_a, udata_b, len_a) != 0)
-		print_err("Rule userdata mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_udata_buf *udata;
 	struct nftnl_rule *a, *b;
 	char buf[4096];
 	struct nlmsghdr *nlh;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -68,8 +36,8 @@ int main(int argc, char *argv[])
 	udata = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
 	oom_assert(udata, argv[0]);
 
-	if (!nftnl_udata_put_strz(udata, 0, "hello world"))
-		print_err("User data too big");
+	ret = nftnl_udata_put_strz(udata, 0, "hello world");
+	test_ok &= test_assert(ret, "User data too big");
 
 	nftnl_rule_set_u32(a, NFTNL_RULE_FAMILY, AF_INET);
 	nftnl_rule_set_str(a, NFTNL_RULE_TABLE, "table");
@@ -86,13 +54,13 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
-	cmp_nftnl_rule(a,b);
+	test_ok &= test_assert_rule(a, b);
 
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-set-test.c b/tests/nft-set-test.c
index 6f9b03d..24e1c62 100644
--- a/tests/nft-set-test.c
+++ b/tests/nft-set-test.c
@@ -18,32 +18,44 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_set(struct nftnl_set *a, struct nftnl_set *b)
+static bool cmp_nftnl_set(struct nftnl_set *a, struct nftnl_set *b)
 {
-	if (strcmp(nftnl_set_get_str(a, NFTNL_SET_TABLE),
-		   nftnl_set_get_str(b, NFTNL_SET_TABLE)) != 0)
-		print_err("Set table mismatches");
-	if (strcmp(nftnl_set_get_str(a, NFTNL_SET_NAME),
-		   nftnl_set_get_str(b, NFTNL_SET_NAME)) != 0)
-		print_err("Set name mismatches");
-	if (nftnl_set_get_u32(a, NFTNL_SET_FLAGS) !=
-	    nftnl_set_get_u32(b, NFTNL_SET_FLAGS))
-		print_err("Set flags mismatches");
-	if (nftnl_set_get_u32(a, NFTNL_SET_KEY_TYPE) !=
-	    nftnl_set_get_u32(b, NFTNL_SET_KEY_TYPE))
-		print_err("Set key-type mismatches");
-	if (nftnl_set_get_u32(a, NFTNL_SET_KEY_LEN) !=
-	    nftnl_set_get_u32(b, NFTNL_SET_KEY_LEN))
-		print_err("Set key-len mismatches");
-	if (nftnl_set_get_u32(a, NFTNL_SET_DATA_TYPE) !=
-	    nftnl_set_get_u32(b, NFTNL_SET_DATA_TYPE))
-		print_err("Set data-type mismatches");
-	if (nftnl_set_get_u32(a, NFTNL_SET_DATA_LEN) !=
-	    nftnl_set_get_u32(b, NFTNL_SET_DATA_LEN))
-		print_err("Set data-len mismatches");
-	if (strcmp(nftnl_set_get_str(a, NFTNL_SET_USERDATA),
-		   nftnl_set_get_str(b, NFTNL_SET_USERDATA)) != 0)
-		print_err("Set userdata mismatches");
+	bool test_ok = true;
+	bool ret;
+
+	ret = !strcmp(nftnl_set_get_str(a, NFTNL_SET_TABLE),
+		      nftnl_set_get_str(b, NFTNL_SET_TABLE));
+	test_ok &= test_assert(ret, "Set table mismatches");
+
+	ret = !strcmp(nftnl_set_get_str(a, NFTNL_SET_NAME),
+		      nftnl_set_get_str(b, NFTNL_SET_NAME));
+	test_ok &= test_assert(ret, "Set name mismatches");
+
+	ret = nftnl_set_get_u32(a, NFTNL_SET_FLAGS) ==
+	      nftnl_set_get_u32(b, NFTNL_SET_FLAGS);
+	test_ok &= test_assert(ret, "Set flags mismatches");
+
+	ret = nftnl_set_get_u32(a, NFTNL_SET_KEY_TYPE) ==
+	      nftnl_set_get_u32(b, NFTNL_SET_KEY_TYPE);
+	test_ok &= test_assert(ret, "Set key-type mismatches");
+
+	ret = nftnl_set_get_u32(a, NFTNL_SET_KEY_LEN) ==
+	      nftnl_set_get_u32(b, NFTNL_SET_KEY_LEN);
+	test_ok &= test_assert(ret, "Set key-len mismatches");
+
+	ret = nftnl_set_get_u32(a, NFTNL_SET_DATA_TYPE) ==
+	      nftnl_set_get_u32(b, NFTNL_SET_DATA_TYPE);
+	test_ok &= test_assert(ret, "Set data-type mismatches");
+
+	ret = nftnl_set_get_u32(a, NFTNL_SET_DATA_LEN) ==
+	      nftnl_set_get_u32(b, NFTNL_SET_DATA_LEN);
+	test_ok &= test_assert(ret, "Set data-len mismatches");
+
+	ret = !strcmp(nftnl_set_get_str(a, NFTNL_SET_USERDATA),
+		    nftnl_set_get_str(b, NFTNL_SET_USERDATA));
+	test_ok &= test_assert(ret, "Set userdata mismatches");
+
+	return test_ok;
 }
 
 int main(int argc, char *argv[])
@@ -51,6 +63,8 @@ int main(int argc, char *argv[])
 	struct nftnl_set *a, *b = NULL;
 	char buf[4096];
 	struct nlmsghdr *nlh;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_set_alloc();
 	b = nftnl_set_alloc();
@@ -71,12 +85,12 @@ int main(int argc, char *argv[])
 	nlh = nftnl_set_nlmsg_build_hdr(buf, NFT_MSG_NEWSET, AF_INET, 0, 1234);
 	nftnl_set_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_set_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_set_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
-	cmp_nftnl_set(a,b);
+	test_ok &= cmp_nftnl_set(a,b);
 
 	nftnl_set_free(a); nftnl_set_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-table-test.c b/tests/nft-table-test.c
index 6b0418f..d53541a 100644
--- a/tests/nft-table-test.c
+++ b/tests/nft-table-test.c
@@ -18,17 +18,24 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_table(struct nftnl_table *a, struct nftnl_table *b)
+static bool cmp_nftnl_table(struct nftnl_table *a, struct nftnl_table *b)
 {
-	if (strcmp(nftnl_table_get_str(a, NFTNL_TABLE_NAME),
-		   nftnl_table_get_str(b, NFTNL_TABLE_NAME)) != 0)
-		print_err("table name mismatches");
-	if (nftnl_table_get_u32(a, NFTNL_TABLE_FLAGS) !=
-	    nftnl_table_get_u32(b, NFTNL_TABLE_FLAGS))
-		print_err("table flags mismatches");
-	if (nftnl_table_get_u32(a, NFTNL_TABLE_FAMILY) !=
-	    nftnl_table_get_u32(b, NFTNL_TABLE_FAMILY))
-		print_err("tabke family mismatches");
+	bool test_ok = true;
+	bool ret;
+
+	ret = !strcmp(nftnl_table_get_str(a, NFTNL_TABLE_NAME),
+		      nftnl_table_get_str(b, NFTNL_TABLE_NAME));
+	test_ok &= test_assert(ret, "table name mismatches");
+
+	ret = nftnl_table_get_u32(a, NFTNL_TABLE_FLAGS) ==
+	      nftnl_table_get_u32(b, NFTNL_TABLE_FLAGS);
+	test_ok &= test_assert(ret, "table flags mismatches");
+
+	ret = nftnl_table_get_u32(a, NFTNL_TABLE_FAMILY) ==
+	      nftnl_table_get_u32(b, NFTNL_TABLE_FAMILY);
+	test_ok &= test_assert(ret, "table family mismatches");
+
+	return test_ok;
 }
 
 int main(int argc, char *argv[])
@@ -38,6 +45,9 @@ int main(int argc, char *argv[])
 
 	struct nftnl_table *a = NULL;
 	struct nftnl_table *b = NULL;
+	bool test_ok = true;
+	bool ret;
+
 	a = nftnl_table_alloc();
 	b = nftnl_table_alloc();
 
@@ -53,13 +63,13 @@ int main(int argc, char *argv[])
 					1234);
 	nftnl_table_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_table_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_table_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
-	cmp_nftnl_table(a,b);
+	test_ok &= cmp_nftnl_table(a,b);
 
 	nftnl_table_free(a);
 	nftnl_table_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
-- 
2.8.3


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/2 v2 libnftnl] test: Use libnftnl comparators in all tests
  2016-08-15 12:23         ` [PATCH 2/2 v2 libnftnl] test: Use libnftnl comparators in all tests Carlos Falgueras García
@ 2016-08-15 12:27           ` Pablo Neira Ayuso
  2016-08-16 10:30             ` [PATCH 1/3 v3 nft] tests: Consolidate printing error utilities Carlos Falgueras García
  0 siblings, 1 reply; 31+ messages in thread
From: Pablo Neira Ayuso @ 2016-08-15 12:27 UTC (permalink / raw)
  To: Carlos Falgueras García; +Cc: netfilter-devel

On Mon, Aug 15, 2016 at 02:23:43PM +0200, Carlos Falgueras García wrote:
> Use 'nftnl_expr_cmp' and 'nftnl_rule_cmp' in all tests instead of custom
> comparator for each one. If objects differ both are printed.
>
[...] 
> diff --git a/tests/nft-chain-test.c b/tests/nft-chain-test.c
> index b42fb86..1b6672a 100644
> --- a/tests/nft-chain-test.c
> +++ b/tests/nft-chain-test.c
> @@ -19,43 +19,56 @@
>  
>  static void cmp_nftnl_chain(struct nftnl_chain *a, struct nftnl_chain *b)
>  {
> +	bool test_ok = true;
> +	bool ret;
>  
> -	if (strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_NAME),
> -		   nftnl_chain_get_str(b, NFTNL_CHAIN_NAME)) != 0)
> -		print_err("Chain name mismatches");
> -	if (strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_TABLE),
> -		   nftnl_chain_get_str(b, NFTNL_CHAIN_TABLE)) != 0)
> -		print_err("Chain table mismatches");
> -	if (nftnl_chain_get_u32(a, NFTNL_CHAIN_FAMILY) !=
> -	    nftnl_chain_get_u32(b, NFTNL_CHAIN_FAMILY))
> -		print_err("Chain family mismatches");
> -	if (nftnl_chain_get_u32(a, NFTNL_CHAIN_POLICY) !=
> -	    nftnl_chain_get_u32(b, NFTNL_CHAIN_POLICY))
> -		print_err("Chain policy mismatches");
> -	if (nftnl_chain_get_u32(a, NFTNL_CHAIN_HOOKNUM) !=
> -	    nftnl_chain_get_u32(b, NFTNL_CHAIN_HOOKNUM))
> -		print_err("Chain hooknum mismatches");
> -	if (nftnl_chain_get_s32(a, NFTNL_CHAIN_PRIO) !=
> -	    nftnl_chain_get_s32(b, NFTNL_CHAIN_PRIO))
> -		print_err("Chain Prio mismatches");
> -	if (nftnl_chain_get_u32(a, NFTNL_CHAIN_USE) !=
> -	    nftnl_chain_get_u32(b, NFTNL_CHAIN_USE))
> -		print_err("Chain use mismatches");
> -	if (nftnl_chain_get_u64(a, NFTNL_CHAIN_PACKETS) !=
> -	    nftnl_chain_get_u64(b, NFTNL_CHAIN_PACKETS))
> -		print_err("Chain packets mismatches");
> -	if (nftnl_chain_get_u64(a, NFTNL_CHAIN_BYTES) !=
> -	    nftnl_chain_get_u64(b, NFTNL_CHAIN_BYTES))
> -		print_err("Chain bytes mismatches");
> -	if (nftnl_chain_get_u64(a, NFTNL_CHAIN_HANDLE) !=
> -	    nftnl_chain_get_u64(b, NFTNL_CHAIN_HANDLE))
> -		print_err("Chain handle mismatches");
> -	if (strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_TYPE),
> -		   nftnl_chain_get_str(b, NFTNL_CHAIN_TYPE)) != 0)
> -		print_err("Chain type mismatches");
> -	if (strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_DEV),
> -		   nftnl_chain_get_str(b, NFTNL_CHAIN_DEV)) != 0)
> -		print_err("Chain device mismatches");

You description says your our aiming at expressions and rules, but
this is also modifying chain.

Please, check this chunk out of this patch, same for other objects
that are not expression and rules. This patch is already quite large
so not need to get this more complicated.

Thanks.

^ permalink raw reply	[flat|nested] 31+ messages in thread

* [PATCH 1/3 v3 nft] tests: Consolidate printing error utilities
  2016-08-15 12:27           ` Pablo Neira Ayuso
@ 2016-08-16 10:30             ` Carlos Falgueras García
  2016-08-16 10:30               ` [PATCH 2/3 v3 nft] tests: Use libnftnl comparators in all tests Carlos Falgueras García
  2016-08-16 10:30               ` [PATCH 3/3 v3 nft] tests: Elimine static variable 'test_ok' Carlos Falgueras García
  0 siblings, 2 replies; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-16 10:30 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

This patch adds libtest.c and libtest.h to reduce test code and
consolidate it.

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 .gitignore                      |  1 +
 tests/Makefile.am               | 52 +++++++++++++++++++++-------------------
 tests/libtest.c                 | 53 +++++++++++++++++++++++++++++++++++++++++
 tests/libtest.h                 | 11 +++++++++
 tests/nft-chain-test.c          | 18 ++++----------
 tests/nft-expr_bitwise-test.c   | 29 +++++++---------------
 tests/nft-expr_byteorder-test.c | 29 +++++++---------------
 tests/nft-expr_cmp-test.c       | 29 +++++++---------------
 tests/nft-expr_counter-test.c   | 27 +++++++--------------
 tests/nft-expr_ct-test.c        | 28 +++++++---------------
 tests/nft-expr_dup-test.c       | 28 +++++++---------------
 tests/nft-expr_exthdr-test.c    | 28 +++++++---------------
 tests/nft-expr_fwd-test.c       | 28 +++++++---------------
 tests/nft-expr_immediate-test.c | 34 ++++++++++----------------
 tests/nft-expr_limit-test.c     | 29 +++++++---------------
 tests/nft-expr_log-test.c       | 29 +++++++---------------
 tests/nft-expr_lookup-test.c    | 30 +++++++----------------
 tests/nft-expr_masq-test.c      | 29 +++++++---------------
 tests/nft-expr_match-test.c     | 38 +++++++++--------------------
 tests/nft-expr_meta-test.c      | 29 +++++++---------------
 tests/nft-expr_nat-test.c       | 29 +++++++---------------
 tests/nft-expr_payload-test.c   | 29 +++++++---------------
 tests/nft-expr_queue-test.c     | 29 +++++++---------------
 tests/nft-expr_redir-test.c     | 29 +++++++---------------
 tests/nft-expr_reject-test.c    | 29 +++++++---------------
 tests/nft-expr_target-test.c    | 37 +++++++++-------------------
 tests/nft-rule-test.c           | 20 ++++------------
 tests/nft-set-test.c            | 18 ++++----------
 tests/nft-table-test.c          | 17 ++++---------
 29 files changed, 305 insertions(+), 511 deletions(-)
 create mode 100644 tests/libtest.c
 create mode 100644 tests/libtest.h

diff --git a/.gitignore b/.gitignore
index 1650e58..5a781db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -28,4 +28,5 @@ examples/*
 !examples/Makefile.am
 tests/*
 !tests/*.c
+!tests/*.h
 !tests/Makefile.am
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0377081..b55aeba 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -4,6 +4,8 @@ EXTRA_DIST =		test-script.sh			\
 			jsonfiles			\
 			xmlfiles
 
+LIBTEST =		libtest.c
+
 check_PROGRAMS = 	nft-parsing-test		\
 			nft-table-test			\
 			nft-chain-test			\
@@ -34,77 +36,77 @@ check_PROGRAMS = 	nft-parsing-test		\
 nft_parsing_test_SOURCES = nft-parsing-test.c
 nft_parsing_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS} ${LIBXML_LIBS} ${LIBJSON_LIBS}
 
-nft_table_test_SOURCES = nft-table-test.c
+nft_table_test_SOURCES = nft-table-test.c ${LIBTEST}
 nft_table_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_chain_test_SOURCES = nft-chain-test.c
+nft_chain_test_SOURCES = nft-chain-test.c ${LIBTEST}
 nft_chain_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_rule_test_SOURCES = nft-rule-test.c
+nft_rule_test_SOURCES = nft-rule-test.c ${LIBTEST}
 nft_rule_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_set_test_SOURCES = nft-set-test.c
+nft_set_test_SOURCES = nft-set-test.c ${LIBTEST}
 nft_set_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_bitwise_test_SOURCES = nft-expr_bitwise-test.c
+nft_expr_bitwise_test_SOURCES = nft-expr_bitwise-test.c ${LIBTEST}
 nft_expr_bitwise_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_byteorder_test_SOURCES = nft-expr_byteorder-test.c
+nft_expr_byteorder_test_SOURCES = nft-expr_byteorder-test.c ${LIBTEST}
 nft_expr_byteorder_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_cmp_test_SOURCES = nft-expr_cmp-test.c
+nft_expr_cmp_test_SOURCES = nft-expr_cmp-test.c ${LIBTEST}
 nft_expr_cmp_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_counter_test_SOURCES = nft-expr_counter-test.c
+nft_expr_counter_test_SOURCES = nft-expr_counter-test.c ${LIBTEST}
 nft_expr_counter_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_exthdr_test_SOURCES = nft-expr_exthdr-test.c
+nft_expr_exthdr_test_SOURCES = nft-expr_exthdr-test.c ${LIBTEST}
 nft_expr_exthdr_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_ct_test_SOURCES = nft-expr_ct-test.c
+nft_expr_ct_test_SOURCES = nft-expr_ct-test.c ${LIBTEST}
 nft_expr_ct_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_dup_test_SOURCES = nft-expr_dup-test.c
+nft_expr_dup_test_SOURCES = nft-expr_dup-test.c ${LIBTEST}
 nft_expr_dup_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_fwd_test_SOURCES = nft-expr_fwd-test.c
+nft_expr_fwd_test_SOURCES = nft-expr_fwd-test.c ${LIBTEST}
 nft_expr_fwd_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_immediate_test_SOURCES = nft-expr_immediate-test.c
+nft_expr_immediate_test_SOURCES = nft-expr_immediate-test.c ${LIBTEST}
 nft_expr_immediate_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_limit_test_SOURCES = nft-expr_limit-test.c
+nft_expr_limit_test_SOURCES = nft-expr_limit-test.c ${LIBTEST}
 nft_expr_limit_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_lookup_test_SOURCES = nft-expr_lookup-test.c
+nft_expr_lookup_test_SOURCES = nft-expr_lookup-test.c ${LIBTEST}
 nft_expr_lookup_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_log_test_SOURCES = nft-expr_log-test.c
+nft_expr_log_test_SOURCES = nft-expr_log-test.c ${LIBTEST}
 nft_expr_log_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_match_test_SOURCES = nft-expr_match-test.c
+nft_expr_match_test_SOURCES = nft-expr_match-test.c ${LIBTEST}
 nft_expr_match_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_masq_test_SOURCES = nft-expr_masq-test.c
+nft_expr_masq_test_SOURCES = nft-expr_masq-test.c ${LIBTEST}
 nft_expr_masq_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_meta_test_SOURCES = nft-expr_meta-test.c
+nft_expr_meta_test_SOURCES = nft-expr_meta-test.c ${LIBTEST}
 nft_expr_meta_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_nat_test_SOURCES = nft-expr_nat-test.c
+nft_expr_nat_test_SOURCES = nft-expr_nat-test.c ${LIBTEST}
 nft_expr_nat_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_payload_test_SOURCES = nft-expr_payload-test.c
+nft_expr_payload_test_SOURCES = nft-expr_payload-test.c ${LIBTEST}
 nft_expr_payload_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_queue_test_SOURCES = nft-expr_queue-test.c
+nft_expr_queue_test_SOURCES = nft-expr_queue-test.c ${LIBTEST}
 nft_expr_queue_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_reject_test_SOURCES = nft-expr_reject-test.c
+nft_expr_reject_test_SOURCES = nft-expr_reject-test.c ${LIBTEST}
 nft_expr_reject_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_redir_test_SOURCES = nft-expr_redir-test.c
+nft_expr_redir_test_SOURCES = nft-expr_redir-test.c ${LIBTEST}
 nft_expr_redir_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
 
-nft_expr_target_test_SOURCES = nft-expr_target-test.c
+nft_expr_target_test_SOURCES = nft-expr_target-test.c ${LIBTEST}
 nft_expr_target_test_LDADD = ../src/libnftnl.la ${LIBMNL_LIBS}
diff --git a/tests/libtest.c b/tests/libtest.c
new file mode 100644
index 0000000..ed7eafa
--- /dev/null
+++ b/tests/libtest.c
@@ -0,0 +1,53 @@
+#include <libtest.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <stdbool.h>
+
+#define COLOR_RED     "\x1b[31m"
+#define COLOR_GREEN   "\x1b[32m"
+#define COLOR_RESET   "\x1b[0m"
+
+static bool test_ok = true;
+
+void __oom_assert(bool cond, const char *prog, const char *file, int line)
+{
+	if (cond)
+		return;
+
+	fprintf(stderr,
+		COLOR_RED "OOM" COLOR_RESET " at %s:%d\n\t%s\n", file, line,
+		strerror(errno));
+
+	test_ok = false;
+	test_report(prog);
+	exit(EXIT_FAILURE);
+}
+
+void print_err(const char *fmt, ...)
+{
+	va_list args;
+
+	fprintf(stderr, COLOR_RED "ERROR: " COLOR_RESET);
+	va_start(args, fmt);
+	vfprintf(stderr, fmt, args);
+	va_end(args);
+	fprintf(stderr, "\n");
+
+	test_ok = false;
+}
+
+int test_report(const char *prog)
+{
+	switch (test_ok) {
+	case true:
+		printf("%s: " COLOR_GREEN "OK\n" COLOR_RESET, prog);
+		return EXIT_SUCCESS;
+	case false:
+		printf("%s: " COLOR_RED "FAIL\n" COLOR_RESET, prog);
+		return EXIT_FAILURE;
+	}
+}
diff --git a/tests/libtest.h b/tests/libtest.h
new file mode 100644
index 0000000..f570057
--- /dev/null
+++ b/tests/libtest.h
@@ -0,0 +1,11 @@
+#ifndef _TESTS_UTILS_H
+#define _TESTS_UTILS_H
+
+#include <stdbool.h>
+
+#define oom_assert(cond, prog) __oom_assert(cond, prog, __FILE__, __LINE__)
+void __oom_assert(bool cond, const char *prog, const char *file, int line);
+void print_err(const char *fmt, ...);
+int test_report(const char *prog);
+
+#endif
diff --git a/tests/nft-chain-test.c b/tests/nft-chain-test.c
index d678d46..b42fb86 100644
--- a/tests/nft-chain-test.c
+++ b/tests/nft-chain-test.c
@@ -15,13 +15,7 @@
 #include <linux/netfilter/nf_tables.h>
 #include <libnftnl/chain.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_chain(struct nftnl_chain *a, struct nftnl_chain *b)
 {
@@ -72,8 +66,8 @@ int main(int argc, char *argv[])
 
 	a = nftnl_chain_alloc();
 	b = nftnl_chain_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	nftnl_chain_set_str(a, NFTNL_CHAIN_NAME, "test");
 	nftnl_chain_set_u32(a, NFTNL_CHAIN_FAMILY, AF_INET);
@@ -101,10 +95,6 @@ int main(int argc, char *argv[])
 	nftnl_chain_free(a);
 	nftnl_chain_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 
 }
diff --git a/tests/nft-expr_bitwise-test.c b/tests/nft-expr_bitwise-test.c
index 64c1446..42e9bb2 100644
--- a/tests/nft-expr_bitwise-test.c
+++ b/tests/nft-expr_bitwise-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -65,11 +59,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("bitwise");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_SREG, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BITWISE_DREG, 0x78123456);
@@ -87,13 +80,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
@@ -107,9 +100,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_byteorder-test.c b/tests/nft-expr_byteorder-test.c
index 5994e5b..9a25667 100644
--- a/tests/nft-expr_byteorder-test.c
+++ b/tests/nft-expr_byteorder-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -58,11 +52,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("byteorder");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BYTEORDER_SREG, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_BYTEORDER_DREG, 0x12345678);
@@ -80,13 +73,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a,rule_b);
 
@@ -99,9 +92,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_cmp-test.c b/tests/nft-expr_cmp-test.c
index ec00bb9..570db2c 100644
--- a/tests/nft-expr_cmp-test.c
+++ b/tests/nft-expr_cmp-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -56,11 +50,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("cmp");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set(ex, NFTNL_EXPR_CMP_DATA, &data_len, sizeof(data_len));
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_CMP_SREG, 0x12345678);
@@ -76,12 +69,12 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -94,9 +87,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_counter-test.c b/tests/nft-expr_counter-test.c
index 519bc1f..7066c26 100644
--- a/tests/nft-expr_counter-test.c
+++ b/tests/nft-expr_counter-test.c
@@ -19,13 +19,8 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
+#include "libtest.h"
 
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -49,12 +44,11 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	ex = nftnl_expr_alloc("counter");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u64(ex, NFTNL_EXPR_CTR_BYTES, 0x123456789abcdef0);
 	nftnl_expr_set_u64(ex, NFTNL_EXPR_CTR_PACKETS, 0xf0123456789abcde);
@@ -68,12 +62,12 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -86,8 +80,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_ct-test.c b/tests/nft-expr_ct-test.c
index e98fbab..cfbe0d6 100644
--- a/tests/nft-expr_ct-test.c
+++ b/tests/nft-expr_ct-test.c
@@ -19,12 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -50,11 +45,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("ct");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_CT_KEY, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_CT_DIR, 0x12);
@@ -70,13 +64,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -89,9 +83,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_dup-test.c b/tests/nft-expr_dup-test.c
index 3c37d4a..4ae112d 100644
--- a/tests/nft-expr_dup-test.c
+++ b/tests/nft-expr_dup-test.c
@@ -19,12 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -48,11 +43,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("dup");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_DUP_SREG_ADDR, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_DUP_SREG_DEV,  0x78123456);
@@ -67,13 +61,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -86,9 +80,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_exthdr-test.c b/tests/nft-expr_exthdr-test.c
index fef2dd0..56652b5 100644
--- a/tests/nft-expr_exthdr-test.c
+++ b/tests/nft-expr_exthdr-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -55,11 +49,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("exthdr");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_EXTHDR_DREG, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_EXTHDR_TYPE, 0x12);
@@ -75,13 +68,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -93,9 +86,6 @@ int main(int argc, char *argv[])
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
-	if (!test_ok)
-		exit(EXIT_FAILURE);
 
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_fwd-test.c b/tests/nft-expr_fwd-test.c
index 4fdf53d..7a27299 100644
--- a/tests/nft-expr_fwd-test.c
+++ b/tests/nft-expr_fwd-test.c
@@ -19,12 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -45,11 +40,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("dup");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_FWD_SREG_DEV,  0x78123456);
 
@@ -63,13 +57,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -82,9 +76,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_immediate-test.c b/tests/nft-expr_immediate-test.c
index 60a1450..1e9749f 100644
--- a/tests/nft-expr_immediate-test.c
+++ b/tests/nft-expr_immediate-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr_verdict(struct nftnl_expr *rule_a,
 				   struct nftnl_expr *rule_b)
@@ -76,12 +70,12 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex_val = nftnl_expr_alloc("immediate");
 	ex_ver = nftnl_expr_alloc("immediate");
-	if (!ex_val || !ex_ver)
-		print_err("OOM");
+	oom_assert(ex_val, argv[0]);
+	oom_assert(ex_ver, argv[0]);
 
 	nftnl_expr_set_u32(ex_val, NFTNL_EXPR_IMM_DREG, 0x1234568);
 	nftnl_expr_set(ex_val,     NFTNL_EXPR_IMM_DATA, data, sizeof(data));
@@ -101,20 +95,20 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr_value(rule_a, rule_b);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr_verdict(rule_a, rule_b);
 
@@ -127,9 +121,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_limit-test.c b/tests/nft-expr_limit-test.c
index 2838941..7848e29 100644
--- a/tests/nft-expr_limit-test.c
+++ b/tests/nft-expr_limit-test.c
@@ -20,13 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -59,11 +53,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("limit");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u64(ex, NFTNL_EXPR_LIMIT_RATE, 0x123456789abcdef0);
 	nftnl_expr_set_u64(ex, NFTNL_EXPR_LIMIT_UNIT, 0xf0123456789abcde);
@@ -81,13 +74,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -100,9 +93,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_log-test.c b/tests/nft-expr_log-test.c
index b7aa302..a2c1f1d 100644
--- a/tests/nft-expr_log-test.c
+++ b/tests/nft-expr_log-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-	test_ok = 0;
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -55,11 +49,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("log");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_LOG_SNAPLEN, 0x12345678);
 	nftnl_expr_set_u16(ex, NFTNL_EXPR_LOG_GROUP, 0x1234);
@@ -75,12 +68,12 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -93,9 +86,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_lookup-test.c b/tests/nft-expr_lookup-test.c
index 28c1204..34dffdf 100644
--- a/tests/nft-expr_lookup-test.c
+++ b/tests/nft-expr_lookup-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -63,11 +57,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("lookup");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_LOOKUP_SREG, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_LOOKUP_DREG, 0x78123456);
@@ -84,12 +77,12 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -102,10 +95,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_masq-test.c b/tests/nft-expr_masq-test.c
index 3f9903d..fdfbf03 100644
--- a/tests/nft-expr_masq-test.c
+++ b/tests/nft-expr_masq-test.c
@@ -17,13 +17,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -50,11 +44,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("masq");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_MASQ_FLAGS, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_MASQ_REG_PROTO_MIN, 0x5432178);
@@ -70,13 +63,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -89,9 +82,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_match-test.c b/tests/nft-expr_match-test.c
index 39a49d8..9902d2f 100644
--- a/tests/nft-expr_match-test.c
+++ b/tests/nft-expr_match-test.c
@@ -20,19 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
-
-static void print_err2(const char *msg, uint32_t a, uint32_t b)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s size a: %d b: %d \n", msg, a, b);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -48,7 +36,8 @@ static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 	nftnl_expr_get(rule_a, NFTNL_EXPR_MT_INFO, &lena);
 	nftnl_expr_get(rule_b, NFTNL_EXPR_MT_INFO, &lenb);
 	if (lena != lenb)
-		print_err2("Expr NFTNL_EXPR_MT_INFO size mismatches", lena, lenb);
+		print_err("Expr NFTNL_EXPR_MT_INFO size mismatches: %d != %d",
+			  lena, lenb);
 }
 
 int main(int argc, char *argv[])
@@ -63,11 +52,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("match");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_str(ex, NFTNL_EXPR_MT_NAME, "Tests");
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_MT_REV, 0x12345678);
@@ -81,13 +69,13 @@ int main(int argc, char *argv[])
 		print_err("parsing problems");
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -100,9 +88,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_meta-test.c b/tests/nft-expr_meta-test.c
index 8fb7873..e528631 100644
--- a/tests/nft-expr_meta-test.c
+++ b/tests/nft-expr_meta-test.c
@@ -19,13 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -49,11 +43,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("meta");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_META_KEY, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_META_DREG, 0x78123456);
@@ -67,13 +60,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -86,9 +79,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_nat-test.c b/tests/nft-expr_nat-test.c
index fd3a488..d1cc0b1 100644
--- a/tests/nft-expr_nat-test.c
+++ b/tests/nft-expr_nat-test.c
@@ -20,13 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -65,11 +59,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("nat");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_NAT_TYPE, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_NAT_FAMILY, 0x3456721);
@@ -89,13 +82,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -108,9 +101,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_payload-test.c b/tests/nft-expr_payload-test.c
index 371372c..0812d6d 100644
--- a/tests/nft-expr_payload-test.c
+++ b/tests/nft-expr_payload-test.c
@@ -20,13 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -56,11 +50,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("payload");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_PAYLOAD_DREG, 0x1234568);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_PAYLOAD_BASE, 0x78123456);
@@ -76,13 +69,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -95,9 +88,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_queue-test.c b/tests/nft-expr_queue-test.c
index 1cc39aa..327e8fd 100644
--- a/tests/nft-expr_queue-test.c
+++ b/tests/nft-expr_queue-test.c
@@ -22,13 +22,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -52,11 +46,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("queue");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u16(ex, NFTNL_EXPR_QUEUE_NUM, 0x01010);
 	nftnl_expr_set_u16(ex, NFTNL_EXPR_QUEUE_TOTAL, 0x1234);
@@ -72,13 +65,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -91,9 +84,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_redir-test.c b/tests/nft-expr_redir-test.c
index 6c8caec..ce97928 100644
--- a/tests/nft-expr_redir-test.c
+++ b/tests/nft-expr_redir-test.c
@@ -17,13 +17,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -50,11 +44,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("redir");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_REDIR_REG_PROTO_MIN, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_REDIR_REG_PROTO_MAX, 0x56781234);
@@ -70,13 +63,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -89,9 +82,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_reject-test.c b/tests/nft-expr_reject-test.c
index d8189ea..426f9e9 100644
--- a/tests/nft-expr_reject-test.c
+++ b/tests/nft-expr_reject-test.c
@@ -20,13 +20,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -50,11 +44,10 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 	ex = nftnl_expr_alloc("reject");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_REJECT_TYPE, 0x12345678);
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_REJECT_CODE, 0x45681234);
@@ -69,13 +62,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -88,9 +81,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-expr_target-test.c b/tests/nft-expr_target-test.c
index ba56b27..82a4a9f 100644
--- a/tests/nft-expr_target-test.c
+++ b/tests/nft-expr_target-test.c
@@ -19,19 +19,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/expr.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
-
-static void print_err2(const char *msg, uint32_t a, uint32_t b)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s size a: %d b: %d \n",msg, a, b);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 			      struct nftnl_expr *rule_b)
@@ -47,7 +35,8 @@ static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
 	nftnl_expr_get(rule_a, NFTNL_EXPR_TG_INFO, &lena);
 	nftnl_expr_get(rule_b, NFTNL_EXPR_TG_INFO, &lenb);
 	if (lena != lenb)
-		print_err2("Expr NFTNL_EXPR_TG_INFO size mismatches", lena, lenb);
+		print_err("Expr NFTNL_EXPR_TG_INFO size mismatches: %d != %d",
+			  lena, lenb);
 }
 
 int main(int argc, char *argv[])
@@ -62,12 +51,11 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	ex = nftnl_expr_alloc("target");
-	if (ex == NULL)
-		print_err("OOM");
+	oom_assert(ex, argv[0]);
 
 	nftnl_expr_set(ex, NFTNL_EXPR_TG_NAME, "test", strlen("test"));
 	nftnl_expr_set_u32(ex, NFTNL_EXPR_TG_REV, 0x56781234);
@@ -82,13 +70,13 @@ int main(int argc, char *argv[])
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
-	if (iter_a == NULL || iter_b == NULL)
-		print_err("OOM");
+	oom_assert(iter_a, argv[0]);
+	oom_assert(iter_b, argv[0]);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
-	if (rule_a == NULL || rule_b == NULL)
-		print_err("OOM");
+	oom_assert(rule_a, argv[0]);
+	oom_assert(rule_b, argv[0]);
 
 	cmp_nftnl_expr(rule_a, rule_b);
 
@@ -101,8 +89,5 @@ int main(int argc, char *argv[])
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-rule-test.c b/tests/nft-rule-test.c
index dee3530..c6ba719 100644
--- a/tests/nft-rule-test.c
+++ b/tests/nft-rule-test.c
@@ -17,13 +17,7 @@
 #include <libnftnl/rule.h>
 #include <libnftnl/udata.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_rule(struct nftnl_rule *a, struct nftnl_rule *b)
 {
@@ -68,12 +62,11 @@ int main(int argc, char *argv[])
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	udata = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
-	if (!udata)
-		print_err("OOM");
+	oom_assert(udata, argv[0]);
 
 	if (!nftnl_udata_put_strz(udata, 0, "hello world"))
 		print_err("User data too big");
@@ -100,9 +93,6 @@ int main(int argc, char *argv[])
 
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
-	if (!test_ok)
-		exit(EXIT_FAILURE);
 
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-set-test.c b/tests/nft-set-test.c
index 173c17f..6f9b03d 100644
--- a/tests/nft-set-test.c
+++ b/tests/nft-set-test.c
@@ -16,13 +16,7 @@
 
 #include <libnftnl/set.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_set(struct nftnl_set *a, struct nftnl_set *b)
 {
@@ -60,8 +54,8 @@ int main(int argc, char *argv[])
 
 	a = nftnl_set_alloc();
 	b = nftnl_set_alloc();
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	nftnl_set_set_str(a, NFTNL_SET_TABLE, "test-table");
 	nftnl_set_set_str(a, NFTNL_SET_NAME, "test-name");
@@ -84,9 +78,5 @@ int main(int argc, char *argv[])
 
 	nftnl_set_free(a); nftnl_set_free(b);
 
-	if (!test_ok)
-		exit(EXIT_FAILURE);
-
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
diff --git a/tests/nft-table-test.c b/tests/nft-table-test.c
index 1031ffe..6b0418f 100644
--- a/tests/nft-table-test.c
+++ b/tests/nft-table-test.c
@@ -16,13 +16,7 @@
 #include <linux/netfilter/nf_tables.h>
 #include <libnftnl/table.h>
 
-static int test_ok = 1;
-
-static void print_err(const char *msg)
-{
-	test_ok = 0;
-	printf("\033[31mERROR:\e[0m %s\n", msg);
-}
+#include "libtest.h"
 
 static void cmp_nftnl_table(struct nftnl_table *a, struct nftnl_table *b)
 {
@@ -47,8 +41,8 @@ int main(int argc, char *argv[])
 	a = nftnl_table_alloc();
 	b = nftnl_table_alloc();
 
-	if (a == NULL || b == NULL)
-		print_err("OOM");
+	oom_assert(a, argv[0]);
+	oom_assert(b, argv[0]);
 
 	nftnl_table_set_str(a, NFTNL_TABLE_NAME, "test");
 	nftnl_table_set_u32(a, NFTNL_TABLE_FAMILY, AF_INET);
@@ -66,9 +60,6 @@ int main(int argc, char *argv[])
 
 	nftnl_table_free(a);
 	nftnl_table_free(b);
-	if (!test_ok)
-		exit(EXIT_FAILURE);
 
-	printf("%s: \033[32mOK\e[0m\n", argv[0]);
-	return EXIT_SUCCESS;
+	return test_report(argv[0]);
 }
-- 
2.8.3


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 2/3 v3 nft] tests: Use libnftnl comparators in all tests
  2016-08-16 10:30             ` [PATCH 1/3 v3 nft] tests: Consolidate printing error utilities Carlos Falgueras García
@ 2016-08-16 10:30               ` Carlos Falgueras García
  2016-08-16 11:58                 ` Pablo Neira Ayuso
  2016-08-16 10:30               ` [PATCH 3/3 v3 nft] tests: Elimine static variable 'test_ok' Carlos Falgueras García
  1 sibling, 1 reply; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-16 10:30 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

Use 'nftnl_expr_cmp' and 'nftnl_rule_cmp' in all tests instead of custom
comparator for each one. If objects differ both are printed.

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 tests/libtest.c                 | 30 ++++++++++++++++++++++++++++++
 tests/libtest.h                 |  6 ++++++
 tests/nft-expr_bitwise-test.c   | 27 +--------------------------
 tests/nft-expr_byteorder-test.c | 22 +---------------------
 tests/nft-expr_cmp-test.c       | 19 +------------------
 tests/nft-expr_counter-test.c   | 13 +------------
 tests/nft-expr_ct-test.c        | 15 +--------------
 tests/nft-expr_dup-test.c       | 13 +------------
 tests/nft-expr_exthdr-test.c    | 19 +------------------
 tests/nft-expr_fwd-test.c       | 10 +---------
 tests/nft-expr_immediate-test.c | 40 ++--------------------------------------
 tests/nft-expr_limit-test.c     | 22 +---------------------
 tests/nft-expr_log-test.c       | 19 +------------------
 tests/nft-expr_lookup-test.c    | 25 +------------------------
 tests/nft-expr_masq-test.c      | 16 +---------------
 tests/nft-expr_match-test.c     | 20 +-------------------
 tests/nft-expr_meta-test.c      | 13 +------------
 tests/nft-expr_nat-test.c       | 28 +---------------------------
 tests/nft-expr_payload-test.c   | 19 +------------------
 tests/nft-expr_queue-test.c     | 13 +------------
 tests/nft-expr_redir-test.c     | 16 +---------------
 tests/nft-expr_reject-test.c    | 13 +------------
 tests/nft-expr_target-test.c    | 20 +-------------------
 tests/nft-rule-test.c           | 36 +-----------------------------------
 24 files changed, 59 insertions(+), 415 deletions(-)

diff --git a/tests/libtest.c b/tests/libtest.c
index ed7eafa..883e7a7 100644
--- a/tests/libtest.c
+++ b/tests/libtest.c
@@ -51,3 +51,33 @@ int test_report(const char *prog)
 		return EXIT_FAILURE;
 	}
 }
+
+#define SNPRINTF_BUFF_LEN 1024
+
+static const char *rule2str(const struct nftnl_rule *r)
+{
+	static char buff[SNPRINTF_BUFF_LEN];
+	nftnl_rule_snprintf(buff, SNPRINTF_BUFF_LEN, r, NFTNL_OUTPUT_DEFAULT, 0);
+	return buff;
+}
+
+static const char *expr2str(const struct nftnl_expr *e)
+{
+	static char buff[SNPRINTF_BUFF_LEN];
+	nftnl_expr_snprintf(buff, SNPRINTF_BUFF_LEN, e, NFTNL_OUTPUT_DEFAULT, 0);
+	return buff;
+}
+
+void test_assert_expr(const struct nftnl_expr *e1, const struct nftnl_expr *e2)
+{
+	if (!nftnl_expr_cmp(e1, e2))
+		print_err("expressions mismatch:\n\texpr 1: %s\n\texpr 2: %s",
+			  expr2str(e1), expr2str(e2));
+}
+
+void test_assert_rule(const struct nftnl_rule *r1, const struct nftnl_rule *r2)
+{
+	if (!nftnl_rule_cmp(r1, r2))
+		print_err("rules mismatch:\nRULE 1:\n%s\nRULE 2:\n%s",
+			  rule2str(r1), rule2str(r2));
+}
diff --git a/tests/libtest.h b/tests/libtest.h
index f570057..dd1d5cb 100644
--- a/tests/libtest.h
+++ b/tests/libtest.h
@@ -2,10 +2,16 @@
 #define _TESTS_UTILS_H
 
 #include <stdbool.h>
+#include <libmnl/libmnl.h>
+#include <libnftnl/common.h>
+#include <libnftnl/rule.h>
+#include <libnftnl/expr.h>
 
 #define oom_assert(cond, prog) __oom_assert(cond, prog, __FILE__, __LINE__)
 void __oom_assert(bool cond, const char *prog, const char *file, int line);
 void print_err(const char *fmt, ...);
 int test_report(const char *prog);
+void test_assert_expr(const struct nftnl_expr *e1, const struct nftnl_expr *e2);
+void test_assert_rule(const struct nftnl_rule *r1, const struct nftnl_rule *r2);
 
 #endif
diff --git a/tests/nft-expr_bitwise-test.c b/tests/nft-expr_bitwise-test.c
index 42e9bb2..1eff343 100644
--- a/tests/nft-expr_bitwise-test.c
+++ b/tests/nft-expr_bitwise-test.c
@@ -21,31 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	uint32_t maska, maskb;
-	uint32_t xora, xorb;
-
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_DREG))
-		print_err("Expr BITWISE_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BITWISE_SREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BITWISE_SREG))
-		print_err("Expr BITWISE_SREG mismatches");
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_BITWISE_LEN) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_BITWISE_LEN))
-		print_err("Expr BITWISE_DREG mismatches");
-	nftnl_expr_get(rule_a, NFTNL_EXPR_BITWISE_MASK, &maska);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_BITWISE_MASK, &maskb);
-	if (maska != maskb)
-		print_err("Size of BITWISE_MASK mismatches");
-	nftnl_expr_get(rule_a, NFTNL_EXPR_BITWISE_XOR, &xora);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_BITWISE_XOR, &xorb);
-	if (xora != xorb)
-		print_err("Size of BITWISE_XOR mismatches");
-
-}
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b = NULL;
@@ -95,7 +70,7 @@ int main(int argc, char *argv[])
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 
-	cmp_nftnl_expr(rule_a,rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
diff --git a/tests/nft-expr_byteorder-test.c b/tests/nft-expr_byteorder-test.c
index 9a25667..1f77ea7 100644
--- a/tests/nft-expr_byteorder-test.c
+++ b/tests/nft-expr_byteorder-test.c
@@ -21,26 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_DREG))
-		print_err("Expr NFTNL_EXPR_BYTEORDER_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_SREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_SREG))
-		print_err("Expr NFTNL_EXPR_BYTEORDER_SREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_OP) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_OP))
-		print_err("Expr NFTNL_EXPR_BYTEORDER_OP mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_LEN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_LEN))
-		print_err("Expr NFTNL_EXPR_BYTEORDER_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_BYTEORDER_SIZE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_BYTEORDER_SIZE))
-		print_err("Expr NFTNL_EXPR_BITWISE_SIZE mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -81,7 +61,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a,rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_cmp-test.c b/tests/nft-expr_cmp-test.c
index 570db2c..90c78b0 100644
--- a/tests/nft-expr_cmp-test.c
+++ b/tests/nft-expr_cmp-test.c
@@ -21,23 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	uint32_t data_lena, data_lenb;
-
-	nftnl_expr_get(rule_a, NFTNL_EXPR_CMP_DATA, &data_lena);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_CMP_DATA, &data_lenb);
-	if (data_lena != data_lenb)
-		print_err("Size of NFTNL_EXPR_CMP_DATA mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CMP_SREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CMP_SREG))
-		print_err("Expr NFTNL_EXPR_CMP_SREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CMP_OP) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CMP_OP))
-		print_err("Expr NFTNL_EXPR_CMP_OP mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -76,7 +59,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_counter-test.c b/tests/nft-expr_counter-test.c
index 7066c26..d784a11 100644
--- a/tests/nft-expr_counter-test.c
+++ b/tests/nft-expr_counter-test.c
@@ -22,17 +22,6 @@
 #include "libtest.h"
 
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_CTR_BYTES) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_CTR_BYTES))
-		print_err("Expr NFTNL_EXPR_CTR_BYTES mismatches");
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_CTR_PACKETS) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_CTR_PACKETS))
-		print_err("Expr NFTNL_EXPR_CTR_PACKETS mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -69,7 +58,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_ct-test.c b/tests/nft-expr_ct-test.c
index cfbe0d6..936803e 100644
--- a/tests/nft-expr_ct-test.c
+++ b/tests/nft-expr_ct-test.c
@@ -21,19 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CT_KEY) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CT_KEY))
-		print_err("Expr CT_KEY mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CT_DIR) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CT_DIR))
-		print_err("Expr CT_DIR mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_CT_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_CT_DREG))
-		print_err("Expr CT_DREG mismatches");
-}
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -72,7 +59,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_dup-test.c b/tests/nft-expr_dup-test.c
index 4ae112d..9c24764 100644
--- a/tests/nft-expr_dup-test.c
+++ b/tests/nft-expr_dup-test.c
@@ -21,17 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_DUP_SREG_ADDR) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_DUP_SREG_ADDR))
-		print_err("Expr SREG_TO mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_DUP_SREG_DEV) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_DUP_SREG_DEV))
-		print_err("Expr SREG_OIF mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -69,7 +58,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_exthdr-test.c b/tests/nft-expr_exthdr-test.c
index 56652b5..82c442e 100644
--- a/tests/nft-expr_exthdr-test.c
+++ b/tests/nft-expr_exthdr-test.c
@@ -21,23 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_EXTHDR_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_EXTHDR_DREG))
-		print_err("Expr NFTNL_EXPR_EXTHDR_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_EXTHDR_TYPE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_EXTHDR_TYPE))
-		print_err("Expr NFTNL_EXPR_EXTHDR_TYPE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_EXTHDR_OFFSET) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_EXTHDR_OFFSET))
-		print_err("Expr NFTNL_EXPR_EXTHDR_OFFSET mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_EXTHDR_LEN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_EXTHDR_LEN))
-		print_err("Expr NFTNL_EXPR_EXTHDR_LEN mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -76,7 +59,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_fwd-test.c b/tests/nft-expr_fwd-test.c
index 7a27299..3f04a3f 100644
--- a/tests/nft-expr_fwd-test.c
+++ b/tests/nft-expr_fwd-test.c
@@ -21,14 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_FWD_SREG_DEV) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_FWD_SREG_DEV))
-		print_err("Expr SREG_OIF mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -65,7 +57,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_immediate-test.c b/tests/nft-expr_immediate-test.c
index 1e9749f..763eb0f 100644
--- a/tests/nft-expr_immediate-test.c
+++ b/tests/nft-expr_immediate-test.c
@@ -21,42 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr_verdict(struct nftnl_expr *rule_a,
-				   struct nftnl_expr *rule_b)
-{
-	const char *chain_a, *chain_b;
-	uint32_t len_a, len_b;
-
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_IMM_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_IMM_DREG))
-		print_err("Expr NFTNL_EXPR_IMM_DREG mismatches");
-
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_IMM_VERDICT) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_IMM_VERDICT))
-		print_err("Expr NFTNL_EXPR_IMM_VERDICT mismatches");
-
-	chain_a = nftnl_expr_get(rule_a, NFTNL_EXPR_IMM_CHAIN, &len_a);
-	chain_b = nftnl_expr_get(rule_b, NFTNL_EXPR_IMM_CHAIN, &len_b);
-	if (len_a != len_b || strncmp(chain_a, chain_b, len_a))
-		print_err("Expr NFTNL_EXPR_IMM_CHAIN mismatches");
-}
-
-static void cmp_nftnl_expr_value(struct nftnl_expr *rule_a,
-				 struct nftnl_expr *rule_b)
-{
-	const uint32_t *data_a, *data_b;
-	uint32_t len_a, len_b;
-
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_IMM_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_IMM_DREG))
-		print_err("Expr NFTNL_EXPR_IMM_DREG mismatches");
-
-	data_a = nftnl_expr_get(rule_a, NFTNL_EXPR_IMM_DATA, &len_a);
-	data_b = nftnl_expr_get(rule_b, NFTNL_EXPR_IMM_DATA, &len_b);
-	if (len_a != len_b || memcmp(data_a, data_b, len_a))
-		print_err("Expr NFTNL_EXPR_IMM_DATA mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -103,14 +67,14 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr_value(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr_verdict(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_limit-test.c b/tests/nft-expr_limit-test.c
index 7848e29..bcdd357 100644
--- a/tests/nft-expr_limit-test.c
+++ b/tests/nft-expr_limit-test.c
@@ -22,26 +22,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_RATE) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_RATE))
-		print_err("Expr CTR_BYTES mismatches");
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_UNIT) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_UNIT))
-		print_err("Expr CTR_PACKET mismatches");
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_BURST) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_BURST))
-		print_err("Expr CTR_PACKET mismatches");
-	if (nftnl_expr_get_u64(rule_a, NFTNL_EXPR_LIMIT_TYPE) !=
-	    nftnl_expr_get_u64(rule_b, NFTNL_EXPR_LIMIT_TYPE))
-		print_err("Expr TYPE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LIMIT_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LIMIT_FLAGS))
-		print_err("Expr FLAGS mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -82,7 +62,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_log-test.c b/tests/nft-expr_log-test.c
index a2c1f1d..aad71b5 100644
--- a/tests/nft-expr_log-test.c
+++ b/tests/nft-expr_log-test.c
@@ -21,23 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOG_SNAPLEN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOG_SNAPLEN))
-		print_err("Expr NFTNL_EXPR_LOG_SNAPLEN mismatches");
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_LOG_GROUP) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_LOG_GROUP))
-		print_err("Expr NFTNL_EXPR_LOG_GROUP mismatches");
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_LOG_QTHRESHOLD) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_LOG_QTHRESHOLD))
-		print_err("Expr NFTNL_EXPR_LOG_QTHRESHOLD mismatches");
-	if(strcmp(nftnl_expr_get_str(rule_a, NFTNL_EXPR_LOG_PREFIX),
-		  nftnl_expr_get_str(rule_b, NFTNL_EXPR_LOG_PREFIX)) != 0)
-		print_err("Expr NFTNL_EXPR_LOG_PREFIX mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -75,7 +58,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_lookup-test.c b/tests/nft-expr_lookup-test.c
index 34dffdf..dcbbcdb 100644
--- a/tests/nft-expr_lookup-test.c
+++ b/tests/nft-expr_lookup-test.c
@@ -21,29 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_SREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_SREG))
-		print_err("Expr NFTNL_EXPR_LOOKUP_SREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_DREG))
-		print_err("Expr NFTNL_EXPR_LOOKUP_DREG mismatches");
-	if (strcmp(nftnl_expr_get_str(rule_a, NFTNL_EXPR_LOOKUP_SET),
-		   nftnl_expr_get_str(rule_b, NFTNL_EXPR_LOOKUP_SET)))
-		print_err("Expr NFTNL_EXPR_LOOKUP_SET mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_SET_ID) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_SET_ID))
-		print_err("Expr NFTNL_EXPR_LOOKUP_SET_ID mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_FLAGS)) {
-		print_err("Expr NFTNL_EXPR_LOOKUP_FLAGS mismatches");
-		printf("%X %X\n",
-			nftnl_expr_get_u32(rule_a, NFTNL_EXPR_LOOKUP_FLAGS),
-			nftnl_expr_get_u32(rule_b, NFTNL_EXPR_LOOKUP_FLAGS));
-	}
-}
 
 int main(int argc, char *argv[])
 {
@@ -84,7 +61,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_masq-test.c b/tests/nft-expr_masq-test.c
index fdfbf03..8b7cfc7 100644
--- a/tests/nft-expr_masq-test.c
+++ b/tests/nft-expr_masq-test.c
@@ -19,20 +19,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_MASQ_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_MASQ_FLAGS))
-		print_err("Expr NFTNL_EXPR_MASQ_FLAGS mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_MASQ_REG_PROTO_MIN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_MASQ_REG_PROTO_MIN))
-		print_err("Expr NFTNL_EXPR_MASQ_REG_PROTO_MIN mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_MASQ_REG_PROTO_MAX) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_MASQ_REG_PROTO_MAX))
-		print_err("Expr NFTNL_EXPR_MASQ_REG_PROTO_MAX mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -71,7 +57,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_match-test.c b/tests/nft-expr_match-test.c
index 9902d2f..b410bc9 100644
--- a/tests/nft-expr_match-test.c
+++ b/tests/nft-expr_match-test.c
@@ -22,24 +22,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	uint32_t lena, lenb;
-
-	if (strcmp(nftnl_expr_get_str(rule_a, NFTNL_EXPR_MT_NAME),
-		   nftnl_expr_get_str(rule_b, NFTNL_EXPR_MT_NAME)) != 0)
-		print_err("Expr NFTNL_EXPR_MT_NAME mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_MT_REV) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_MT_REV))
-		print_err("Expr NFTNL_EXPR_MT_REV mismatches");
-	nftnl_expr_get(rule_a, NFTNL_EXPR_MT_INFO, &lena);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_MT_INFO, &lenb);
-	if (lena != lenb)
-		print_err("Expr NFTNL_EXPR_MT_INFO size mismatches: %d != %d",
-			  lena, lenb);
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -77,7 +59,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_meta-test.c b/tests/nft-expr_meta-test.c
index e528631..9a812b7 100644
--- a/tests/nft-expr_meta-test.c
+++ b/tests/nft-expr_meta-test.c
@@ -21,17 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_META_KEY) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_META_KEY))
-		print_err("Expr NFTNL_EXPR_META_KEY mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_META_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_META_DREG))
-		print_err("Expr NFTNL_EXPR_META_DREG mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -68,7 +57,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_nat-test.c b/tests/nft-expr_nat-test.c
index d1cc0b1..eb8e2a5 100644
--- a/tests/nft-expr_nat-test.c
+++ b/tests/nft-expr_nat-test.c
@@ -22,32 +22,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_TYPE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_TYPE))
-		print_err("Expr NFTNL_EXPR_NAT_TYPE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_FAMILY) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_FAMILY))
-		print_err("Expr NFTNL_EXPR_NAT_FAMILY mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_REG_ADDR_MIN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_REG_ADDR_MIN))
-		print_err("Expr NFTNL_EXPR_NAT_REG_ADDR_MIN mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_REG_ADDR_MAX) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_REG_ADDR_MAX))
-		print_err("Expr NFTNL_EXPR_NAT_REG_ADDR_MAX mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_REG_PROTO_MIN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_REG_PROTO_MIN))
-		print_err("Expr NFTNL_EXPR_NAT_REG_PROTO_MIN mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_REG_PROTO_MAX) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_REG_PROTO_MAX))
-		print_err("Expr NFTNL_EXPR_NAT_REG_PROTO_MAX mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_NAT_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_NAT_FLAGS))
-		print_err("Expr NFTNL_EXPR_NAT_FLAGS mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -90,7 +64,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_payload-test.c b/tests/nft-expr_payload-test.c
index 0812d6d..78f11ba 100644
--- a/tests/nft-expr_payload-test.c
+++ b/tests/nft-expr_payload-test.c
@@ -22,23 +22,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_PAYLOAD_DREG) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_PAYLOAD_DREG))
-		print_err("Expr NFTNL_EXPR_PAYLOAD_DREG mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_PAYLOAD_BASE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_PAYLOAD_BASE))
-		print_err("Expr NFTNL_EXPR_PAYLOAD_BASE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_PAYLOAD_OFFSET) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_PAYLOAD_OFFSET))
-		print_err("Expr NFTNL_EXPR_PAYLOAD_OFFSET mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_PAYLOAD_LEN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_PAYLOAD_LEN))
-		print_err("Expr NFTNL_EXPR_PAYLOAD_LEN mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -77,7 +60,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_queue-test.c b/tests/nft-expr_queue-test.c
index 327e8fd..1106766 100644
--- a/tests/nft-expr_queue-test.c
+++ b/tests/nft-expr_queue-test.c
@@ -24,17 +24,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_QUEUE_NUM) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_QUEUE_NUM))
-		print_err("Expr NFTNL_EXPR_QUEUE_NUM mismatches");
-	if (nftnl_expr_get_u16(rule_a, NFTNL_EXPR_QUEUE_TOTAL) !=
-	    nftnl_expr_get_u16(rule_b, NFTNL_EXPR_QUEUE_TOTAL))
-		print_err("Expr NFTNL_EXPR_QUEUE_TOTAL mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -73,7 +62,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_redir-test.c b/tests/nft-expr_redir-test.c
index ce97928..978f09f 100644
--- a/tests/nft-expr_redir-test.c
+++ b/tests/nft-expr_redir-test.c
@@ -19,20 +19,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REDIR_REG_PROTO_MIN) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REDIR_REG_PROTO_MIN))
-		print_err("Expr NFTNL_EXPR_REDIR_REG_PROTO_MIN mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REDIR_REG_PROTO_MAX) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REDIR_REG_PROTO_MAX))
-		print_err("Expr NFTNL_EXPR_REDIR_REG_PROTO_MAX mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REDIR_FLAGS) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REDIR_FLAGS))
-		print_err("Expr NFTNL_EXPR_REDIR_FLAGS mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -71,7 +57,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_reject-test.c b/tests/nft-expr_reject-test.c
index 426f9e9..0e42ae1 100644
--- a/tests/nft-expr_reject-test.c
+++ b/tests/nft-expr_reject-test.c
@@ -22,17 +22,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REJECT_TYPE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REJECT_TYPE))
-		print_err("Expr NFTNL_EXPR_REJECT_TYPE mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_REJECT_CODE) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_REJECT_CODE))
-		print_err("Expr NFTNL_EXPR_REJECT_CODE mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -70,7 +59,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-expr_target-test.c b/tests/nft-expr_target-test.c
index 82a4a9f..1c750b6 100644
--- a/tests/nft-expr_target-test.c
+++ b/tests/nft-expr_target-test.c
@@ -21,24 +21,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_expr(struct nftnl_expr *rule_a,
-			      struct nftnl_expr *rule_b)
-{
-	uint32_t lena, lenb;
-
-	if (strcmp(nftnl_expr_get_str(rule_a, NFTNL_EXPR_TG_NAME),
-		   nftnl_expr_get_str(rule_b, NFTNL_EXPR_TG_NAME)) != 0)
-		print_err("Expr NFTNL_EXPR_TG_NAME mismatches");
-	if (nftnl_expr_get_u32(rule_a, NFTNL_EXPR_TG_REV) !=
-	    nftnl_expr_get_u32(rule_b, NFTNL_EXPR_TG_REV))
-		print_err("Expr NFTNL_EXPR_TG_REV mismatches");
-	nftnl_expr_get(rule_a, NFTNL_EXPR_TG_INFO, &lena);
-	nftnl_expr_get(rule_b, NFTNL_EXPR_TG_INFO, &lenb);
-	if (lena != lenb)
-		print_err("Expr NFTNL_EXPR_TG_INFO size mismatches: %d != %d",
-			  lena, lenb);
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_rule *a, *b;
@@ -78,7 +60,7 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	cmp_nftnl_expr(rule_a, rule_b);
+	test_assert_expr(rule_a, rule_b);
 
 	if (nftnl_expr_iter_next(iter_a) != NULL ||
 	    nftnl_expr_iter_next(iter_b) != NULL)
diff --git a/tests/nft-rule-test.c b/tests/nft-rule-test.c
index c6ba719..a02abbc 100644
--- a/tests/nft-rule-test.c
+++ b/tests/nft-rule-test.c
@@ -19,40 +19,6 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_rule(struct nftnl_rule *a, struct nftnl_rule *b)
-{
-	const void *udata_a, *udata_b;
-	uint32_t len_a, len_b;
-
-	if (nftnl_rule_get_u32(a, NFTNL_RULE_FAMILY) !=
-	    nftnl_rule_get_u32(b, NFTNL_RULE_FAMILY))
-		print_err("Rule family mismatches");
-	if (strcmp(nftnl_rule_get_str(a, NFTNL_RULE_TABLE),
-		   nftnl_rule_get_str(b, NFTNL_RULE_TABLE)) != 0)
-		print_err("Rule table mismatches");
-	if (strcmp(nftnl_rule_get_str(a, NFTNL_RULE_CHAIN),
-		   nftnl_rule_get_str(b, NFTNL_RULE_CHAIN)) != 0)
-		print_err("Rule table mismatches");
-	if (nftnl_rule_get_u64(a, NFTNL_RULE_HANDLE) !=
-	    nftnl_rule_get_u64(b, NFTNL_RULE_HANDLE))
-		print_err("Rule handle mismatches");
-	if (nftnl_rule_get_u32(a, NFTNL_RULE_COMPAT_PROTO) !=
-	    nftnl_rule_get_u32(b, NFTNL_RULE_COMPAT_PROTO))
-		print_err("Rule compat_proto mismatches");
-	if (nftnl_rule_get_u32(a, NFTNL_RULE_COMPAT_FLAGS) !=
-	    nftnl_rule_get_u32(b, NFTNL_RULE_COMPAT_FLAGS))
-		print_err("Rule compat_flags mismatches");
-	if (nftnl_rule_get_u64(a, NFTNL_RULE_POSITION) !=
-	    nftnl_rule_get_u64(b, NFTNL_RULE_POSITION))
-		print_err("Rule compat_position mismatches");
-
-	udata_a = nftnl_rule_get_data(a, NFTNL_RULE_USERDATA, &len_a);
-	udata_b = nftnl_rule_get_data(b, NFTNL_RULE_USERDATA, &len_b);
-
-	if (len_a != len_b || memcmp(udata_a, udata_b, len_a) != 0)
-		print_err("Rule userdata mismatches");
-}
-
 int main(int argc, char *argv[])
 {
 	struct nftnl_udata_buf *udata;
@@ -89,7 +55,7 @@ int main(int argc, char *argv[])
 	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
 		print_err("parsing problems");
 
-	cmp_nftnl_rule(a,b);
+	test_assert_rule(a, b);
 
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
-- 
2.8.3


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* [PATCH 3/3 v3 nft] tests: Elimine static variable 'test_ok'
  2016-08-16 10:30             ` [PATCH 1/3 v3 nft] tests: Consolidate printing error utilities Carlos Falgueras García
  2016-08-16 10:30               ` [PATCH 2/3 v3 nft] tests: Use libnftnl comparators in all tests Carlos Falgueras García
@ 2016-08-16 10:30               ` Carlos Falgueras García
  1 sibling, 0 replies; 31+ messages in thread
From: Carlos Falgueras García @ 2016-08-16 10:30 UTC (permalink / raw)
  To: netfilter-devel; +Cc: pablo

* Modifies 'test_report' to receive a boolean that replaces 'test_ok'.
* Renames 'print_err' to 'test_assert' and adds a similar parameter.
* 'test_assert_{expr|rule}()' returns a boolean.
* Adapts all test to the new functions.

Signed-off-by: Carlos Falgueras García <carlosfg@riseup.net>
---
 tests/libtest.c                 | 30 ++++++-------
 tests/libtest.h                 |  8 ++--
 tests/nft-chain-test.c          | 93 ++++++++++++++++++++++++-----------------
 tests/nft-expr_bitwise-test.c   | 15 +++----
 tests/nft-expr_byteorder-test.c | 15 +++----
 tests/nft-expr_cmp-test.c       | 15 +++----
 tests/nft-expr_counter-test.c   | 15 +++----
 tests/nft-expr_ct-test.c        | 15 +++----
 tests/nft-expr_dup-test.c       | 15 +++----
 tests/nft-expr_exthdr-test.c    | 15 +++----
 tests/nft-expr_fwd-test.c       | 15 +++----
 tests/nft-expr_immediate-test.c | 17 ++++----
 tests/nft-expr_limit-test.c     | 15 +++----
 tests/nft-expr_log-test.c       | 15 +++----
 tests/nft-expr_lookup-test.c    | 15 +++----
 tests/nft-expr_masq-test.c      | 15 +++----
 tests/nft-expr_match-test.c     | 15 +++----
 tests/nft-expr_meta-test.c      | 15 +++----
 tests/nft-expr_nat-test.c       | 15 +++----
 tests/nft-expr_payload-test.c   | 15 +++----
 tests/nft-expr_queue-test.c     | 15 +++----
 tests/nft-expr_redir-test.c     | 15 +++----
 tests/nft-expr_reject-test.c    | 15 +++----
 tests/nft-expr_target-test.c    | 15 +++----
 tests/nft-rule-test.c           | 14 ++++---
 tests/nft-set-test.c            | 72 ++++++++++++++++++-------------
 tests/nft-table-test.c          | 38 ++++++++++-------
 27 files changed, 317 insertions(+), 255 deletions(-)

diff --git a/tests/libtest.c b/tests/libtest.c
index 883e7a7..4b36f55 100644
--- a/tests/libtest.c
+++ b/tests/libtest.c
@@ -11,8 +11,6 @@
 #define COLOR_GREEN   "\x1b[32m"
 #define COLOR_RESET   "\x1b[0m"
 
-static bool test_ok = true;
-
 void __oom_assert(bool cond, const char *prog, const char *file, int line)
 {
 	if (cond)
@@ -22,25 +20,27 @@ void __oom_assert(bool cond, const char *prog, const char *file, int line)
 		COLOR_RED "OOM" COLOR_RESET " at %s:%d\n\t%s\n", file, line,
 		strerror(errno));
 
-	test_ok = false;
-	test_report(prog);
+	test_report(false, prog);
 	exit(EXIT_FAILURE);
 }
 
-void print_err(const char *fmt, ...)
+bool test_assert(bool cond, const char *fmt, ...)
 {
 	va_list args;
 
+	if (cond)
+		return true;
+
 	fprintf(stderr, COLOR_RED "ERROR: " COLOR_RESET);
 	va_start(args, fmt);
 	vfprintf(stderr, fmt, args);
 	va_end(args);
 	fprintf(stderr, "\n");
 
-	test_ok = false;
+	return false;
 }
 
-int test_report(const char *prog)
+int test_report(bool test_ok, const char *prog)
 {
 	switch (test_ok) {
 	case true:
@@ -68,16 +68,16 @@ static const char *expr2str(const struct nftnl_expr *e)
 	return buff;
 }
 
-void test_assert_expr(const struct nftnl_expr *e1, const struct nftnl_expr *e2)
+bool test_assert_expr(const struct nftnl_expr *e1, const struct nftnl_expr *e2)
 {
-	if (!nftnl_expr_cmp(e1, e2))
-		print_err("expressions mismatch:\n\texpr 1: %s\n\texpr 2: %s",
-			  expr2str(e1), expr2str(e2));
+	return test_assert(nftnl_expr_cmp(e1, e2),
+			   "expressions mismatch:\n\texpr 1: %s\n\texpr 2: %s",
+			   expr2str(e1), expr2str(e2));
 }
 
-void test_assert_rule(const struct nftnl_rule *r1, const struct nftnl_rule *r2)
+bool test_assert_rule(const struct nftnl_rule *r1, const struct nftnl_rule *r2)
 {
-	if (!nftnl_rule_cmp(r1, r2))
-		print_err("rules mismatch:\nRULE 1:\n%s\nRULE 2:\n%s",
-			  rule2str(r1), rule2str(r2));
+	return test_assert(nftnl_rule_cmp(r1, r2),
+			   "rules mismatch:\nRULE 1:\n%s\nRULE 2:\n%s",
+			   rule2str(r1), rule2str(r2));
 }
diff --git a/tests/libtest.h b/tests/libtest.h
index dd1d5cb..969fcdc 100644
--- a/tests/libtest.h
+++ b/tests/libtest.h
@@ -9,9 +9,9 @@
 
 #define oom_assert(cond, prog) __oom_assert(cond, prog, __FILE__, __LINE__)
 void __oom_assert(bool cond, const char *prog, const char *file, int line);
-void print_err(const char *fmt, ...);
-int test_report(const char *prog);
-void test_assert_expr(const struct nftnl_expr *e1, const struct nftnl_expr *e2);
-void test_assert_rule(const struct nftnl_rule *r1, const struct nftnl_rule *r2);
+bool test_assert(bool cond, const char *fmt, ...);
+int test_report(bool test_ok, const char *prog);
+bool test_assert_expr(const struct nftnl_expr *e1, const struct nftnl_expr *e2);
+bool test_assert_rule(const struct nftnl_rule *r1, const struct nftnl_rule *r2);
 
 #endif
diff --git a/tests/nft-chain-test.c b/tests/nft-chain-test.c
index b42fb86..1b6672a 100644
--- a/tests/nft-chain-test.c
+++ b/tests/nft-chain-test.c
@@ -19,43 +19,56 @@
 
 static void cmp_nftnl_chain(struct nftnl_chain *a, struct nftnl_chain *b)
 {
+	bool test_ok = true;
+	bool ret;
 
-	if (strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_NAME),
-		   nftnl_chain_get_str(b, NFTNL_CHAIN_NAME)) != 0)
-		print_err("Chain name mismatches");
-	if (strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_TABLE),
-		   nftnl_chain_get_str(b, NFTNL_CHAIN_TABLE)) != 0)
-		print_err("Chain table mismatches");
-	if (nftnl_chain_get_u32(a, NFTNL_CHAIN_FAMILY) !=
-	    nftnl_chain_get_u32(b, NFTNL_CHAIN_FAMILY))
-		print_err("Chain family mismatches");
-	if (nftnl_chain_get_u32(a, NFTNL_CHAIN_POLICY) !=
-	    nftnl_chain_get_u32(b, NFTNL_CHAIN_POLICY))
-		print_err("Chain policy mismatches");
-	if (nftnl_chain_get_u32(a, NFTNL_CHAIN_HOOKNUM) !=
-	    nftnl_chain_get_u32(b, NFTNL_CHAIN_HOOKNUM))
-		print_err("Chain hooknum mismatches");
-	if (nftnl_chain_get_s32(a, NFTNL_CHAIN_PRIO) !=
-	    nftnl_chain_get_s32(b, NFTNL_CHAIN_PRIO))
-		print_err("Chain Prio mismatches");
-	if (nftnl_chain_get_u32(a, NFTNL_CHAIN_USE) !=
-	    nftnl_chain_get_u32(b, NFTNL_CHAIN_USE))
-		print_err("Chain use mismatches");
-	if (nftnl_chain_get_u64(a, NFTNL_CHAIN_PACKETS) !=
-	    nftnl_chain_get_u64(b, NFTNL_CHAIN_PACKETS))
-		print_err("Chain packets mismatches");
-	if (nftnl_chain_get_u64(a, NFTNL_CHAIN_BYTES) !=
-	    nftnl_chain_get_u64(b, NFTNL_CHAIN_BYTES))
-		print_err("Chain bytes mismatches");
-	if (nftnl_chain_get_u64(a, NFTNL_CHAIN_HANDLE) !=
-	    nftnl_chain_get_u64(b, NFTNL_CHAIN_HANDLE))
-		print_err("Chain handle mismatches");
-	if (strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_TYPE),
-		   nftnl_chain_get_str(b, NFTNL_CHAIN_TYPE)) != 0)
-		print_err("Chain type mismatches");
-	if (strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_DEV),
-		   nftnl_chain_get_str(b, NFTNL_CHAIN_DEV)) != 0)
-		print_err("Chain device mismatches");
+	ret = !strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_NAME),
+		      nftnl_chain_get_str(b, NFTNL_CHAIN_NAME));
+	test_ok &= test_assert(ret, "Chain name mismatches");
+
+	ret = !strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_TABLE),
+		      nftnl_chain_get_str(b, NFTNL_CHAIN_TABLE));
+	test_ok &= test_assert(ret, "Chain table mismatches");
+
+	ret = nftnl_chain_get_u32(a, NFTNL_CHAIN_FAMILY) ==
+	      nftnl_chain_get_u32(b, NFTNL_CHAIN_FAMILY);
+	test_ok &= test_assert(ret, "Chain family mismatches");
+
+	ret = nftnl_chain_get_u32(a, NFTNL_CHAIN_POLICY) ==
+	      nftnl_chain_get_u32(b, NFTNL_CHAIN_POLICY);
+	test_ok &= test_assert(ret, "Chain policy mismatches");
+
+	ret = nftnl_chain_get_u32(a, NFTNL_CHAIN_HOOKNUM) ==
+	      nftnl_chain_get_u32(b, NFTNL_CHAIN_HOOKNUM);
+	test_ok &= test_assert(ret, "Chain hooknum mismatches");
+
+	ret = nftnl_chain_get_s32(a, NFTNL_CHAIN_PRIO) ==
+	      nftnl_chain_get_s32(b, NFTNL_CHAIN_PRIO);
+	test_ok &= test_assert(ret, "Chain Prio mismatches");
+
+	ret = nftnl_chain_get_u32(a, NFTNL_CHAIN_USE) ==
+	      nftnl_chain_get_u32(b, NFTNL_CHAIN_USE);
+	test_ok &= test_assert(ret, "Chain use mismatches");
+
+	ret = nftnl_chain_get_u64(a, NFTNL_CHAIN_PACKETS) ==
+	      nftnl_chain_get_u64(b, NFTNL_CHAIN_PACKETS);
+	test_ok &= test_assert(ret, "Chain packets mismatches");
+
+	ret = nftnl_chain_get_u64(a, NFTNL_CHAIN_BYTES) ==
+	      nftnl_chain_get_u64(b, NFTNL_CHAIN_BYTES);
+	test_ok &= test_assert(ret, "Chain bytes mismatches");
+
+	ret = nftnl_chain_get_u64(a, NFTNL_CHAIN_HANDLE) ==
+	      nftnl_chain_get_u64(b, NFTNL_CHAIN_HANDLE);
+	test_ok &= test_assert(ret, "Chain handle mismatches");
+
+	ret = !strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_TYPE),
+		      nftnl_chain_get_str(b, NFTNL_CHAIN_TYPE));
+	test_ok &= test_assert(ret, "Chain type mismatches");
+
+	ret = !strcmp(nftnl_chain_get_str(a, NFTNL_CHAIN_DEV),
+		      nftnl_chain_get_str(b, NFTNL_CHAIN_DEV));
+	test_ok &= test_assert(ret, "Chain device mismatches");
 }
 
 int main(int argc, char *argv[])
@@ -63,6 +76,8 @@ int main(int argc, char *argv[])
 	struct nftnl_chain *a, *b;
 	char buf[4096];
 	struct nlmsghdr *nlh;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_chain_alloc();
 	b = nftnl_chain_alloc();
@@ -87,14 +102,14 @@ int main(int argc, char *argv[])
 					0, 1234);
 	nftnl_chain_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_chain_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_chain_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	cmp_nftnl_chain(a, b);
 
 	nftnl_chain_free(a);
 	nftnl_chain_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 
 }
diff --git a/tests/nft-expr_bitwise-test.c b/tests/nft-expr_bitwise-test.c
index 1eff343..8f6781f 100644
--- a/tests/nft-expr_bitwise-test.c
+++ b/tests/nft-expr_bitwise-test.c
@@ -31,6 +31,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr *rule_a, *rule_b = NULL;
 	uint32_t mask = 0x01010101;
 	uint32_t xor = 0x12345678;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -50,8 +52,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -63,17 +65,16 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_byteorder-test.c b/tests/nft-expr_byteorder-test.c
index 1f77ea7..29df7a6 100644
--- a/tests/nft-expr_byteorder-test.c
+++ b/tests/nft-expr_byteorder-test.c
@@ -29,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -48,8 +50,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -61,16 +63,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_cmp-test.c b/tests/nft-expr_cmp-test.c
index 90c78b0..e8cd90b 100644
--- a/tests/nft-expr_cmp-test.c
+++ b/tests/nft-expr_cmp-test.c
@@ -30,6 +30,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
 	uint32_t data_len = 0x01010101;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -47,8 +49,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -59,16 +61,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_counter-test.c b/tests/nft-expr_counter-test.c
index d784a11..a6cb95d 100644
--- a/tests/nft-expr_counter-test.c
+++ b/tests/nft-expr_counter-test.c
@@ -30,6 +30,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -46,8 +48,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -58,16 +60,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_ct-test.c b/tests/nft-expr_ct-test.c
index 936803e..55f6d52 100644
--- a/tests/nft-expr_ct-test.c
+++ b/tests/nft-expr_ct-test.c
@@ -29,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -46,8 +48,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -59,16 +61,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_dup-test.c b/tests/nft-expr_dup-test.c
index 9c24764..4c90b41 100644
--- a/tests/nft-expr_dup-test.c
+++ b/tests/nft-expr_dup-test.c
@@ -29,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -45,8 +47,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -58,16 +60,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_exthdr-test.c b/tests/nft-expr_exthdr-test.c
index 82c442e..26642c3 100644
--- a/tests/nft-expr_exthdr-test.c
+++ b/tests/nft-expr_exthdr-test.c
@@ -29,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -46,8 +48,8 @@ int main(int argc, char *argv[])
 
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -59,16 +61,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_fwd-test.c b/tests/nft-expr_fwd-test.c
index 3f04a3f..385ca8e 100644
--- a/tests/nft-expr_fwd-test.c
+++ b/tests/nft-expr_fwd-test.c
@@ -29,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -44,8 +46,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -57,16 +59,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_immediate-test.c b/tests/nft-expr_immediate-test.c
index 763eb0f..8987677 100644
--- a/tests/nft-expr_immediate-test.c
+++ b/tests/nft-expr_immediate-test.c
@@ -31,6 +31,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr *rule_a, *rule_b;
 	char *chain = "tests_chain01234";
 	char *data = "test_data_01234";
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -54,8 +56,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -67,23 +69,22 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
 	rule_a = nftnl_expr_iter_next(iter_a);
 	rule_b = nftnl_expr_iter_next(iter_b);
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 2 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 2 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_limit-test.c b/tests/nft-expr_limit-test.c
index bcdd357..a5cb137 100644
--- a/tests/nft-expr_limit-test.c
+++ b/tests/nft-expr_limit-test.c
@@ -30,6 +30,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -49,8 +51,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -62,16 +64,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_log-test.c b/tests/nft-expr_log-test.c
index aad71b5..7dbbf34 100644
--- a/tests/nft-expr_log-test.c
+++ b/tests/nft-expr_log-test.c
@@ -29,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -46,8 +48,8 @@ int main(int argc, char *argv[])
 
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -58,16 +60,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_lookup-test.c b/tests/nft-expr_lookup-test.c
index dcbbcdb..537adfd 100644
--- a/tests/nft-expr_lookup-test.c
+++ b/tests/nft-expr_lookup-test.c
@@ -31,6 +31,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
 	char *lookup_set = "test_set_01243";
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -49,8 +51,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -61,16 +63,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_masq-test.c b/tests/nft-expr_masq-test.c
index 8b7cfc7..b93fc27 100644
--- a/tests/nft-expr_masq-test.c
+++ b/tests/nft-expr_masq-test.c
@@ -27,6 +27,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -44,8 +46,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -57,16 +59,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_match-test.c b/tests/nft-expr_match-test.c
index b410bc9..78868bf 100644
--- a/tests/nft-expr_match-test.c
+++ b/tests/nft-expr_match-test.c
@@ -31,6 +31,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
 	char data[16] = "0123456789abcdef";
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -47,8 +49,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
 	oom_assert(iter_a, argv[0]);
@@ -59,16 +61,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_meta-test.c b/tests/nft-expr_meta-test.c
index 9a812b7..44fa022 100644
--- a/tests/nft-expr_meta-test.c
+++ b/tests/nft-expr_meta-test.c
@@ -29,6 +29,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -44,8 +46,8 @@ int main(int argc, char *argv[])
 
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -57,16 +59,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_nat-test.c b/tests/nft-expr_nat-test.c
index eb8e2a5..ea26e7c 100644
--- a/tests/nft-expr_nat-test.c
+++ b/tests/nft-expr_nat-test.c
@@ -30,6 +30,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -51,8 +53,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -64,16 +66,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_payload-test.c b/tests/nft-expr_payload-test.c
index 78f11ba..dc52916 100644
--- a/tests/nft-expr_payload-test.c
+++ b/tests/nft-expr_payload-test.c
@@ -30,6 +30,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -47,8 +49,8 @@ int main(int argc, char *argv[])
 
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -60,16 +62,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_queue-test.c b/tests/nft-expr_queue-test.c
index 1106766..d266882 100644
--- a/tests/nft-expr_queue-test.c
+++ b/tests/nft-expr_queue-test.c
@@ -32,6 +32,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -49,8 +51,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -62,16 +64,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_redir-test.c b/tests/nft-expr_redir-test.c
index 978f09f..ed3ff65 100644
--- a/tests/nft-expr_redir-test.c
+++ b/tests/nft-expr_redir-test.c
@@ -27,6 +27,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -44,8 +46,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("Parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "Parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -57,16 +59,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More than 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More than 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_reject-test.c b/tests/nft-expr_reject-test.c
index 0e42ae1..8edc240 100644
--- a/tests/nft-expr_reject-test.c
+++ b/tests/nft-expr_reject-test.c
@@ -30,6 +30,8 @@ int main(int argc, char *argv[])
 	char buf[4096];
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -46,8 +48,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -59,16 +61,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-expr_target-test.c b/tests/nft-expr_target-test.c
index 1c750b6..00a3c0d 100644
--- a/tests/nft-expr_target-test.c
+++ b/tests/nft-expr_target-test.c
@@ -30,6 +30,8 @@ int main(int argc, char *argv[])
 	struct nftnl_expr_iter *iter_a, *iter_b;
 	struct nftnl_expr *rule_a, *rule_b;
 	char data[16] = "0123456789abcdef";
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -47,8 +49,8 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
 	iter_a = nftnl_expr_iter_create(a);
 	iter_b = nftnl_expr_iter_create(b);
@@ -60,16 +62,15 @@ int main(int argc, char *argv[])
 	oom_assert(rule_a, argv[0]);
 	oom_assert(rule_b, argv[0]);
 
-	test_assert_expr(rule_a, rule_b);
+	test_ok &= test_assert_expr(rule_a, rule_b);
 
-	if (nftnl_expr_iter_next(iter_a) != NULL ||
-	    nftnl_expr_iter_next(iter_b) != NULL)
-		print_err("More 1 expr.");
+	ret = !nftnl_expr_iter_next(iter_a) && !nftnl_expr_iter_next(iter_b);
+	test_ok &= test_assert(ret, "More 1 expr.");
 
 	nftnl_expr_iter_destroy(iter_a);
 	nftnl_expr_iter_destroy(iter_b);
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-rule-test.c b/tests/nft-rule-test.c
index a02abbc..2479cc3 100644
--- a/tests/nft-rule-test.c
+++ b/tests/nft-rule-test.c
@@ -25,6 +25,8 @@ int main(int argc, char *argv[])
 	struct nftnl_rule *a, *b;
 	char buf[4096];
 	struct nlmsghdr *nlh;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_rule_alloc();
 	b = nftnl_rule_alloc();
@@ -34,8 +36,8 @@ int main(int argc, char *argv[])
 	udata = nftnl_udata_buf_alloc(NFT_USERDATA_MAXLEN);
 	oom_assert(udata, argv[0]);
 
-	if (!nftnl_udata_put_strz(udata, 0, "hello world"))
-		print_err("User data too big");
+	ret = nftnl_udata_put_strz(udata, 0, "hello world");
+	test_ok &= test_assert(ret, "User data too big");
 
 	nftnl_rule_set_u32(a, NFTNL_RULE_FAMILY, AF_INET);
 	nftnl_rule_set_str(a, NFTNL_RULE_TABLE, "table");
@@ -52,13 +54,13 @@ int main(int argc, char *argv[])
 	nlh = nftnl_rule_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE, AF_INET, 0, 1234);
 	nftnl_rule_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_rule_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_rule_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
-	test_assert_rule(a, b);
+	test_ok &= test_assert_rule(a, b);
 
 	nftnl_rule_free(a);
 	nftnl_rule_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-set-test.c b/tests/nft-set-test.c
index 6f9b03d..24e1c62 100644
--- a/tests/nft-set-test.c
+++ b/tests/nft-set-test.c
@@ -18,32 +18,44 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_set(struct nftnl_set *a, struct nftnl_set *b)
+static bool cmp_nftnl_set(struct nftnl_set *a, struct nftnl_set *b)
 {
-	if (strcmp(nftnl_set_get_str(a, NFTNL_SET_TABLE),
-		   nftnl_set_get_str(b, NFTNL_SET_TABLE)) != 0)
-		print_err("Set table mismatches");
-	if (strcmp(nftnl_set_get_str(a, NFTNL_SET_NAME),
-		   nftnl_set_get_str(b, NFTNL_SET_NAME)) != 0)
-		print_err("Set name mismatches");
-	if (nftnl_set_get_u32(a, NFTNL_SET_FLAGS) !=
-	    nftnl_set_get_u32(b, NFTNL_SET_FLAGS))
-		print_err("Set flags mismatches");
-	if (nftnl_set_get_u32(a, NFTNL_SET_KEY_TYPE) !=
-	    nftnl_set_get_u32(b, NFTNL_SET_KEY_TYPE))
-		print_err("Set key-type mismatches");
-	if (nftnl_set_get_u32(a, NFTNL_SET_KEY_LEN) !=
-	    nftnl_set_get_u32(b, NFTNL_SET_KEY_LEN))
-		print_err("Set key-len mismatches");
-	if (nftnl_set_get_u32(a, NFTNL_SET_DATA_TYPE) !=
-	    nftnl_set_get_u32(b, NFTNL_SET_DATA_TYPE))
-		print_err("Set data-type mismatches");
-	if (nftnl_set_get_u32(a, NFTNL_SET_DATA_LEN) !=
-	    nftnl_set_get_u32(b, NFTNL_SET_DATA_LEN))
-		print_err("Set data-len mismatches");
-	if (strcmp(nftnl_set_get_str(a, NFTNL_SET_USERDATA),
-		   nftnl_set_get_str(b, NFTNL_SET_USERDATA)) != 0)
-		print_err("Set userdata mismatches");
+	bool test_ok = true;
+	bool ret;
+
+	ret = !strcmp(nftnl_set_get_str(a, NFTNL_SET_TABLE),
+		      nftnl_set_get_str(b, NFTNL_SET_TABLE));
+	test_ok &= test_assert(ret, "Set table mismatches");
+
+	ret = !strcmp(nftnl_set_get_str(a, NFTNL_SET_NAME),
+		      nftnl_set_get_str(b, NFTNL_SET_NAME));
+	test_ok &= test_assert(ret, "Set name mismatches");
+
+	ret = nftnl_set_get_u32(a, NFTNL_SET_FLAGS) ==
+	      nftnl_set_get_u32(b, NFTNL_SET_FLAGS);
+	test_ok &= test_assert(ret, "Set flags mismatches");
+
+	ret = nftnl_set_get_u32(a, NFTNL_SET_KEY_TYPE) ==
+	      nftnl_set_get_u32(b, NFTNL_SET_KEY_TYPE);
+	test_ok &= test_assert(ret, "Set key-type mismatches");
+
+	ret = nftnl_set_get_u32(a, NFTNL_SET_KEY_LEN) ==
+	      nftnl_set_get_u32(b, NFTNL_SET_KEY_LEN);
+	test_ok &= test_assert(ret, "Set key-len mismatches");
+
+	ret = nftnl_set_get_u32(a, NFTNL_SET_DATA_TYPE) ==
+	      nftnl_set_get_u32(b, NFTNL_SET_DATA_TYPE);
+	test_ok &= test_assert(ret, "Set data-type mismatches");
+
+	ret = nftnl_set_get_u32(a, NFTNL_SET_DATA_LEN) ==
+	      nftnl_set_get_u32(b, NFTNL_SET_DATA_LEN);
+	test_ok &= test_assert(ret, "Set data-len mismatches");
+
+	ret = !strcmp(nftnl_set_get_str(a, NFTNL_SET_USERDATA),
+		    nftnl_set_get_str(b, NFTNL_SET_USERDATA));
+	test_ok &= test_assert(ret, "Set userdata mismatches");
+
+	return test_ok;
 }
 
 int main(int argc, char *argv[])
@@ -51,6 +63,8 @@ int main(int argc, char *argv[])
 	struct nftnl_set *a, *b = NULL;
 	char buf[4096];
 	struct nlmsghdr *nlh;
+	bool test_ok = true;
+	bool ret;
 
 	a = nftnl_set_alloc();
 	b = nftnl_set_alloc();
@@ -71,12 +85,12 @@ int main(int argc, char *argv[])
 	nlh = nftnl_set_nlmsg_build_hdr(buf, NFT_MSG_NEWSET, AF_INET, 0, 1234);
 	nftnl_set_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_set_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_set_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
-	cmp_nftnl_set(a,b);
+	test_ok &= cmp_nftnl_set(a,b);
 
 	nftnl_set_free(a); nftnl_set_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
diff --git a/tests/nft-table-test.c b/tests/nft-table-test.c
index 6b0418f..d53541a 100644
--- a/tests/nft-table-test.c
+++ b/tests/nft-table-test.c
@@ -18,17 +18,24 @@
 
 #include "libtest.h"
 
-static void cmp_nftnl_table(struct nftnl_table *a, struct nftnl_table *b)
+static bool cmp_nftnl_table(struct nftnl_table *a, struct nftnl_table *b)
 {
-	if (strcmp(nftnl_table_get_str(a, NFTNL_TABLE_NAME),
-		   nftnl_table_get_str(b, NFTNL_TABLE_NAME)) != 0)
-		print_err("table name mismatches");
-	if (nftnl_table_get_u32(a, NFTNL_TABLE_FLAGS) !=
-	    nftnl_table_get_u32(b, NFTNL_TABLE_FLAGS))
-		print_err("table flags mismatches");
-	if (nftnl_table_get_u32(a, NFTNL_TABLE_FAMILY) !=
-	    nftnl_table_get_u32(b, NFTNL_TABLE_FAMILY))
-		print_err("tabke family mismatches");
+	bool test_ok = true;
+	bool ret;
+
+	ret = !strcmp(nftnl_table_get_str(a, NFTNL_TABLE_NAME),
+		      nftnl_table_get_str(b, NFTNL_TABLE_NAME));
+	test_ok &= test_assert(ret, "table name mismatches");
+
+	ret = nftnl_table_get_u32(a, NFTNL_TABLE_FLAGS) ==
+	      nftnl_table_get_u32(b, NFTNL_TABLE_FLAGS);
+	test_ok &= test_assert(ret, "table flags mismatches");
+
+	ret = nftnl_table_get_u32(a, NFTNL_TABLE_FAMILY) ==
+	      nftnl_table_get_u32(b, NFTNL_TABLE_FAMILY);
+	test_ok &= test_assert(ret, "table family mismatches");
+
+	return test_ok;
 }
 
 int main(int argc, char *argv[])
@@ -38,6 +45,9 @@ int main(int argc, char *argv[])
 
 	struct nftnl_table *a = NULL;
 	struct nftnl_table *b = NULL;
+	bool test_ok = true;
+	bool ret;
+
 	a = nftnl_table_alloc();
 	b = nftnl_table_alloc();
 
@@ -53,13 +63,13 @@ int main(int argc, char *argv[])
 					1234);
 	nftnl_table_nlmsg_build_payload(nlh, a);
 
-	if (nftnl_table_nlmsg_parse(nlh, b) < 0)
-		print_err("parsing problems");
+	ret = nftnl_table_nlmsg_parse(nlh, b) >= 0;
+	test_ok &= test_assert(ret, "parsing problems");
 
-	cmp_nftnl_table(a,b);
+	test_ok &= cmp_nftnl_table(a,b);
 
 	nftnl_table_free(a);
 	nftnl_table_free(b);
 
-	return test_report(argv[0]);
+	return test_report(test_ok, argv[0]);
 }
-- 
2.8.3


^ permalink raw reply related	[flat|nested] 31+ messages in thread

* Re: [PATCH 2/3 v3 nft] tests: Use libnftnl comparators in all tests
  2016-08-16 10:30               ` [PATCH 2/3 v3 nft] tests: Use libnftnl comparators in all tests Carlos Falgueras García
@ 2016-08-16 11:58                 ` Pablo Neira Ayuso
  0 siblings, 0 replies; 31+ messages in thread
From: Pablo Neira Ayuso @ 2016-08-16 11:58 UTC (permalink / raw)
  To: Carlos Falgueras García; +Cc: netfilter-devel

On Tue, Aug 16, 2016 at 12:30:24PM +0200, Carlos Falgueras García wrote:
> Use 'nftnl_expr_cmp' and 'nftnl_rule_cmp' in all tests instead of custom
> comparator for each one. If objects differ both are printed.

Please, please. One at a time...

This depends on your previois patchset so I cannot take this patchset.
Sorry.

^ permalink raw reply	[flat|nested] 31+ messages in thread

end of thread, other threads:[~2016-08-16 11:59 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-11 13:25 [PATCH 1/2, libnftnl] tests: Consolidate printing error utilities Carlos Falgueras García
2016-08-11 13:25 ` [PATCH 2/2, libnftnl] Use libnftnl comparators in all tests Carlos Falgueras García
2016-08-11 23:32   ` Pablo Neira Ayuso
2016-08-12 20:16     ` Carlos Falgueras García
2016-08-15 12:23       ` [PATCH 1/2 v2 libnftnl] tests: Consolidate printing error utilities Carlos Falgueras García
2016-08-15 12:23         ` [PATCH 2/2 v2 libnftnl] test: Use libnftnl comparators in all tests Carlos Falgueras García
2016-08-15 12:27           ` Pablo Neira Ayuso
2016-08-16 10:30             ` [PATCH 1/3 v3 nft] tests: Consolidate printing error utilities Carlos Falgueras García
2016-08-16 10:30               ` [PATCH 2/3 v3 nft] tests: Use libnftnl comparators in all tests Carlos Falgueras García
2016-08-16 11:58                 ` Pablo Neira Ayuso
2016-08-16 10:30               ` [PATCH 3/3 v3 nft] tests: Elimine static variable 'test_ok' Carlos Falgueras García
2016-08-12 20:17     ` [PATCH 1/4, V2, libnftnl] tests: Fix segfaults due outbound access Carlos Falgueras García
2016-08-12 20:17       ` [PATCH 2/4, V2, libnftnl] tests: Fix wrong expression creation Carlos Falgueras García
2016-08-13 10:25         ` Pablo Neira Ayuso
2016-08-12 20:17       ` [PATCH 3/4, V2, libnftnl] tests: Consolidate printing error utilities Carlos Falgueras García
2016-08-12 20:17       ` [PATCH 4/4, V2, libnftnl] tests: Use libnftnl comparators in all tests Carlos Falgueras García
2016-08-13 10:12       ` [PATCH 1/4, V2, libnftnl] tests: Fix segfaults due outbound access Pablo Neira Ayuso
2016-08-13 15:25         ` Carlos Falgueras García
2016-08-15  9:12           ` Pablo Neira Ayuso
2016-08-15 10:27             ` [PATCH 1/2 libnftnl] expr: Improve bound checking in stringification functions Carlos Falgueras García
2016-08-15 10:27               ` [PATCH 2/2 libnftnl] expr: cmp: Use cmp2str() instead of directly access to array Carlos Falgueras García
2016-08-15 10:32                 ` Pablo Neira Ayuso
2016-08-15 10:51                   ` [PATCH 1/2 libnftnl] utils: Fix out of bound access in nftnl_family2str Carlos Falgueras García
2016-08-15 10:51                     ` [PATCH 2/2 libnfntl] expr: cmp: Use cmp2str() instead of directly access to array Carlos Falgueras García
2016-08-15 11:49                       ` Pablo Neira Ayuso
2016-08-15 11:03                     ` [PATCH 1/2 libnftnl] utils: Fix out of bound access in nftnl_family2str Pablo Neira Ayuso
2016-08-15 11:45                       ` Carlos Falgueras García
2016-08-15 11:46                         ` Pablo Neira Ayuso
2016-08-15 10:32               ` [PATCH 1/2 libnftnl] expr: Improve bound checking in stringification functions Pablo Neira Ayuso
2016-08-11 23:26 ` [PATCH 1/2, libnftnl] tests: Consolidate printing error utilities Pablo Neira Ayuso
2016-08-12 20:16   ` Carlos Falgueras García

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).