Merge branch 'travis-ci'
authorTobias Brunner <tobias@strongswan.org>
Thu, 20 Mar 2014 17:49:03 +0000 (18:49 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 20 Mar 2014 17:50:57 +0000 (18:50 +0100)
Adds a config file and build script for Travis CI. Makes the unit tests
buildable with Clang, and test vectors are now actually verified when
the unit tests are executed.

Also adds options to run only selected test suites and to increase the debug
level during unit tests.

The --enable/disable configure options have been reordered and grouped, and
an option to enable all the features has been added (plus an option to
select a specific printf-hook implementation).

12 files changed:
.travis.yml [new file with mode: 0644]
configure.ac
m4/macros/enable-disable.m4
scripts/test.sh [new file with mode: 0755]
src/libcharon/plugins/tnc_pdp/Makefile.am
src/libstrongswan/crypto/crypto_factory.c
src/libstrongswan/crypto/crypto_tester.c
src/libstrongswan/tests/suites/test_ntru.c
src/libstrongswan/tests/suites/test_vectors.c
src/libstrongswan/tests/test_runner.c
src/libstrongswan/utils/test.c
src/libstrongswan/utils/test.h

diff --git a/.travis.yml b/.travis.yml
new file mode 100644 (file)
index 0000000..e7b0f7e
--- /dev/null
@@ -0,0 +1,38 @@
+language: c
+
+compiler:
+  - gcc
+  - clang
+
+before_install:
+  - sudo apt-get update -qq
+  - sudo apt-get install -qq bison flex gperf gettext
+  - ./scripts/test.sh deps
+
+script:
+  - ./autogen.sh
+  - ./scripts/test.sh
+
+env:
+  global:
+    - TESTS_REDUCED_KEYLENGTHS=yes
+    - LEAK_DETECTIVE=no
+    - MONOLITHIC=no
+  matrix:
+    - TEST=default
+    - TEST=default MONOLITHIC=yes
+    - TEST=default LEAK_DETECTIVE=yes
+    - TEST=openssl
+    - TEST=openssl LEAK_DETECTIVE=yes
+    # libgcrypt can't be deinitialized so we can't test it with leak detective
+    - TEST=gcrypt
+    # we can't test Vstr as negative int args are not properly passed to CBs
+    - TEST=printf-builtin
+    - TEST=printf-builtin LEAK_DETECTIVE=yes
+    - TEST=all
+    - TEST=all MONOLITHIC=yes
+
+matrix:
+  include:
+    - compiler: gcc
+      env: TEST=dist
index e4d5bc1..568b9e2 100644 (file)
@@ -66,6 +66,7 @@ ARG_WITH_SET([tss],                  [no], [set implementation of the Trusted Co
 ARG_WITH_SET([capabilities],         [no], [set capability dropping library. Currently supported values are "libcap" and "native"])
 ARG_WITH_SET([mpz_powm_sec],         [yes], [use the more side-channel resistant mpz_powm_sec in libgmp, if available])
 ARG_WITH_SET([dev-headers],          [no], [install strongSwan development headers to directory.])
+ARG_WITH_SET([printf-hooks],         [auto], [force the use of a specific printf hook implementation (auto, builtin, glibc, vstr).])
 
 if test -n "$PKG_CONFIG"; then
        systemdsystemunitdir_default=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
@@ -118,53 +119,56 @@ AC_SUBST(ipsec_script_upper, [`echo -n "$ipsec_script" | tr a-z A-Z`])
 
 m4_include(m4/macros/enable-disable.m4)
 
-ARG_ENABL_SET([curl],           [enable CURL fetcher plugin to fetch files via libcurl. Requires libcurl.])
-ARG_ENABL_SET([unbound],        [enable UNBOUND resolver plugin to perform DNS queries via libunbound. Requires libldns and libunbound.])
-ARG_ENABL_SET([soup],           [enable soup fetcher plugin to fetch from HTTP via libsoup. Requires libsoup.])
-ARG_ENABL_SET([ldap],           [enable LDAP fetching plugin to fetch files via libldap. Requires openLDAP.])
+# crypto plugins
 ARG_DISBL_SET([aes],            [disable AES software implementation plugin.])
-ARG_DISBL_SET([des],            [disable DES/3DES software implementation plugin.])
+ARG_ENABL_SET([af-alg],         [enable AF_ALG crypto interface to Linux Crypto API.])
 ARG_ENABL_SET([blowfish],       [enable Blowfish software implementation plugin.])
-ARG_DISBL_SET([rc2],            [disable RC2 software implementation plugin.])
+ARG_ENABL_SET([ccm],            [enables the CCM AEAD wrapper crypto plugin.])
+ARG_DISBL_SET([cmac],           [disable CMAC crypto implementation plugin.])
+ARG_ENABL_SET([ctr],            [enables the Counter Mode wrapper crypto plugin.])
+ARG_DISBL_SET([des],            [disable DES/3DES software implementation plugin.])
+ARG_DISBL_SET([fips-prf],       [disable FIPS PRF software implementation plugin.])
+ARG_ENABL_SET([gcm],            [enables the GCM AEAD wrapper crypto plugin.])
+ARG_ENABL_SET([gcrypt],         [enables the libgcrypt plugin.])
+ARG_DISBL_SET([gmp],            [disable GNU MP (libgmp) based crypto implementation plugin.])
+ARG_DISBL_SET([hmac],           [disable HMAC crypto implementation plugin.])
 ARG_ENABL_SET([md4],            [enable MD4 software implementation plugin.])
 ARG_DISBL_SET([md5],            [disable MD5 software implementation plugin.])
+ARG_DISBL_SET([nonce],          [disable nonce generation plugin.])
+ARG_ENABL_SET([ntru],           [enables the NTRU crypto plugin.])
+ARG_ENABL_SET([openssl],        [enables the OpenSSL crypto plugin.])
+ARG_ENABL_SET([padlock],        [enables VIA Padlock crypto plugin.])
+ARG_DISBL_SET([random],         [disable RNG implementation on top of /dev/(u)random.])
+ARG_DISBL_SET([rc2],            [disable RC2 software implementation plugin.])
+ARG_ENABL_SET([rdrand],         [enable Intel RDRAND random generator plugin.])
 ARG_DISBL_SET([sha1],           [disable SHA1 software implementation plugin.])
 ARG_DISBL_SET([sha2],           [disable SHA256/SHA384/SHA512 software implementation plugin.])
-ARG_DISBL_SET([fips-prf],       [disable FIPS PRF software implementation plugin.])
-ARG_DISBL_SET([gmp],            [disable GNU MP (libgmp) based crypto implementation plugin.])
-ARG_ENABL_SET([rdrand],         [enable Intel RDRAND random generator plugin.])
-ARG_DISBL_SET([random],         [disable RNG implementation on top of /dev/(u)random.])
-ARG_DISBL_SET([nonce],          [disable nonce generation plugin.])
-ARG_DISBL_SET([x509],           [disable X509 certificate implementation plugin.])
-ARG_DISBL_SET([revocation],     [disable X509 CRL/OCSP revocation check plugin.])
-ARG_DISBL_SET([constraints],    [disable advanced X509 constraint checking plugin.])
-ARG_DISBL_SET([pubkey],         [disable RAW public key support plugin.])
+ARG_DISBL_SET([xcbc],           [disable xcbc crypto implementation plugin.])
+# encoding/decoding plugins
+ARG_DISBL_SET([dnskey],         [disable DNS RR key decoding plugin.])
+ARG_DISBL_SET([pem],            [disable PEM decoding plugin.])
+ARG_DISBL_SET([pgp],            [disable PGP key decoding plugin.])
 ARG_DISBL_SET([pkcs1],          [disable PKCS1 key decoding plugin.])
 ARG_DISBL_SET([pkcs7],          [disable PKCS7 container support plugin.])
 ARG_DISBL_SET([pkcs8],          [disable PKCS8 private key decoding plugin.])
 ARG_DISBL_SET([pkcs12],         [disable PKCS12 container support plugin.])
-ARG_DISBL_SET([pgp],            [disable PGP key decoding plugin.])
-ARG_DISBL_SET([dnskey],         [disable DNS RR key decoding plugin.])
+ARG_DISBL_SET([pubkey],         [disable RAW public key support plugin.])
 ARG_DISBL_SET([sshkey],         [disable SSH key decoding plugin.])
-ARG_ENABL_SET([dnscert],        [enable DNSCERT authentication plugin.])
-ARG_ENABL_SET([ipseckey],       [enable IPSECKEY authentication plugin.])
-ARG_DISBL_SET([pem],            [disable PEM decoding plugin.])
-ARG_DISBL_SET([hmac],           [disable HMAC crypto implementation plugin.])
-ARG_DISBL_SET([cmac],           [disable CMAC crypto implementation plugin.])
-ARG_DISBL_SET([xcbc],           [disable xcbc crypto implementation plugin.])
-ARG_ENABL_SET([af-alg],         [enable AF_ALG crypto interface to Linux Crypto API.])
-ARG_ENABL_SET([test-vectors],   [enable plugin providing crypto test vectors.])
+ARG_DISBL_SET([x509],           [disable X509 certificate implementation plugin.])
+# fetcher/resolver plugins
+ARG_ENABL_SET([curl],           [enable CURL fetcher plugin to fetch files via libcurl. Requires libcurl.])
+ARG_ENABL_SET([ldap],           [enable LDAP fetching plugin to fetch files via libldap. Requires openLDAP.])
+ARG_ENABL_SET([soup],           [enable soup fetcher plugin to fetch from HTTP via libsoup. Requires libsoup.])
+ARG_ENABL_SET([unbound],        [enable UNBOUND resolver plugin to perform DNS queries via libunbound. Requires libldns and libunbound.])
+# database plugins
 ARG_ENABL_SET([mysql],          [enable MySQL database support. Requires libmysqlclient_r.])
 ARG_ENABL_SET([sqlite],         [enable SQLite database support. Requires libsqlite3.])
-ARG_DISBL_SET([stroke],         [disable charons stroke configuration backend.])
-ARG_ENABL_SET([medsrv],         [enable mediation server web frontend and daemon plugin.])
-ARG_ENABL_SET([medcli],         [enable mediation client configuration database plugin.])
-ARG_ENABL_SET([smp],            [enable SMP configuration and control interface. Requires libxml.])
-ARG_ENABL_SET([sql],            [enable SQL database configuration backend.])
-ARG_ENABL_SET([leak-detective], [enable malloc hooks to find memory leaks.])
-ARG_ENABL_SET([lock-profiler],  [enable lock/mutex profiling code.])
-ARG_ENABL_SET([unit-tester],    [enable unit tests on IKEv2 daemon startup.])
-ARG_ENABL_SET([load-tester],    [enable load testing plugin for IKEv2 daemon.])
+# authentication/credential plugins
+ARG_ENABL_SET([addrblock],      [enables RFC 3779 address block constraint support.])
+ARG_ENABL_SET([agent],          [enables the ssh-agent signing plugin.])
+ARG_DISBL_SET([constraints],    [disable advanced X509 constraint checking plugin.])
+ARG_ENABL_SET([coupling],       [enable IKEv2 plugin to couple peer certificates permanently to authentication.])
+ARG_ENABL_SET([dnscert],        [enable DNSCERT authentication plugin.])
 ARG_ENABL_SET([eap-sim],        [enable SIM authentication module for EAP.])
 ARG_ENABL_SET([eap-sim-file],   [enable EAP-SIM backend based on a triplet file.])
 ARG_ENABL_SET([eap-sim-pcsc],   [enable EAP-SIM backend based on a smartcard reader. Requires libpcsclite.])
@@ -183,88 +187,97 @@ ARG_ENABL_SET([eap-peap],       [enable EAP PEAP authentication module.])
 ARG_ENABL_SET([eap-tnc],        [enable EAP TNC trusted network connect module.])
 ARG_ENABL_SET([eap-dynamic],    [enable dynamic EAP proxy module.])
 ARG_ENABL_SET([eap-radius],     [enable RADIUS proxy authentication module.])
+ARG_ENABL_SET([ipseckey],       [enable IPSECKEY authentication plugin.])
+ARG_ENABL_SET([keychain],       [enables OS X Keychain Services credential set.])
+ARG_ENABL_SET([pkcs11],         [enables the PKCS11 token support plugin.])
+ARG_DISBL_SET([revocation],     [disable X509 CRL/OCSP revocation check plugin.])
+ARG_ENABL_SET([whitelist],      [enable peer identity whitelisting plugin.])
 ARG_DISBL_SET([xauth-generic],  [disable generic XAuth backend.])
 ARG_ENABL_SET([xauth-eap],      [enable XAuth backend using EAP methods to verify passwords.])
 ARG_ENABL_SET([xauth-pam],      [enable XAuth backend using PAM to verify passwords.])
 ARG_ENABL_SET([xauth-noauth],   [enable XAuth pseudo-backend that does not actually verify or even request any credentials.])
-ARG_ENABL_SET([tnc-ifmap],      [enable TNC IF-MAP module. Requires libxml])
-ARG_ENABL_SET([tnc-pdp],        [enable TNC policy decision point module.])
-ARG_ENABL_SET([tnc-imc],        [enable TNC IMC module.])
-ARG_ENABL_SET([tnc-imv],        [enable TNC IMV module.])
-ARG_ENABL_SET([tnccs-11],       [enable TNCCS 1.1 protocol module. Requires libxml])
-ARG_ENABL_SET([tnccs-20],       [enable TNCCS 2.0 protocol module.])
-ARG_ENABL_SET([tnccs-dynamic],  [enable dynamic TNCCS protocol discovery module.])
-ARG_ENABL_SET([imc-test],       [enable IMC test module.])
-ARG_ENABL_SET([imv-test],       [enable IMV test module.])
-ARG_ENABL_SET([imc-scanner],    [enable IMC port scanner module.])
-ARG_ENABL_SET([imv-scanner],    [enable IMV port scanner module.])
-ARG_ENABL_SET([imc-os],         [enable IMC operating system module.])
-ARG_ENABL_SET([imv-os],         [enable IMV operating system module.])
-ARG_ENABL_SET([imc-attestation],[enable IMC attestation module.])
-ARG_ENABL_SET([imv-attestation],[enable IMV attestation module.])
-ARG_ENABL_SET([imc-swid],       [enable IMC swid module.])
-ARG_ENABL_SET([imv-swid],       [enable IMV swid module.])
+# kernel interfaces / sockets
 ARG_DISBL_SET([kernel-netlink], [disable the netlink kernel interface.])
 ARG_ENABL_SET([kernel-pfkey],   [enable the PF_KEY kernel interface.])
 ARG_ENABL_SET([kernel-pfroute], [enable the PF_ROUTE kernel interface.])
 ARG_ENABL_SET([kernel-klips],   [enable the KLIPS kernel interface.])
 ARG_ENABL_SET([kernel-libipsec],[enable the libipsec kernel interface.])
-ARG_ENABL_SET([libipsec],       [enable user space IPsec implementation.])
 ARG_DISBL_SET([socket-default], [disable default socket implementation for charon.])
 ARG_ENABL_SET([socket-dynamic], [enable dynamic socket implementation for charon])
-ARG_ENABL_SET([farp],           [enable ARP faking plugin that responds to ARP requests to peers virtual IP])
-ARG_ENABL_SET([dumm],           [enable the DUMM UML test framework.])
-ARG_ENABL_SET([fast],           [enable libfast (FastCGI Application Server w/ templates.])
-ARG_ENABL_SET([manager],        [enable web management console (proof of concept).])
-ARG_ENABL_SET([mediation],      [enable IKEv2 Mediation Extension.])
-ARG_ENABL_SET([integrity-test], [enable integrity testing of libstrongswan and plugins.])
-ARG_DISBL_SET([load-warning],   [disable the charon plugin load option warning in starter.])
-ARG_DISBL_SET([ikev1],          [disable IKEv1 protocol support in charon.])
-ARG_DISBL_SET([ikev2],          [disable IKEv2 protocol support in charon.])
-ARG_DISBL_SET([charon],         [disable the IKEv1/IKEv2 keying daemon charon.])
-ARG_DISBL_SET([tools],          [disable additional utilities (openac, scepclient and pki).])
-ARG_DISBL_SET([scripts],        [disable additional utilities (found in directory scripts).])
-ARG_ENABL_SET([conftest],       [enforce Suite B conformance test framework.])
-ARG_DISBL_SET([updown],         [disable updown firewall script plugin.])
+# configuration/control plugins
+ARG_DISBL_SET([stroke],         [disable charons stroke configuration backend.])
+ARG_ENABL_SET([smp],            [enable SMP configuration and control interface. Requires libxml.])
+ARG_ENABL_SET([sql],            [enable SQL database configuration backend.])
+ARG_ENABL_SET([uci],            [enable OpenWRT UCI configuration plugin.])
+# attribute provider/consumer plugins
+ARG_ENABL_SET([android-dns],    [enable Android specific DNS handler.])
 ARG_DISBL_SET([attr],           [disable strongswan.conf based configuration attribute plugin.])
 ARG_ENABL_SET([attr-sql],       [enable SQL based configuration attribute plugin.])
 ARG_ENABL_SET([dhcp],           [enable DHCP based attribute provider plugin.])
+ARG_ENABL_SET([osx-attr],       [enable OS X SystemConfiguration attribute handler.])
 ARG_DISBL_SET([resolve],        [disable resolve DNS handler plugin.])
-ARG_ENABL_SET([padlock],        [enables VIA Padlock crypto plugin.])
-ARG_ENABL_SET([openssl],        [enables the OpenSSL crypto plugin.])
-ARG_ENABL_SET([gcrypt],         [enables the libgcrypt plugin.])
-ARG_ENABL_SET([agent],          [enables the ssh-agent signing plugin.])
-ARG_ENABL_SET([keychain],       [enables OS X Keychain Services credential set.])
-ARG_ENABL_SET([pkcs11],         [enables the PKCS11 token support plugin.])
-ARG_ENABL_SET([ctr],            [enables the Counter Mode wrapper crypto plugin.])
-ARG_ENABL_SET([ccm],            [enables the CCM AEAD wrapper crypto plugin.])
-ARG_ENABL_SET([gcm],            [enables the GCM AEAD wrapper crypto plugin.])
-ARG_ENABL_SET([ntru],           [enables the NTRU crypto plugin.])
-ARG_ENABL_SET([addrblock],      [enables RFC 3779 address block constraint support.])
 ARG_ENABL_SET([unity],          [enables Cisco Unity extension plugin.])
-ARG_ENABL_SET([uci],            [enable OpenWRT UCI configuration plugin.])
-ARG_ENABL_SET([osx-attr],       [enable OS X SystemConfiguration attribute handler.])
-ARG_ENABL_SET([android-dns],    [enable Android specific DNS handler.])
+# TNC modules/plugins
+ARG_ENABL_SET([imc-test],       [enable IMC test module.])
+ARG_ENABL_SET([imv-test],       [enable IMV test module.])
+ARG_ENABL_SET([imc-scanner],    [enable IMC port scanner module.])
+ARG_ENABL_SET([imv-scanner],    [enable IMV port scanner module.])
+ARG_ENABL_SET([imc-os],         [enable IMC operating system module.])
+ARG_ENABL_SET([imv-os],         [enable IMV operating system module.])
+ARG_ENABL_SET([imc-attestation],[enable IMC attestation module.])
+ARG_ENABL_SET([imv-attestation],[enable IMV attestation module.])
+ARG_ENABL_SET([imc-swid],       [enable IMC swid module.])
+ARG_ENABL_SET([imv-swid],       [enable IMV swid module.])
+ARG_ENABL_SET([tnc-ifmap],      [enable TNC IF-MAP module. Requires libxml])
+ARG_ENABL_SET([tnc-imc],        [enable TNC IMC module.])
+ARG_ENABL_SET([tnc-imv],        [enable TNC IMV module.])
+ARG_ENABL_SET([tnc-pdp],        [enable TNC policy decision point module.])
+ARG_ENABL_SET([tnccs-11],       [enable TNCCS 1.1 protocol module. Requires libxml])
+ARG_ENABL_SET([tnccs-20],       [enable TNCCS 2.0 protocol module.])
+ARG_ENABL_SET([tnccs-dynamic],  [enable dynamic TNCCS protocol discovery module.])
+# misc plugins
 ARG_ENABL_SET([android-log],    [enable Android specific logger plugin.])
-ARG_ENABL_SET([maemo],          [enable Maemo specific plugin.])
-ARG_ENABL_SET([nm],             [enable NetworkManager backend.])
-ARG_ENABL_SET([ha],             [enable high availability cluster plugin.])
-ARG_ENABL_SET([whitelist],      [enable peer identity whitelisting plugin.])
-ARG_ENABL_SET([lookip],         [enable fast virtual IP lookup and notification plugin.])
-ARG_ENABL_SET([error-notify],   [enable error notification plugin.])
 ARG_ENABL_SET([certexpire],     [enable CSV export of expiration dates of used certificates.])
-ARG_ENABL_SET([systime-fix],    [enable plugin to handle cert lifetimes with invalid system time gracefully.])
-ARG_ENABL_SET([led],            [enable plugin to control LEDs on IKEv2 activity using the Linux kernel LED subsystem.])
 ARG_ENABL_SET([duplicheck],     [advanced duplicate checking plugin using liveness checks.])
-ARG_ENABL_SET([coupling],       [enable IKEv2 plugin to couple peer certificates permanently to authentication.])
+ARG_ENABL_SET([error-notify],   [enable error notification plugin.])
+ARG_ENABL_SET([farp],           [enable ARP faking plugin that responds to ARP requests to peers virtual IP])
+ARG_ENABL_SET([ha],             [enable high availability cluster plugin.])
+ARG_ENABL_SET([led],            [enable plugin to control LEDs on IKEv2 activity using the Linux kernel LED subsystem.])
+ARG_ENABL_SET([load-tester],    [enable load testing plugin for IKEv2 daemon.])
+ARG_ENABL_SET([lookip],         [enable fast virtual IP lookup and notification plugin.])
+ARG_ENABL_SET([maemo],          [enable Maemo specific plugin.])
 ARG_ENABL_SET([radattr],        [enable plugin to inject and process custom RADIUS attributes as IKEv2 client.])
-ARG_ENABL_SET([vstr],           [enforce using the Vstr string library to replace glibc-like printf hooks.])
-ARG_ENABL_SET([monolithic],     [build monolithic version of libstrongswan that includes all enabled plugins. Similarly, the plugins of charon are assembled in libcharon.])
+ARG_ENABL_SET([systime-fix],    [enable plugin to handle cert lifetimes with invalid system time gracefully.])
+ARG_ENABL_SET([test-vectors],   [enable plugin providing crypto test vectors.])
+ARG_ENABL_SET([unit-tester],    [enable unit tests on IKEv2 daemon startup.])
+ARG_DISBL_SET([updown],         [disable updown firewall script plugin.])
+# programs/components
+ARG_DISBL_SET([charon],         [disable the IKEv1/IKEv2 keying daemon charon.])
+ARG_ENABL_SET([cmd],            [enable the command line IKE client charon-cmd.])
+ARG_ENABL_SET([conftest],       [enforce Suite B conformance test framework.])
+ARG_ENABL_SET([dumm],           [enable the DUMM UML test framework.])
+ARG_ENABL_SET([fast],           [enable libfast (FastCGI Application Server w/ templates.])
+ARG_ENABL_SET([libipsec],       [enable user space IPsec implementation.])
+ARG_ENABL_SET([manager],        [enable web management console (proof of concept).])
+ARG_ENABL_SET([medcli],         [enable mediation client configuration database plugin.])
+ARG_ENABL_SET([medsrv],         [enable mediation server web frontend and daemon plugin.])
+ARG_ENABL_SET([nm],             [enable NetworkManager backend.])
+ARG_DISBL_SET([scripts],        [disable additional utilities (found in directory scripts).])
+ARG_ENABL_SET([tkm],            [enable Trusted Key Manager support.])
+ARG_DISBL_SET([tools],          [disable additional utilities (openac, scepclient and pki).])
+# optional features
 ARG_ENABL_SET([bfd-backtraces], [use binutils libbfd to resolve backtraces for memory leaks and segfaults.])
+ARG_DISBL_SET([ikev1],          [disable IKEv1 protocol support in charon.])
+ARG_DISBL_SET([ikev2],          [disable IKEv2 protocol support in charon.])
+ARG_ENABL_SET([integrity-test], [enable integrity testing of libstrongswan and plugins.])
+ARG_DISBL_SET([load-warning],   [disable the charon plugin load option warning in starter.])
+ARG_ENABL_SET([mediation],      [enable IKEv2 Mediation Extension.])
 ARG_ENABL_SET([unwind-backtraces],[use libunwind to create backtraces for memory leaks and segfaults.])
+# compile options
 ARG_ENABL_SET([coverage],       [enable lcov coverage report generation.])
-ARG_ENABL_SET([tkm],            [enable Trusted Key Manager support.])
-ARG_ENABL_SET([cmd],            [enable the command line IKE client charon-cmd.])
+ARG_ENABL_SET([leak-detective], [enable malloc hooks to find memory leaks.])
+ARG_ENABL_SET([lock-profiler],  [enable lock/mutex profiling code.])
+ARG_ENABL_SET([monolithic],     [build monolithic version of libstrongswan that includes all enabled plugins. Similarly, the plugins of charon are assembled in libcharon.])
 
 # ===================================
 #  option to disable default options
@@ -275,7 +288,20 @@ ARG_DISBL_SET([defaults],       [disable all default plugins (they can be enable
 if test x$defaults = xfalse; then
        for option in $enabled_by_default; do
                eval test x\${${option}_given} = xtrue && continue
-               let $option=false
+               eval $option=false
+       done
+fi
+
+# ==============================
+#  option to enable all options
+# ==============================
+
+ARG_ENABL_SET([all],            [enable all plugins and features (they can be disabled with their respective --disable options). Mainly for testing.])
+
+if test x$all_given = xtrue; then
+       for option in $disabled_by_default; do
+               eval test x\${${option}_given} = xtrue && continue
+               eval $option=true
        done
 fi
 
@@ -659,28 +685,43 @@ AC_RUN_IFELSE([AC_LANG_SOURCE(
        [AC_MSG_RESULT([no])]
 )
 
-# check for the new register_printf_specifier function with len argument,
-# or the deprecated register_printf_function without
-AC_CHECK_FUNC(
-       [register_printf_specifier],
-       [AC_DEFINE([HAVE_PRINTF_SPECIFIER], [], [have register_printf_specifier()])],
-       [AC_CHECK_FUNC(
-               [register_printf_function],
-               [AC_DEFINE([HAVE_PRINTF_FUNCTION], [], [have register_printf_function()])],
-               [
-                       AC_MSG_NOTICE([printf does not support custom format specifiers!])
-                       builtin_printf=true
-               ]
-       )]
-)
+case "$printf_hooks" in
+auto|builtin|glibc|vstr)
+       ;;
+*)
+       AC_MSG_NOTICE([invalid printf hook implementation, defaulting to 'auto'])
+       printf_hooks=auto
+       ;;
+esac
+
+if test x$printf_hooks = xauto -o x$printf_hooks = xglibc; then
+       # check for the new register_printf_specifier function with len argument,
+       # or the deprecated register_printf_function without
+       AC_CHECK_FUNC(
+               [register_printf_specifier],
+               [AC_DEFINE([HAVE_PRINTF_SPECIFIER], [], [have register_printf_specifier()])],
+               [AC_CHECK_FUNC(
+                       [register_printf_function],
+                       [AC_DEFINE([HAVE_PRINTF_FUNCTION], [], [have register_printf_function()])],
+                       [
+                               AC_MSG_NOTICE([printf(3) does not support custom format specifiers!])
+                               if test x$printf_hooks = xglibc; then
+                                       AC_MSG_ERROR([please select a different printf hook implementation])
+                               else
+                                       # fallback to builtin printf hook implementation
+                                       printf_hooks=builtin
+                               fi
+                       ]
+               )]
+       )
+fi
 
-if test x$vstr = xtrue; then
+if test x$printf_hooks = xvstr; then
        AC_CHECK_LIB([vstr],[main],[LIBS="$LIBS"],[AC_MSG_ERROR([Vstr string library not found])],[])
        AC_DEFINE([USE_VSTR], [], [use Vstr string library for printf hooks])
-       builtin_printf=false
 fi
 
-if test x$builtin_printf = xtrue; then
+if test x$printf_hooks = xbuiltin; then
        AC_DEFINE([USE_BUILTIN_PRINTF], [], [using builtin printf for printf hooks])
 fi
 
@@ -1328,8 +1369,8 @@ AM_CONDITIONAL(USE_LIBPTTLS, test x$tnc_tnccs = xtrue)
 AM_CONDITIONAL(USE_FILE_CONFIG, test x$stroke = xtrue)
 AM_CONDITIONAL(USE_IPSEC_SCRIPT, test x$stroke = xtrue -o x$tools = xtrue -o x$conftest = xtrue)
 AM_CONDITIONAL(USE_LIBCAP, test x$capabilities = xlibcap)
-AM_CONDITIONAL(USE_VSTR, test x$vstr = xtrue)
-AM_CONDITIONAL(USE_BUILTIN_PRINTF, test x$builtin_printf = xtrue)
+AM_CONDITIONAL(USE_VSTR, test x$printf_hooks = xvstr)
+AM_CONDITIONAL(USE_BUILTIN_PRINTF, test x$printf_hooks = xbuiltin)
 AM_CONDITIONAL(USE_SIMAKA, test x$simaka = xtrue)
 AM_CONDITIONAL(USE_TLS, test x$tls = xtrue)
 AM_CONDITIONAL(USE_RADIUS, test x$radius = xtrue)
index 2e45520..9d51cb9 100644 (file)
@@ -2,6 +2,7 @@
 # ARG_ENABL_SET(option, help)
 # ---------------------------
 # Create a --enable-$1 option with helptext, set a variable $1 to true/false
+# All $1 are collected in the variable $disabled_by_default
 AC_DEFUN([ARG_ENABL_SET],
        [AC_ARG_ENABLE(
                [$1],
@@ -14,7 +15,8 @@ AC_DEFUN([ARG_ENABL_SET],
                fi],
                [patsubst([$1], [-], [_])=false
                patsubst([$1], [-], [_])_given=false]
-       )]
+       )
+       disabled_by_default=${disabled_by_default}" patsubst([$1], [-], [_])"]
 )
 
 # ARG_DISBL_SET(option, help)
diff --git a/scripts/test.sh b/scripts/test.sh
new file mode 100755 (executable)
index 0000000..4785d06
--- /dev/null
@@ -0,0 +1,65 @@
+#!/bin/sh
+# Build script for Travis CI
+
+if test -z $TRAVIS_BUILD_DIR; then
+       TRAVIS_BUILD_DIR=$PWD
+fi
+
+cd $TRAVIS_BUILD_DIR
+
+TARGET=check
+
+DEPS="libgmp-dev"
+
+case "$TEST" in
+default)
+       # should be the default, but lets make sure
+       CONFIG="--with-printf-hooks=glibc"
+       ;;
+openssl)
+       CONFIG="--disable-defaults --enable-tools --enable-openssl"
+       DEPS="libssl-dev"
+       ;;
+gcrypt)
+       CONFIG="--disable-defaults --enable-tools --enable-gcrypt --enable-pkcs1"
+       DEPS="libgcrypt11-dev"
+       ;;
+printf-builtin)
+       CONFIG="--with-printf-hooks=builtin"
+       ;;
+all)
+       CONFIG="--enable-all --disable-android-dns --disable-android-log
+                       --disable-dumm --disable-kernel-pfroute --disable-keychain
+                       --disable-lock-profiler --disable-maemo --disable-padlock
+                       --disable-osx-attr --disable-tkm --disable-uci"
+       # not enabled on the build server
+       CONFIG="$CONFIG --disable-af-alg"
+       # TODO: enable? perhaps via coveralls.io (cpp-coveralls)?
+       CONFIG="$CONFIG --disable-coverage"
+       DEPS="$DEPS libcurl4-gnutls-dev libsoup2.4-dev libunbound-dev libldns-dev
+                 libmysqlclient-dev libsqlite3-dev clearsilver-dev libfcgi-dev
+                 libnm-glib-dev libnm-glib-vpn-dev libpcsclite-dev libpam0g-dev
+                 binutils-dev libunwind7-dev"
+       ;;
+dist)
+       TARGET=distcheck
+       ;;
+*)
+       echo "$0: unknown test $TEST" >&2
+       exit 1
+       ;;
+esac
+
+if test "$1" = "deps"; then
+       sudo apt-get install -qq $DEPS
+       exit $?
+fi
+
+CONFIG="$CONFIG
+       --enable-silent-rules
+       --enable-test-vectors
+       --enable-monolithic=${MONOLITHIC-no}
+       --enable-leak-detective=${LEAK_DETECTIVE-no}"
+
+echo "$ ./configure $CONFIG && make $TARGET"
+./configure $CONFIG && make -j4 $TARGET
index cc7c934..48de825 100644 (file)
@@ -15,12 +15,13 @@ if MONOLITHIC
 noinst_LTLIBRARIES = libstrongswan-tnc-pdp.la
 else
 plugin_LTLIBRARIES = libstrongswan-tnc-pdp.la
