diff --git a/configure.ac b/configure.ac index 2a18f9e3..626b3f38 100644 --- a/configure.ac +++ b/configure.ac @@ -120,6 +120,20 @@ AC_PROG_LN_S AC_PROG_MAKE_SET AC_PROG_LIBTOOL +dnl Decide whether or not to build binaries with profiling coverage support +dnl +want_profile_coverage=no +AC_ARG_ENABLE([profile-coverage], + [AS_HELP_STRING([--enable-profile-coverage], + [Build fwknop binaries with profile coverage support @<:@default is to disable@:>@])], + [want_profile_coverage=$enableval], + []) + +if test "x$want_profile_coverage" = "xyes"; then + CFLAGS="-g -O0" + FKO_CHECK_COMPILER_ARG([-fprofile-arcs -ftest-coverage -fno-inline]) +fi + dnl Decide whether or not to enable all warnings with -Wall dnl use_wall=yes diff --git a/test/test-coverage/iptables/zero_called_functions b/test/test-coverage/iptables/zero_called_functions new file mode 100644 index 00000000..12b80770 --- /dev/null +++ b/test/test-coverage/iptables/zero_called_functions @@ -0,0 +1,79 @@ +[+] TEST: [profile coverage] gcov profile coverage +CMD: grep "called 0 returned" ../client/*.gcov +../client/config_init.c.gcov:function digest_strtoint called 0 returned 0% blocks executed 0% +../client/config_init.c.gcov:function proto_strtoint called 0 returned 0% blocks executed 0% +../client/config_init.c.gcov:function create_fwknoprc called 0 returned 0% blocks executed 0% +../client/config_init.c.gcov:function parse_rc_param called 0 returned 0% blocks executed 0% +../client/fwknop.c.gcov:function show_last_command called 0 returned 0% blocks executed 0% +../client/fwknop.c.gcov:function run_last_args called 0 returned 0% blocks executed 0% +../client/getpasswd.c.gcov:function getpasswd called 0 returned 0% blocks executed 0% +../client/http_resolve_host.c.gcov:function parse_url called 0 returned 0% blocks executed 0% +../client/http_resolve_host.c.gcov:function resolve_ip_http called 0 returned 0% blocks executed 0% +../client/spa_comm.c.gcov:function chksum called 0 returned 0% blocks executed 0% +../client/spa_comm.c.gcov:function send_spa_packet_tcp_raw called 0 returned 0% blocks executed 0% +../client/spa_comm.c.gcov:function send_spa_packet_icmp called 0 returned 0% blocks executed 0% +../client/spa_comm.c.gcov:function send_spa_packet_http called 0 returned 0% blocks executed 0% +../client/spa_comm.c.gcov:function write_spa_packet_data called 0 returned 0% blocks executed 0% +../client/utils.c.gcov:function hex_dump called 0 returned 0% blocks executed 0% +CMD: grep "called 0 returned" ../server/*.gcov +../server/access.c.gcov:function acc_check_gpg_remote_id called 0 returned 0% blocks executed 0% +../server/config_init.c.gcov:function config_entry_index called 0 returned 0% blocks executed 0% +../server/extcmd.c.gcov:function run_extcmd_as called 0 returned 0% blocks executed 0% +../server/fwknopd.c.gcov:function make_dir_path called 0 returned 0% blocks executed 0% +../server/fwknopd.c.gcov:function daemonize_process called 0 returned 0% blocks executed 0% +../server/log_msg.c.gcov:function set_log_facility called 0 returned 0% blocks executed 0% +../server/replay_cache.c.gcov:function rotate_digest_cache_file called 0 returned 0% blocks executed 0% +../server/tcp_server.c.gcov:function run_tcp_server called 0 returned 0% blocks executed 0% +../server/utils.c.gcov:function hex_dump called 0 returned 0% blocks executed 0% +CMD: grep "called 0 returned" ../lib/.libs/*.gcov +../lib/.libs/digest.c.gcov:function digest_to_hex called 0 returned 0% blocks executed 0% +../lib/.libs/digest.c.gcov:function md5_hex called 0 returned 0% blocks executed 0% +../lib/.libs/digest.c.gcov:function md5_base64 called 0 returned 0% blocks executed 0% +../lib/.libs/digest.c.gcov:function sha1 called 0 returned 0% blocks executed 0% +../lib/.libs/digest.c.gcov:function sha1_hex called 0 returned 0% blocks executed 0% +../lib/.libs/digest.c.gcov:function sha1_base64 called 0 returned 0% blocks executed 0% +../lib/.libs/digest.c.gcov:function sha256_hex called 0 returned 0% blocks executed 0% +../lib/.libs/digest.c.gcov:function sha384 called 0 returned 0% blocks executed 0% +../lib/.libs/digest.c.gcov:function sha384_hex called 0 returned 0% blocks executed 0% +../lib/.libs/digest.c.gcov:function sha384_base64 called 0 returned 0% blocks executed 0% +../lib/.libs/digest.c.gcov:function sha512 called 0 returned 0% blocks executed 0% +../lib/.libs/digest.c.gcov:function sha512_hex called 0 returned 0% blocks executed 0% +../lib/.libs/digest.c.gcov:function sha512_base64 called 0 returned 0% blocks executed 0% +../lib/.libs/fko_encryption.c.gcov:function fko_get_spa_encryption_type called 0 returned 0% blocks executed 0% +../lib/.libs/fko_encryption.c.gcov:function fko_set_gpg_exe called 0 returned 0% blocks executed 0% +../lib/.libs/fko_encryption.c.gcov:function fko_get_gpg_exe called 0 returned 0% blocks executed 0% +../lib/.libs/fko_encryption.c.gcov:function fko_get_gpg_recipient called 0 returned 0% blocks executed 0% +../lib/.libs/fko_encryption.c.gcov:function fko_get_gpg_signer called 0 returned 0% blocks executed 0% +../lib/.libs/fko_encryption.c.gcov:function fko_get_gpg_home_dir called 0 returned 0% blocks executed 0% +../lib/.libs/fko_encryption.c.gcov:function fko_get_gpg_signature_verify called 0 returned 0% blocks executed 0% +../lib/.libs/fko_encryption.c.gcov:function fko_get_gpg_ignore_verify_error called 0 returned 0% blocks executed 0% +../lib/.libs/fko_encryption.c.gcov:function fko_get_gpg_signature_fpr called 0 returned 0% blocks executed 0% +../lib/.libs/fko_encryption.c.gcov:function fko_get_gpg_signature_id called 0 returned 0% blocks executed 0% +../lib/.libs/fko_encryption.c.gcov:function fko_get_gpg_signature_summary called 0 returned 0% blocks executed 0% +../lib/.libs/fko_encryption.c.gcov:function fko_get_gpg_signature_status called 0 returned 0% blocks executed 0% +../lib/.libs/fko_encryption.c.gcov:function fko_gpg_signature_id_match called 0 returned 0% blocks executed 0% +../lib/.libs/fko_encryption.c.gcov:function fko_gpg_signature_fpr_match called 0 returned 0% blocks executed 0% +../lib/.libs/fko_funcs.c.gcov:function fko_set_spa_data called 0 returned 0% blocks executed 0% +../lib/.libs/fko_message.c.gcov:function validate_cmd_msg called 0 returned 0% blocks executed 0% +../lib/.libs/fko_server_auth.c.gcov:function fko_set_spa_server_auth called 0 returned 0% blocks executed 0% +../lib/.libs/gpgme.h.gcov:function gpgme_err_code called 0 returned 0% blocks executed 0% +../lib/.libs/gpgme_funcs.c.gcov:function process_sigs called 0 returned 0% blocks executed 0% +../lib/.libs/sha1.c.gcov:function sha1_transform called 0 returned 0% blocks executed 0% +../lib/.libs/sha1.c.gcov:function sha1_init called 0 returned 0% blocks executed 0% +../lib/.libs/sha1.c.gcov:function sha1_update called 0 returned 0% blocks executed 0% +../lib/.libs/sha1.c.gcov:function sha1_transform_and_copy called 0 returned 0% blocks executed 0% +../lib/.libs/sha1.c.gcov:function sha1_final called 0 returned 0% blocks executed 0% +../lib/.libs/sha2.c.gcov:function SHA256_End called 0 returned 0% blocks executed 0% +../lib/.libs/sha2.c.gcov:function SHA256_Data called 0 returned 0% blocks executed 0% +../lib/.libs/sha2.c.gcov:function SHA512_Init called 0 returned 0% blocks executed 0% +../lib/.libs/sha2.c.gcov:function SHA512_Transform called 0 returned 0% blocks executed 0% +../lib/.libs/sha2.c.gcov:function SHA512_Update called 0 returned 0% blocks executed 0% +../lib/.libs/sha2.c.gcov:function SHA512_Last called 0 returned 0% blocks executed 0% +../lib/.libs/sha2.c.gcov:function SHA512_Final called 0 returned 0% blocks executed 0% +../lib/.libs/sha2.c.gcov:function SHA512_End called 0 returned 0% blocks executed 0% +../lib/.libs/sha2.c.gcov:function SHA512_Data called 0 returned 0% blocks executed 0% +../lib/.libs/sha2.c.gcov:function SHA384_Init called 0 returned 0% blocks executed 0% +../lib/.libs/sha2.c.gcov:function SHA384_Update called 0 returned 0% blocks executed 0% +../lib/.libs/sha2.c.gcov:function SHA384_Final called 0 returned 0% blocks executed 0% +../lib/.libs/sha2.c.gcov:function SHA384_End called 0 returned 0% blocks executed 0% +../lib/.libs/sha2.c.gcov:function SHA384_Data called 0 returned 0% blocks executed 0% diff --git a/test/test-fwknop.pl b/test/test-fwknop.pl index a5f0ab2f..f59e5c03 100755 --- a/test/test-fwknop.pl +++ b/test/test-fwknop.pl @@ -4,6 +4,7 @@ use File::Copy; use File::Path; use IO::Socket; use Data::Dumper; +use Cwd; use Getopt::Long 'GetOptions'; use strict; @@ -85,7 +86,9 @@ my $valgrind_str = ''; my $saved_last_results = 0; my $diff_mode = 0; my $enable_recompilation_warnings_check = 0; +my $enable_profile_coverage_check = 0; my $sudo_path = ''; +my $gcov_path = ''; my $platform = ''; my $help = 0; my $YES = 1; @@ -115,6 +118,7 @@ exit 1 unless GetOptions( 'test-exclude=s' => \$test_exclude, 'exclude=s' => \$test_exclude, ### synonym 'enable-recompile-check' => \$enable_recompilation_warnings_check, + 'enable-profile-coverage-check' => \$enable_profile_coverage_check, 'List-mode' => \$list_mode, 'enable-valgrind' => \$use_valgrind, 'valgrind-path=s' => \$valgrindCmd, @@ -1307,6 +1311,14 @@ my @tests = ( 'function' => \&digest_cache_structure, 'fatal' => $NO }, + + { + 'category' => 'profile coverage', + 'detail' => 'gcov profile coverage', + 'err_msg' => 'profile coverage failed', + 'function' => \&profile_coverage, + 'fatal' => $NO + }, ); my %test_keys = ( @@ -1526,7 +1538,8 @@ sub compile_warnings() { ### look for compilation warnings - something like: ### warning: ‘test’ is used uninitialized in this function - return 0 if &file_find_regex([qr/\swarning:\s/, qr/gcc\:.*\sunused/], $current_test_file); + return 0 if &file_find_regex([qr/\swarning:\s/, qr/gcc\:.*\sunused/], + $current_test_file); ### the new binaries should exist unless (-e $fwknopCmd and -x $fwknopCmd) { @@ -1541,6 +1554,32 @@ sub compile_warnings() { return 1; } +sub profile_coverage() { + + ### check for any *.gcno files - if they don't exist, then fwknop was + ### not compiled with profile support + unless (glob('../client/*.gcno') and glob('../server/*.gcno')) { + &write_test_file("[-] ../client/*.gcno and " . + "../server/*.gcno files do not exist.\n", $current_test_file); + return 0; + } + + my $curr_dir = getcwd() or die $!; + + ### gcov -b ../client/*.gcno + for my $dir ('../client', '../server', '../lib/.libs') { + next unless -d $dir; + chdir $dir or die $!; + system "$gcov_path -b -u *.gcno > /dev/null 2>&1"; + chdir $curr_dir or die $!; + + &run_cmd(qq|grep "called 0 returned" $dir/*.gcov|, + $cmd_out_tmp, $current_test_file); + } + + return 1; +} + sub binary_exists() { my $test_hr = shift; return 0 unless $test_hr->{'binary'}; @@ -2576,6 +2615,10 @@ sub init() { push @tests_to_exclude, 'recompilation'; } + unless ($enable_profile_coverage_check) { + push @tests_to_exclude, 'profile coverage'; + } + $sudo_path = &find_command('sudo'); unless ((&find_command('cc') or &find_command('gcc')) and &find_command('make')) { @@ -2583,6 +2626,19 @@ sub init() { push @tests_to_exclude, 'recompilation'; } + $gcov_path = &find_command('gcov'); + + if ($gcov_path) { + if ($enable_profile_coverage_check) { + for my $extension ('*.gcov', '*.gcda') { + ### remove profile output from any previous run + system qq{find .. -name $extension | xargs rm 2> /dev/null}; + } + } + } else { + push @tests_to_exclude, 'profile coverage'; + } + open UNAME, "uname |" or die "[*] Could not execute uname: $!"; while () { if (/linux/i) { @@ -2766,3 +2822,7 @@ sub logr() { close F; return; } + +sub usage() { + return; +}