File Coverage

blib/lib/Respite/Server/Test.pm
Criterion Covered Total %
statement 64 70 91.4
branch 17 34 50.0
condition 9 26 34.6
subroutine 9 9 100.0
pod 0 1 0.0
total 99 140 70.7


line stmt bran cond sub pod time code
1             package Respite::Server::Test;
2              
3 4     4   292010 use strict;
  4         8  
  4         131  
4 4     4   26 use warnings;
  4         8  
  4         196  
5 4     4   21 use Test::More;
  4         8  
  4         24  
6 4     4   4806 use File::Temp;
  4         72642  
  4         346  
7 4     4   1067 use Throw qw(throw import);
  4         10286  
  4         16  
8 4     4   340 use Time::HiRes qw(sleep);
  4         9  
  4         40  
9 4     4   1924 use End;
  4         1450  
  4         4012  
10             #use Data::Debug;
11              
12             sub setup_test_server {
13 5   50 5 0 286525 my $args = shift || {};
14 5 50       29 my $verbose = exists($args->{'verbose'}) ? $args->{'verbose'} : 1;
15              
16             # setup some defaults
17 5   33     57 my $port = $args->{'port'} || do {
18             require IO::Socket;
19             my $sock = IO::Socket::INET->new;
20             $sock->configure({
21             LocalPort => 0,
22             Listen => 1,
23             Proto => 'tcp',
24             ReuseAddr => 1,
25             }) || throw "Could not create temp socket", {msg => $!};
26             my $port = $sock->sockport || throw "Could not generate random usable sockport";
27             };
28 5         452 my $tmpnam = File::Temp->new;
29 5   33     4996 my $pid_file = $args->{'pid_file'} || "$tmpnam.$$.pid";
30 5   33     119 my $access_file = $args->{'access_file'} || "$tmpnam.$$.access";
31 5   33     71 my $error_file = $args->{'error_file'} || "$tmpnam.$$.error";
32 5         53 undef $tmpnam;
33 5 50       1592 my $no_brand = exists($args->{'no_brand'}) ? 1 : 0;
34 5 50       17 my $no_ssl = exists($args->{'no_ssl'}) ? 1 : 0;
35             #$no_ssl = 1;
36 5 50       39 my $flat = exists($args->{'flat'}) ? 1 : 0;
37              
38 5   33     41 my $server = $args->{'server'} || do {
39             my $pkg = $args->{'server_class'} || 'Respite::Server';
40             (my $file = "$pkg.pm") =~ s|::|/|g;
41             eval { require $file } || throw "Could not require client library", {msg => $@};
42             $pkg->new({
43             no_brand => $no_brand,
44             ($args->{'service'} ? (server_name => $args->{'service'}) : ()),
45             ($args->{'api_meta'} ? (api_meta => $args->{'api_meta'}) : ()),
46             port => $port,
47             server_type => $args->{'server_type'} || 'Fork',
48             no_ssl => $no_ssl,
49             flat => $flat,
50             host => $args->{'host'} || 'localhost',
51             pass => $args->{'pass'},
52             pid_file => $pid_file,
53             access_log_file => $access_file,
54             log_file => $error_file,
55             user => defined($args->{'user'}) ? $args->{'user'} : $<,
56             group => defined($args->{'group'}) ? $args->{'group'} : $(,
57             });
58             };
59             #debug $server;
60 5         53 my $service = $server->server_name;
61 5         10 $service =~ s/_server$//;
62              
63 5 50       36 my $encoded = exists($args->{'utf8_encoded'}) ? 1 : 0;
64 5   33     44 my $client = $args->{'client'} || do {
65             my $pkg = $args->{'client_class'} || 'Respite::Client';
66             (my $file = "$pkg.pm") =~ s|::|/|g;
67             eval { require $file } || throw "Could not require client library", {msg => $@};
68             $pkg->new({
69             no_brand => $no_brand,
70             service => $service,
71             port => $port,
72             host => $server->{'host'},
73             pass => $args->{'pass'},
74             no_ssl => $no_ssl,
75             flat => $flat,
76             utf8_encoded => $encoded,
77             ($args->{'brand'} ? (brand => $args->{'brand'}) : ()),
78             });
79             };
80             #debug $client;
81              
82             ###----------------------------------------------------------------###
83             # start the server in a child, block the parent until ready
84              
85 5         14270 my $pid = fork;
86 5 50       501 die "Could not fork during test\n" if ! defined $pid;
87 5 100       255 if (!$pid) { # child
88 2         203 local @ARGV;
89 2         288 $server->run_server(setsid => 0, background => 0); # allow a kill term to close the server too
90 0         0 exit;
91             }
92              
93             $client->{'_test_ender'} = end {
94 3 50   3   217175 diag("Process list") if $verbose;
95 3         5208 $server->__ps;
96              
97 3         76 diag("Stop server");
98 3         3835 $server->__stop;
99             # get some info - then tear down
100              
101 3 50       37 diag("Tail of the error_log") if $verbose;
102 3 50       2680 $server->__tail_error(1000) if $verbose;
103              
104 3 50       98 diag("Tail of the access_log") if $verbose;
105 3 50 50     4407 $server->__tail_access($server->{'tail_access'} || 20) if $verbose;
106              
107 3 50       113 diag("Shut down server") if $verbose;
108 3         5332 unlink $_ for $pid_file, $access_file, $error_file; # double check
109 3         756 };
110              
111             # block the parent (that will run client tests) until the child running the server is fully setup
112 3         333 my $connected;
113 3         117 for (1 .. 30) {
114 3         300710 sleep 0.1;
115 3         48 my $class = 'IO::Socket::INET';
116 3 50       47 if (!$no_ssl) {
117 0         0 require IO::Socket::SSL;
118 0         0 $class = 'IO::Socket::SSL';
119             }
120 3   50     175 my $sock = $class->new(PeerHost => "localhost", PeerPort => $port, SSL_verify_mode => 0) || next;
121 3         5429 print $sock "GET /waited_until_child HTTP/1.0\n\n";
122 3         30 $connected = 1;
123 3         155 last;
124             }
125 3 50       62 if (! $connected) {
126 0         0 diag("Tail of the error_log");
127 0 0 0     0 $server->__tail_error($server->{'tail_error'} || 20) if $verbose;
128 0         0 die "Failed to connect to the server: $!";
129             }
130              
131 3 50       231 return wantarray ? ($client, $server) : $client;
132             }
133              
134             1;
135              
136             __END__