Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

Journal of markjugg (792)

Saturday December 17, 2005
05:21 PM

recipe for happy forking in a Test::More test script

[ #28038 ]

I recently picked up work again on CGI::Uploader

As part of updating the test suite, I doing away with the homemade hack I had for simulating a file upload. The best solution for this now appears to be to use HTTP::Request::AsCGI. However, it apparently depends on a newer 'libwww' than I have, so I devised a solution that uses HTTP::Request::Common directly.

This involved forking in the test script, with the parent serving the content and the child process working like a web client.

In the process I ran into and overcame some gotchas with forking with Test::More that seemed worth having better documentation for.

In summary, it is possible with these caveats:

  • You have to declare a plan eventually, our you'll get a complaint at the end about "Don't know which tests failed".
  • You need this: Test::More->builder->no_ending(1);
  • After you fork, you can't run anymore tests in the parent.

Here's the basic recipe I used for the forking par, with much help and code borrowing from Cees Hek, who in turn got key tips from adrianh:

# Fake a web server CGI request by building a proper
# POST request, setting some ENV variables and
# forking a child process that gets the POST
# content from STDIN
my $req = &HTTP::Request::Common::POST(
    '/dummy_location',
    Content_Type => 'form-data',
    Content      => [
        name   => 'name1',
        test   => 'name2',
        image1 => ["t/image.jpg"],
    ]
);
$ENV{REQUEST_METHOD} = 'POST';
$ENV{CONTENT_TYPE}   = 'multipart/form-data';
$ENV{CONTENT_LENGTH} = $req->content_length;
if ( open( CHILD, "|-" ) ) {    # cparent
    print CHILD $req->content;
    close CHILD;
    exit 0;
}

# at this point, we're in a new (child) process
# and CGI.pm can read the POST params from STDIN
# as in a real request
my $q = CGI->new;

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.