commit 74d8861cced9ca583039438354e7e9665f99129d
parent 77c51f8bd803b8cde13f2cee3217a32d5d88c684
Author: Kyle Milz <kyle@0x30.net>
Date: Sun, 26 Jun 2016 21:14:34 -0600
Test/Viewer: rework to be more sane
- add test ok()'s to functions in this class
- rename some things to match runtime
- add some helpers for test verification and use them
Diffstat:
5 files changed, 91 insertions(+), 109 deletions(-)
diff --git a/Test/Viewer.pm b/Test/Viewer.pm
@@ -2,7 +2,8 @@ package Test::Viewer;
use strict;
use IO::Socket::UNIX;
-use Test;
+use List::MoreUtils qw( each_array );
+use Test::More;
my $viewer_socket_name = "citrun-test.socket";
@@ -25,64 +26,64 @@ sub new {
sub accept {
my ($self) = @_;
+ # Accept a new connection on the listening viewer socket.
my $socket = $self->{viewer_socket};
- $self->{client_socket} = $socket->accept();
-}
-sub get_metadata {
- my ($self) = @_;
- my $client = $self->{client_socket};
+ my $client = $socket->accept();
+ $self->{client_socket} = $client;
- # First thing sent is total number of translation units
+ # Read the total number of instrumented translation units.
my $buf = read_all($client, 8);
- my $num_tus = unpack("Q", $buf);
+ $self->{num_tus} = unpack("Q", $buf);
- # Next is the 3 4 byte pid_t's
+ # Read three 4 byte pid_t's
$buf = read_all($client, 12);
- my ($pid, $ppid, $pgrp) = unpack("L3", $buf);
-
- my $runtime_metadata = {
- num_tus => $num_tus,
- pid => $pid,
- ppid => $ppid,
- pgrp => $pgrp,
- };
-
- my @tus_ordered;
- my %tus;
- for (1..$num_tus) {
+ ($self->{pid}, $self->{ppid}, $self->{pgrp}) = unpack("L3", $buf);
+
+ # Always sanity check these.
+ cmp_ok( $self->{pid}, ">", 1, "pid lower bound check" );
+ cmp_ok( $self->{pid}, "<", 100000, "pid upper bound check" );
+ cmp_ok( $self->{ppid}, ">", 1, "ppid lower bound check" );
+ cmp_ok( $self->{ppid}, "<", 100000, "ppid upper bound check" );
+ cmp_ok( $self->{pgrp}, ">", 1, "pgrp lower bound check" );
+ cmp_ok( $self->{pgrp}, "<", 100000, "pgrp upper bound check" );
+
+ # Read the static translation unit information.
+ my @tus;
+ for (1..$self->{num_tus}) {
+ # Size of absolute file path.
my $buf = read_all($client, 8);
my $file_name_sz = unpack("Q", $buf);
+ # Absolute file path.
my $file_name = read_all($client, $file_name_sz);
+ # Total number of lines in primary source file.
$buf = read_all($client, 4);
my $num_lines = unpack("L", $buf);
+ # Number of instrumentation sites in primary source file.
$buf = read_all($client, 4);
my $inst_sites = unpack("L", $buf);
- push @tus_ordered, $file_name;
- $tus{$file_name} = { lines => $num_lines, inst_sites => $inst_sites };
+ # Keep this in order so it's easy to fetch dynamic data.
+ push @tus, [ $file_name, $num_lines, $inst_sites ];
}
- $runtime_metadata->{tus_ordered} = \@tus_ordered;
- $runtime_metadata->{tus} = \%tus;
-
- return $runtime_metadata;
+ $self->{tus} = \@tus;
}
-sub get_execution_data {
- my ($self, $tus_ordered, $tus) = @_;
- my $client = $self->{client_socket};
+sub get_dynamic_data {
+ my ($self) = @_;
+ my $client = $self->{client_socket};
my %data;
- for my $file_name (@$tus_ordered) {
- my $num_lines = $tus->{$file_name}->{lines};
+ for my $tu (@{ $self->{tus} }) {
+ my $num_lines = $tu->[1];
my $buf = read_all($client, 8 * $num_lines);
my @data_tmp = unpack("Q$num_lines", $buf);
- $data{$file_name} = \@data_tmp;
+ $data{$tu->[0]} = \@data_tmp;
}
# Send an 'ok' response
@@ -91,6 +92,25 @@ sub get_execution_data {
return \%data;
}
+sub cmp_static_data {
+ my ($self, $known_good) = @_;
+
+ # Sort these alphabetically by file name (field 0).
+ my @sorted_tus = sort { $a->[0] cmp $b->[0] } @{ $self->{tus} };
+
+ # Walk two lists at the same time
+ # http://stackoverflow.com/questions/822563/how-can-i-iterate-over-multiple-lists-at-the-same-time-in-perl
+ my $it = each_array( @$known_good, @sorted_tus );
+ while ( my ($x, $y) = $it->() ) {
+ like( $y->[0], qr/.*$x->[0]/, "$x->[0]: filename check" );
+ is ( $y->[1], $x->[1], "$x->[0]: total lines check" );
+
+ # Check instrumented sites ranges
+ cmp_ok ( $y->[2], ">", $x->[2] - 5, "$x->[0]: instr sites check lower" );
+ cmp_ok ( $y->[2], "<", $x->[2] + 5, "$x->[0]: instr sites check upper" );
+ }
+}
+
sub read_all {
my ($sock, $bytes_total) = @_;
diff --git a/t/runtime_counters_increase.t b/t/runtime_counters_increase.t
@@ -1,6 +1,7 @@
use strict;
-use Test::More tests => 14;
+use Data::Dumper;
+use Test::More tests => 25;
use Test::Differences;
use Test::Project;
@@ -40,32 +41,28 @@ main(int argc, char *argv[])
}
EOF
-# Compile the above inefficient program and have it compute the input 40, which
-# takes a few seconds
+# Compile above inefficient program and let it run for a few seconds.
$project->compile();
$project->run(45);
-# Accept the runtime's connection
+# Accept the runtime connection and check a few things.
$viewer->accept();
-my $runtime_metadata = $viewer->get_metadata();
-my $tus_ordered = $runtime_metadata->{tus_ordered};
-my $tus = $runtime_metadata->{tus};
+is( $viewer->{num_tus}, 1, "num tus check" );
+$viewer->cmp_static_data([ [ "source_0.c", 28, 18 ] ]);
-my ($file_name) = keys %$tus;
-like ($file_name, qr/.*source_0\.c/, "runtime filename check");
-is( $tus->{$file_name}->{lines}, 28, "runtime lines count" );
+my $data = $viewer->get_dynamic_data();
+ok( keys %$data == 1, "single dynamic data key" );
+my ($exec_lines1) = values %$data;
-my $data = $viewer->get_execution_data($tus_ordered, $tus);
-my @exec_lines1 = @{ $data->{$file_name} };
-
-my $data = $viewer->get_execution_data($tus_ordered, $tus);
-my @exec_lines2 = @{ $data->{$file_name} };
+my $data = $viewer->get_dynamic_data();
+ok( keys %$data == 1, "single dynamic data key" );
+my ($exec_lines2) = values %$data;
# Only lines 8 - 12 in the source code above are executing
for (8..12) {
- cmp_ok( $exec_lines1[$_], ">", 0, "line $_ executed nonzero times" );
+ cmp_ok( $exec_lines1->[$_], ">", 0, "line $_ executed nonzero times" );
# Make sure the second time we queried the execution counts they were higher
- cmp_ok( $exec_lines2[$_], ">=", $exec_lines1[$_], "line $_ after > before" );
+ cmp_ok( $exec_lines2->[$_], ">=", $exec_lines1->[$_], "line $_ after > before" );
}
$project->kill();
diff --git a/t/runtime_metadata.t b/t/runtime_metadata.t
@@ -1,6 +1,6 @@
use strict;
-use Test::More tests => 11;
+use Test::More tests => 13;
use Test::Project;
use Test::Viewer;
@@ -22,28 +22,10 @@ $project->compile();
$project->run();
$viewer->accept();
+is( $viewer->{num_tus}, 1, "translation unit count" );
-# Request and check metadata first
-my $runtime_metadata = $viewer->get_metadata();
-
-my $pid = $runtime_metadata->{pid};
-my $ppid = $runtime_metadata->{ppid};
-my $pgrp = $runtime_metadata->{pgrp};
-
-cmp_ok( $pid, ">", 1, "pid is positive" );
-cmp_ok( $ppid, ">", 1, "ppid is positive" );
-cmp_ok( $pgrp, ">", 1, "pgrp is positive" );
-
-cmp_ok( $pid, "<", 100 * 1000, "pid is a reasonable value" );
-cmp_ok( $ppid, "<", 100 * 1000, "ppid is a reasonable value" );
-cmp_ok( $pgrp, "<", 100 * 1000, "pgrp is a reasonable value" );
-
-my $tus = $runtime_metadata->{tus};
-is ( scalar(keys %$tus), 1, "translation unit count" );
-
-my ($file_name) = keys %$tus;
-like( $file_name, qr/.*source_0.c/, "filename check" );
-is( $tus->{$file_name}->{lines}, 8, "line count check" );
+my @known_good = [ [ "source_0.c", 8, 2 ] ];
+$viewer->cmp_static_data(@known_good);
$project->kill();
my ($ret, $err) = $project->wait();
diff --git a/t/runtime_reconnect.t b/t/runtime_reconnect.t
@@ -1,6 +1,6 @@
use strict;
-use Test::More tests => 5;
+use Test::More tests => 13;
use Test::Project;
use Test::Viewer;
@@ -24,16 +24,8 @@ sleep(1);
my $viewer = Test::Viewer->new();
$viewer->accept();
-
-# Request and check metadata first
-my $runtime_metadata = $viewer->get_metadata();
-
-my $tus = $runtime_metadata->{tus};
-is ( scalar(keys %$tus), 1, "translation unit count" );
-
-my ($file_name) = keys %$tus;
-like( $file_name, qr/.*source_0.c/, "filename check" );
-is( $tus->{$file_name}->{lines}, 7, "line count check" );
+is( $viewer->{num_tus}, 1, "num tus check" );
+$viewer->cmp_static_data([ [ "source_0.c", 7, 2 ] ]);
$project->kill();
my ($ret, $err) = $project->wait();
diff --git a/t/runtime_sanity.t b/t/runtime_sanity.t
@@ -1,7 +1,7 @@
use strict;
use Data::Dumper;
-use Test::More tests => 50;
+use Test::More tests => 58;
use Test::Differences;
use Test::Project;
@@ -61,33 +61,24 @@ $project->compile();
$project->run(45);
$viewer->accept();
+is( $viewer->{num_tus}, 3, "translation unit count" );
-# Request and check metadata first
-my $runtime_metadata = $viewer->get_metadata();
-my $tus_ordered = $runtime_metadata->{tus_ordered};
-my $tus = $runtime_metadata->{tus};
+# Check static data.
+my @known_good = [
+ # filename lines inst sites
+ [ "source_0.c", 20, 9 ],
+ [ "source_1.c", 11, 7 ],
+ [ "source_2.c", 9, 6 ],
+];
+$viewer->cmp_static_data(@known_good);
-my ($fn0, $fn1, $fn2) = sort keys %$tus;
-like( $fn0, qr/.*source_0.c/, "runtime filename check 0" );
-is( $tus->{$fn0}->{lines}, 20, "runtime line count check 0" );
-my $sites0 = $tus->{$fn0}->{inst_sites};
-cmp_ok( $sites0, ">=", 6, "site count 0 lower" );
-cmp_ok( $sites0, "<=", 11, "site count 0 upper" );
+# Request and check execution data.
+my $data = $viewer->get_dynamic_data();
-like( $fn1, qr/.*source_1.c/, "runtime filename check 1" );
-is( $tus->{$fn1}->{lines}, 11, "runtime line count check 1" );
-is( $tus->{$fn1}->{inst_sites}, 7, "instrumented site count 1" );
+# The nodes can be in any order.
+my ($s0, $s1, $s2) = sort keys %$data;
-like( $fn2, qr/.*source_2.c/, "runtime filename check 2" );
-is( $tus->{$fn2}->{lines}, 9, "runtime line count check 2" );
-my $sites2 = $tus->{$fn2}->{inst_sites};
-cmp_ok( $sites2, ">=", 5, "site count 2 lower" );
-cmp_ok( $sites2, "<=", 6, "site count 2 upper" );
-
-# Request and check execution data
-my $data = $viewer->get_execution_data($tus_ordered, $tus);
-
-my @lines = @{ $data->{$fn0} };
+my @lines = @{ $data->{$s0} };
is( $lines[$_], 0, "src 0 line $_ check" ) for (1..11);
is( $lines[12], 1, "src 0 line 14 check" );
is( $lines[$_], 0, "src 0 line $_ check" ) for (13..14);
@@ -96,12 +87,12 @@ is( $lines[16], 0, "src 0 line 16 check" );
is( $lines[17], 2, "src 0 line 17 check" );
is( $lines[$_], 0, "src 0 line $_ check" ) for (18..19);
-my @lines = @{ $data->{$fn1} };
+my @lines = @{ $data->{$s1} };
is( $lines[$_], 0, "src 1 line $_ check" ) for (0..3);
cmp_ok ( $lines[$_], ">", 10, "src 1 line $_ check" ) for (4..7);
is( $lines[8], 0, "src 1 line 8 check" );
-my @lines = @{ $data->{$fn2} };
+my @lines = @{ $data->{$s2} };
is( $lines[$_], 0, "src 2 line $_ check" ) for (0..8);
$project->kill();