New test file that exercises Perl's DTrace support
authorShawn M Moore <sartak@gmail.com>
Mon, 11 Jul 2011 20:24:07 +0000 (16:24 -0400)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 12 Jul 2011 03:29:55 +0000 (20:29 -0700)
MANIFEST
t/run/dtrace.t [new file with mode: 0644]

index e6ee5ac..5a0e303 100644 (file)
--- a/MANIFEST
+++ b/MANIFEST
@@ -5083,6 +5083,7 @@ t/re/substT.t                     See if substitution works with -T
 t/re/subst_wamp.t              See if substitution works with $& present
 t/re/uniprops.t                        Test unicode \p{} regex constructs
 t/run/cloexec.t                        Test close-on-exec.
+t/run/dtrace.t                 Test for DTrace probes
 t/run/exit.t                   Test perl's exit status.
 t/run/fresh_perl.t             Tests that require a fresh perl.
 t/run/locale.t         Tests related to locale handling
diff --git a/t/run/dtrace.t b/t/run/dtrace.t
new file mode 100644 (file)
index 0000000..746f9ae
--- /dev/null
@@ -0,0 +1,94 @@
+#!./perl
+use strict;
+use warnings;
+use IPC::Open2;
+
+my $Perl;
+my $dtrace;
+
+BEGIN {
+    chdir 't';
+    @INC = '../lib';
+    require './test.pl';
+
+    skip_all_without_config("usedtrace");
+
+    $dtrace = $Config::Config{dtrace};
+
+    $Perl = which_perl();
+
+    `$dtrace -V` or skip_all("$dtrace unavailable");
+
+    my $result = `$dtrace -qnBEGIN -c'$Perl -e 1' 2>&1`;
+    $? && skip_all("Apparently can't probe using $dtrace (perhaps you need root?): $result");
+}
+
+plan(tests => 2);
+
+dtrace_like(
+    '1',
+    'BEGIN { trace(42+666) }',
+    qr/708/,
+    'really running DTrace',
+);
+
+dtrace_like(
+    'package My;
+        sub outer { Your::inner() }
+     package Your;
+        sub inner { }
+     package Other;
+        My::outer();
+        Your::inner();',
+
+    'sub-entry { printf("-> %s::%s at %s line %d!\n", copyinstr(arg3), copyinstr(arg0), copyinstr(arg1), arg2) }
+     sub-return { printf("<- %s::%s at %s line %d!\n", copyinstr(arg3), copyinstr(arg0), copyinstr(arg1), arg2) }',
+
+     qr/-> My::outer at - line 2!
+-> Your::inner at - line 4!
+<- Your::inner at - line 4!
+<- My::outer at - line 2!
+-> Your::inner at - line 4!
+<- Your::inner at - line 4!/,
+
+    'traced multiple function calls',
+);
+
+sub dtrace_like {
+    my $perl     = shift;
+    my $probes   = shift;
+    my $expected = shift;
+    my $name     = shift;
+
+    my ($reader, $writer);
+
+    my $pid = open2($reader, $writer,
+        $dtrace,
+        '-q',
+        '-n', 'BEGIN { trace("ready!\n") }', # necessary! see below
+        '-n', $probes,
+        '-c', $Perl,
+    );
+
+    # wait until DTrace tells us that it is initialized
+    # otherwise our probes won't properly fire
+    chomp(my $throwaway = <$reader>);
+    $throwaway eq "ready!" or die "Unexpected 'ready!' result from DTrace: $throwaway";
+
+    # now we can start executing our perl
+    print $writer $perl;
+    close $writer;
+
+    # read all the dtrace results back in
+    local $/;
+    my $result = <$reader>;
+
+    # make sure that dtrace is all done and successful
+    waitpid($pid, 0);
+    my $child_exit_status = $? >> 8;
+    die "Unexpected error from DTrace: $result"
+        if $child_exit_status != 0;
+
+    like($result, $expected, $name);
+}
+