commit 79240861a80ea5a0d3a7eb14ee66a66955718210
parent 1cbcadace764312fcc0fc9c1e028e3b8843b7f83
Author: Kyle Milz <kyle@0x30.net>
Date: Mon, 29 Aug 2016 20:32:28 -0600
t: convert exec totals to perl
Diffstat:
3 files changed, 120 insertions(+), 37 deletions(-)
diff --git a/t/rt_exectotals.sh b/t/rt_exectotals.sh
@@ -1,37 +0,0 @@
-#
-# Test that we can count an executing program as its running.
-#
-. test/utils.sh
-plan 4
-
-cat <<EOF > check_totals.cc
-#include "src/process_dir.h"
-#include "test/basic.h"
-
-#include <iostream>
-
-int
-main(void)
-{
- ProcessDir pdir;
- pdir.scan();
-
- ProcessFile f = pdir.m_procfiles[0];
-
- for (int i = 0; i < 60; i++)
- std::cout << f.total_execs() << std::endl;
-}
-EOF
-
-ok "tap program compile" clang++ -std=c++11 -c check_totals.cc \
- -I$CITRUN_TOOLS/..
-ok "tap program link" clang++ -o tap_program check_totals.o \
- $CITRUN_TOOLS/utils.a $CITRUN_TOOLS/../test/tap.a
-
-program 45 &
-pid=$!
-
-ok "tap program run" tap_program
-
-kill $pid
-wait
diff --git a/t/rt_exectotals.t b/t/rt_exectotals.t
@@ -0,0 +1,33 @@
+#
+# Test that we can count an executing program as its running.
+#
+use strict;
+use warnings;
+use POSIX;
+use Test::More tests => 100;
+use Time::HiRes qw( usleep );
+use test::shm;
+
+my $child_pid = fork();
+if ($child_pid == 0) {
+ # Child.
+ exec ("test/program", "45");
+}
+
+sleep 1;
+my $shm = test::shm->new();
+
+my $last_total = 0;
+for (0..99) {
+ usleep 10 * 1000;
+ my $total = 0;
+
+ for (0..2) {
+ my $execs = $shm->execs_for($_);
+ $total += $_ for (@$execs);
+ }
+ cmp_ok $total, '>', $last_total, "new total > old total";
+}
+
+kill 'TERM', $child_pid;
+wait;
diff --git a/test/shm.pm b/test/shm.pm
@@ -0,0 +1,87 @@
+package test::shm;
+use strict;
+use warnings;
+use Cwd;
+use POSIX;
+
+$ENV{CITRUN_TOOLS} = cwd . '/src';
+
+sub new {
+ my ($class) = @_;
+
+ my $self = {};
+ bless($self, $class);
+
+ open(my $fh, "<:mmap", "procfile.shm") or die $!;
+ $self->{fh} = $fh;
+ $self->{size} = (stat "procfile.shm")[7];
+
+ ($self->{major}, $self->{minor}) = unpack("C2", xread($fh, 2));
+ @{ $self->{pids} } = unpack("L3", xread($fh, 12));
+
+ ($self->{prg_sz}) = unpack("S", xread($fh, 2));
+ ($self->{progname}) = xread($fh, $self->{prg_sz});
+ ($self->{cwd_sz}) = unpack("S", xread($fh, 2));
+ ($self->{cwd}) = xread($fh, $self->{cwd_sz});
+ $self->next_page();
+
+ my @translation_units;
+ while (tell $fh < $self->{size}) {
+ my %tu;
+ ($tu{size}) = unpack("L", xread($fh, 4));
+
+ ($tu{cmp_sz}) = unpack("S", xread($fh, 2));
+ $tu{comp_file_name} = xread($fh, $tu{cmp_sz});
+ ($tu{abs_sz}) = unpack("S", xread($fh, 2));
+ $tu{abs_file_path} = xread($fh, $tu{abs_sz});
+
+ $tu{exec_buf_pos} = tell $fh;
+ xread($fh, $tu{size} * 8);
+ $self->next_page();
+
+ push @translation_units, (\%tu);
+ }
+ $self->{translation_units} = \@translation_units;
+
+ return $self;
+}
+
+sub next_page {
+ my ($self) = @_;
+
+ my $pagesize = POSIX::sysconf(POSIX::_SC_PAGESIZE);
+ my $cur_pos = tell $self->{fh};
+ xread($self->{fh}, $pagesize - ($cur_pos % $pagesize));
+}
+
+sub execs_for {
+ my ($self, $tu_num) = @_;
+
+ my $tu = $self->{translation_units}->[$tu_num];
+ seek $self->{fh}, $tu->{exec_buf_pos}, 0;
+ my @execs = unpack("Q$tu->{size}", xread($self->{fh}, $tu->{size} * 8));
+ return \@execs;
+}
+
+#
+# Read an exact amount of bytes.
+#
+sub xread {
+ my ($fh, $bytes_total) = @_;
+
+ my $data;
+ my $bytes_read = 0;
+ while ($bytes_total > 0) {
+ my $read = read($fh, $data, $bytes_total, $bytes_read);
+
+ die "error: read failed: $!" if (!defined $read);
+ die "disconnected!\n" if ($read == 0);
+
+ $bytes_total -= $read;
+ $bytes_read += $read;
+ }
+
+ return $data;
+}
+
+1;