+endif
+
 libstrongswan_tnc_pdp_la_LIBADD = \
        $(top_builddir)/src/libradius/libradius.la \
        $(top_builddir)/src/libpttls/libpttls.la \
        $(top_builddir)/src/libtls/libtls.la \
        $(top_builddir)/src/libtnccs/libtnccs.la
-endif
 
 libstrongswan_tnc_pdp_la_SOURCES = \
        tnc_pdp_plugin.h tnc_pdp_plugin.c \
index dba3f6f..69225bd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013 Tobias Brunner
+ * Copyright (C) 2013-2014 Tobias Brunner
  * Copyright (C) 2008 Martin Willi
  * Hochschule fuer Technik Rapperswil
  *
@@ -20,6 +20,7 @@
 #include <threading/rwlock.h>
 #include <collections/linked_list.h>
 #include <crypto/crypto_tester.h>
+#include <utils/test.h>
 
 const char *default_plugin_name = "default";
 
@@ -976,3 +977,39 @@ crypto_factory_t *crypto_factory_create()
 
        return &this->public;
 }
+
+/**
+ * Manually verify all registered algorithms against test vectors
+ */
+static u_int verify_registered_algorithms(crypto_factory_t *factory)
+{
+       private_crypto_factory_t *this = (private_crypto_factory_t*)factory;
+       enumerator_t *enumerator;
+       entry_t *entry;
+       u_int failures = 0;
+
+#define TEST_ALGORITHMS(test, ...) do { \
+       enumerator = this->test##s->create_enumerator(this->test##s); \
+       while (enumerator->enumerate(enumerator, &entry)) \
+       { \
+               if (!this->tester->test_##test(this->tester, entry->algo, ##__VA_ARGS__, \
+                                                       entry->create_##test, NULL, entry->plugin_name)) \
+               { \
+                       failures++; \
+               } \
+       } \
+       enumerator->destroy(enumerator); \
+} while (0)
+
+       this->lock->read_lock(this->lock);
+       TEST_ALGORITHMS(crypter, 0);
+       TEST_ALGORITHMS(aead, 0);
+       TEST_ALGORITHMS(signer);
+       TEST_ALGORITHMS(hasher);
+       TEST_ALGORITHMS(prf);
+       TEST_ALGORITHMS(rng);
+       this->lock->unlock(this->lock);
+       return failures;
+}
+
+EXPORT_FUNCTION_FOR_TESTS(crypto, verify_registered_algorithms);
index 30724b1..40c4fd3 100644 (file)
@@ -204,16 +204,13 @@ METHOD(crypto_tester_t, test_crypter, bool,
                        continue;
                }
 
