[Catalyst-dev] Make Catalyst::Engine::HTTP run in background easily [Patch + Test]

Emanuele Zeppieri ema_zep at libero.it
Wed Sep 5 19:51:27 GMT 2007


This patch simply makes the Catalyst::Engine::HTTP->run() method return
the child pid instead of just exit()-ing, when invoked with
$options->{background} set.

This is IMO quite useful, since it permits to fire a non-blocking
external Cat HTTP server simply with something like:

my $pid =3D CatApp->run( $PORT, undef, {background =3D> 1} );
# Here go for example tests which connect to the external server...
# ... Then use $pid to kill the server.

which permits to write self-contained test scripts which use an external
Cat HTTP server (which is needed to correctly reproduce an HTTP
transaction).

Please have a look at the attached test: it demonstrates exactly this
kind of use.

This for example permitted to uncover a bug in
Test::WWW::Mechanize::Catalyst which arose *only* when used with an
external server:
http://rt.cpan.org/Ticket/Display.html?id=3D29143

Cheers,
Emanuele Zeppieri.


-------------- next part --------------
--- HTTP.pm	2007-09-05 19:40:55.843134100 +0200
+++ HTTP.pm.new	2007-09-05 19:43:19.527134100 +0200
@@ -184,7 +184,7 @@
     if ($options->{background}) {
         my $child =3D fork;
         die "Can't fork: $!" unless defined($child);
-        exit if $child;
+        return $child if $child;
     }
 =

     my $restart =3D 0;

-------------- next part --------------
#!perl

#------------------------------
# Emanuele Zeppieri - Sep 2007
#------------------------------

use strict;
use warnings;

use lib 'lib';

our $PORT;

BEGIN {
    $PORT =3D $ENV{CAT_TEST_PORT} || 7357;
    $ENV{CATALYST_SERVER} =3D "http://localhost:$PORT"
}

package ExternalCatty;

use Catalyst qw/-Debug -Engine=3DHTTP/;

our $VERSION =3D '0.01';

__PACKAGE__->config( name =3D> 'ExternalCatty' );
__PACKAGE__->setup;

sub default : Private {
    my ($self, $c) =3D @_;
    $c->response->content_type('text/html; charset=3Dutf-8');
    $c->response->output( html('Root', 'Hello, test!') )
}

sub html {
    my ($title, $body) =3D @_;
    return qq[
<html>
<head>
    <title>$title</title>
</head>
<body>$body</body>
</html>
];
}

# Back in main.
package main;

use Test::More tests =3D> 4;

BEGIN {
    diag(
        "##################################################################=
#\n",
        "Starting an external Catalyst HTTP server on port $PORT\n",
        "To change the port, please set the CAT_TEST_PORT env variable.\n",
        "(The server will be automatically shut-down right after the tests)=
.\n",
        "##################################################################=
#\n"
    )
}

# Let's catch interrupts to force the END block execution.
$SIG{INT} =3D sub { warn "INT:$$"; exit };

# Fire an external Catalyst HTTP server without blocking!
my $pid =3D ExternalCatty->run( $PORT, undef, {background =3D> 1} );

# Test the Cat app through the external server.
use Test::WWW::Mechanize::Catalyst 'ExternalCatty';
my $m =3D Test::WWW::Mechanize::Catalyst->new;

$m->get_ok('/', 'Get a page from the external server');
is( $m->ct, 'text/html', 'Get the page Content-Type from the external serve=
r');
$m->title_is('Root', 'Get page title from the external server');
$m->content_contains(
    'Hello, test!',
    'get the page body from the external server'
);

END { kill(9, $pid) if defined $pid }

1;



More information about the Catalyst-dev mailing list