1package Jifty::TestServer;
2use Any::Moose;
3
4use strict;
5use warnings;
6use File::Spec;
7use Test::Builder;
8use Test::Script::Run 'get_perl_cmd';
9use Plack::Loader;
10
11has port => (is => "rw", isa => "Int");
12
13=head1 NAME
14
15Jifty::TestServer - Starting and stopping jifty server for tests
16
17=head1 DESCRIPTION
18
19=head1 METHOD
20
21=head2 started_ok
22
23Like started_ok in C<Test::HTTP::Server::Simple>, start the server and
24return the URL.
25
26=head2 BUILD
27
28Sets up the server instance.
29
30=cut
31
32sub BUILD {
33    my $self = shift;
34    Jifty->config->framework('Web')->{'Port'} = $self->port if $self->port;
35    $self->port( Jifty->config->framework('Web')->{'Port'} || 8888 );
36}
37
38sub started_ok {
39    my $self = shift;
40    my $text = shift;
41    $text = 'started server' unless defined $text;
42
43    if ($^O eq 'MSWin32') {
44        # dirty hack until Test::Builder->skip_rest comes true
45
46        my $why = "live test doesn't work on Win32 at the moment";
47
48        my $Tester = Test::Builder->new;
49        $Tester->skip($why);
50
51        unless ($Tester->{No_Plan}) {
52            for (my $ct = $Tester->{Curr_Test};
53                    $ct < $Tester->{Expected_Tests};
54                    $ct++
55            ) {
56                $Tester->skip($why); # skip rest of the test
57            }
58        }
59        exit(0);
60    }
61
62    $self->{plack_server} = Plack::Loader->load
63        ($ENV{JIFTY_TEST_SERVER},
64         port => $self->port,
65         server_ready => sub {
66             kill 'USR1' => getppid();
67         });
68    $Jifty::SERVER = $self;
69
70    my $pid = fork();
71    die "failed to fork" unless defined $pid;
72
73    if ($pid) {
74        # We are expecting a USR1 from the child process after it's
75        # ready to listen.
76        my $handled;
77        $SIG{USR1} = sub { $handled = 1};
78        sleep 15;
79        Test::More::diag "did not get expected USR1 for test server readiness"
80            unless $handled;
81        $self->{cleanup} = [sub { kill TERM => $pid }];
82        my $Tester = Test::Builder->new;
83        $Tester->ok(1, $text);
84        # XXX: pull from jifty::config maybe
85        return "http://localhost:".$self->port;
86    } else {
87        Jifty->handle->dbh->{'InactiveDestroy'} = 1;
88        Jifty->setup_database_connection;
89    }
90
91    require POSIX;
92    if ( $^O !~ /MSWin32/ ) {
93        POSIX::setsid()
94            or die "Can't start a new session: $!";
95    }
96
97    $self->{plack_server}->run(Jifty->handler->psgi_app);
98    exit;
99}
100
101=head2 DEMOLISH
102
103Calls any cleanup handlers before exiting
104
105=cut
106
107sub DEMOLISH {
108    $_->() for @{$_[0]->{cleanup}}
109}
110
111__PACKAGE__->meta->make_immutable;
112no Any::Moose;
1131;
114