-               tested++;
-               failed = TRUE;
                crypter = create(alg, vector->key_size);
                if (!crypter)
-               {
-                       DBG1(DBG_LIB, "%N[%s]: %u bit key size not supported",
-                                encryption_algorithm_names, alg, plugin_name,
-                                BITS_PER_BYTE * vector->key_size);
+               {       /* key size not supported */
                        continue;
                }
+               tested++;
+               failed = TRUE;
 
                key = chunk_create(vector->key, crypter->get_key_size(crypter));
                if (!crypter->set_key(crypter, key))
index 3204c89..9e6c5d7 100644 (file)
@@ -94,7 +94,8 @@ START_TEST(test_ntru_drbg_strength)
        entropy = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
        ck_assert(entropy != NULL);
 
-       drbg = ntru_drbg_create(strengths[_i].requested, chunk_empty, entropy);
+       drbg = TEST_FUNCTION(ntru, ntru_drbg_create, strengths[_i].requested,
+                                                chunk_empty, entropy);
        if (strengths[_i].standard)
        {
                ck_assert(drbg != NULL);
@@ -251,7 +252,8 @@ START_TEST(test_ntru_drbg)
 
        out = chunk_alloc(128);
        entropy = test_rng_create(drbg_tests[_i].entropy);
-       drbg = ntru_drbg_create(256, drbg_tests[_i].pers_str, entropy);
+       drbg = TEST_FUNCTION(ntru, ntru_drbg_create, 256, drbg_tests[_i].pers_str,
+                                                entropy);
        ck_assert(drbg != NULL);
        ck_assert(drbg->reseed(drbg));
        ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
@@ -273,7 +275,7 @@ START_TEST(test_ntru_drbg_reseed)
                                                  "libstrongswan.plugins.ntru.max_drbg_requests", 2);
        out = chunk_alloc(128);
        entropy = test_rng_create(drbg_tests[0].entropy);
-       drbg = ntru_drbg_create(256, chunk_empty, entropy);
+       drbg = TEST_FUNCTION(ntru, ntru_drbg_create, 256, chunk_empty, entropy);
 
        /* bad output parameters */
        ck_assert(!drbg->generate(drbg, 256, 0, out.ptr));
@@ -291,13 +293,13 @@ START_TEST(test_ntru_drbg_reseed)
        drbg->destroy(drbg);
 
        /* no entropy available for DRBG instantiation */
-       drbg = ntru_drbg_create(256, chunk_empty, entropy);
+       drbg = TEST_FUNCTION(ntru, ntru_drbg_create, 256, chunk_empty, entropy);
        ck_assert(drbg == NULL);
        entropy->destroy(entropy);
 
        /* one automatic reseeding occurs */
        entropy = test_rng_create(drbg_tests[0].entropy);
-       drbg = ntru_drbg_create(256, chunk_empty, entropy);
+       drbg = TEST_FUNCTION(ntru, ntru_drbg_create, 256, chunk_empty, entropy);
        ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
        ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
        ck_assert(drbg->generate(drbg, 256, 128, out.ptr));
@@ -382,7 +384,7 @@ uint16_t indices_ees1171ep1[] = {
  */
 mgf1_test_t mgf1_tests[] = {
        {       HASH_SHA1, 20, 60, 20, 15, 24,
-               chunk_from_chars( 
+               chunk_from_chars(
                                                0xED, 0xA5, 0xC3, 0xBC, 0xAF, 0xB3, 0x20, 0x7D,
                                                0x14, 0xA1, 0x54, 0xF7, 0x8B, 0x37, 0xF2, 0x8D,
                                                0x8C, 0x9B, 0xD5, 0x63, 0x57, 0x38, 0x11, 0xC2,
@@ -416,7 +418,7 @@ mgf1_test_t mgf1_tests[] = {
                                                0x40, 0x4B, 0xE7, 0x22, 0x3A, 0x56, 0x10, 0x6D,
                                                0x4D, 0x29, 0x0B, 0xCE, 0xA6, 0x21, 0xB5, 0x5C,
                                                0x71, 0x66, 0x2F, 0x70, 0x35, 0xD8, 0x8A, 0x92,
-                                               0x33, 0xF0, 0x16, 0xD4, 0x0E, 0x43, 0x8A, 0x14), 
+                                               0x33, 0xF0, 0x16, 0xD4, 0x0E, 0x43, 0x8A, 0x14),
                chunk_from_chars(
                                1, 2, 1, 0, 0,  1, 1, 1, 2, 0,  1, 0, 1, 1, 1,  0, 2, 0, 1, 1,
                                0, 0, 0, 1, 1,  0, 2, 0, 2, 2,  1, 2, 2, 2, 1,  2, 1, 1, 0, 0,
@@ -474,7 +476,7 @@ mgf1_test_t mgf1_tests[] = {
                                                0x76, 0x89, 0x8B, 0x1B, 0x60, 0xEC, 0x10, 0x9D,
                                                0x8F, 0x13, 0xF2, 0xFE, 0xD9, 0x85, 0xC1, 0xAB,
                                                0x7E, 0xEE, 0xB1, 0x31, 0xDD, 0xF7, 0x7F, 0x0C,
-                                               0x7D, 0xF9, 0x6B, 0x7B, 0x19, 0x80, 0xBD, 0x28), 
+                                               0x7D, 0xF9, 0x6B, 0x7B, 0x19, 0x80, 0xBD, 0x28),
                chunk_from_chars(
                                                0xF1, 0x19, 0x02, 0x4F, 0xDA, 0x58, 0x05, 0x9A,
                                                0x07, 0xDF, 0x61, 0x81, 0x22, 0x0E, 0x15, 0x46,
@@ -550,14 +552,17 @@ START_TEST(test_ntru_mgf1)
        mask2.len = mgf1_tests[_i].ml2;
        mask3.len = mgf1_tests[_i].ml3;
 
-       mgf1 = ntru_mgf1_create(HASH_UNKNOWN, mgf1_tests[_i].seed, TRUE);
+       mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, HASH_UNKNOWN,
+                                                mgf1_tests[_i].seed, TRUE);
        ck_assert(mgf1 == NULL);
 
-       mgf1 = ntru_mgf1_create(mgf1_tests[_i].alg, chunk_empty, TRUE);
+       mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg,
+                                                chunk_empty, TRUE);
        ck_assert(mgf1 == NULL);
 
        /* return mask in allocated chunk */
-       mgf1 = ntru_mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE);
+       mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg,
+                                                mgf1_tests[_i].seed, TRUE);
        ck_assert(mgf1);
 
        /* check hash size */
@@ -573,14 +578,16 @@ START_TEST(test_ntru_mgf1)
        mgf1->destroy(mgf1);
 
        /* copy mask to pre-allocated buffer */
-       mgf1 = ntru_mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].seed, TRUE);
+       mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg,
+                                                mgf1_tests[_i].seed, TRUE);
        ck_assert(mgf1);
        ck_assert(mgf1->get_mask(mgf1, mgf1_tests[_i].mask.len, mask.ptr));
        ck_assert(chunk_equals(mask, mgf1_tests[_i].mask));
        mgf1->destroy(mgf1);
 
        /* get mask in batches without hashing the seed */
