]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
Unit tests for packing/unpacking.
authorVincent Bernat <bernat@luffy.cx>
Sun, 5 Jul 2009 17:30:56 +0000 (19:30 +0200)
committerVincent Bernat <bernat@luffy.cx>
Tue, 7 Jul 2009 13:23:39 +0000 (15:23 +0200)
We build a static library liblldpd.la to ease linking to tests.
liblldpd.la is equal to lldpd except:
 - no main (but lldpd_main instead)
 - no link to netsnmp (because libtool try to link many many more
   things)

Makefile.am
configure.ac
src/Makefile.am
src/lldpd.c
src/lldpd.h
src/main.c [new file with mode: 0644]
tests/Makefile.am [new file with mode: 0644]
tests/check_pack.c [new file with mode: 0644]

index c28b8c1616021f7643b97de5d62c05bdb32a56dc..75efe649d9c7d3622cbaeced3cd4653c500e3365 100644 (file)
@@ -1,2 +1,3 @@
-SUBDIRS = src man
+ACLOCAL_AMFLAGS = -I m4
+SUBDIRS = src man tests
 dist_doc_DATA = README
index 466a7e2b755e52dfa48fb30b16b2ded4a69952bb..d74bcd011ccd0ced03c98c0ac1eb6725bc9c4afd 100644 (file)
@@ -6,10 +6,16 @@ AC_INIT(lldpd, 0.5.0, bernat@luffy.cx)
 AM_INIT_AUTOMAKE([foreign])
 AC_CONFIG_SRCDIR([src/lldpd.c])
 AC_CONFIG_HEADER([config.h])
-AC_CONFIG_FILES([Makefile src/Makefile man/Makefile])
+AC_CONFIG_FILES([Makefile src/Makefile man/Makefile tests/Makefile])
+AC_CONFIG_MACRO_DIR([m4])
 
 # Checks for programs.
 AC_PROG_CC
+AC_PROG_LIBTOOL
+
+# Unit tests
+PKG_CHECK_MODULES([CHECK], [check >= 0.9.4], have_check=yes, have_check=no)
+AM_CONDITIONAL(HAVE_CHECK, test x$have_check = xyes)
 
 # Checks for libraries.
 AC_ARG_WITH(snmp,
index 82329974d5bf5f6ec4ca69f9d3c7134f34705244..79e9d81200feb06a91db8829db61393c734c1f6c 100644 (file)
@@ -1,14 +1,19 @@
 sbin_PROGRAMS = lldpd lldpctl
+noinst_LTLIBRARIES = liblldpd.la
 
 COMMON = log.c ctl.c lldpd.h lldp.h cdp.h compat.h sonmp.h edp.h
-lldpd_SOURCES = frame.h frame.c lldpd.c lldp.c cdp.c sonmp.c edp.c interfaces.c client.c priv.c privsep_fdpass.c dmi.c $(COMMON)
+liblldpd_la_SOURCES = frame.h frame.c lldpd.c lldp.c cdp.c sonmp.c edp.c interfaces.c client.c priv.c privsep_fdpass.c dmi.c $(COMMON)
 lldpctl_SOURCES = lldpctl.c $(COMMON)
 
-lldpd_LDADD = @LIBOBJS@
+liblldpd_la_LIBADD = @LTLIBOBJS@
 lldpctl_LDADD = @LIBOBJS@
 lldpctl_CFLAGS = -DCLIENT_ONLY
 
+lldpd_SOURCES = main.c
+lldpd_LDADD = liblldpd.la
+
 if USE_SNMP
-lldpd_SOURCES += agent.c agent_priv.c
+liblldpd_la_SOURCES += agent.c agent_priv.c
 lldpd_LDADD += @NETSNMP_LIB@
 endif
+
index 63989b55a4b004ea21ca89d3ce5ca05ce6770267..20bd73b2e2e4b6c72f1506a53098e3f965e0308d 100644 (file)
@@ -724,7 +724,7 @@ lldpd_exit()
 }
 
 int
