[Rt-commit] rt branch, 4.0/dbh-disconnect-after-safe-run-child, updated. rt-4.0.3-43-g72ddb36

Ruslan Zakirov ruz at bestpractical.com
Sat Nov 12 17:10:06 EST 2011


The branch, 4.0/dbh-disconnect-after-safe-run-child has been updated
       via  72ddb36099be24f17fb7ee27a0666786729ed6ac (commit)
       via  2a25100668b34aaf22345b0622eb65ca508e1911 (commit)
      from  e96831cf8f457b1601dc778cc336d43105f7a38b (commit)

Summary of changes:
 lib/RT/Util.pm              |   13 +++--
 t/api/safe-run-child-util.t |  124 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 133 insertions(+), 4 deletions(-)
 create mode 100644 t/api/safe-run-child-util.t

- Log -----------------------------------------------------------------
commit 2a25100668b34aaf22345b0622eb65ca508e1911
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Sun Nov 13 02:08:15 2011 +0400

    test safe_run_child from RT::Util

diff --git a/t/api/safe-run-child-util.t b/t/api/safe-run-child-util.t
new file mode 100644
index 0000000..e9674cf
--- /dev/null
+++ b/t/api/safe-run-child-util.t
@@ -0,0 +1,124 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use RT::Test tests => 23;
+
+use RT::Util qw(safe_run_child);
+
+is_handle_ok();
+
+{
+    my $res = safe_run_child { return 1 };
+    is $res, 1, "correct return value";
+    is_handle_ok();
+}
+
+# test context
+{
+    my $context;
+    my $sub = sub {
+        if ( wantarray ) {
+            $context = 'array'; return 1, 2, 3;
+        } elsif ( defined wantarray ) {
+            $context = 'scalar'; return 'foo';
+        } elsif ( !wantarray ) {
+            $context = 'void'; return;
+        }
+    };
+    is_deeply [ safe_run_child { $sub->(@_) } ], [1, 2, 3];
+    is $context, 'array';
+    is_handle_ok();
+
+    is scalar safe_run_child {$sub->(@_)}, 'foo';
+    is $context, 'scalar';
+    is_handle_ok();
+
+    safe_run_child {$sub->(@_)};
+    is $context, 'void';
+    is_handle_ok();
+}
+
+# fork+child returns
+{
+    my $res = safe_run_child {
+        if (fork) { wait; return 'parent' }
+
+        open my $fh, '>', RT::Test->temp_directory .'/tttt';
+        print $fh "child";
+        close $fh;
+
+        return 'child';
+    };
+    is $res, 'parent', "correct return value";
+    is( RT::Test->file_content([RT::Test->temp_directory, 'tttt'], unlink => 1 ),
+        'child',
+        'correct file content',
+    );
+    is_handle_ok();
+}
+
+# fork+child dies
+{
+    my $res = safe_run_child {
+        if (fork) { wait; return 'parent' }
+
+        open my $fh, '>', RT::Test->temp_directory .'/tttt';
+        print $fh "child";
+        close $fh;
+
+        die 'child';
+    };
+    is $res, 'parent', "correct return value";
+    is( RT::Test->file_content([RT::Test->temp_directory, 'tttt'], unlink => 1 ),
+        'child',
+        'correct file content',
+    );
+    is_handle_ok();
+}
+
+# parent dies
+{
+    my $res = eval { safe_run_child { die 'parent'; } };
+    is $res, undef, "correct return value";
+    like $@, qr'parent', "correct return value";
+    is_handle_ok();
+}
+
+# fork+exec
+{
+    my $script = RT::Test->temp_directory .'/true.pl';
+    open my $fh, '>', $script;
+    print $fh <<END;
+#!$^X
+
+open my \$fh, '>', '$script.res';
+print \$fh "child";
+close \$fh;
+
+exit 0;
+END
+    close $fh;
+    chmod 0777, $script;
+
+    my $res = safe_run_child {
+        if (fork) { wait; return 'parent' }
+        exec $script;
+    };
+    is $res, 'parent', "correct return value";
+    is( RT::Test->file_content([$script .'.res'], unlink => 1 ),
+        'child',
+        'correct file content',
+    );
+    is_handle_ok();
+}
+
+sub is_handle_ok {
+    local $Test::Builder::Level = $Test::Builder::Level + 1;
+    my $test = $RT::Handle->dbh->selectall_arrayref(
+        "SELECT id FROM Users WHERE Name = 'Nobody'"
+    );
+    ok $test && $test->[0][0], "selected, DB is there";
+}
+

commit 72ddb36099be24f17fb7ee27a0666786729ed6ac
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Sun Nov 13 02:08:39 2011 +0400

    don't let child continue it work in safe_run_child

diff --git a/lib/RT/Util.pm b/lib/RT/Util.pm
index 70d4625..b66b607 100644
--- a/lib/RT/Util.pm
+++ b/lib/RT/Util.pm
@@ -81,17 +81,22 @@ sub safe_run_child (&) {
         } else {
             @res = ( scalar $code->() );
         }
+        exit 0 if $our_pid != $$;
         1;
     } or do {
         my $err = $@;
+        $RT::Logger->error( $err ) if $our_pid == $$;
+        $err =~ s/^Stack:.*$//ms;
         if ( $our_pid == $$ ) {
-            $RT::Logger->error( $err );
             $dbh->{'InactiveDestroy'} = 0 if $dbh;
             $RT::Handle->{'DisconnectHandleOnDestroy'} = 1;
+            #TODO we need to localize this
+            die 'System Error: ' . $err;
+        } else {
+            local $SIG{__WARN__};
+            warn 'System Error: ' . $err;
+            exit 1;
         }
-        $err =~ s/^Stack:.*$//ms;
-        #TODO we need to localize this
-        die 'System Error: ' . $err;
     };
     $dbh->{'InactiveDestroy'} = 0 if $dbh;
     $RT::Handle->{'DisconnectHandleOnDestroy'} = 1;

-----------------------------------------------------------------------


More information about the Rt-commit mailing list