-       mgf1 = ntru_mgf1_create(mgf1_tests[_i].alg, mgf1_tests[_i].hashed_seed, FALSE);
+       mgf1 = TEST_FUNCTION(ntru, ntru_mgf1_create, mgf1_tests[_i].alg,
+                                                mgf1_tests[_i].hashed_seed, FALSE);
        ck_assert(mgf1);
 
        /* first batch */
@@ -608,16 +615,16 @@ START_TEST(test_ntru_trits)
        ntru_trits_t *mask;
        chunk_t trits;
 
-       mask = ntru_trits_create(mgf1_tests[_i].trits.len, HASH_UNKNOWN,
-                                                        mgf1_tests[_i].seed);
+       mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len,
+                                                HASH_UNKNOWN, mgf1_tests[_i].seed);
        ck_assert(mask == NULL);
 
-       mask = ntru_trits_create(mgf1_tests[_i].trits.len, mgf1_tests[_i].alg,
-                                                        chunk_empty);
+       mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len,
+                                                mgf1_tests[_i].alg, chunk_empty);
        ck_assert(mask == NULL);
 
-       mask = ntru_trits_create(mgf1_tests[_i].trits.len, mgf1_tests[_i].alg,
-                                                        mgf1_tests[_i].seed);
+       mask = TEST_FUNCTION(ntru, ntru_trits_create, mgf1_tests[_i].trits.len,
+                                                mgf1_tests[_i].alg, mgf1_tests[_i].seed);
        ck_assert(mask);
 
        trits = chunk_create(mask->get_trits(mask), mask->get_size(mask));