-main(int argc, char *argv[])
+lldpd_main(int argc, char *argv[])
 {
        struct lldpd *cfg;
        struct lldpd_chassis *lchassis;
index de76fa639ae72b8389bbd795ade5b5a8d0b8f599..796786c4720b42e078333ebed6f48b5ae5c3b016 100644 (file)
@@ -35,6 +35,7 @@
 #include <net/ethernet.h>
 #include <netinet/in.h>
 #include <linux/ethtool.h>
+#include <sys/un.h>
 
 #include "compat.h"
 #include "lldp.h"
@@ -344,6 +345,7 @@ void         lldpd_port_cleanup(struct lldpd_port *, int);
 void    lldpd_chassis_cleanup(struct lldpd_chassis *, int);
 int     lldpd_callback_add(struct lldpd *, int, void(*fn)(CALLBACK_SIG), void *);
 void    lldpd_callback_del(struct lldpd *, int, void(*fn)(CALLBACK_SIG));
+int     lldpd_main(int, char **);
 
 /* lldp.c */
 int     lldp_send(PROTO_SEND_SIG);
diff --git a/src/main.c b/src/main.c
new file mode 100644 (file)
index 0000000..5670e9f
--- /dev/null
@@ -0,0 +1,7 @@
+#include "lldpd.h"
+
+int
+main(int argc, char **argv)
+{
+       return lldpd_main(argc, argv);
+}
diff --git a/tests/Makefile.am b/tests/Makefile.am
new file mode 100644 (file)
index 0000000..0a8a08b
--- /dev/null
@@ -0,0 +1,16 @@
+TESTS = check_pack
+
+if HAVE_CHECK
+
+check_PROGRAMS = check_pack
+
+check_pack_SOURCES = check_pack.c \
+       $(top_builddir)/src/lldpd.h
+check_pack_CFLAGS = @CHECK_CFLAGS@
+check_pack_LDADD = $(top_builddir)/src/liblldpd.la @CHECK_LIBS@
+
+if USE_SNMP
+check_pack_LDADD += @NETSNMP_LIB@
+endif
+
+endif
diff --git a/tests/check_pack.c b/tests/check_pack.c
new file mode 100644 (file)
index 0000000..a6cc3a7
--- /dev/null
@@ -0,0 +1,542 @@
+#include <stdlib.h>
+#include <unistd.h>
+#include <check.h>
+#include <time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "../src/lldpd.h"
+
+struct hmsg *h = NULL;
+
+void
+setup()
+{
+       h = (struct hmsg *)calloc(1, MAX_HMSGSIZE);
+       fail_unless(h != NULL);
+}
+
+void teardown()
+{
+       free(h); h = NULL;
+}
+
+START_TEST (test_pack_byte)
+{
+       /* Packing a single byte */
+       char byte = 18;
+       void *p;
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_pack_structure("b", &byte, sizeof(char),
+               h, &p) != -1);
+       mark_point();
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_unpack_structure("b", &byte, sizeof(char),
+               h, &p) != -1);
+       ck_assert_int_eq(byte, 18);
+}
+END_TEST
+
+START_TEST (test_pack_word)
+{
+       /* Packing a single word */
+       u_int16_t word = 7874;
+       void *p;
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_pack_structure("w", &word, sizeof(u_int16_t),
+               h, &p) != -1);
+       mark_point();
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_unpack_structure("w", &word, sizeof(u_int16_t),
+               h, &p) != -1);
+       ck_assert_int_eq(word, 7874);
+}
+END_TEST
+
+START_TEST (test_pack_long)
+{
+       /* Packing a single long */
+       u_int32_t l = 14523657;
+       void *p;
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_pack_structure("l", &l, sizeof(u_int32_t),
+               h, &p) != -1);
+       mark_point();
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_unpack_structure("l", &l, sizeof(u_int32_t),
+               h, &p) != -1);
+       ck_assert_int_eq(l, 14523657);
+}
+END_TEST
+
+START_TEST (test_pack_time)
+{
+       /* Packing a single time_t */
+       time_t t = time(NULL);
+       time_t t2;
+       void *p;
+       t2 = t;
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_pack_structure("t", &t, sizeof(time_t),
+               h, &p) != -1);
+       mark_point();
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_unpack_structure("t", &t, sizeof(time_t),
+               h, &p) != -1);
+       ck_assert_int_eq(t, t2);
+}
+END_TEST
+
+START_TEST (test_pack_string)
+{
+       /* Packing a single string */
+       char *s = "My simple string";
+       char *rs;
+       void *p;
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_pack_structure("s", &s, sizeof(char *),
+               h, &p) != -1);
+       mark_point();
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_unpack_structure("s", &rs, sizeof(char *),
+               h, &p) != -1);
+       ck_assert_str_eq(s, rs);
+       ck_assert_str_eq(rs, "My simple string");
+       free(rs);
+}
+END_TEST
+
+START_TEST (test_pack_null_string)
+{
+       /* Packing a single empty string */
+       char *s = "";
+       char *rs;
+       void *p;
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_pack_structure("s", &s, sizeof(char *),
+               h, &p) != -1);
+       mark_point();
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_unpack_structure("s", &rs, sizeof(char *),
+               h, &p) != -1);
+       ck_assert_str_eq(s, rs);
+       ck_assert_int_eq(strlen(rs), 0);
+       free(rs);
+}
+END_TEST
+
+struct tpls {
+       char *s;
+       int l;
+};
+
+START_TEST (test_pack_len_string)
+{
+       /* Packing a single string with its length */
+       struct tpls t;
+       void *p;
+
+       t.s = "My string";
+       t.l = strlen(t.s);
+
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_pack_structure("C", &t, sizeof(struct tpls),
+               h, &p) != -1);
+       mark_point();
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_unpack_structure("C", &t, sizeof(struct tpls),
+               h, &p) != -1);
+       ck_assert_int_eq(t.l, strlen("My string"));
+       fail_unless(memcmp(t.s, "My string", t.l) == 0);
+       free(t.s);
+}
+END_TEST
+
+struct tps1 {
+       u_int8_t a;
+       u_int16_t b;
+       u_int32_t c;
+       u_int8_t d;
+       void *e;
+       u_int8_t f;
+       time_t g;
+};
+
+START_TEST (test_pack_structures1)
+{
+       /* Test padding */
+       struct tps1 t;
+       void *p;
+       t.a = 129;
+       t.b = 37814;
+       t.c = 3456781258;
+       t.d = 14;
+       t.e = &t;
+       t.f = 47;
+       t.g = 1246799447;
+
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_pack_structure("bwlbPbt", &t, sizeof(struct tps1),
+               h, &p) != -1);
+       mark_point();
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_unpack_structure("bwlbPbt", &t, sizeof(struct tps1),
+               h, &p) != -1);
+       ck_assert_int_eq(t.a, 129);
+       ck_assert_int_eq(t.b, 37814);
+       ck_assert_int_eq(t.c, 3456781258);
+       ck_assert_int_eq(t.d, 14);
+       ck_assert_int_eq(t.f, 47);
+       ck_assert_int_eq(t.g, 1246799447);
+}
+END_TEST
+
+struct tps2 {
+       u_int8_t a;
+       void *b;
+       u_int16_t c;
+       void *d;
+       u_int32_t e;
+       void *f;
+       time_t g;
+       void *h;
+       u_int8_t i;
+};
+
+START_TEST (test_pack_structures2)
+{
+       /* More padding */
+       struct tps2 t;
+       void *p;
+       t.a = 129;
+       t.c = 37814;
+       t.e = 3456781258;
+       t.g = 1246799447;
+       t.i = 12;
+
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_pack_structure("bPwPlPtPb", &t, sizeof(struct tps2),
+               h, &p) != -1);
+       mark_point();
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_unpack_structure("bPwPlPtPb", &t, sizeof(struct tps2),
+               h, &p) != -1);
+       ck_assert_int_eq(t.a, 129);
+       ck_assert_int_eq(t.c, 37814);
+       ck_assert_int_eq(t.e, 3456781258);
+       ck_assert_int_eq(t.g, 1246799447);
+       ck_assert_int_eq(t.i, 12);
+}
+END_TEST
+
+struct tps3 {
+       u_int8_t a;
+       char *b;
+       u_int16_t c;
+       char *d;
+       u_int32_t e;
+       char *f;
+       time_t g;
+       char *h;
+       u_int8_t i;
+       char *j;
+       int l;
+       u_int8_t k;
+       char *m;
+};
+
+START_TEST (test_pack_structures3)
+{
+       /* More padding, with strings */
+       struct tps3 t;
+       void *p;
+       t.a = 129;
+       t.b = "First string";
+       t.c = 37814;
+       t.d = "Second string";
+       t.e = 3456781258;
+       t.f = "Third string";
+       t.g = 1246799447;
+       t.h = "Fourth string";
+       t.i = 12;
+       t.j = "Fifth string";
+       t.l = strlen(t.j);
+       t.k = 89;
+       t.m = "Last string";
+
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_pack_structure("bswslstsbCbs", &t, sizeof(struct tps3),
+               h, &p) != -1);
+       mark_point();
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_unpack_structure("bswslstsbCbs", &t, sizeof(struct tps3),
+               h, &p) != -1);
+       ck_assert_int_eq(t.a, 129);
+       ck_assert_str_eq(t.b, "First string");
+       ck_assert_int_eq(t.c, 37814);
+       ck_assert_str_eq(t.d, "Second string");
+       ck_assert_int_eq(t.e, 3456781258);
+       ck_assert_str_eq(t.f, "Third string");
+       ck_assert_int_eq(t.g, 1246799447);
+       ck_assert_str_eq(t.h, "Fourth string");
+       ck_assert_int_eq(t.i, 12);
+       ck_assert_int_eq(t.l, strlen("Fifth string"));
+       fail_unless(memcmp(t.j, "Fifth string", t.l) == 0);
+       ck_assert_int_eq(t.k, 89);
+       ck_assert_str_eq(t.m, "Last string");
+       free(t.b); free(t.d); free(t.f); free(t.h); free(t.j); free(t.m);
+}
+END_TEST
+
+struct tps4_1 {
+       u_int8_t a;
+       u_int16_t b;
+       u_int32_t c;
+       time_t d;
+       u_int8_t e;
+       void *f;
+       u_int8_t g;
+       char *h;
+       u_int8_t i;
+};
+#define TPS41 "(bwltbPbsb)"
+
+struct tps4 {
+       u_int8_t a;
+       struct tps4_1 b;
+       u_int16_t c;
+       struct tps4_1 d;
+       u_int32_t e;
+       struct tps4_1 f;
+       void *g;
+       struct tps4_1 h;
+       struct tps4_1 i;
+       u_int8_t j;
+};
+#define TPS4 "b" TPS41 "w" TPS41 "l" TPS41 "P" TPS41 TPS41 "b"
+
+START_TEST (test_pack_structures4)
+{
+       /* More padding, with substructures */
+       struct tps4 t;
+       void *p;
+       t.a = 129;
+       t.b.a = 178;
+       t.b.b = 37894;
+       t.b.c = 345678914;
+       t.b.d = 345781741;
+       t.b.e = 74;
+       t.b.g = 78;
+       t.b.h = "First string";
+       t.b.i = 230;
+       t.c = 37814;
+       t.d.a = t.b.a + 1;
+       t.d.b = t.b.b + 1;
+       t.d.c = t.b.c + 1;
+       t.d.d = t.b.d + 1;
+       t.d.e = t.b.e + 1;
+       t.d.g = t.b.g + 1;
+       t.d.h = "Second string";
+       t.d.i = t.b.i + 1;
+       t.e = 3456781258;
+       t.f.a = t.b.a + 2;
+       t.f.b = t.b.b + 2;
+       t.f.c = t.b.c + 2;
+       t.f.d = t.b.d + 2;
+       t.f.e = t.b.e + 2;
+       t.f.g = t.b.g + 2;
+       t.f.h = "Third string";
+       t.f.i = t.b.i + 2;
+       t.h.a = t.b.a + 3;
+       t.h.b = t.b.b + 3;
+       t.h.c = t.b.c + 3;
+       t.h.d = t.b.d + 3;
+       t.h.e = t.b.e + 3;
+       t.h.g = t.b.g + 3;
+       t.h.h = "Fourth string";
+       t.h.i = t.b.i + 3;
+       t.i.a = t.b.a + 4;
+       t.i.b = t.b.b + 4;
+       t.i.c = t.b.c + 4;
+       t.i.d = t.b.d + 4;
+       t.i.e = t.b.e + 4;
+       t.i.g = t.b.g + 4;
+       t.i.h = "Fifth string";
+       t.i.i = t.b.i + 4;
+       t.j = 12;
+
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_pack_structure(TPS4, &t, sizeof(struct tps4),
+               h, &p) != -1);
+       mark_point();
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_unpack_structure(TPS4, &t, sizeof(struct tps4),
+               h, &p) != -1);
+
+       ck_assert_int_eq(t.a, 129);
+       ck_assert_int_eq(t.b.a, 178);
+       ck_assert_int_eq(t.b.b, 37894);
+       ck_assert_int_eq(t.b.c, 345678914);
+       ck_assert_int_eq(t.b.d, 345781741);
+       ck_assert_int_eq(t.b.e, 74);
+       ck_assert_int_eq(t.b.g, 78);
+       ck_assert_str_eq(t.b.h, "First string");
+       ck_assert_int_eq(t.b.i, 230);
+       ck_assert_int_eq(t.c, 37814);
+       ck_assert_int_eq(t.d.a, t.b.a + 1);
+       ck_assert_int_eq(t.d.b, t.b.b + 1);
+       ck_assert_int_eq(t.d.c, t.b.c + 1);
+       ck_assert_int_eq(t.d.d, t.b.d + 1);
+       ck_assert_int_eq(t.d.e, t.b.e + 1);
+       ck_assert_int_eq(t.d.g, t.b.g + 1);
+       ck_assert_str_eq(t.d.h, "Second string");
+       ck_assert_int_eq(t.d.i, t.b.i + 1);
+       ck_assert_int_eq(t.e, 3456781258);
+       ck_assert_int_eq(t.f.a, t.b.a + 2);
+       ck_assert_int_eq(t.f.b, t.b.b + 2);
+       ck_assert_int_eq(t.f.c, t.b.c + 2);
+       ck_assert_int_eq(t.f.d, t.b.d + 2);
+       ck_assert_int_eq(t.f.e, t.b.e + 2);
+       ck_assert_int_eq(t.f.g, t.b.g + 2);
+       ck_assert_str_eq(t.f.h, "Third string");
+       ck_assert_int_eq(t.f.i, t.b.i + 2);
+       ck_assert_int_eq(t.h.a, t.b.a + 3);
+       ck_assert_int_eq(t.h.b, t.b.b + 3);
+       ck_assert_int_eq(t.h.c, t.b.c + 3);
+       ck_assert_int_eq(t.h.d, t.b.d + 3);
+       ck_assert_int_eq(t.h.e, t.b.e + 3);
+       ck_assert_int_eq(t.h.g, t.b.g + 3);
+       fail_unless(strcmp(t.h.h, "Fourth string") == 0);
+       ck_assert_int_eq(t.h.i, t.b.i + 3);
+       ck_assert_int_eq(t.i.a, t.b.a + 4);
+       ck_assert_int_eq(t.i.b, t.b.b + 4);
+       ck_assert_int_eq(t.i.c, t.b.c + 4);
+       ck_assert_int_eq(t.i.d, t.b.d + 4);
+       ck_assert_int_eq(t.i.e, t.b.e + 4);
+       ck_assert_int_eq(t.i.g, t.b.g + 4);
+       ck_assert_str_eq(t.i.h, "Fifth string");
+       ck_assert_int_eq(t.i.i, t.b.i + 4);
+       ck_assert_int_eq(t.j, 12);
+       free(t.i.h); free(t.h.h); free(t.f.h); free(t.d.h); free(t.b.h);
+}
+END_TEST
+
+struct tps51 {
+       u_int8_t a;
+       u_int16_t b;
+       u_int32_t c;
+       u_int8_t e;
+       time_t f;
+       u_int16_t g;
+       u_int8_t h;
+       u_int32_t i;
+       u_int16_t j;
+};
+#define TPS51 "(bwlbtwblw)"
+
+struct tps52 {
+       u_int8_t a;
+       struct tps51 b;
+       u_int16_t c;
+       struct tps51 d;
+       u_int32_t e;
+       struct tps51 f;
+       struct tps51 g;
+       u_int8_t h;
+};
+#define TPS52 "(b" TPS51 "w" TPS51 "l" TPS51 TPS51 "b)"
+
+struct tps53 {
+       u_int8_t a;
+       struct tps52 b;
+       u_int16_t c;
+       struct tps52 d;
+       u_int32_t e;
+       struct tps51 f;
+       struct tps52 g;
+       u_int8_t h;
+};
+#define TPS53 "(b" TPS52 "w" TPS52 "l" TPS51 TPS52 "b)"
+
+struct tps5 {
+       u_int8_t a;
+       struct tps51 b;
+       u_int16_t c;
+       struct tps53 d;
+       u_int32_t e;
+       struct tps53 f;
+       struct tps53 g;
+       u_int8_t h;
+};
+#define TPS5 "(b" TPS51 "w" TPS53 "l" TPS53 TPS53 "b)"
+
+START_TEST (test_pack_structures5)
+{
+       /* More padding, with recursive substructures */
+       struct tps5 t;
+       struct tps5 tc;
+       int f, n;
+       void *p;
+
+       f = open("/dev/urandom", O_RDONLY);
+       fail_unless(f != -1);
+       n = read(f, &t, sizeof(struct tps5));
+       fail_unless(n == sizeof(struct tps5),
+           "Should have read %d bytes from /dev/random but got %d",
+           sizeof(struct tps5), n);
+       memcpy(&tc, &t, sizeof(struct tps5));
+       close(f);
+
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_pack_structure(TPS5, &t, sizeof(struct tps5),
+               h, &p) != -1);
+       mark_point();
+       p = (char*)&h->data;
+       fail_unless(ctl_msg_unpack_structure(TPS5, &t, sizeof(struct tps5),
+               h, &p) != -1);
+
+       fail_unless(memcmp(&t, &tc, sizeof(struct tps5)) == 0);
+}
+END_TEST
+
+Suite *
+pack_suite(void)
+{
+       Suite *s = suite_create("Packing");
+
+       /* Single objects packing/unpacking */
+       TCase *tc_core = tcase_create("Single objects");
+       tcase_add_checked_fixture(tc_core, setup, teardown);
+       tcase_add_test(tc_core, test_pack_byte);
+       tcase_add_test(tc_core, test_pack_word);
+       tcase_add_test(tc_core, test_pack_long);
+       tcase_add_test(tc_core, test_pack_time);
+       tcase_add_test(tc_core, test_pack_string);
+       tcase_add_test(tc_core, test_pack_null_string);
+       tcase_add_test(tc_core, test_pack_len_string);
+       suite_add_tcase(s, tc_core);
+
+       /* Complex structure packing/unpacking */
+       TCase *tc_structures = tcase_create("Structures");
+       tcase_add_checked_fixture(tc_structures, setup, teardown);
+       tcase_add_test(tc_structures, test_pack_structures1);
+       tcase_add_test(tc_structures, test_pack_structures2);
+       tcase_add_test(tc_structures, test_pack_structures3);
+       tcase_add_test(tc_structures, test_pack_structures4);
+       tcase_add_test(tc_structures, test_pack_structures5);
+       suite_add_tcase(s, tc_structures);
+
+       return s;
+}
+
+int
+main()
+{
+       int number_failed;
+       Suite *s = pack_suite ();
+       SRunner *sr = srunner_create (s);
+       srunner_run_all (sr, CK_ENV);
+       number_failed = srunner_ntests_failed (sr);
+       srunner_free (sr);
+       return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
+}