citrun

watch C/C++ source code execute
Log | Files | Refs | LICENSE

commit 916457a12e9ecaaaaeee08995c77480ad0f06fc2
parent 7bf9c8071d19ad0edcdf7856e4c3c911c03443a7
Author: Kyle Milz <kyle@getaddrinfo.net>
Date:   Sun, 13 Mar 2016 14:08:59 -0600

t: add a ->kill() method and use it to speed up tests

- before we would wait for tests to finish, but this is too volatile
- instead, compute something outrageous, gather info, and kill it early

Diffstat:
MSCV/Project.pm | 5+++++
At/runtime_counters_increase.t | 84+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mt/runtime_sanity.t | 103++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Dt/runtime_sanity_multisource.t | 96-------------------------------------------------------------------------------
4 files changed, 146 insertions(+), 142 deletions(-)

diff --git a/SCV/Project.pm b/SCV/Project.pm @@ -85,6 +85,11 @@ sub run { $self->{pid} = open3(undef, undef, \*CHLD_ERR, "$tmp_dir/program", @args); } +sub kill { + my ($self) = @_; + kill 'TERM', $self->{pid}; +} + sub wait { my ($self) = @_; diff --git a/t/runtime_counters_increase.t b/t/runtime_counters_increase.t @@ -0,0 +1,84 @@ +use strict; +use SCV::Project; +use SCV::Viewer; +use Test::More tests => 38; +use Test::Differences; +use Time::HiRes qw( usleep ); + +my $project = SCV::Project->new(); +my $viewer = SCV::Viewer->new(); +unified_diff; + +$project->add_src( +<<EOF +#include <err.h> +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> + +long long +fib(long long n) +{ + if (n == 0) + return 0; + else if (n == 1) + return 1; + + return fib(n - 1) + fib(n - 2); +} + +int +main(int argc, char *argv[]) +{ + long long n; + const char *errstr = NULL; + + if (argc != 2) + errx(1, "argc != 2"); + + n = strtonum(argv[1], LONG_MIN, LONG_MAX, &errstr); + if (errstr) + err(1, "%s", errstr); + + fprintf(stderr, "%lli", fib(n)); + return 0; +} +EOF +); + +# Compile the above inefficient program and have it compute the input 40, which +# takes a few seconds +$project->compile(); +$project->run(45); + +# Accept the runtime's connection +$viewer->accept(); + +usleep(100 * 1000); +my $data = $viewer->request_data(); + +my ($file_name, @others) = keys %$data; +like ($file_name, qr/tmp\/.*source_0\.c/, "runtime filename check"); +is( @others, 0, "runtime check for a single tu" ); + +my @lines = @{ $data->{$file_name} }; +is (scalar(@lines), 33, "runtime lines count"); + +# Do a pretty thorough coverage check +is ( $lines[$_], 0, "line $_ check" ) for (0..8); +cmp_ok ( $lines[$_], ">", 0, "line $_ check" ) for (9..12); +is ( $lines[13], 0, "line 13 check" ); +cmp_ok ( $lines[14], ">", 0, "line 14 check" ); +is ( $lines[$_], 0, "line $_ check" ) for (15..22); +is ( $lines[23], 1, "line 23 check" ); +is ( $lines[$_], 0, "line $_ check" ) for (24..25); +is ( $lines[$_], 1, "line $_ check" ) for (26..27); +is ( $lines[$_], 0, "line $_ check" ) for (28..29); +is ( $lines[30], 2, "line 30 check" ); +# Make sure return code hasn't fired yet +is ( $lines[$_], 0, "line $_ check" ) for (31..32); + +$project->kill(); +my ($ret, $err) = $project->wait(); +is( $ret, 0, "runtime sanity return code check" ); +is( $err, undef, "runtime sanity program output" ); diff --git a/t/runtime_sanity.t b/t/runtime_sanity.t @@ -1,31 +1,21 @@ use strict; +use Data::Dumper; use SCV::Project; use SCV::Viewer; -use Test::More tests => 38; +use Test::More tests => 47; use Test::Differences; -use Time::HiRes qw( usleep ); -my $project = SCV::Project->new(); my $viewer = SCV::Viewer->new(); +my $project = SCV::Project->new(); unified_diff; -$project->add_src( -<<EOF +$project->add_src(<<EOF #include <err.h> #include <limits.h> -#include <stdio.h> -#include <stdlib.h> +#include <stdlib.h> /* strtonum */ -long long -fib(long long n) -{ - if (n == 0) - return 0; - else if (n == 1) - return 1; - - return fib(n - 1) + fib(n - 2); -} +long long fib(long long); +void print_output(long long); int main(int argc, char *argv[]) @@ -40,44 +30,65 @@ main(int argc, char *argv[]) if (errstr) err(1, "%s", errstr); - fprintf(stderr, "%lli", fib(n)); + print_output(fib(n)); return 0; } EOF ); -# Compile the above inefficient program and have it compute the input 40, which -# takes a few seconds +$project->add_src(<<EOF +long long +fib(long long n) +{ + if (n == 0) + return 0; + else if (n == 1) + return 1; + + return fib(n - 1) + fib(n - 2); +} +EOF +); + +$project->add_src(<<EOF +#include <stdio.h> + +void +print_output(long long n) +{ + fprintf(stderr, "%lli", n); + return; +} +EOF +); + $project->compile(); -$project->run(40); +$project->run(45); -# Accept the runtime's connection $viewer->accept(); - -usleep(100 * 1000); my $data = $viewer->request_data(); -my ($file_name, @others) = keys %$data; -like ($file_name, qr/tmp\/.*source_0\.c/, "runtime filename check"); -is( @others, 0, "runtime check for a single tu" ); - -my @lines = @{ $data->{$file_name} }; -is (scalar(@lines), 33, "runtime lines count"); - -# Do a pretty thorough coverage check -is ( $lines[$_], 0, "line $_ check" ) for (0..8); -cmp_ok ( $lines[$_], ">", 0, "line $_ check" ) for (9..12); -is ( $lines[13], 0, "line 13 check" ); -cmp_ok ( $lines[14], ">", 0, "line 14 check" ); -is ( $lines[$_], 0, "line $_ check" ) for (15..22); -is ( $lines[23], 1, "line 23 check" ); -is ( $lines[$_], 0, "line $_ check" ) for (24..25); -is ( $lines[$_], 1, "line $_ check" ) for (26..27); -is ( $lines[$_], 0, "line $_ check" ) for (28..29); -is ( $lines[30], 2, "line 30 check" ); -# Make sure return code hasn't fired yet -is ( $lines[$_], 0, "line $_ check" ) for (31..32); +like ($_, qr/tmp\/.*source_.*\.c/, "runtime filename check") for (keys %$data); +my ($src_filename_0, $src_filename_1, $src_filename_2) = sort keys %$data; + +my @lines = @{ $data->{$src_filename_0} }; +is ( $lines[$_], 0, "src 0 line $_ check" ) for (0..13); +is ( $lines[14], 1, "src 0 line 14 check" ); +is ( $lines[$_], 0, "src 0 line $_ check" ) for (15..16); +is ( $lines[$_], 1, "src 0 line $_ check" ) for (17..18); +is ( $lines[$_], 0, "src 0 line $_ check" ) for (19..20); +is ( $lines[21], 2, "src 0 line 21 check" ); +is ( $lines[$_], 0, "src 0 line $_ check" ) for (22..23); + +my @lines = @{ $data->{$src_filename_1} }; +is ( $lines[$_], 0, "src 1 line $_ check" ) for (0..3); +cmp_ok ( $lines[$_], ">", 100, "src 1 line $_ check" ) for (4..7); +is ( $lines[8], 0, "src 1 line 8 check" ); + +my @lines = @{ $data->{$src_filename_2} }; +is ( $lines[$_], 0, "src 2 line $_ check" ) for (0..8); +$project->kill(); my ($ret, $err) = $project->wait(); -is( $ret, 0, "runtime sanity return code check" ); -is( $err, "102334155", "runtime sanity program output" ); +is( $ret, 0, "instrumented program check return code" ); +is( $err, undef, "instrumented program check stderr" ); diff --git a/t/runtime_sanity_multisource.t b/t/runtime_sanity_multisource.t @@ -1,96 +0,0 @@ -use strict; -use Data::Dumper; -use SCV::Project; -use SCV::Viewer; -use Test::More tests => 47; -use Test::Differences; - -my $viewer = SCV::Viewer->new(); -my $project = SCV::Project->new(); -unified_diff; - -$project->add_src(<<EOF -#include <err.h> -#include <limits.h> -#include <stdlib.h> /* strtonum */ - -long long factorial(long long); -void print_output(long long); - -int -main(int argc, char *argv[]) -{ - long long n; - const char *errstr = NULL; - - if (argc != 2) - errx(1, "argc != 2"); - - n = strtonum(argv[1], LONG_MIN, LONG_MAX, &errstr); - if (errstr) - err(1, "%s", errstr); - - print_output(factorial(n)); - return 0; -} -EOF -); - -$project->add_src(<<EOF -long long -factorial(long long n) -{ - if (n == 0) - return 1; - - return n * factorial(n - 1); -} -EOF -); - -$project->add_src(<<EOF -#include <stdio.h> - -void -print_output(long long n) -{ - fprintf(stderr, "%lli", n); - return; -} -EOF -); - -$project->compile(); -$project->run(17); - -$viewer->accept(); -my $data = $viewer->request_data(); - -like ($_, qr/tmp\/.*source_.*\.c/, "runtime filename check") for (keys %$data); -my ($src_filename_0, $src_filename_1, $src_filename_2) = sort keys %$data; - -my @lines = @{ $data->{$src_filename_0} }; -is ( $lines[$_], 0, "src 0 line $_ check" ) for (0..13); -is ( $lines[14], 1, "src 0 line 14 check" ); -is ( $lines[$_], 0, "src 0 line $_ check" ) for (15..16); -is ( $lines[$_], 1, "src 0 line $_ check" ) for (17..18); -is ( $lines[$_], 0, "src 0 line $_ check" ) for (19..20); -is ( $lines[21], 2, "src 0 line 21 check" ); -is ( $lines[$_], 0, "src 0 line $_ check" ) for (22..23); - -my @lines = @{ $data->{$src_filename_1} }; -is ( $lines[$_], 0, "src 1 line $_ check" ) for (0..3); -is ( $lines[4], 18, "src 1 line 4 check" ); -is ( $lines[5], 1, "src 1 line 5 check" ); -is ( $lines[6], 0, "src 1 line 6 check" ); -is ( $lines[7], 34, "src 1 line 7 check" ); -is ( $lines[8], 0, "src 1 line 8 check" ); - -my @lines = @{ $data->{$src_filename_2} }; -is ( $lines[$_], 0, "src 2 line $_ check" ) for (0..5); -is ( $lines[6], 1, "src 2 line 6 check" ); -is ( $lines[$_], 0, "src 2 line $_ check" ) for (7..8); - -my ($ret, $err) = $project->wait(); -is( $ret, 0, "instrumented program check return code" ); -is( $err, "355687428096000", "instrumented program check stderr" );