@@ -625,7 +632,8 @@ START_TEST(test_ntru_trits)
        mask->destroy(mask);
 
        /* generate a multiple of 5 trits */
-       mask = ntru_trits_create(10, mgf1_tests[_i].alg, mgf1_tests[_i].seed);
+       mask = TEST_FUNCTION(ntru, ntru_trits_create, 10, mgf1_tests[_i].alg,
+                                                mgf1_tests[_i].seed);
        ck_assert(mask);
 
        trits = chunk_create(mask->get_trits(mask), mask->get_size(mask));
@@ -646,17 +654,17 @@ START_TEST(test_ntru_poly)
        seed.len = mgf1_tests[_i].seed_len;
 
        p = &mgf1_tests[_i].poly_test[0];
-       poly = ntru_poly_create_from_seed(HASH_UNKNOWN, seed, p->c_bits, p->N, p->q,
-                                                                         p->indices_len, p->indices_len,
-                                                                         p->is_product_form);
+       poly = TEST_FUNCTION(ntru, ntru_poly_create_from_seed, HASH_UNKNOWN, seed,
+                                                p->c_bits, p->N, p->q, p->indices_len, p->indices_len,
+                                                p->is_product_form);
        ck_assert(poly == NULL);
 
        for (n = 0; n < 2; n++)
        {
                p = &mgf1_tests[_i].poly_test[n];
-               poly = ntru_poly_create_from_seed(mgf1_tests[_i].alg, seed, p->c_bits,
-                                                                                 p->N, p->q, p->indices_len,
-                                                                                 p->indices_len, p->is_product_form);
+               poly = TEST_FUNCTION(ntru, ntru_poly_create_from_seed,
+                                                       mgf1_tests[_i].alg, seed, p->c_bits, p->N, p->q,
+                                                       p->indices_len, p->indices_len, p->is_product_form);
                ck_assert(poly != NULL && poly->get_size(poly) == p->indices_size);
 
                indices = poly->get_indices(poly);
@@ -756,8 +764,9 @@ START_TEST(test_ntru_ring_mult)
        int i;
 
        t = &ring_mult_tests[_i];
-       poly = ntru_poly_create_from_data(t->indices, t->N, t->q, t->indices_len_p,
-                                                                         t->indices_len_m, t->is_product_form);
+       poly = TEST_FUNCTION(ntru, ntru_poly_create_from_data, t->indices, t->N,
+                                                t->q, t->indices_len_p, t->indices_len_m,
+                                                t->is_product_form);
        ck_assert(poly != NULL);
 
        c = malloc(t->N * sizeof(uint16_t));
@@ -784,8 +793,9 @@ START_TEST(test_ntru_array)
 
        t = &ring_mult_tests[array_tests[_i]];
 
-       poly = ntru_poly_create_from_data(t->indices, t->N, t->q, t->indices_len_p,
-                                                                         t->indices_len_m, t->is_product_form);
+       poly = TEST_FUNCTION(ntru, ntru_poly_create_from_data, t->indices, t->N,
+                                                t->q, t->indices_len_p, t->indices_len_m,
+                                                t->is_product_form);
        ck_assert(poly != NULL);
 
        c = malloc(t->N * sizeof(uint16_t));
@@ -803,8 +813,8 @@ END_TEST
 
 START_TEST(test_ntru_param_set)
 {
-       ck_assert(ntru_param_set_get_by_id(-1) == NULL);
-       ck_assert(ntru_param_set_get_by_id(16) == NULL);
+       ck_assert(TEST_FUNCTION(ntru, ntru_param_set_get_by_id, -1) == NULL);
+       ck_assert(TEST_FUNCTION(ntru, ntru_param_set_get_by_id, 16) == NULL);
 }
 END_TEST
 
@@ -964,7 +974,7 @@ privkey_test_t privkey_tests[] = {
                                                0xB1, 0x6D, 0x88, 0x41, 0x62, 0x4D, 0x18, 0xB6,
                                                0x3F, 0x12, 0x81, 0xDE, 0xE6, 0xDC, 0x4A, 0x31,
                                                0x61, 0x26, 0xB1, 0x4B, 0x95, 0xC1, 0x69, 0xDC,
-                                               0xDC, 0xAC, 0xD0, 0x15, 0xFC, 0x21, 0xC5, 0x20, 
+                                               0xDC, 0xAC, 0xD0, 0x15, 0xFC, 0x21, 0xC5, 0x20,
                                                0x5F, 0x97, 0x76, 0x41, 0xC1, 0xF2, 0xD7, 0x95,
                                                0x1D, 0x25, 0x23, 0x36, 0x86, 0xFA, 0x7E, 0xF4,
                                                0x14, 0x9F, 0x9D, 0x9F, 0xB2, 0xBB, 0x25, 0x1D,
@@ -1066,13 +1076,15 @@ START_TEST(test_ntru_privkey)
        uint32_t strength;
        chunk_t encoding, privkey_encoding, pubkey_encoding;
 
-       params = ntru_param_set_get_by_id(privkey_tests[_i].id);
+       params = TEST_FUNCTION(ntru, ntru_param_set_get_by_id,
+                                                  privkey_tests[_i].id);
        strength = params->sec_strength_len * BITS_PER_BYTE;
        entropy = test_rng_create(privkey_tests[_i].entropy);
-       drbg = ntru_drbg_create(strength, chunk_from_str("IKE NTRU-KE"), entropy);
+       drbg = TEST_FUNCTION(ntru, ntru_drbg_create, strength,
+                                                chunk_from_str("IKE NTRU-KE"), entropy);
        ck_assert(drbg != NULL);
 
-       privkey = ntru_private_key_create(drbg, params);
+       privkey = TEST_FUNCTION(ntru, ntru_private_key_create, drbg, params);
        ck_assert(privkey);
 
        privkey_encoding = privkey->get_encoding(privkey);
index 242ac9d..a1205d0 100644 (file)
@@ -1,4 +1,7 @@
 /*
+ * Copyright (C) 2014 Tobias Brunner
+ * Hochschule fuer Technik Rapperswil
+ *
  * Copyright (C) 2013 Martin Willi
  * Copyright (C) 2013 revosec AG
  *
 
 #include "test_suite.h"
 
-/*******************************************************************************
- * Check if test vectors have been successful during transform registration
- */
+#include <utils/test.h>
+
+IMPORT_FUNCTION_FOR_TESTS(crypto, verify_registered_algorithms, u_int,
+                                                 crypto_factory_t *factory);
 
 START_TEST(test_vectors)
 {
-       u_int failed = lib->crypto->get_test_vector_failures(lib->crypto);
+       u_int failed = TEST_FUNCTION(crypto, verify_registered_algorithms,
+                                                                lib->crypto);
        fail_if(failed > 0, "%u test vectors failed", failed);
 }
 END_TEST
index 0b26ee1..6bb1b29 100644 (file)
@@ -22,6 +22,7 @@
 #include <collections/array.h>
 #include <utils/test.h>
 
+#include <stdlib.h>
 #include <dirent.h>
 #include <unistd.h>
 #include <limits.h>
 #define TTY(color) tty_escape_get(2, TTY_FG_##color)
 
 /**
- * Initialize the lookup table for testable functions (defined in libstrongswan)
+ * 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.
  */
-static void testable_functions_create() __attribute__ ((constructor(1000)));
-static void testable_functions_create()
+void testable_functions_create()
 {
-       testable_functions = hashtable_create(hashtable_hash_str,
-                                                                                 hashtable_equals_str, 8);
+       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(1000)));
+static void testable_functions_destroy() __attribute__ ((destructor));
 static void testable_functions_destroy()
 {
-       testable_functions->destroy(testable_functions);
+       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, even though the priority says differently, make sure this
-        * does not crash */
+        * terminates, make sure this does not crash */
        testable_functions = NULL;
 }
 
 /**
- * Load all available test suites
+ * Destroy a single test suite and associated data
+ */
+static void destroy_suite(test_suite_t *suite)
+{
+       test_case_t *tcase;
+
+       while (array_remove(suite->tcases, 0, &tcase))
+       {
+               array_destroy(tcase->functions);
+               array_destroy(tcase->fixtures);
+       }
+       free(suite);
+}
+
+/**
+ * Removes and destroys test suites that are not selected.
+ */
+static void filter_suites(array_t *loaded)
+{
+       enumerator_t *enumerator, *names;
+       hashtable_t *selected;
+       test_suite_t *suite;
+       char *suites, *name;
+
+       suites = getenv("TESTS_SUITES");
+       if (!suites)
+       {
+               return;
+       }
+       selected = hashtable_create(hashtable_hash_str, hashtable_equals_str, 8);
+       names = enumerator_create_token(suites, ",", " ");
+       while (names->enumerate(names, &name))
+       {
+               selected->put(selected, name, name);
+       }
+       enumerator = array_create_enumerator(loaded);
+       while (enumerator->enumerate(enumerator, &suite))
+       {
+               if (!selected->get(selected, suite->name))
+               {
+                       array_remove_at(loaded, enumerator);
+                       destroy_suite(suite);
+               }
+       }
+       enumerator->destroy(enumerator);
+       selected->destroy(selected);
+       names->destroy(names);
+}
+
+/**
+ * Load all available test suites, or optionally only selected ones.
  */
 static array_t *load_suites(test_configuration_t configs[],
                                                        test_runner_init_t init)
@@ -91,6 +146,7 @@ static array_t *load_suites(test_configuration_t configs[],
                        array_insert(suites, -1, configs[i].suite());
                }
        }
