Skip to content

Instantly share code, notes, and snippets.

@mcast
Last active March 29, 2016 15:02
Show Gist options
  • Save mcast/f527e7aa36d2ab9788ce to your computer and use it in GitHub Desktop.
Save mcast/f527e7aa36d2ab9788ce to your computer and use it in GitHub Desktop.
Try::Tiny + qx forks the unit test

Report

I was surprised to find my unit test had forked, and so was producing multiple copies of ok messages. I managed to reduce this to, I think, the combination of

  • Try::Tiny
  • use warnings FATAL => 'all'
  • Running a command which doesn't exist

I suspect that the warning of "command not found" is promoted to an error, which is then rescued by try, and this cuts out some tidying up. This is affecting Perl's fork in system and qx.

$ /software/perl-5.22.1/bin/prove -lcv t/plain-system.t
t/plain-system.t ..
1..3
# {
# 'Perl' => '/software/perl-5.22.1/bin/perl',
# 'Try::Tiny' => '0.24',
# 'warnings' => '1.34'
# }
# pre(20243) for echo
# done(20243) for echo
ok 1 - test ok
# pre(20243) for junk
# done(20245) for junk
not ok 2 - junk
not ok 3 - same process
# Failed test 'junk'
# at t/plain-system.t line 19.
# 'ERR: in foo(junk; splat): Can't exec "junk": No such file or directory at t/plain-system.t line 33.
# '
# doesn't match '(?^:^fail:exit=(-1|65280)$)'
# Failed test 'same process'
# at t/plain-system.t line 20.
# got: '20245'
# expected: '20243'
# done(20243) for junk
not ok 2 - junk
# Failed test 'junk'
# at t/plain-system.t line 19.
# ''
# doesn't match '(?^:^fail:exit=(-1|65280)$)'
ok 3 - same process
# Looks like you failed 1 test of 3.
Dubious, test returned 1 (wstat 256, 0x100)
Failed 2/3 subtests
Test Summary Report
-------------------
t/plain-system.t (Wstat: 256 Tests: 5 Failed: 4)
Failed tests: 2, 2-3, 3
Non-zero exit status: 1
Parse errors: Tests out of sequence. Found (2) but expected (4)
Tests out of sequence. Found (3) but expected (5)
Bad plan. You planned 3 tests but ran 5.
Files=1, Tests=5, 0 wallclock secs ( 0.07 usr 0.03 sys + 0.04 cusr 0.02 csys = 0.16 CPU)
Result: FAIL
#! /usr/bin/env perl
use strict;
use Test::More;
use warnings 1.13 FATAL=>'all'; # weirdly, necessary for the fail
use Try::Tiny 0.16;
sub main {
plan tests => 3;
diag explain
{ Perl => $^X,
'Try::Tiny' => $Try::Tiny::VERSION,
warnings => $warnings::VERSION,
};
my $myproc = $$;
is(foo(qw( echo test )), "test\n", 'test ok');
like(foo(qw( junk splat )), qr{^fail:exit=(-1|65280)$}, 'junk');
is($$, $myproc, "same process");
return 0;
}
exit main();
sub foo {
my ($cmd, @args) = @_;
diag("pre($$) for $cmd");
my $out = try {
my $txt = qx{ $cmd @args };
if ($?) {
"fail:exit=$?";
} else {
$txt;
}
} catch {
"ERR: in foo($cmd; @args): $_";
};
diag("done($$) for $cmd");
return $out;
}
@mcast
Copy link
Author

mcast commented Mar 29, 2016

Reported as a bug against Try::Tiny.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment