summaryrefslogtreecommitdiff
path: root/src/libstrongswan/tests
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstrongswan/tests')
-rw-r--r--src/libstrongswan/tests/Makefile.am3
-rw-r--r--src/libstrongswan/tests/Makefile.in27
-rw-r--r--src/libstrongswan/tests/suites/test_asn1.c4
-rw-r--r--src/libstrongswan/tests/suites/test_chunk.c12
-rw-r--r--src/libstrongswan/tests/suites/test_crypto_factory.c312
-rw-r--r--src/libstrongswan/tests/suites/test_enum.c52
-rw-r--r--src/libstrongswan/tests/suites/test_fetch_http.c84
-rw-r--r--src/libstrongswan/tests/suites/test_host.c4
-rw-r--r--src/libstrongswan/tests/suites/test_identification.c8
-rw-r--r--src/libstrongswan/tests/suites/test_settings.c435
-rw-r--r--src/libstrongswan/tests/suites/test_stream.c3
-rw-r--r--src/libstrongswan/tests/suites/test_threading.c6
-rw-r--r--src/libstrongswan/tests/suites/test_utils.c82
-rw-r--r--src/libstrongswan/tests/suites/test_watcher.c9
-rw-r--r--src/libstrongswan/tests/test_runner.c67
-rw-r--r--src/libstrongswan/tests/test_runner.h8
-rw-r--r--src/libstrongswan/tests/test_suite.c232
-rw-r--r--src/libstrongswan/tests/test_suite.h46
-rw-r--r--src/libstrongswan/tests/tests.c10
-rw-r--r--src/libstrongswan/tests/tests.h1
20 files changed, 1120 insertions, 285 deletions
diff --git a/src/libstrongswan/tests/Makefile.am b/src/libstrongswan/tests/Makefile.am
index 331a5480d..e8e8090f3 100644
--- a/src/libstrongswan/tests/Makefile.am
+++ b/src/libstrongswan/tests/Makefile.am
@@ -42,6 +42,7 @@ tests_SOURCES = tests.h tests.c \
suites/test_host.c \
suites/test_hasher.c \
suites/test_crypter.c \
+ suites/test_crypto_factory.c \
suites/test_pen.c \
suites/test_asn1.c \
suites/test_asn1_parser.c \
@@ -52,7 +53,7 @@ tests_SOURCES = tests.h tests.c \
tests_CFLAGS = \
-I$(top_srcdir)/src/libstrongswan \
-I$(top_srcdir)/src/libstrongswan/tests \
- -DPLUGINDIR=\""$(top_builddir)/src/libstrongswan/plugins\"" \
+ -DPLUGINDIR=\""$(abs_top_builddir)/src/libstrongswan/plugins\"" \
-DPLUGINS=\""${s_plugins}\"" \
@COVERAGE_CFLAGS@
diff --git a/src/libstrongswan/tests/Makefile.in b/src/libstrongswan/tests/Makefile.in
index e58831c5b..1d2d5ebd1 100644
--- a/src/libstrongswan/tests/Makefile.in
+++ b/src/libstrongswan/tests/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.13.3 from Makefile.am.
+# Makefile.in generated by automake 1.14.1 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
@@ -138,6 +138,7 @@ am_tests_OBJECTS = tests-tests.$(OBJEXT) \
suites/tests-test_host.$(OBJEXT) \
suites/tests-test_hasher.$(OBJEXT) \
suites/tests-test_crypter.$(OBJEXT) \
+ suites/tests-test_crypto_factory.$(OBJEXT) \
suites/tests-test_pen.$(OBJEXT) \
suites/tests-test_asn1.$(OBJEXT) \
suites/tests-test_asn1_parser.$(OBJEXT) \
@@ -295,6 +296,7 @@ NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
+OPENSSL_LIB = @OPENSSL_LIB@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
@@ -313,6 +315,7 @@ PERL = @PERL@
PKG_CONFIG = @PKG_CONFIG@
PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@
PKG_CONFIG_PATH = @PKG_CONFIG_PATH@
+PLUGIN_CFLAGS = @PLUGIN_CFLAGS@
PTHREADLIB = @PTHREADLIB@
PYTHON = @PYTHON@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
@@ -340,6 +343,7 @@ abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
+aikgen_plugins = @aikgen_plugins@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -431,6 +435,7 @@ srcdir = @srcdir@
starter_plugins = @starter_plugins@
strongswan_conf = @strongswan_conf@
strongswan_options = @strongswan_options@
+swanctldir = @swanctldir@
sysconfdir = @sysconfdir@
systemdsystemunitdir = @systemdsystemunitdir@
t_plugins = @t_plugins@
@@ -479,6 +484,7 @@ tests_SOURCES = tests.h tests.c \
suites/test_host.c \
suites/test_hasher.c \
suites/test_crypter.c \
+ suites/test_crypto_factory.c \
suites/test_pen.c \
suites/test_asn1.c \
suites/test_asn1_parser.c \
@@ -489,7 +495,7 @@ tests_SOURCES = tests.h tests.c \
tests_CFLAGS = \
-I$(top_srcdir)/src/libstrongswan \
-I$(top_srcdir)/src/libstrongswan/tests \
- -DPLUGINDIR=\""$(top_builddir)/src/libstrongswan/plugins\"" \
+ -DPLUGINDIR=\""$(abs_top_builddir)/src/libstrongswan/plugins\"" \
-DPLUGINS=\""${s_plugins}\"" \
@COVERAGE_CFLAGS@
@@ -613,6 +619,8 @@ suites/tests-test_hasher.$(OBJEXT): suites/$(am__dirstamp) \
suites/$(DEPDIR)/$(am__dirstamp)
suites/tests-test_crypter.$(OBJEXT): suites/$(am__dirstamp) \
suites/$(DEPDIR)/$(am__dirstamp)
+suites/tests-test_crypto_factory.$(OBJEXT): suites/$(am__dirstamp) \
+ suites/$(DEPDIR)/$(am__dirstamp)
suites/tests-test_pen.$(OBJEXT): suites/$(am__dirstamp) \
suites/$(DEPDIR)/$(am__dirstamp)
suites/tests-test_asn1.$(OBJEXT): suites/$(am__dirstamp) \
@@ -649,6 +657,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_bio_writer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_chunk.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_crypter.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_crypto_factory.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_ecdsa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_enum.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@suites/$(DEPDIR)/tests-test_enumerator.Po@am__quote@
@@ -1039,6 +1048,20 @@ suites/tests-test_crypter.obj: suites/test_crypter.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_crypter.obj `if test -f 'suites/test_crypter.c'; then $(CYGPATH_W) 'suites/test_crypter.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_crypter.c'; fi`
+suites/tests-test_crypto_factory.o: suites/test_crypto_factory.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_crypto_factory.o -MD -MP -MF suites/$(DEPDIR)/tests-test_crypto_factory.Tpo -c -o suites/tests-test_crypto_factory.o `test -f 'suites/test_crypto_factory.c' || echo '$(srcdir)/'`suites/test_crypto_factory.c
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_crypto_factory.Tpo suites/$(DEPDIR)/tests-test_crypto_factory.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_crypto_factory.c' object='suites/tests-test_crypto_factory.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_crypto_factory.o `test -f 'suites/test_crypto_factory.c' || echo '$(srcdir)/'`suites/test_crypto_factory.c
+
+suites/tests-test_crypto_factory.obj: suites/test_crypto_factory.c
+@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_crypto_factory.obj -MD -MP -MF suites/$(DEPDIR)/tests-test_crypto_factory.Tpo -c -o suites/tests-test_crypto_factory.obj `if test -f 'suites/test_crypto_factory.c'; then $(CYGPATH_W) 'suites/test_crypto_factory.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_crypto_factory.c'; fi`
+@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_crypto_factory.Tpo suites/$(DEPDIR)/tests-test_crypto_factory.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='suites/test_crypto_factory.c' object='suites/tests-test_crypto_factory.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -c -o suites/tests-test_crypto_factory.obj `if test -f 'suites/test_crypto_factory.c'; then $(CYGPATH_W) 'suites/test_crypto_factory.c'; else $(CYGPATH_W) '$(srcdir)/suites/test_crypto_factory.c'; fi`
+
suites/tests-test_pen.o: suites/test_pen.c
@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(tests_CFLAGS) $(CFLAGS) -MT suites/tests-test_pen.o -MD -MP -MF suites/$(DEPDIR)/tests-test_pen.Tpo -c -o suites/tests-test_pen.o `test -f 'suites/test_pen.c' || echo '$(srcdir)/'`suites/test_pen.c
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) suites/$(DEPDIR)/tests-test_pen.Tpo suites/$(DEPDIR)/tests-test_pen.Po
diff --git a/src/libstrongswan/tests/suites/test_asn1.c b/src/libstrongswan/tests/suites/test_asn1.c
index d0cd7e6e4..ac7c5519e 100644
--- a/src/libstrongswan/tests/suites/test_asn1.c
+++ b/src/libstrongswan/tests/suites/test_asn1.c
@@ -335,8 +335,8 @@ START_TEST(test_asn1_length)
/* largest chunk on 32 bit system */
a = chunk_from_chars(0x04, 0x84, 0xff, 0xff, 0xff, 0xf9, 0xaa);
- a.len = 4294967295;
- ck_assert(asn1_length(&a) == 4294967289);
+ a.len = 4294967295U;
+ ck_assert(asn1_length(&a) == 4294967289U);
}
END_TEST
diff --git a/src/libstrongswan/tests/suites/test_chunk.c b/src/libstrongswan/tests/suites/test_chunk.c
index 34ace2894..b33d70ec7 100644
--- a/src/libstrongswan/tests/suites/test_chunk.c
+++ b/src/libstrongswan/tests/suites/test_chunk.c
@@ -790,7 +790,11 @@ END_TEST
START_TEST(test_chunk_map)
{
chunk_t *map, contents = chunk_from_chars(0x01,0x02,0x03,0x04,0x05);
+#ifdef WIN32
+ char *path = "C:\\Windows\\Temp\\strongswan-chunk-map-test";
+#else
char *path = "/tmp/strongswan-chunk-map-test";
+#endif
ck_assert(chunk_write(contents, path, 022, TRUE));
@@ -827,7 +831,11 @@ END_TEST
START_TEST(test_chunk_from_fd_file)
{
chunk_t in, contents = chunk_from_chars(0x01,0x02,0x03,0x04,0x05);
+#ifdef WIN32
+ char *path = "C:\\Windows\\Temp\\strongswan-chunk-fd-test";
+#else
char *path = "/tmp/strongswan-chunk-fd-test";
+#endif
int fd;
ck_assert(chunk_write(contents, path, 022, TRUE));
@@ -849,7 +857,7 @@ START_TEST(test_chunk_from_fd_skt)
int s[2];
ck_assert(socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0);
- ck_assert(write(s[1], contents.ptr, contents.len) == contents.len);
+ ck_assert_int_eq(send(s[1], contents.ptr, contents.len, 0), contents.len);
close(s[1]);
ck_assert_msg(chunk_from_fd(s[0], &in), "%s", strerror(errno));
close(s[0]);
@@ -866,7 +874,7 @@ void *chunk_from_fd_run(void *data)
for (i = 0; i < FROM_FD_COUNT; i++)
{
- ck_assert(write(fd, &i, sizeof(i)) == sizeof(i));
+ ck_assert(send(fd, &i, sizeof(i), 0) == sizeof(i));
}
close(fd);
return NULL;
diff --git a/src/libstrongswan/tests/suites/test_crypto_factory.c b/src/libstrongswan/tests/suites/test_crypto_factory.c
new file mode 100644
index 000000000..94f45dada
--- /dev/null
+++ b/src/libstrongswan/tests/suites/test_crypto_factory.c
@@ -0,0 +1,312 @@
+/*
+ * Copyright (C) 2014 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+#include "test_suite.h"
+
+#include <crypto/crypto_factory.h>
+
+static rng_t *rng_create(rng_quality_t quality)
+{
+ rng_quality_t *q = malloc_thing(rng_quality_t);
+ *q = quality;
+ return (rng_t*)q;
+}
+
+static rng_t *rng_create_weak(rng_quality_t quality)
+{
+ ck_assert(quality == RNG_WEAK);
+ return rng_create(RNG_WEAK);
+}
+
+static rng_t *rng_create_strong(rng_quality_t quality)
+{
+ ck_assert(quality <= RNG_STRONG);
+ return rng_create(RNG_STRONG);
+}
+
+static rng_t *rng_create_true(rng_quality_t quality)
+{
+ ck_assert(quality <= RNG_TRUE);
+ return rng_create(RNG_TRUE);
+}
+
+static rng_t *rng_create_true_second(rng_quality_t quality)
+{
+ fail("should never be called");
+ return rng_create(RNG_TRUE);
+}
+
+static rng_quality_t rng_weak = RNG_WEAK;
+static rng_quality_t rng_strong = RNG_STRONG;
+static rng_quality_t rng_true = RNG_TRUE;
+
+static struct {
+ rng_quality_t *exp_weak;
+ rng_quality_t *exp_strong;
+ rng_quality_t *exp_true;
+ struct {
+ rng_quality_t *q;
+ rng_constructor_t create;
+ } data[4];
+} rng_data[] = {
+ { NULL, NULL, NULL, {
+ { NULL, NULL }
+ }},
+ { &rng_weak, NULL, NULL, {
+ { &rng_weak, rng_create_weak },
+ { NULL, NULL }
+ }},
+ { &rng_strong, &rng_strong, NULL, {
+ { &rng_strong, rng_create_strong },
+ { NULL, NULL }
+ }},
+ { &rng_true, &rng_true, &rng_true, {
+ { &rng_true, rng_create_true },
+ { NULL, NULL }
+ }},
+ { &rng_true, &rng_true, &rng_true, {
+ { &rng_true, rng_create_true },
+ { &rng_true, rng_create_true_second },
+ { NULL, NULL }
+ }},
+ { &rng_weak, &rng_true, &rng_true, {
+ { &rng_weak, rng_create_weak },
+ { &rng_true, rng_create_true },
+ { NULL, NULL }
+ }},
+ { &rng_weak, &rng_strong, &rng_true, {
+ { &rng_true, rng_create_true },
+ { &rng_strong, rng_create_strong },
+ { &rng_weak, rng_create_weak },
+ { NULL, NULL }
+ }},
+ { &rng_weak, &rng_strong, &rng_true, {
+ { &rng_weak, rng_create_weak },
+ { &rng_strong, rng_create_strong },
+ { &rng_true, rng_create_true },
+ { NULL, NULL }
+ }},
+};
+
+static void verify_rng(crypto_factory_t *factory, rng_quality_t request,
+ rng_quality_t *expected)
+{
+ rng_quality_t *res;
+
+ res = (rng_quality_t*)factory->create_rng(factory, request);
+ if (!expected)
+ {
+ ck_assert(!res);
+ }
+ else
+ {
+ ck_assert(res);
+ ck_assert_int_eq(*expected, *res);
+ free(res);
+ }
+}
+
+START_TEST(test_create_rng)
+{
+ crypto_factory_t *factory;
+ int i;
+
+ factory = crypto_factory_create();
+ for (i = 0; rng_data[_i].data[i].q; i++)
+ {
+ ck_assert(factory->add_rng(factory, *rng_data[_i].data[i].q, "test",
+ rng_data[_i].data[i].create));
+ }
+ verify_rng(factory, RNG_WEAK, rng_data[_i].exp_weak);
+ verify_rng(factory, RNG_STRONG, rng_data[_i].exp_strong);
+ verify_rng(factory, RNG_TRUE, rng_data[_i].exp_true);
+ for (i = 0; rng_data[_i].data[i].q; i++)
+ {
+ factory->remove_rng(factory, rng_data[_i].data[i].create);
+ }
+ factory->destroy(factory);
+}
+END_TEST
+
+static diffie_hellman_t *dh_create(char *plugin)
+{
+ return (diffie_hellman_t*)plugin;
+}
+
+static diffie_hellman_t *dh_create_modp1024(diffie_hellman_group_t group, ...)
+{
+ ck_assert(group == MODP_1024_BIT);
+ return dh_create("plugin1");
+}
+
+static diffie_hellman_t *dh_create_modp1024_second(diffie_hellman_group_t group,
+ ...)
+{
+ ck_assert(group == MODP_1024_BIT);
+ return dh_create("plugin2");
+}
+
+static diffie_hellman_t *dh_create_modp2048(diffie_hellman_group_t group, ...)
+{
+ ck_assert(group == MODP_2048_BIT);
+ return dh_create("plugin1");
+}
+
+static diffie_hellman_t *dh_create_modp2048_second(diffie_hellman_group_t group,
+ ...)
+{
+ ck_assert(group == MODP_2048_BIT);
+ return dh_create("plugin2");
+}
+
+static struct {
+ char *exp1024;
+ char *exp2048;
+ struct {
+ diffie_hellman_group_t g;
+ dh_constructor_t create;
+ char *plugin;
+ } data[4];
+} dh_data[] = {
+ { NULL, NULL, {
+ { MODP_NONE, NULL, NULL }
+ }},
+ { "plugin1", NULL, {
+ { MODP_1024_BIT, dh_create_modp1024, "plugin1" },
+ { MODP_NONE, NULL, NULL }
+ }},
+ { "plugin1", NULL, {
+ { MODP_1024_BIT, dh_create_modp1024, "plugin1" },
+ { MODP_1024_BIT, dh_create_modp1024_second, "plugin2" },
+ { MODP_NONE, NULL, NULL }
+ }},
+ { "plugin2", NULL, {
+ { MODP_1024_BIT, dh_create_modp1024_second, "plugin2" },
+ { MODP_1024_BIT, dh_create_modp1024, "plugin1" },
+ { MODP_NONE, NULL, NULL }
+ }},
+ { "plugin1", "plugin1", {
+ { MODP_1024_BIT, dh_create_modp1024, "plugin1" },
+ { MODP_2048_BIT, dh_create_modp2048, "plugin1" },
+ { MODP_NONE, NULL }
+ }},
+ { "plugin1", "plugin1", {
+ { MODP_2048_BIT, dh_create_modp2048, "plugin1" },
+ { MODP_1024_BIT, dh_create_modp1024, "plugin1" },
+ { MODP_NONE, NULL }
+ }},
+ { "plugin1", "plugin1", {
+ { MODP_2048_BIT, dh_create_modp2048, "plugin1" },
+ { MODP_2048_BIT, dh_create_modp2048_second, "plugin2" },
+ { MODP_1024_BIT, dh_create_modp1024, "plugin1" },
+ { MODP_NONE, NULL }
+ }},
+ { "plugin1", "plugin2", {
+ { MODP_2048_BIT, dh_create_modp2048_second, "plugin2" },
+ { MODP_2048_BIT, dh_create_modp2048, "plugin1" },
+ { MODP_1024_BIT, dh_create_modp1024, "plugin1" },
+ { MODP_NONE, NULL }
+ }},
+};
+
+static void verify_dh(crypto_factory_t *factory, diffie_hellman_group_t request,
+ char *expected)
+{
+ char *plugin;
+
+ plugin = (char*)factory->create_dh(factory, request);
+ if (!expected)
+ {
+ ck_assert(!plugin);
+ }
+ else
+ {
+ ck_assert(plugin);
+ ck_assert_str_eq(expected, plugin);
+ }
+}
+
+START_TEST(test_create_dh)
+{
+ enumerator_t *enumerator;
+ crypto_factory_t *factory;
+ diffie_hellman_group_t group;
+ char *plugin;
+ int i, len = 0;
+
+
+ factory = crypto_factory_create();
+ for (i = 0; dh_data[_i].data[i].g != MODP_NONE; i++)
+ {
+ ck_assert(factory->add_dh(factory, dh_data[_i].data[i].g,
+ dh_data[_i].data[i].plugin,
+ dh_data[_i].data[i].create));
+ }
+ verify_dh(factory, MODP_1024_BIT, dh_data[_i].exp1024);
+ verify_dh(factory, MODP_2048_BIT, dh_data[_i].exp2048);
+
+ len = countof(dh_data[_i].data);
+ enumerator = factory->create_dh_enumerator(factory);
+ for (i = 0; enumerator->enumerate(enumerator, &group, &plugin) && i < len;)
+ {
+ ck_assert_int_eq(dh_data[_i].data[i].g, group);
+ while (dh_data[_i].data[i].g == group)
+ { /* skip other entries by the same group */
+ i++;
+ }
+ switch (group)
+ {
+ case MODP_1024_BIT:
+ ck_assert(dh_data[_i].exp1024);
+ ck_assert_str_eq(dh_data[_i].exp1024, plugin);
+ break;
+ case MODP_2048_BIT:
+ ck_assert(dh_data[_i].exp2048);
+ ck_assert_str_eq(dh_data[_i].exp2048, plugin);
+ break;
+ default:
+ fail("unexpected DH group");
+ break;
+ }
+ }
+ ck_assert(!enumerator->enumerate(enumerator));
+ ck_assert_int_eq(dh_data[_i].data[i].g, MODP_NONE);
+ enumerator->destroy(enumerator);
+
+ for (i = 0; dh_data[_i].data[i].g != MODP_NONE; i++)
+ {
+ factory->remove_dh(factory, dh_data[_i].data[i].create);
+ }
+ factory->destroy(factory);
+}
+END_TEST
+
+Suite *crypto_factory_suite_create()
+{
+ Suite *s;
+ TCase *tc;
+
+ s = suite_create("crypto-factory");
+
+ tc = tcase_create("create_rng");
+ tcase_add_loop_test(tc, test_create_rng, 0, countof(rng_data));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("create_dh");
+ tcase_add_loop_test(tc, test_create_dh, 0, countof(dh_data));
+ suite_add_tcase(s, tc);
+
+ return s;
+}
diff --git a/src/libstrongswan/tests/suites/test_enum.c b/src/libstrongswan/tests/suites/test_enum.c
index 990d9cfad..b48b51c0e 100644
--- a/src/libstrongswan/tests/suites/test_enum.c
+++ b/src/libstrongswan/tests/suites/test_enum.c
@@ -15,7 +15,6 @@
#include "test_suite.h"
-#include <utils/enum.h>
#include <utils/utils.h>
/*******************************************************************************
@@ -121,41 +120,50 @@ END_TEST
*/
static struct {
+ bool found;
int val;
char *str;
} enum_tests_cont[] = {
- {CONT1, "CONT1"},
- {CONT2, "CONT2"},
- {CONT2, "CoNt2"},
- {CONT3, "CONT3"},
- {CONT4, "CONT4"},
- {CONT5, "CONT5"},
- {-1, "asdf"},
- {-1, ""},
- {-1, NULL},
+ {TRUE, CONT1, "CONT1"},
+ {TRUE, CONT2, "CONT2"},
+ {TRUE, CONT2, "CoNt2"},
+ {TRUE, CONT3, "CONT3"},
+ {TRUE, CONT4, "CONT4"},
+ {TRUE, CONT5, "CONT5"},
+ {FALSE, 0, "asdf"},
+ {FALSE, 0, ""},
+ {FALSE, 0, NULL},
}, enum_tests_split[] = {
- {SPLIT1, "SPLIT1"},
- {SPLIT1, "split1"},
- {SPLIT2, "SPLIT2"},
- {SPLIT2, "SpLiT2"},
- {SPLIT3, "SPLIT3"},
- {SPLIT4, "SPLIT4"},
- {SPLIT5, "SPLIT5"},
- {-1, "asdf"},
- {-1, ""},
- {-1, NULL},
+ {TRUE, SPLIT1, "SPLIT1"},
+ {TRUE, SPLIT1, "split1"},
+ {TRUE, SPLIT2, "SPLIT2"},
+ {TRUE, SPLIT2, "SpLiT2"},
+ {TRUE, SPLIT3, "SPLIT3"},
+ {TRUE, SPLIT4, "SPLIT4"},
+ {TRUE, SPLIT5, "SPLIT5"},
+ {FALSE, 0, "asdf"},
+ {FALSE, 0, ""},
+ {FALSE, 0, NULL},
};
START_TEST(test_enum_from_name_cont)
{
- int val = enum_from_name(test_enum_cont_names, enum_tests_cont[_i].str);
+ int val = 0;
+ bool found;
+
+ found = enum_from_name(test_enum_cont_names, enum_tests_cont[_i].str, &val);
+ ck_assert(enum_tests_cont[_i].found == found);
ck_assert_int_eq(val, enum_tests_cont[_i].val);
}
END_TEST
START_TEST(test_enum_from_name_split)
{
- int val = enum_from_name(test_enum_split_names, enum_tests_split[_i].str);
+ int val = 0;
+ bool found;
+
+ found = enum_from_name(test_enum_split_names, enum_tests_split[_i].str, &val);
+ ck_assert(enum_tests_split[_i].found == found);
ck_assert_int_eq(val, enum_tests_split[_i].val);
}
END_TEST
diff --git a/src/libstrongswan/tests/suites/test_fetch_http.c b/src/libstrongswan/tests/suites/test_fetch_http.c
index 8749ff375..9f1eef2f3 100644
--- a/src/libstrongswan/tests/suites/test_fetch_http.c
+++ b/src/libstrongswan/tests/suites/test_fetch_http.c
@@ -18,6 +18,8 @@
#include <unistd.h>
#include <time.h>
+#define HTTP_SUCCESS(status) ((status) >= 200 && (status) < 300)
+
/**
* HTTP test definition
*/
@@ -42,6 +44,8 @@ typedef struct {
void *res;
/* length of response data */
int res_len;
+ /* status code, defaults to 200 */
+ u_int code;
} test_service_t;
static char large[] = {
@@ -147,40 +151,50 @@ static bool servicing(void *data, stream_t *stream)
ck_assert(memeq(body, test->req, test->req_len));
}
+ if (!test->code)
+ {
+ test->code = 200;
+ }
+
/* response headers */
- snprintf(buf, sizeof(buf), "HTTP/1.%u 200 OK\r\n", test->minor);
+ snprintf(buf, sizeof(buf), "HTTP/1.%u %u OK\r\n", test->minor, test->code);
ck_assert(stream->write_all(stream, buf, strlen(buf)));
+
+ /* if the response code indicates an error the following write operations
+ * might fail because the client already terminated the TCP connection */
+#define may_fail(test, op) ck_assert(op || !HTTP_SUCCESS(test->code))
+
t = time(NULL);
gmtime_r(&t, &tm);
strftime(buf, sizeof(buf), "%a, %d %b %Y %T %z", &tm);
- ck_assert(stream->write_all(stream, buf, strlen(buf)));
+ may_fail(test, stream->write_all(stream, buf, strlen(buf)));
snprintf(buf, sizeof(buf), "Server: strongSwan unit test\r\n");
- ck_assert(stream->write_all(stream, buf, strlen(buf)));
+ may_fail(test, stream->write_all(stream, buf, strlen(buf)));
/* rest of response headers */
snprintf(buf, sizeof(buf), "Content-Type: text/plain\r\n");
- ck_assert(stream->write_all(stream, buf, strlen(buf)));
+ may_fail(test, stream->write_all(stream, buf, strlen(buf)));
snprintf(buf, sizeof(buf), "Content-Length: %u\r\n", test->res_len);
- ck_assert(stream->write_all(stream, buf, strlen(buf)));
+ may_fail(test, stream->write_all(stream, buf, strlen(buf)));
snprintf(buf, sizeof(buf), "Connection: close\r\n");
- ck_assert(stream->write_all(stream, buf, strlen(buf)));
+ may_fail(test, stream->write_all(stream, buf, strlen(buf)));
snprintf(buf, sizeof(buf), "\r\n");
- ck_assert(stream->write_all(stream, buf, strlen(buf)));
+ may_fail(test, stream->write_all(stream, buf, strlen(buf)));
/* response body */
- ck_assert(stream->write_all(stream, test->res, test->res_len));
+ may_fail(test, stream->write_all(stream, test->res, test->res_len));
return FALSE;
}
static test_service_t gtests[] = {
{ "GET", 1, "127.0.0.1", 6543, "/a/test/?b=c", NULL,
- NULL, 0, "\x12\x34", 2 },
+ NULL, 0, "\x12\x34", 2, 0 },
{ "GET", 0, "localhost", 6543, "/", NULL,
- NULL, 0, NULL, 0 },
+ NULL, 0, NULL, 0, 0 },
{ "GET", 0, "127.0.0.1", 6543, "/largefile", NULL,
- NULL, 0, large, sizeof(large) },
+ NULL, 0, large, sizeof(large), 0 },
{ "GET", 1, "[::1]", 6543, "/ipv6-url", NULL,
- NULL, 0, "\x00\r\n\r\x00testdatablabla", 20 },
+ NULL, 0, "\x00\r\n\r\x00testdatablabla", 20, 0 },
};
START_TEST(test_get)
@@ -215,11 +229,11 @@ END_TEST
static test_service_t ptests[] = {
{ "POST", 1, "127.0.0.1", 6543, "/a/test/?b=c", "application/binary",
- "\x23\x45", 2, "\x12\x34", 2 },
+ "\x23\x45", 2, "\x12\x34", 2, 0 },
{ "POST", 0, "localhost", 6543, "/largefile", "application/x-large",
- large, sizeof(large), large, sizeof(large) },
+ large, sizeof(large), large, sizeof(large), 0 },
{ "POST", 1, "[::1]", 6543, "/ipv6-url", "text/plain",
- "\x00\r\n\r\x00testdatablabla", 20, "\x00\r\n\r\x00testdatablabla", 20 },
+ "\x00\r\n\r\x00testdatablabla", 20, "\x00\r\n\r\x00testdatablabla", 20, 0 },
};
START_TEST(test_post)
@@ -254,6 +268,42 @@ START_TEST(test_post)
}
END_TEST
+
+static test_service_t rtests[] = {
+ { "GET", 1, "localhost", 6544, "/", NULL, NULL, 0, NULL, 0, 200 },
+ { "GET", 1, "localhost", 6544, "/", NULL, NULL, 0, NULL, 0, 204 },
+ { "GET", 1, "localhost", 6544, "/", NULL, NULL, 0, NULL, 0, 400 },
+ { "GET", 1, "localhost", 6544, "/", NULL, NULL, 0, NULL, 0, 404 },
+ { "GET", 1, "localhost", 6544, "/", NULL, NULL, 0, NULL, 0, 500 },
+};
+
+START_TEST(test_response_code)
+{
+ stream_service_t *service;
+ status_t status;
+ chunk_t data = chunk_empty;
+ char uri[256];
+ u_int code;
+
+ lib->processor->set_threads(lib->processor, 8);
+
+ snprintf(uri, sizeof(uri), "tcp://%s:%u", rtests[_i].host, rtests[_i].port);
+ service = lib->streams->create_service(lib->streams, uri, 1);
+ ck_assert(service != NULL);
+ service->on_accept(service, servicing, &rtests[_i], JOB_PRIO_HIGH, 0);
+
+ snprintf(uri, sizeof(uri), "http://%s:%u%s",
+ rtests[_i].host, rtests[_i].port, rtests[_i].path);
+ status = lib->fetcher->fetch(lib->fetcher, uri, &data,
+ FETCH_RESPONSE_CODE, &code, FETCH_END);
+ ck_assert_int_eq(status, HTTP_SUCCESS(rtests[_i].code) ? SUCCESS : FAILED);
+ ck_assert_int_eq(code, rtests[_i].code);
+ free(data.ptr);
+
+ service->destroy(service);
+}
+END_TEST
+
Suite *fetch_http_suite_create()
{
Suite *s;
@@ -269,5 +319,9 @@ Suite *fetch_http_suite_create()
tcase_add_loop_test(tc, test_post, 0, countof(ptests));
suite_add_tcase(s, tc);
+ tc = tcase_create("response code");
+ tcase_add_loop_test(tc, test_response_code, 0, countof(rtests));
+ suite_add_tcase(s, tc);
+
return s;
}
diff --git a/src/libstrongswan/tests/suites/test_host.c b/src/libstrongswan/tests/suites/test_host.c
index 30b9eb940..63442083a 100644
--- a/src/libstrongswan/tests/suites/test_host.c
+++ b/src/libstrongswan/tests/suites/test_host.c
@@ -286,8 +286,8 @@ END_TEST
START_TEST(test_create_from_sockaddr_other)
{
- struct sockaddr_un addr = {
- .sun_family = AF_UNIX,
+ struct sockaddr addr = {
+ .sa_family = AF_UNIX,
};
host_t *host;
diff --git a/src/libstrongswan/tests/suites/test_identification.c b/src/libstrongswan/tests/suites/test_identification.c
index edf53f0fd..5de785710 100644
--- a/src/libstrongswan/tests/suites/test_identification.c
+++ b/src/libstrongswan/tests/suites/test_identification.c
@@ -376,14 +376,14 @@ START_TEST(test_equals)
"C=CH, E=moon@strongswan.org, CN=moon");
ck_assert(id_equals(a, "C=CH, E=moon@strongswan.org, CN=moon"));
- ck_assert(id_equals(a, "C==CH, E==moon@strongswan.org,,, CN==moon"));
+ ck_assert(id_equals(a, "C==CH , E==moon@strongswan.org , CN==moon"));
ck_assert(id_equals(a, " C=CH, E=moon@strongswan.org, CN=moon "));
ck_assert(id_equals(a, "C=ch, E=moon@STRONGSWAN.ORG, CN=Moon"));
ck_assert(id_equals(a, "/C=CH/E=moon@strongswan.org/CN=moon"));
- ck_assert(id_equals(a, "C=CH/E=moon@strongswan.org/CN=moon"));
- ck_assert(id_equals(a, "C=CH/E=moon@strongswan.org,CN=moon"));
- ck_assert(id_equals(a, "C=CH / E=moon@strongswan.org , CN=moon"));
+ ck_assert(id_equals(a, " / C=CH / E=moon@strongswan.org / CN=moon"));
+ ck_assert(!id_equals(a, "C=CH/E=moon@strongswan.org/CN=moon"));
+ ck_assert(!id_equals(a, "C=CH/E=moon@strongswan.org,CN=moon"));
ck_assert(!id_equals(a, "C=CH E=moon@strongswan.org CN=moon"));
ck_assert(!id_equals(a, "C=CN, E=moon@strongswan.org, CN=moon"));
ck_assert(!id_equals(a, "E=moon@strongswan.org, C=CH, CN=moon"));
diff --git a/src/libstrongswan/tests/suites/test_settings.c b/src/libstrongswan/tests/suites/test_settings.c
index 096465191..b9d429a24 100644
--- a/src/libstrongswan/tests/suites/test_settings.c
+++ b/src/libstrongswan/tests/suites/test_settings.c
@@ -17,12 +17,16 @@
#include <unistd.h>
-#include <utils/settings.h>
+#include <settings/settings.h>
#include <utils/chunk.h>
#include <utils/utils.h>
#include <collections/linked_list.h>
+#ifdef WIN32
+static char *path = "C:\\Windows\\Temp\\strongswan-settings-test";
+#else
static char *path = "/tmp/strongswan-settings-test";
+#endif
static settings_t *settings;
static void create_settings(chunk_t contents)
@@ -39,6 +43,7 @@ START_SETUP(setup_base_config)
" # this gets overridden below\n"
" key2 = val2\n"
" none = \n"
+ " empty = \"\"\n"
" sub1 {\n"
" key = value\n"
" key2 = value2\n"
@@ -51,7 +56,8 @@ START_SETUP(setup_base_config)
" sub% {\n"
" id = %any\n"
" }\n"
- " key2 = with spaces\n"
+ " key2 = with space\n"
+ " key3 = \"string with\\nnewline\"\n"
"}\n"
"out = side\n"
"other {\n"
@@ -79,7 +85,9 @@ START_TEST(test_get_str)
verify_string("val1", "main.key1");
verify_string("val1", "main..key1");
verify_string("val1", ".main.key1");
- verify_string("with spaces", "main.key2");
+ verify_string("", "main.empty");
+ verify_string("with space", "main.key2");
+ verify_string("string with\nnewline", "main.key3");
verify_string("value", "main.sub1.key");
verify_string("value2", "main.sub1.key2");
verify_string("bar", "main.sub1.subsub.foo");
@@ -88,10 +96,8 @@ START_TEST(test_get_str)
verify_string("side", "out");
verify_string("other val", "other.key1");
- /* FIXME: should this rather be undefined i.e. return the default value? */
- verify_string("", "main.none");
-
- verify_null("main.key3");
+ verify_null("main.none");
+ verify_null("main.key4");
verify_null("other.sub");
}
END_TEST
@@ -125,16 +131,35 @@ START_TEST(test_get_str_printf)
* probably document it at least */
verify_null("main.%s%u.key%d", "sub", 1, 2);
- verify_null("%s.%s%d", "main", "key", 3);
+ verify_null("%s.%s%d", "main", "key", 4);
}
END_TEST
START_TEST(test_set_str)
{
+ char *val1, *val2;
+
+ val1 = settings->get_str(settings, "main.key1", NULL);
+ ck_assert_str_eq("val1", val1);
settings->set_str(settings, "main.key1", "val");
verify_string("val", "main.key1");
+ /* the pointer we got before is still valid */
+ ck_assert_str_eq("val1", val1);
+
+ val2 = settings->get_str(settings, "main.key1", NULL);
+ ck_assert_str_eq("val", val2);
settings->set_str(settings, "main.key1", "longer value");
verify_string("longer value", "main.key1");
+ /* the pointers we got before are still valid */
+ ck_assert_str_eq("val1", val1);
+ ck_assert_str_eq("val", val2);
+
+ val1 = settings->get_str(settings, "main.key1", NULL);
+ settings->set_str(settings, "main.key1", "longer value");
+ val2 = settings->get_str(settings, "main.key1", NULL);
+ /* setting the same string should should get us the same pointer */
+ ck_assert(val1 == val2);
+
settings->set_str(settings, "main", "main val");
verify_string("main val", "main");
settings->set_str(settings, "main.sub1.new", "added");
@@ -183,6 +208,7 @@ START_SETUP(setup_bool_config)
" key7 = disabled\n"
" key8 = 0\n"
" key9 = 5\n"
+ " empty = \"\"\n"
" none = \n"
" foo = bar\n"
"}"));
@@ -203,6 +229,8 @@ START_TEST(test_get_bool)
verify_bool(FALSE, TRUE, "main.key7");
verify_bool(FALSE, TRUE, "main.key8");
+ verify_bool(FALSE, FALSE, "main.empty");
+ verify_bool(TRUE, TRUE, "main.empty");
verify_bool(FALSE, FALSE, "main.none");
verify_bool(TRUE, TRUE, "main.none");
verify_bool(FALSE, FALSE, "main.foo");
@@ -237,9 +265,9 @@ START_SETUP(setup_int_config)
create_settings(chunk_from_str(
"main {\n"
" key1 = 5\n"
- " # gets cut off\n"
" key2 = 5.5\n"
" key3 = -42\n"
+ " empty = \"\"\n"
" none = \n"
" foo1 = bar\n"
" foo2 = bar13\n"
@@ -254,14 +282,14 @@ END_SETUP
START_TEST(test_get_int)
{
verify_int(5, 0, "main.key1");
- verify_int(5, 0, "main.key2");
+ verify_int(0, 0, "main.key2");
verify_int(-42, 0, "main.key3");
- /* FIXME: do we want this behavior? */
- verify_int(0, 11, "main.none");
- verify_int(0, 11, "main.foo1");
- verify_int(0, 11, "main.foo2");
- verify_int(13, 11, "main.foo3");
+ verify_int(11, 11, "main.empty");
+ verify_int(11, 11, "main.none");
+ verify_int(11, 11, "main.foo1");
+ verify_int(11, 11, "main.foo2");
+ verify_int(11, 11, "main.foo3");
verify_int(13, 13, "main.key4");
verify_int(-13, -13, "main");
@@ -291,6 +319,7 @@ START_SETUP(setup_double_config)
" key2 = 5.5\n"
" key3 = -42\n"
" key4 = -42.5\n"
+ " empty = \"\"\n"
" none = \n"
" foo1 = bar\n"
" foo2 = bar13.5\n"
@@ -309,11 +338,11 @@ START_TEST(test_get_double)
verify_double(-42, 0, "main.key3");
verify_double(-42.5, 0, "main.key4");
- /* FIXME: do we want this behavior? */
- verify_double(0, 11.5, "main.none");
- verify_double(0, 11.5, "main.foo1");
- verify_double(0, 11.5, "main.foo2");
- verify_double(13.5, 11.5, "main.foo3");
+ verify_double(11.5, 11.5, "main.empty");
+ verify_double(11.5, 11.5, "main.none");
+ verify_double(11.5, 11.5, "main.foo1");
+ verify_double(11.5, 11.5, "main.foo2");
+ verify_double(11.5, 11.5, "main.foo3");
verify_double(11.5, 11.5, "main.key5");
verify_double(-11.5, -11.5, "main");
@@ -341,10 +370,12 @@ START_SETUP(setup_time_config)
{
create_settings(chunk_from_str(
"main {\n"
+ " key0 = 5\n"
" key1 = 5s\n"
" key2 = 5m\n"
- " key3 = 5h\n"
- " key4 = 5d\n"
+ " key3 = 5 h\n"
+ " key4 = 5\td\n"
+ " empty = \"\"\n"
" none = \n"
" foo1 = bar\n"
" foo2 = bar13\n"
@@ -358,16 +389,17 @@ END_SETUP
START_TEST(test_get_time)
{
+ verify_time(5, 0, "main.key0");
verify_time(5, 0, "main.key1");
verify_time(300, 0, "main.key2");
verify_time(18000, 0, "main.key3");
verify_time(432000, 0, "main.key4");
- /* FIXME: do we want this behavior? */
- verify_time(0, 11, "main.none");
- verify_time(0, 11, "main.foo1");
- verify_time(0, 11, "main.foo2");
- verify_time(13, 11, "main.foo3");
+ verify_time(11, 11, "main.empty");
+ verify_time(11, 11, "main.none");
+ verify_time(11, 11, "main.foo1");
+ verify_time(11, 11, "main.foo2");
+ verify_time(11, 11, "main.foo3");
verify_time(11, 11, "main.key5");
verify_time(11, 11, "main");
@@ -387,37 +419,21 @@ START_TEST(test_set_time)
}
END_TEST
-static bool verify_section(linked_list_t *verifier, char *section)
-{
- enumerator_t *enumerator;
- char *current;
- bool result = FALSE;
-
- enumerator = verifier->create_enumerator(verifier);
- while (enumerator->enumerate(enumerator, &current))
- {
- if (streq(current, section))
- {
- verifier->remove_at(verifier, enumerator);
- result = TRUE;
- break;
- }
- }
- enumerator->destroy(enumerator);
- return result;
-}
-
static void verify_sections(linked_list_t *verifier, char *parent)
{
- enumerator_t *enumerator;
- char *section;
+ enumerator_t *enumerator, *ver;
+ char *section, *current;
enumerator = settings->create_section_enumerator(settings, parent);
- while (enumerator->enumerate(enumerator, &section))
+ ver = verifier->create_enumerator(verifier);
+ while (enumerator->enumerate(enumerator, &section) &&
+ ver->enumerate(ver, &current))
{
- ck_assert(verify_section(verifier, section));
+ ck_assert_str_eq(section, current);
+ verifier->remove_at(verifier, ver);
}
enumerator->destroy(enumerator);
+ ver->destroy(ver);
ck_assert_int_eq(0, verifier->get_count(verifier));
verifier->destroy(verifier);
}
@@ -429,8 +445,8 @@ START_TEST(test_section_enumerator)
verifier = linked_list_create_with_items("sub1", "sub%", NULL);
verify_sections(verifier, "main");
- settings->set_str(settings, "main.sub2.new", "added");
- verifier = linked_list_create_with_items("sub1", "sub%", "sub2", NULL);
+ settings->set_str(settings, "main.sub0.new", "added");
+ verifier = linked_list_create_with_items("sub1", "sub%", "sub0", NULL);
verify_sections(verifier, "main");
verifier = linked_list_create_with_items("subsub", NULL);
@@ -447,44 +463,27 @@ START_TEST(test_section_enumerator)
}
END_TEST
-static bool verify_key_value(linked_list_t *keys, linked_list_t *values,
- char *key, char *value)
+static void verify_key_values(linked_list_t *keys, linked_list_t *values,
+ char *parent)
{
- enumerator_t *enum_keys, *enum_values;
- char *current_key, *current_value;
- bool result = FALSE;
+ enumerator_t *enumerator, *enum_keys, *enum_values;
+ char *key, *value, *current_key, *current_value;
+ enumerator = settings->create_key_value_enumerator(settings, parent);
enum_keys = keys->create_enumerator(keys);
enum_values = values->create_enumerator(values);
- while (enum_keys->enumerate(enum_keys, &current_key) &&
+ while (enumerator->enumerate(enumerator, &key, &value) &&
+ enum_keys->enumerate(enum_keys, &current_key) &&
enum_values->enumerate(enum_values, &current_value))
{
- if (streq(current_key, key))
- {
- ck_assert_str_eq(current_value, value);
- keys->remove_at(keys, enum_keys);
- values->remove_at(values, enum_values);
- result = TRUE;
- break;
- }
+ ck_assert_str_eq(current_key, key);
+ ck_assert_str_eq(current_value, value);
+ keys->remove_at(keys, enum_keys);
+ values->remove_at(values, enum_values);
}
+ enumerator->destroy(enumerator);
enum_keys->destroy(enum_keys);
enum_values->destroy(enum_values);
- return result;
-}
-
-static void verify_key_values(linked_list_t *keys, linked_list_t *values,
- char *parent)
-{
- enumerator_t *enumerator;
- char *key, *value;
-
- enumerator = settings->create_key_value_enumerator(settings, parent);
- while (enumerator->enumerate(enumerator, &key, &value))
- {
- ck_assert(verify_key_value(keys, values, key, value));
- }
- enumerator->destroy(enumerator);
ck_assert_int_eq(0, keys->get_count(keys));
keys->destroy(keys);
values->destroy(values);
@@ -494,8 +493,8 @@ START_TEST(test_key_value_enumerator)
{
linked_list_t *keys, *values;
- keys = linked_list_create_with_items("key1", "key2", "none", NULL);
- values = linked_list_create_with_items("val1", "with spaces", "", NULL);
+ keys = linked_list_create_with_items("key1", "key2", "empty", "key3", NULL);
+ values = linked_list_create_with_items("val1", "with space", "", "string with\nnewline", NULL);
verify_key_values(keys, values, "main");
keys = linked_list_create_with_items("key", "key2", "subsub", NULL);
@@ -522,8 +521,13 @@ START_TEST(test_key_value_enumerator)
}
END_TEST
-#define include1 "/tmp/strongswan-settings-test-include1"
-#define include2 "/tmp/strongswan-settings-test-include2"
+#ifdef WIN32
+# define include1 "C:\\Windows\\Temp\\strongswan-settings-test-include1"
+# define include2 "C:\\Windows\\Temp\\strongswan-settings-test-include2"
+#else
+# define include1 "/tmp/strongswan-settings-test-include1"
+# define include2 "/tmp/strongswan-settings-test-include2"
+#endif
START_SETUP(setup_include_config)
{
@@ -531,6 +535,7 @@ START_SETUP(setup_include_config)
"main {\n"
" key1 = n1\n"
" key2 = n2\n"
+ " key3 = val3\n"
" none = \n"
" sub1 {\n"
" key3 = value\n"
@@ -563,13 +568,15 @@ static void verify_include()
{
verify_string("n1", "main.key1");
verify_string("v2", "main.key2");
- verify_string("", "main.none");
+ verify_string("val3", "main.key3");
verify_string("val", "main.sub1.key");
verify_string("v2", "main.sub1.key2");
verify_string("val", "main.sub1.sub1.key");
verify_string("value", "main.sub1.key3");
verify_string("value", "main.sub1.include");
verify_string("val3", "main.sub2.sub3");
+
+ verify_null("main.none");
}
START_TEST(test_include)
@@ -580,13 +587,13 @@ START_TEST(test_include)
" key2 = val2\n"
" none = x\n"
" sub1 {\n"
+ " include this/does/not/exist.conf\n"
" include = value\n"
" key2 = value2\n"
" include " include2 "\n"
" }\n"
"}\n"
- "# currently there must be a newline after include statements\n"
- "include " include1 "\n");
+ "include " include1);
create_settings(contents);
verify_include();
@@ -599,6 +606,7 @@ START_TEST(test_load_files)
"main {\n"
" key1 = val1\n"
" key2 = val2\n"
+ " key3 = val3\n"
" none = x\n"
" sub1 {\n"
" include = value\n"
@@ -608,7 +616,33 @@ START_TEST(test_load_files)
" }\n"
" }\n"
"}");
+ char *val1, *val2, *val3;
+
+ create_settings(contents);
+
+ val1 = settings->get_str(settings, "main.key1", NULL);
+ val2 = settings->get_str(settings, "main.sub1.key2", NULL);
+ /* loading the same file twice should not change anything, with... */
+ ck_assert(settings->load_files(settings, path, TRUE));
+ ck_assert(val1 == settings->get_str(settings, "main.key1", NULL));
+ ck_assert(val2 == settings->get_str(settings, "main.sub1.key2", NULL));
+ /* ...or without merging */
+ ck_assert(settings->load_files(settings, path, FALSE));
+ ck_assert(val1 == settings->get_str(settings, "main.key1", NULL));
+ ck_assert(val2 == settings->get_str(settings, "main.sub1.key2", NULL));
+
+ val1 = settings->get_str(settings, "main.key2", NULL);
+ val2 = settings->get_str(settings, "main.key3", NULL);
+ val3 = settings->get_str(settings, "main.none", NULL);
+ /* only pointers for modified settings should change, but still be valid */
+ ck_assert(settings->load_files(settings, include1, FALSE));
+ ck_assert(val1 != settings->get_str(settings, "main.key2", NULL));
+ ck_assert_str_eq(val1, "val2");
+ ck_assert(val2 == settings->get_str(settings, "main.key3", NULL));
+ ck_assert(val3 != settings->get_str(settings, "main.none", NULL));
+ ck_assert_str_eq(val3, "x");
+ settings->destroy(settings);
create_settings(contents);
ck_assert(settings->load_files(settings, include1, TRUE));
@@ -641,15 +675,20 @@ START_TEST(test_load_files_section)
ck_assert(settings->load_files_section(settings, include2, TRUE, "main.sub1"));
verify_include();
- /* non existing files are no failure */
- ck_assert(settings->load_files_section(settings, include1".conf", TRUE, ""));
+ /* non existing files are a failure here */
+ ck_assert(!settings->load_files_section(settings, include1".conf", TRUE, ""));
verify_include();
- /* unreadable files are */
- ck_assert(chunk_write(contents, include1".no", 0444, TRUE));
- ck_assert(!settings->load_files_section(settings, include1".no", TRUE, ""));
- unlink(include1".no");
- verify_include();
+#ifndef WIN32
+ /* unreadable files are too (only fails when not running as root) */
+ if (getuid() != 0)
+ {
+ ck_assert(chunk_write(contents, include1".no", 0444, TRUE));
+ ck_assert(!settings->load_files_section(settings, include1".no", TRUE, ""));
+ unlink(include1".no");
+ verify_include();
+ }
+#endif
ck_assert(settings->load_files_section(settings, include2, FALSE, "main"));
verify_null("main.key1");
@@ -664,6 +703,87 @@ START_TEST(test_load_files_section)
}
END_TEST
+START_TEST(test_order_kv)
+{
+ chunk_t base = chunk_from_str(
+ "main {\n"
+ " key1 = val1\n"
+ " key2 = val2\n"
+ " key3 = val3\n"
+ "}");
+ chunk_t include = chunk_from_str(
+ "main {\n"
+ " key0 = val0\n"
+ " key3 = val3\n"
+ " key1 = val1\n"
+ "}");
+ linked_list_t *keys, *values;
+
+ create_settings(base);
+ ck_assert(chunk_write(include, include1, 0022, TRUE));
+
+ keys = linked_list_create_with_items("key1", "key2", "key3", NULL);
+ values = linked_list_create_with_items("val1", "val2", "val3", NULL);
+ verify_key_values(keys, values, "main");
+
+ /* the original order is maintained if the settings are merged */
+ ck_assert(settings->load_files(settings, include1, TRUE));
+ keys = linked_list_create_with_items("key1", "key2", "key3", "key0", NULL);
+ values = linked_list_create_with_items("val1", "val2", "val3", "val0", NULL);
+ verify_key_values(keys, values, "main");
+
+ /* but the new order is adopted if the settings are replaced */
+ ck_assert(settings->load_files(settings, include1, FALSE));
+ keys = linked_list_create_with_items("key0", "key3", "key1", NULL);
+ values = linked_list_create_with_items("val0", "val3", "val1", NULL);
+ verify_key_values(keys, values, "main");
+
+ unlink(include1);
+}
+END_TEST
+
+START_TEST(test_order_section)
+{
+ chunk_t base = chunk_from_str(
+ "main {\n"
+ " sub1 {\n"
+ " }\n"
+ " sub2 {\n"
+ " }\n"
+ " sub3 {\n"
+ " }\n"
+ "}");
+ chunk_t include = chunk_from_str(
+ "main {\n"
+ " sub0 {\n"
+ " }\n"
+ " sub3 {\n"
+ " }\n"
+ " sub1 {\n"
+ " }\n"
+ "}");
+ linked_list_t *sections;
+
+ create_settings(base);
+ ck_assert(chunk_write(include, include1, 0022, TRUE));
+
+ sections = linked_list_create_with_items("sub1", "sub2", "sub3", NULL);
+ verify_sections(sections, "main");
+
+ /* the original order is maintained if the settings are merged */
+ ck_assert(settings->load_files(settings, include1, TRUE));
+ sections = linked_list_create_with_items("sub1", "sub2", "sub3", "sub0", NULL);
+ verify_sections(sections, "main");
+
+ /* but the new order is adopted if the settings are replaced */
+ ck_assert(settings->load_files(settings, include1, FALSE));
+ sections = linked_list_create_with_items("sub0", "sub3", "sub1", NULL);
+ verify_sections(sections, "main");
+
+ unlink(include1);
+}
+END_TEST
+
START_SETUP(setup_fallback_config)
{
create_settings(chunk_from_str(
@@ -781,57 +901,85 @@ START_TEST(test_add_fallback_printf)
}
END_TEST
-START_SETUP(setup_invalid_config)
+START_SETUP(setup_string_config)
{
create_settings(chunk_from_str(
- "# section without name\n"
- "{\n"
- " key1 = val1\n"
- "}\n"
- "main {\n"
- " key2 = val2\n"
- " # value without key\n"
- " = val3\n"
- " key4 = val4\n"
- " # key without value does not change it\n"
- " key4\n"
- " # subsection without name\n"
- " {\n"
- " key5 = val5\n"
- " }\n"
- " # empty include pattern\n"
- " include\n"
- " key6 = val6\n"
- "}"));
+ "string = \" with accurate\twhitespace\"\n"
+ "special = \"all { special } characters # can be used.\"\n"
+ "unterminated = \"is fine\n"
+ "but = produces a warning\n"
+ "newlines = \"can either be encoded\\nor\\\n"
+ "escaped\"\n"
+ "quotes = \"\\\"and\\\" slashes \\\\ can \\\\ be\" # escaped too\n"
+ "multiple = \"strings\" are \"combined\"\n"
+ ));
}
END_SETUP
-START_TEST(test_invalid)
+START_TEST(test_strings)
+{
+ verify_string(" with accurate\twhitespace", "string");
+ verify_string("all { special } characters # can be used.", "special");
+ verify_string("is fine", "unterminated");
+ verify_string("produces a warning", "but");
+ verify_string("can either be encoded\nor\nescaped", "newlines");
+ verify_string("\"and\" slashes \\ can \\ be", "quotes");
+ verify_string("strings are combined", "multiple");
+}
+END_TEST
+
+START_TEST(test_valid)
{
- linked_list_t *keys, *values;
chunk_t contents;
- verify_null("key1");
- verify_null(".key1");
- verify_null("%s.key1", "");
- verify_string("val2", "main.key2");
- verify_string("val4", "main.key4");
- verify_null("main..key5");
- verify_string("val6", "main.key6");
+ contents = chunk_from_str(
+ "single = value");
+ ck_assert(chunk_write(contents, path, 0022, TRUE));
+ ck_assert(settings->load_files(settings, path, FALSE));
+ verify_string("value", "single");
- keys = linked_list_create_with_items("main", NULL);
- verify_sections(keys, "");
+ contents = chunk_from_str(
+ "singleline { single = value }");
+ ck_assert(chunk_write(contents, path, 0022, TRUE));
+ ck_assert(settings->load_files(settings, path, FALSE));
+ verify_string("value", "singleline.single");
- keys = linked_list_create_with_items(NULL);
- verify_sections(keys, "main");
+ contents = chunk_from_str(
+ "singleline { sub { sub1 = val1 } single = value }");
+ ck_assert(chunk_write(contents, path, 0022, TRUE));
+ ck_assert(settings->load_files(settings, path, FALSE));
+ verify_string("val1", "singleline.sub.sub1");
- keys = linked_list_create_with_items("key2", "key4", "key6", NULL);
- values = linked_list_create_with_items("val2", "val4", "val6", NULL);
- verify_key_values(keys, values, "main");
+ contents = chunk_from_str(
+ "newline\n { single = value }");
+ ck_assert(chunk_write(contents, path, 0022, TRUE));
+ ck_assert(settings->load_files(settings, path, FALSE));
+ verify_string("value", "newline.single");
+
+ contents = chunk_from_str(
+ "section {\n"
+ " include # without pattern produces a warning, but is fine\n"
+ "}\n");
+ ck_assert(chunk_write(contents, path, 0022, TRUE));
+ ck_assert(settings->load_files(settings, path, FALSE));
+}
+END_TEST
+
+START_TEST(test_invalid)
+{
+ chunk_t contents;
+
+ contents = chunk_from_str(
+ "{\n"
+ " no = section name\n"
+ "}\n");
+ ck_assert(chunk_write(contents, path, 0022, TRUE));
+ ck_assert(!settings->load_files(settings, path, FALSE));
- /* FIXME: we should probably fix this */
contents = chunk_from_str(
- "requires = newline");
+ "no {\n"
+ " = key name\n"
+ "}\n");
ck_assert(chunk_write(contents, path, 0022, TRUE));
ck_assert(!settings->load_files(settings, path, FALSE));
@@ -842,7 +990,12 @@ START_TEST(test_invalid)
ck_assert(!settings->load_files(settings, path, FALSE));
contents = chunk_from_str(
- "singleline { not = valid }\n");
+ "spaces in name {}");
+ ck_assert(chunk_write(contents, path, 0022, TRUE));
+ ck_assert(!settings->load_files(settings, path, FALSE));
+
+ contents = chunk_from_str(
+ "only = a single setting = per line");
ck_assert(chunk_write(contents, path, 0022, TRUE));
ck_assert(!settings->load_files(settings, path, FALSE));
}
@@ -903,6 +1056,8 @@ Suite *settings_suite_create()
tcase_add_test(tc, test_include);
tcase_add_test(tc, test_load_files);
tcase_add_test(tc, test_load_files_section);
+ tcase_add_test(tc, test_order_kv);
+ tcase_add_test(tc, test_order_section);
suite_add_tcase(s, tc);
tc = tcase_create("fallback");
@@ -911,8 +1066,14 @@ Suite *settings_suite_create()
tcase_add_test(tc, test_add_fallback_printf);
suite_add_tcase(s, tc);
- tc = tcase_create("invalid data");
- tcase_add_checked_fixture(tc, setup_invalid_config, teardown_config);
+ tc = tcase_create("strings");
+ tcase_add_checked_fixture(tc, setup_string_config, teardown_config);
+ tcase_add_test(tc, test_strings);
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("valid/invalid data");
+ tcase_add_checked_fixture(tc, setup_base_config, teardown_config);
+ tcase_add_test(tc, test_valid);
tcase_add_test(tc, test_invalid);
suite_add_tcase(s, tc);
diff --git a/src/libstrongswan/tests/suites/test_stream.c b/src/libstrongswan/tests/suites/test_stream.c
index 2d3173d46..899306af2 100644
--- a/src/libstrongswan/tests/suites/test_stream.c
+++ b/src/libstrongswan/tests/suites/test_stream.c
@@ -18,7 +18,9 @@
#include <unistd.h>
static char* services[] = {
+#ifndef WIN32
"unix:///tmp/strongswan-test-service.sck",
+#endif
"tcp://127.0.0.1:7766",
"tcp://[::1]:7766",
};
@@ -121,7 +123,6 @@ START_TEST(test_async)
stream_service_t *service;
stream_t *stream;
-
lib->processor->set_threads(lib->processor, 8);
service = lib->streams->create_service(lib->streams, services[_i], 1);
diff --git a/src/libstrongswan/tests/suites/test_threading.c b/src/libstrongswan/tests/suites/test_threading.c
index 844959e46..0526d9d6e 100644
--- a/src/libstrongswan/tests/suites/test_threading.c
+++ b/src/libstrongswan/tests/suites/test_threading.c
@@ -16,7 +16,6 @@
#include "test_suite.h"
-#include <sched.h>
#include <unistd.h>
#include <threading/thread.h>
@@ -1215,6 +1214,8 @@ static void *cleanup_cancel_run(void *data)
{
thread_cancelability(FALSE);
+ barrier_wait(barrier);
+
thread_cleanup_push(cleanup3, data);
thread_cleanup_push(cleanup2, data);
thread_cleanup_push(cleanup1, data);
@@ -1234,11 +1235,13 @@ START_TEST(test_cleanup_cancel)
uintptr_t values[THREADS];
int i;
+ barrier = barrier_create(THREADS+1);
for (i = 0; i < THREADS; i++)
{
values[i] = 1;
threads[i] = thread_create(cleanup_cancel_run, &values[i]);
}
+ barrier_wait(barrier);
for (i = 0; i < THREADS; i++)
{
threads[i]->cancel(threads[i]);
@@ -1248,6 +1251,7 @@ START_TEST(test_cleanup_cancel)
threads[i]->join(threads[i]);
ck_assert_int_eq(values[i], 4);
}
+ barrier_destroy(barrier);
}
END_TEST
diff --git a/src/libstrongswan/tests/suites/test_utils.c b/src/libstrongswan/tests/suites/test_utils.c
index 0260726b2..abca4620e 100644
--- a/src/libstrongswan/tests/suites/test_utils.c
+++ b/src/libstrongswan/tests/suites/test_utils.c
@@ -508,34 +508,55 @@ START_TEST(test_strreplace)
END_TEST
/*******************************************************************************
- * path_dirname/basename
+ * path_dirname/basename/absolute
*/
static struct {
char *path;
char *dir;
char *base;
+ bool absolute;
} path_data[] = {
- {NULL, ".", "."},
- {"", ".", "."},
- {".", ".", "."},
- {"..", ".", ".."},
- {"/", "/", "/"},
- {"//", "/", "/"},
- {"foo", ".", "foo"},
- {"f/", ".", "f"},
- {"foo/", ".", "foo"},
- {"foo//", ".", "foo"},
- {"/f", "/", "f"},
- {"/f/", "/", "f"},
- {"/foo", "/", "foo"},
- {"/foo/", "/", "foo"},
- {"//foo/", "/", "foo"},
- {"foo/bar", "foo", "bar"},
- {"foo//bar", "foo", "bar"},
- {"/foo/bar", "/foo", "bar"},
- {"/foo/bar/", "/foo", "bar"},
- {"/foo/bar/baz", "/foo/bar", "baz"},
+ {NULL, ".", ".", FALSE},
+ {"", ".", ".", FALSE},
+ {".", ".", ".", FALSE},
+ {"..", ".", "..", FALSE},
+#ifdef WIN32
+ {"C:\\", "C:", "C:", TRUE},
+ {"X:\\\\", "X:", "X:", TRUE},
+ {"foo", ".", "foo", FALSE},
+ {"f\\", ".", "f", FALSE},
+ {"foo\\", ".", "foo", FALSE},
+ {"foo\\\\", ".", "foo", FALSE},
+ {"d:\\f", "d:", "f", TRUE},
+ {"C:\\f\\", "C:", "f", TRUE},
+ {"C:\\foo", "C:", "foo", TRUE},
+ {"C:\\foo\\", "C:", "foo", TRUE},
+ {"foo\\bar", "foo", "bar", FALSE},
+ {"foo\\\\bar", "foo", "bar", FALSE},
+ {"C:\\foo\\bar", "C:\\foo", "bar", TRUE},
+ {"C:\\foo\\bar\\", "C:\\foo", "bar", TRUE},
+ {"C:\\foo\\bar\\baz", "C:\\foo\\bar", "baz", TRUE},
+ {"\\foo\\bar", "\\foo", "bar", FALSE},
+ {"\\\\foo\\bar", "\\\\foo", "bar", TRUE},
+#else /* !WIN32 */
+ {"/", "/", "/", TRUE},
+ {"//", "/", "/", TRUE},
+ {"foo", ".", "foo", FALSE},
+ {"f/", ".", "f", FALSE},
+ {"foo/", ".", "foo", FALSE},
+ {"foo//", ".", "foo", FALSE},
+ {"/f", "/", "f", TRUE},
+ {"/f/", "/", "f", TRUE},
+ {"/foo", "/", "foo", TRUE},
+ {"/foo/", "/", "foo", TRUE},
+ {"//foo/", "/", "foo", TRUE},
+ {"foo/bar", "foo", "bar", FALSE},
+ {"foo//bar", "foo", "bar", FALSE},
+ {"/foo/bar", "/foo", "bar", TRUE},
+ {"/foo/bar/", "/foo", "bar", TRUE},
+ {"/foo/bar/baz", "/foo/bar", "baz", TRUE},
+#endif
};
START_TEST(test_path_dirname)
@@ -558,6 +579,12 @@ START_TEST(test_path_basename)
}
END_TEST
+START_TEST(test_path_absolute)
+{
+ ck_assert(path_data[_i].absolute == path_absolute(path_data[_i].path));
+}
+END_TEST
+
/*******************************************************************************
* time_printf_hook
*/
@@ -674,7 +701,11 @@ Suite *utils_suite_create()
TCase *tc;
/* force a timezone to match non-UTC conversions */
+#ifdef WIN32
+ _putenv("TZ=GST-1GDT");
+#else
setenv("TZ", "Europe/Zurich", 1);
+#endif
tzset();
s = suite_create("utils");
@@ -725,11 +756,18 @@ Suite *utils_suite_create()
tcase_add_loop_test(tc, test_strreplace, 0, countof(strreplace_data));
suite_add_tcase(s, tc);
- tc = tcase_create("path_dirname/basename");
+ tc = tcase_create("path_dirname");
tcase_add_loop_test(tc, test_path_dirname, 0, countof(path_data));
+ suite_add_tcase(s, tc);
+
+ tc = tcase_create("path_basename");
tcase_add_loop_test(tc, test_path_basename, 0, countof(path_data));
suite_add_tcase(s, tc);
+ tc = tcase_create("path_absolute");
+ tcase_add_loop_test(tc, test_path_absolute, 0, countof(path_data));
+ suite_add_tcase(s, tc);
+
tc = tcase_create("printf_hooks");
tcase_add_loop_test(tc, test_time_printf_hook, 0, countof(time_data));
tcase_add_loop_test(tc, test_time_delta_printf_hook, 0, countof(time_delta_data));
diff --git a/src/libstrongswan/tests/suites/test_watcher.c b/src/libstrongswan/tests/suites/test_watcher.c
index 9415bead9..11b4c3a7d 100644
--- a/src/libstrongswan/tests/suites/test_watcher.c
+++ b/src/libstrongswan/tests/suites/test_watcher.c
@@ -17,7 +17,6 @@
#include <library.h>
-#include <sched.h>
#include <unistd.h>
#include <errno.h>
@@ -48,7 +47,7 @@ START_TEST(test_read)
for (c = 'a'; c <= 'z'; c++)
{
- ck_assert_int_eq(write(fd[1], &c, 1), 1);
+ ck_assert_int_eq(send(fd[1], &c, 1, 0), 1);
while (testbuf[0] != c)
{
sched_yield();
@@ -84,7 +83,7 @@ START_TEST(test_write)
lib->watcher->add(lib->watcher, fd[1], WATCHER_WRITE, writecb, &in);
- ck_assert_int_eq(read(fd[0], &out, 1), 1);
+ ck_assert_int_eq(recv(fd[0], &out, 1, 0), 1);
ck_assert_int_eq(out, in);
lib->watcher->remove(lib->watcher, fd[1]);
@@ -123,7 +122,7 @@ START_TEST(test_multiread)
{
for (in = 'a'; in <= 'z'; in++)
{
- ck_assert_int_eq(write(fd[i][1], &in, 1), 1);
+ ck_assert_int_eq(send(fd[i][1], &in, 1, 0), 1);
while (out[i] != in)
{
sched_yield();
@@ -171,7 +170,7 @@ START_TEST(test_multiwrite)
{
for (i = 0; i < countof(fd); i++)
{
- ck_assert_int_eq(read(fd[i][0], &out, 1), 1);
+ ck_assert_int_eq(recv(fd[i][0], &out, 1, 0), 1);
ck_assert_int_eq(out, i);
}
}
diff --git a/src/libstrongswan/tests/test_runner.c b/src/libstrongswan/tests/test_runner.c
index 5ec4198e7..8f2e9855e 100644
--- a/src/libstrongswan/tests/test_runner.c
+++ b/src/libstrongswan/tests/test_runner.c
@@ -18,6 +18,7 @@
#include "test_runner.h"
#include <library.h>
+#include <threading/thread.h>
#include <plugins/plugin_feature.h>
#include <collections/array.h>
#include <utils/test.h>
@@ -26,6 +27,7 @@
#include <dirent.h>
#include <unistd.h>
#include <limits.h>
+#include <stdlib.h>
/**
* Get a tty color escape character for stderr
@@ -33,32 +35,12 @@
#define TTY(color) tty_escape_get(2, TTY_FG_##color)
/**
- * Initialize the lookup table for testable functions (defined in
- * libstrongswan). We don't use the constructor attribute as the order can't
- * really be defined (clang does not support it and gcc does not adhere to it in
- * the monolithic build). The function here is a weak symbol in libstrongswan.
+ * A global symbol indicating libtest linkage
*/
-void testable_functions_create()
-{
- if (!testable_functions)
- {
- testable_functions = hashtable_create(hashtable_hash_str,
- hashtable_equals_str, 8);
- }
-}
-
-/**
- * Destroy the lookup table for testable functions
- */
-static void testable_functions_destroy() __attribute__ ((destructor));
-static void testable_functions_destroy()
-{
- DESTROY_IF(testable_functions);
- /* if leak detective is enabled plugins are not actually unloaded, which
- * means their destructor is called AFTER this one when the process
- * terminates, make sure this does not crash */
- testable_functions = NULL;
-}
+#ifdef WIN32
+__declspec(dllexport)
+#endif
+bool test_runner_available = TRUE;
/**
* Destroy a single test suite and associated data
@@ -114,13 +96,13 @@ static void filter_suites(array_t *loaded)
* Load all available test suites, or optionally only selected ones.
*/
static array_t *load_suites(test_configuration_t configs[],
- test_runner_init_t init)
+ test_runner_init_t init, char *cfg)
{
array_t *suites;
bool old = FALSE;
int i;
- library_init(NULL, "test-runner");
+ library_init(cfg, "test-runner");
test_setup_handler();
@@ -205,11 +187,17 @@ static bool call_fixture(test_case_t *tcase, bool up)
{
if (up)
{
- fixture->setup();
+ if (fixture->setup)
+ {
+ fixture->setup();
+ }
}
else
{
- fixture->teardown();
+ if (fixture->teardown)
+ {
+ fixture->teardown();
+ }
}
}
else
@@ -226,12 +214,12 @@ static bool call_fixture(test_case_t *tcase, bool up)
/**
* Test initialization, initializes libstrongswan for the next run
*/
-static bool pre_test(test_runner_init_t init)
+static bool pre_test(test_runner_init_t init, char *cfg)
{
level_t level = LEVEL_SILENT;
char *verbosity;
- library_init(NULL, "test-runner");
+ library_init(cfg, "test-runner");
/* use non-blocking RNG to generate keys fast */
lib->settings->set_default_str(lib->settings,
@@ -371,6 +359,7 @@ static void print_failures(array_t *failures)
{
failure_t failure;
+ threads_init();
backtrace_init();
while (array_remove(failures, 0, &failure))
@@ -390,12 +379,13 @@ static void print_failures(array_t *failures)
}
backtrace_deinit();
+ threads_deinit();
}
/**
* Run a single test case with fixtures
*/
-static bool run_case(test_case_t *tcase, test_runner_init_t init)
+static bool run_case(test_case_t *tcase, test_runner_init_t init, char *cfg)
{
enumerator_t *enumerator;
test_function_t *tfun;
@@ -414,7 +404,7 @@ static bool run_case(test_case_t *tcase, test_runner_init_t init)
for (i = tfun->start; i < tfun->end; i++)
{
- if (pre_test(init))
+ if (pre_test(init, cfg))
{
bool ok = FALSE;
int leaks = 0;
@@ -483,7 +473,7 @@ static bool run_case(test_case_t *tcase, test_runner_init_t init)
/**
* Run a single test suite
*/
-static bool run_suite(test_suite_t *suite, test_runner_init_t init)
+static bool run_suite(test_suite_t *suite, test_runner_init_t init, char *cfg)
{
enumerator_t *enumerator;
test_case_t *tcase;
@@ -494,7 +484,7 @@ static bool run_suite(test_suite_t *suite, test_runner_init_t init)
enumerator = array_create_enumerator(suite->tcases);
while (enumerator->enumerate(enumerator, &tcase))
{
- if (run_case(tcase, init))
+ if (run_case(tcase, init, cfg))
{
passed++;
}
@@ -522,11 +512,14 @@ int test_runner_run(const char *name, test_configuration_t configs[],
test_suite_t *suite;
enumerator_t *enumerator;
int passed = 0, result;
+ char *cfg;
/* redirect all output to stderr (to redirect make's stdout to /dev/null) */
dup2(2, 1);
- suites = load_suites(configs, init);
+ cfg = getenv("TESTS_STRONGSWAN_CONF");
+
+ suites = load_suites(configs, init, cfg);
if (!suites)
{
return EXIT_FAILURE;
@@ -537,7 +530,7 @@ int test_runner_run(const char *name, test_configuration_t configs[],
enumerator = array_create_enumerator(suites);
while (enumerator->enumerate(enumerator, &suite))
{
- if (run_suite(suite, init))
+ if (run_suite(suite, init, cfg))
{
passed++;
}
diff --git a/src/libstrongswan/tests/test_runner.h b/src/libstrongswan/tests/test_runner.h
index 643b622e5..de87a1f0f 100644
--- a/src/libstrongswan/tests/test_runner.h
+++ b/src/libstrongswan/tests/test_runner.h
@@ -64,7 +64,13 @@ struct test_configuration_t {
/**
* Run test configuration.
*
- * The configs array must be terminated with a NULL element.
+ * The configs array must be terminated with a NULL element. The following
+ * environment variables are currently supported:
+ *
+ * - TESTS_VERBOSITY: Numerical loglevel for debug log
+ * - TESTS_STRONGSWAN_CONF: Specify a path to a custom strongswan.conf
+ * - TESTS_SUITES: Run specific test suites only
+ * - TESTS_REDUCED_KEYLENGTHS: Test minimal keylengths for public key tests only
*
* @param name name of test runner
* @param config test suite constructors with dependencies
diff --git a/src/libstrongswan/tests/test_suite.c b/src/libstrongswan/tests/test_suite.c
index fb40b05c1..00ac31830 100644
--- a/src/libstrongswan/tests/test_suite.c
+++ b/src/libstrongswan/tests/test_suite.c
@@ -18,7 +18,11 @@
#include <signal.h>
#include <unistd.h>
+#ifndef WIN32
#include <pthread.h>
+#endif
+
+#include <threading/thread.h>
/**
* Failure message buf
@@ -41,9 +45,9 @@ static int failure_line;
static backtrace_t *failure_backtrace;
/**
- * Longjump restore point when failing
+ * Flag to indicate if a worker thread failed
*/
-sigjmp_buf test_restore_point_env;
+static bool worker_failed;
/**
* See header.
@@ -119,54 +123,200 @@ void test_suite_add_case(test_suite_t *suite, test_case_t *tcase)
array_insert(suite->tcases, -1, tcase);
}
+#ifdef WIN32
+
/**
- * Main thread performing tests
+ * Longjump restore point when failing
*/
-static pthread_t main_thread;
+jmp_buf test_restore_point_env;
+
+/**
+ * Thread ID of main thread
+ */
+static DWORD main_thread;
+
+/**
+ * APC routine invoked by main thread on worker failure
+ */
+static void WINAPI set_worker_failure(ULONG_PTR dwParam)
+{
+ worker_failed = TRUE;
+}
/**
* Let test case fail
*/
-static inline void test_failure()
+static void test_failure()
{
- if (pthread_self() == main_thread)
+ if (GetCurrentThreadId() == main_thread)
{
- siglongjmp(test_restore_point_env, 1);
+ longjmp(test_restore_point_env, 1);
}
else
{
- pthread_kill(main_thread, SIGUSR1);
- /* terminate thread to prevent it from going wild */
- pthread_exit(NULL);
+ HANDLE *thread;
+
+ thread = OpenThread(THREAD_SET_CONTEXT, FALSE, main_thread);
+ if (thread)
+ {
+ QueueUserAPC(set_worker_failure, thread, (uintptr_t)NULL);
+ CloseHandle(thread);
+ }
+ thread_exit(NULL);
}
}
/**
* See header.
*/
-void test_fail_vmsg(const char *file, int line, char *fmt, va_list args)
+void test_fail_if_worker_failed()
{
- vsnprintf(failure_buf, sizeof(failure_buf), fmt, args);
- failure_line = line;
- failure_file = file;
+ if (GetCurrentThreadId() == main_thread && worker_failed)
+ {
+ test_failure();
+ }
+}
- test_failure();
+/**
+ * Vectored exception handler
+ */
+static long WINAPI eh_handler(PEXCEPTION_POINTERS ei)
+{
+ char *ename;
+ bool old = FALSE;
+
+ switch (ei->ExceptionRecord->ExceptionCode)
+ {
+ case EXCEPTION_ACCESS_VIOLATION:
+ ename = "ACCESS_VIOLATION";
+ break;
+ case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
+ ename = "ARRAY_BOUNDS_EXCEEDED";
+ break;
+ case EXCEPTION_DATATYPE_MISALIGNMENT:
+ ename = "DATATYPE_MISALIGNMENT";
+ break;
+ case EXCEPTION_FLT_DENORMAL_OPERAND:
+ ename = "FLT_DENORMAL_OPERAND";
+ break;
+ case EXCEPTION_FLT_DIVIDE_BY_ZERO:
+ ename = "FLT_DIVIDE_BY_ZERO";
+ break;
+ case EXCEPTION_FLT_INEXACT_RESULT:
+ ename = "FLT_INEXACT_RESULT";
+ break;
+ case EXCEPTION_FLT_INVALID_OPERATION:
+ ename = "FLT_INVALID_OPERATION";
+ break;
+ case EXCEPTION_FLT_OVERFLOW:
+ ename = "FLT_OVERFLOW";
+ break;
+ case EXCEPTION_FLT_STACK_CHECK:
+ ename = "FLT_STACK_CHECK";
+ break;
+ case EXCEPTION_FLT_UNDERFLOW:
+ ename = "FLT_UNDERFLOW";
+ break;
+ case EXCEPTION_ILLEGAL_INSTRUCTION:
+ ename = "ILLEGAL_INSTRUCTION";
+ break;
+ case EXCEPTION_IN_PAGE_ERROR:
+ ename = "IN_PAGE_ERROR";
+ break;
+ case EXCEPTION_INT_DIVIDE_BY_ZERO:
+ ename = "INT_DIVIDE_BY_ZERO";
+ break;
+ case EXCEPTION_INT_OVERFLOW:
+ ename = "INT_OVERFLOW";
+ break;
+ case EXCEPTION_INVALID_DISPOSITION:
+ ename = "INVALID_DISPOSITION";
+ break;
+ case EXCEPTION_NONCONTINUABLE_EXCEPTION:
+ ename = "NONCONTINUABLE_EXCEPTION";
+ break;
+ case EXCEPTION_PRIV_INSTRUCTION:
+ ename = "PRIV_INSTRUCTION";
+ break;
+ case EXCEPTION_STACK_OVERFLOW:
+ ename = "STACK_OVERFLOW";
+ break;
+ default:
+ return EXCEPTION_CONTINUE_EXECUTION;
+ }
+
+ if (lib->leak_detective)
+ {
+ old = lib->leak_detective->set_state(lib->leak_detective, FALSE);
+ }
+ failure_backtrace = backtrace_create(5);
+ if (lib->leak_detective)
+ {
+ lib->leak_detective->set_state(lib->leak_detective, old);
+ }
+ failure_line = 0;
+ test_fail_msg(NULL, 0, "%s exception", ename);
+ /* not reached */
+ return EXCEPTION_CONTINUE_EXECUTION;
}
/**
* See header.
*/
-void test_fail_msg(const char *file, int line, char *fmt, ...)
+void test_setup_handler()
{
- va_list args;
+ main_thread = GetCurrentThreadId();
+ AddVectoredExceptionHandler(0, eh_handler);
+}
- va_start(args, fmt);
- vsnprintf(failure_buf, sizeof(failure_buf), fmt, args);
- failure_line = line;
- failure_file = file;
- va_end(args);
+/**
+ * See header.
+ */
+void test_setup_timeout(int s)
+{
+ /* TODO: currently not supported. SetTimer()? */
- test_failure();
+ worker_failed = FALSE;
+}
+
+#else /* !WIN32 */
+
+/**
+ * Longjump restore point when failing
+ */
+sigjmp_buf test_restore_point_env;
+
+/**
+ * Main thread performing tests
+ */
+static pthread_t main_thread;
+
+/**
+ * Let test case fail
+ */
+static inline void test_failure()
+{
+ if (pthread_self() == main_thread)
+ {
+ siglongjmp(test_restore_point_env, 1);
+ }
+ else
+ {
+ pthread_kill(main_thread, SIGUSR1);
+ /* terminate thread to prevent it from going wild */
+ pthread_exit(NULL);
+ }
+}
+
+/**
+ * See header.
+ */
+void test_fail_if_worker_failed()
+{
+ if (pthread_self() == main_thread && worker_failed)
+ {
+ test_failure();
+ }
}
/**
@@ -180,8 +330,9 @@ static void test_sighandler(int signal)
switch (signal)
{
case SIGUSR1:
- /* a different thread failed, abort test */
- return test_failure();
+ /* a different thread failed, abort test at the next opportunity */
+ worker_failed = TRUE;
+ return;
case SIGSEGV:
signame = "SIGSEGV";
break;
@@ -251,6 +402,37 @@ void test_setup_timeout(int s)
sigaction(SIGUSR1, &action, NULL);
alarm(s);
+
+ worker_failed = FALSE;
+}
+
+#endif /* !WIN32 */
+
+/**
+ * See header.
+ */
+void test_fail_vmsg(const char *file, int line, char *fmt, va_list args)
+{
+ vsnprintf(failure_buf, sizeof(failure_buf), fmt, args);
+ failure_line = line;
+ failure_file = file;
+
+ test_failure();
+}
+/**
+ * See header.
+ */
+void test_fail_msg(const char *file, int line, char *fmt, ...)
+{
+ va_list args;
+
+ va_start(args, fmt);
+ vsnprintf(failure_buf, sizeof(failure_buf), fmt, args);
+ failure_line = line;
+ failure_file = file;
+ va_end(args);
+
+ test_failure();
}
/**
diff --git a/src/libstrongswan/tests/test_suite.h b/src/libstrongswan/tests/test_suite.h
index c44f149f5..da57ab46c 100644
--- a/src/libstrongswan/tests/test_suite.h
+++ b/src/libstrongswan/tests/test_suite.h
@@ -174,7 +174,11 @@ void test_suite_add_case(test_suite_t *suite, test_case_t *tcase);
/**
* sigjmp restore point used by test_restore_point
*/
+#ifdef WIN32
+extern jmp_buf test_restore_point_env;
+#else
extern sigjmp_buf test_restore_point_env;
+#endif
/**
* Set or return from an execution restore point
@@ -185,7 +189,11 @@ extern sigjmp_buf test_restore_point_env;
*
* @return TRUE if restore point set, FALSE when restored
*/
-#define test_restore_point() (sigsetjmp(test_restore_point_env, 1) == 0)
+#ifdef WIN32
+# define test_restore_point() (setjmp(test_restore_point_env) == 0)
+#else
+# define test_restore_point() (sigsetjmp(test_restore_point_env, 1) == 0)
+#endif
/**
* Set up signal handlers for test cases
@@ -237,6 +245,12 @@ void test_fail_vmsg(const char *file, int line, char *fmt, va_list args);
void test_fail_msg(const char *file, int line, char *fmt, ...);
/**
+ * Let a test fail if one of the worker threads has failed (only if called from
+ * the main thread).
+ */
+void test_fail_if_worker_failed();
+
+/**
* Check if two integers equal, fail test if not
*
* @param a first integer
@@ -246,6 +260,7 @@ void test_fail_msg(const char *file, int line, char *fmt, ...);
({ \
typeof(a) _a = a; \
typeof(b) _b = b; \
+ test_fail_if_worker_failed(); \
if (_a != _b) \
{ \
test_fail_msg(__FILE__, __LINE__, #a " != " #b " (%d != %d)", _a, _b); \
@@ -262,6 +277,7 @@ void test_fail_msg(const char *file, int line, char *fmt, ...);
({ \
char* _a = (char*)a; \
char* _b = (char*)b; \
+ test_fail_if_worker_failed(); \
if (!_a || !_b || !streq(_a, _b)) \
{ \
test_fail_msg(__FILE__, __LINE__, \
@@ -270,12 +286,31 @@ void test_fail_msg(const char *file, int line, char *fmt, ...);
})
/**
+ * Check if two chunks are equal, fail test if not
+ *
+ * @param a first chunk
+ * @param b second chunk
+ */
+#define test_chunk_eq(a, b) \
+({ \
+ chunk_t _a = (chunk_t)a; \
+ chunk_t _b = (chunk_t)b; \
+ test_fail_if_worker_failed(); \
+ if (_a.len != _b.len || !memeq(a.ptr, b.ptr, a.len)) \
+ { \
+ test_fail_msg(__FILE__, __LINE__, \
+ #a " != " #b " (\"%#B\" != \"%#B\")", &_a, &_b); \
+ } \
+})
+
+/**
* Check if a statement evaluates to TRUE, fail test if not
*
* @param x statement to evaluate
*/
#define test_assert(x) \
({ \
+ test_fail_if_worker_failed(); \
if (!(x)) \
{ \
test_fail_msg(__FILE__, __LINE__, #x); \
@@ -291,6 +326,7 @@ void test_fail_msg(const char *file, int line, char *fmt, ...);
*/
#define test_assert_msg(x, fmt, ...) \
({ \
+ test_fail_if_worker_failed(); \
if (!(x)) \
{ \
test_fail_msg(__FILE__, __LINE__, #x ": " fmt, ##__VA_ARGS__); \
@@ -306,9 +342,11 @@ void test_fail_msg(const char *file, int line, char *fmt, ...);
#define ck_assert test_assert
#define ck_assert_msg test_assert_msg
#define ck_assert_str_eq test_str_eq
+#define ck_assert_chunk_eq test_chunk_eq
#define fail(fmt, ...) test_fail_msg(__FILE__, __LINE__, fmt, ##__VA_ARGS__)
#define fail_if(x, fmt, ...) \
({ \
+ test_fail_if_worker_failed(); \
if (x) \
{ \
test_fail_msg(__FILE__, __LINE__, #x ": " fmt, ##__VA_ARGS__); \
@@ -323,10 +361,10 @@ void test_fail_msg(const char *file, int line, char *fmt, ...);
#define tcase_set_timeout test_case_set_timeout
#define suite_add_tcase test_suite_add_case
#define START_TEST(name) static void name (int _i) {
-#define END_TEST }
+#define END_TEST test_fail_if_worker_failed(); }
#define START_SETUP(name) static void name() {
-#define END_SETUP }
+#define END_SETUP test_fail_if_worker_failed(); }
#define START_TEARDOWN(name) static void name() {
-#define END_TEARDOWN }
+#define END_TEARDOWN test_fail_if_worker_failed(); }
#endif /** TEST_SUITE_H_ @}*/
diff --git a/src/libstrongswan/tests/tests.c b/src/libstrongswan/tests/tests.c
index 9f2adfd15..d95ddd9d5 100644
--- a/src/libstrongswan/tests/tests.c
+++ b/src/libstrongswan/tests/tests.c
@@ -35,8 +35,14 @@ static bool test_runner_init(bool init)
{
if (init)
{
- plugin_loader_add_plugindirs(PLUGINDIR, PLUGINS);
- if (!lib->plugins->load(lib->plugins, PLUGINS))
+ char *plugins, *plugindir;
+
+ plugins = lib->settings->get_str(lib->settings,
+ "tests.load", PLUGINS);
+ plugindir = lib->settings->get_str(lib->settings,
+ "tests.plugindir", PLUGINDIR);
+ plugin_loader_add_plugindirs(plugindir, plugins);
+ if (!lib->plugins->load(lib->plugins, plugins))
{
return FALSE;
}
diff --git a/src/libstrongswan/tests/tests.h b/src/libstrongswan/tests/tests.h
index 82a5137c1..ab0f642e4 100644
--- a/src/libstrongswan/tests/tests.h
+++ b/src/libstrongswan/tests/tests.h
@@ -35,6 +35,7 @@ TEST_SUITE(host_suite_create)
TEST_SUITE(printf_suite_create)
TEST_SUITE(hasher_suite_create)
TEST_SUITE(crypter_suite_create)
+TEST_SUITE(crypto_factory_suite_create)
TEST_SUITE(pen_suite_create)
TEST_SUITE(asn1_suite_create)
TEST_SUITE(asn1_parser_suite_create)