+       filter_suites(suites);
 
        if (lib->leak_detective)
        {
@@ -112,16 +168,10 @@ static array_t *load_suites(test_configuration_t configs[],
 static void unload_suites(array_t *suites)
 {
        test_suite_t *suite;
-       test_case_t *tcase;
 
        while (array_remove(suites, 0, &suite))
        {
-               while (array_remove(suite->tcases, 0, &tcase))
-               {
-                       array_destroy(tcase->functions);
-                       array_destroy(tcase->fixtures);
-               }
-               free(suite);
+               destroy_suite(suite);
        }
        array_destroy(suites);
 }
@@ -178,6 +228,9 @@ static bool call_fixture(test_case_t *tcase, bool up)
  */
 static bool pre_test(test_runner_init_t init)
 {
+       level_t level = LEVEL_SILENT;
+       char *verbosity;
+
        library_init(NULL, "test-runner");
 
        /* use non-blocking RNG to generate keys fast */
@@ -185,6 +238,9 @@ static bool pre_test(test_runner_init_t init)
                        "libstrongswan.plugins.random.random",
                        lib->settings->get_str(lib->settings,
                                "libstrongswan.plugins.random.urandom", "/dev/urandom"));
+       /* same for the gcrypt plugin */
+       lib->settings->set_default_str(lib->settings,
+                       "libstrongswan.plugins.gcrypt.quick_random", "yes");
 
        if (lib->leak_detective)
        {
@@ -197,7 +253,12 @@ static bool pre_test(test_runner_init_t init)
                library_deinit();
                return FALSE;
        }
-       dbg_default_set_level(LEVEL_SILENT);
+       verbosity = getenv("TESTS_VERBOSITY");
+       if (verbosity)
+       {
+               level = atoi(verbosity);
+       }
+       dbg_default_set_level(level);
        return TRUE;
 }
 
index 7de5a76..624ac4b 100644 (file)
  */
 hashtable_t *testable_functions;
 
+/**
+ * The function that actually initializes the hash table above.  Provided
+ * by the test runner.
+ */
+void testable_functions_create() __attribute__((weak));
+
 /*
  * Described in header.
  */
 void testable_function_register(char *name, void *fn)
 {
-       if (testable_functions)
+       bool old = FALSE;
+
+       if (!testable_functions_create)
+       {       /* not linked to the test runner */
+               return;
+       }
+       else if (!fn && !testable_functions)
+       {       /* ignore as testable_functions has already been destroyed */
+               return;
+       }
+
+       if (lib && lib->leak_detective)
+       {
+               old = lib->leak_detective->set_state(lib->leak_detective, FALSE);
+       }
+       if (!testable_functions)
+       {
+               testable_functions_create();
+       }
+       if (fn)
+       {
+               testable_functions->put(testable_functions, name, fn);
+       }
+       else
+       {
+               testable_functions->remove(testable_functions, name);
+       }
+       if (lib && lib->leak_detective)
        {
-               bool old = FALSE;
-               if (lib->leak_detective)
-               {
-                       old = lib->leak_detective->set_state(lib->leak_detective, FALSE);
-               }
-               if (fn)
-               {
-                       testable_functions->put(testable_functions, name, fn);
-               }
-               else
-               {
-                       testable_functions->remove(testable_functions, name);
-               }
-               if (lib->leak_detective)
-               {
-                       lib->leak_detective->set_state(lib->leak_detective, old);
-               }
+               lib->leak_detective->set_state(lib->leak_detective, old);
        }
 }
index 5b72892..51362a1 100644 (file)
@@ -51,7 +51,7 @@ void testable_function_register(char *name, void *fn);
  * @param fn           function to register
  */
 #define EXPORT_FUNCTION_FOR_TESTS(ns, fn) \
-static void testable_function_register_##fn() __attribute__ ((constructor(2000))); \
+static void testable_function_register_##fn() __attribute__ ((constructor)); \
 static void testable_function_register_##fn() \
 { \
        testable_function_register(#ns "/" #fn, fn); \
@@ -65,32 +65,32 @@ static void testable_function_unregister_##fn() \
 /**
  * Import a registered function so that it can be called from tests.
  *
- * @note If the imported function is static (or no conflicting header files
- * are included) ret can be prefixed with static to declare the function static.
- *
- * @note We allocate an arbitrary amount of stack space, hopefully enough for
- * all arguments.
- *
  * @param ns           namespace of the function
  * @param name         name of the function
  * @param ret          return type of the function
  * @param ...          arguments of the function
  */
 #define IMPORT_FUNCTION_FOR_TESTS(ns, name, ret, ...) \
-ret name(__VA_ARGS__) \
-{ \
-       void (*fn)() = NULL; \
-       if (testable_functions) \
+static ret (*TEST_##ns##name)(__VA_ARGS__);
+
+/**
+ * Call a registered function from tests.
+ *
+ * @param ns           namespace of the function
+ * @param name         name of the function
+ * @param ...          arguments for the function
+ */
+#define TEST_FUNCTION(ns, name, ...) \
+({ \
+       if (!TEST_##ns##name && testable_functions) \
        { \
-               fn = testable_functions->get(testable_functions, #ns "/" #name); \
+               TEST_##ns##name = testable_functions->get(testable_functions, #ns "/" #name); \
        } \
-       if (fn) \
+       if (!TEST_##ns##name) \
        { \
-               void *args = __builtin_apply_args(); \
-               __builtin_return(__builtin_apply(fn, args, 16*sizeof(void*))); \
+               test_fail_msg(__FILE__, __LINE__, "function " #name " (" #ns ") not found"); \
        } \
-       test_fail_msg(__FILE__, __LINE__, "function " #name " (" #ns ") not found"); \
-       __builtin_return(NULL); \
-}
+       TEST_##ns##name(__VA_ARGS__); \
+})
 
 #endif /** TEST_H_ @}*/