Fix optional test for code move
[catagits/Catalyst-Runtime.git] / t / optional_http-server-restart.t
CommitLineData
c7ded7aa 1# This test tests the standalone server's auto-restart feature.
2
3use strict;
4use warnings;
5
4853fb50 6use Test::More;
7BEGIN {
8 plan skip_all => 'set TEST_HTTP to enable this test' unless $ENV{TEST_HTTP};
9}
10
c7ded7aa 11use File::Path;
12use FindBin;
13use LWP::Simple;
14use IO::Socket;
2f381252 15use IPC::Open3;
65b708a6 16use Catalyst::Engine::HTTP::Restarter::Watcher;
c7ded7aa 17use Time::HiRes qw/sleep/;
18eval "use Catalyst::Devel 1.0;";
19
c7ded7aa 20plan skip_all => 'Catalyst::Devel required' if $@;
9c71d51d 21plan skip_all => 'Catalyst::Devel >= 1.04 required' if $Catalyst::Devel::VERSION <= 1.03;
c7ded7aa 22eval "use File::Copy::Recursive";
23plan skip_all => 'File::Copy::Recursive required' if $@;
24
9c71d51d 25plan tests => 120;
c7ded7aa 26
2f381252 27my $tmpdir = "$FindBin::Bin/../t/tmp";
28
c7ded7aa 29# clean up
2f381252 30rmtree $tmpdir if -d $tmpdir;
c7ded7aa 31
32# create a TestApp and copy the test libs into it
2f381252 33mkdir $tmpdir;
34chdir $tmpdir;
35
868a7cca 36system( $^X, "-I$FindBin::Bin/../lib", "$FindBin::Bin/../script/catalyst.pl", 'TestApp' );
2f381252 37
c7ded7aa 38chdir "$FindBin::Bin/..";
39File::Copy::Recursive::dircopy( 't/lib', 't/tmp/TestApp/lib' );
40
41# remove TestApp's tests
42rmtree 't/tmp/TestApp/t';
43
44# spawn the standalone HTTP server
45my $port = 30000 + int rand( 1 + 10000 );
9c71d51d 46
2f381252 47my( $server, $pid );
81f25ce6 48my @cmd = ($^X, "-I$FindBin::Bin/../lib", "-I$FindBin::Bin/lib",
2f381252 49 "$FindBin::Bin/../t/tmp/TestApp/script/testapp_server.pl", '-port',
81f25ce6 50 $port, '-restart');
51
52$pid = open3( undef, $server, undef, @cmd )
2f381252 53 or die "Unable to spawn standalone HTTP server: $!";
c7ded7aa 54
9c71d51d 55# switch to non-blocking reads so we can fail
56# gracefully instead of just hanging forever
57
58$server->blocking( 0 );
59
c7ded7aa 60# wait for it to start
61print "Waiting for server to start...\n";
62while ( check_port( 'localhost', $port ) != 1 ) {
63 sleep 1;
64}
65
66# change various files
67my @files = (
68 "$FindBin::Bin/../t/tmp/TestApp/lib/TestApp.pm",
69 "$FindBin::Bin/../t/tmp/TestApp/lib/TestApp/Controller/Action/Begin.pm",
7d9921b1 70 "$FindBin::Bin/../t/tmp/TestApp/lib/TestApp/Controller/Immutable.pm",
81f25ce6 71 "$FindBin::Bin/../t/tmp/TestApp/lib/TestApp/Controller/Immutable/HardToReload.pm",
c7ded7aa 72);
73
74# change some files and make sure the server restarts itself
9c71d51d 75NON_ERROR_RESTART:
c7ded7aa 76for ( 1 .. 20 ) {
77 my $index = rand @files;
78 open my $pm, '>>', $files[$index]
79 or die "Unable to open $files[$index] for writing: $!";
80 print $pm "\n";
81 close $pm;
82
83 # give the server time to notice the change and restart
84 my $count = 0;
9c71d51d 85 my $line;
9c71d51d 86 while ( ( $line || '' ) !~ /can connect/ ) {
87 # wait for restart message
88 $line = $server->getline;
89 sleep 0.1;
90 if ( $count++ > 100 ) {
91 fail "Server restarted";
92 SKIP: {
93 skip "Server didn't restart, no sense in checking response", 1;
94 }
95 next NON_ERROR_RESTART;
96 }
97 };
98 pass "Server restarted";
99
100 $count = 0;
101 while ( check_port( 'localhost', $port ) != 1 ) {
c7ded7aa 102 # wait for it to restart
103 sleep 0.1;
9c71d51d 104 die "Server appears to have died" if $count++ > 100;
c7ded7aa 105 }
106 my $response = get("http://localhost:$port/action/default");
107 like( $response, qr/Catalyst::Request/, 'Non-error restart, request OK' );
108
9c71d51d 109 # give the server some time to reindex its files
110 sleep 1;
c7ded7aa 111}
112
113# add errors to the file and make sure server does not die or restart
9c71d51d 114NO_RESTART_ON_ERROR:
c7ded7aa 115for ( 1 .. 20 ) {
116 my $index = rand @files;
117 open my $pm, '>>', $files[$index]
118 or die "Unable to open $files[$index] for writing: $!";
119 print $pm "bleh";
120 close $pm;
121
9c71d51d 122 my $count = 0;
123 my $line;
124
125 while ( ( $line || '' ) !~ /failed/ ) {
126 # wait for restart message
127 $line = $server->getline;
128 sleep 0.1;
129 if ( $count++ > 100 ) {
130 fail "Server restarted";
131 SKIP: {
132 skip "Server didn't restart, no sense in checking response", 1;
133 }
134 next NO_RESTART_ON_ERROR;
135 }
136 };
137
138 pass "Server refused to restart";
139
c7ded7aa 140 if ( check_port( 'localhost', $port ) != 1 ) {
141 die "Server appears to have died";
142 }
143 my $response = get("http://localhost:$port/action/default");
144 like( $response, qr/Catalyst::Request/,
145 'Syntax error, no restart, request OK' );
146
9c71d51d 147 # give the server some time to reindex its files
148 sleep 1;
149
c7ded7aa 150}
151
9c71d51d 152# multiple restart directories
153
154# we need different options so we have to rebuild most
155# of the testing environment
156
157kill 'KILL', $pid;
158close $server;
159
160# pick next port because the last one might still be blocked from
161# previous server. This might fail if this port is unavailable
162# but picking the first one has the same problem so this is acceptable
163
164$port += 1;
165
166{ no warnings 'once'; $File::Copy::Recursive::RMTrgFil = 1; }
167File::Copy::Recursive::dircopy( 't/lib', 't/tmp/TestApp/lib' );
168
169# change various files
170@files = (
171 "$FindBin::Bin/../t/tmp/TestApp/lib/TestApp/Controller/Action/Begin.pm",
172 "$FindBin::Bin/../t/tmp/TestApp/lib/TestApp/Controller/Engine/Request/URI.pm",
173);
174
175my $app_root = "$FindBin::Bin/../t/tmp/TestApp";
176my $restartdirs = join ' ', map{
177 "-restartdirectory $app_root/lib/TestApp/Controller/$_"
178} qw/Action Engine/;
179
2f381252 180$pid = open3( undef, $server, undef,
868a7cca 181 $^X, "-I$FindBin::Bin/../lib",
2f381252 182 "$FindBin::Bin/../t/tmp/TestApp/script/testapp_server.pl", '-port',
183 $port, '-restart', $restartdirs )
184 or die "Unable to spawn standalone HTTP server: $!";
9c71d51d 185$server->blocking( 0 );
186
187
188# wait for it to start
189print "Waiting for server to start...\n";
190while ( check_port( 'localhost', $port ) != 1 ) {
191 sleep 1;
192}
193
194MULTI_DIR_RESTART:
195for ( 1 .. 20 ) {
196 my $index = rand @files;
197 open my $pm, '>>', $files[$index]
198 or die "Unable to open $files[$index] for writing: $!";
199 print $pm "\n";
200 close $pm;
201
202 # give the server time to notice the change and restart
203 my $count = 0;
204 my $line;
205
206 while ( ( $line || '' ) !~ /can connect/ ) {
207 # wait for restart message
208 $line = $server->getline;
209 sleep 0.1;
210 if ( $count++ > 100 ) {
211 fail "Server restarted";
191cf700 212 SKIP: {
9c71d51d 213 skip "Server didn't restart, no sense in checking response", 1;
214 }
215 next MULTI_DIR_RESTART;
216 }
217 };
218 pass "Server restarted with multiple restartdirs";
219
220 $count = 0;
221 while ( check_port( 'localhost', $port ) != 1 ) {
222 # wait for it to restart
223 sleep 0.1;
224 die "Server appears to have died" if $count++ > 100;
225 }
226 my $response = get("http://localhost:$port/action/default");
227 like( $response, qr/Catalyst::Request/, 'Non-error restart, request OK' );
228
229 # give the server some time to reindex its files
230 sleep 1;
231}
232
233# shut it down again
234
235kill 'KILL', $pid;
c7ded7aa 236close $server;
237
238# clean up
239rmtree "$FindBin::Bin/../t/tmp" if -d "$FindBin::Bin/../t/tmp";
240
241sub check_port {
242 my ( $host, $port ) = @_;
243
244 my $remote = IO::Socket::INET->new(
245 Proto => "tcp",
246 PeerAddr => $host,
247 PeerPort => $port
248 );
249 if ($remote) {
250 close $remote;
251 return 1;
252 }
253 else {
254 return 0;
255 }
256}