1#!/usr/bin/env perl 2 3=head1 NAME 4 5Options.t - Test commandline options and such 6 7=cut 8 9package FooServer; 10 11use strict; 12use FindBin qw($Bin); 13use lib $Bin; 14use NetServerTest qw(prepare_test ok is use_ok skip like); 15prepare_test({n_tests => 73, plan_only => 1}); 16 17use_ok('Net::Server'); 18@FooServer::ISA = qw(Net::Server); 19 20### override-able options for this package 21sub options { 22 my $self = shift; 23 my $prop = $self->{'server'}; 24 my $template = shift; 25 26 ### setup options in the parent classes 27 $self->SUPER::options($template); 28 29 $template->{'my_option'} = \$prop->{'my_option'}; 30 31 $prop->{'an_arrayref_item'} ||= []; 32 $template->{'an_arrayref_item'} = $prop->{'an_arrayref_item'}; 33} 34 35### provide default values 36sub default_values { 37 return { 38 group => 'defaultgroup', 39 allow => ['127.0.0.1', '192.169.0.1'], 40 }; 41} 42 43#sub proto_object { 44# my ($self, $host, $port, $proto) = @_; 45# #debug $host, $port, $proto; 46# #return $self->SUPER::proto_object($host, $port, $proto); 47# return "Blah"; 48#} 49 50### override these to make run not run 51### this will allow all configuration cycles to be run 52sub bind {} 53sub post_bind {} 54sub loop {} 55sub log {} 56sub server_close { 57 my $self = shift; 58 return $self; 59} 60 61###----------------------------------------------------------------### 62 63my $obj = eval { FooServer->new }; 64ok($obj, "Got an object ($@)"); 65 66my $server = eval { FooServer->run }; 67ok($server, "Got a server ($@)"); 68my $prop = eval { $server->{'server'} } || {}; 69is($prop->{'log_level'}, 2, "Correct default log_level"); 70is($prop->{'log_file'}, "", "Correct default log_file"); 71ok(! $prop->{'user'}, "Correct default user"); 72my $configured_ports = scalar(@{ $prop->{'_bind'} }); 73ok($configured_ports == 1 || $configured_ports == 2, "Had correct configured ports ($configured_ports)"); 74my @socks = @{ $prop->{'sock'} }; 75is(scalar(@socks), scalar(@{ $prop->{'_bind'} }), "Sockets matched ports"); 76my $sock = $socks[0]; 77if ($sock->NS_ipv == 4) { 78 is(eval { $sock->NS_host }, '0.0.0.0', "Right host"); 79} else { 80 is(eval { $sock->NS_host }, '::', "Right host"); 81} 82is(eval { $sock->NS_port }, 20203, "Right port"); 83is(eval { $sock->NS_proto }, 'TCP', "Right proto"); 84 85###----------------------------------------------------------------### 86 87$prop = eval { FooServer->run(port => 2201)->{'server'} }; 88ok($prop, "Loaded server"); 89$prop ||= {}; 90is(scalar(@{ $prop->{'port'} }), 1, "Had 1 configured ports"); 91is($prop->{'port'}->[0], 2201, "Right port"); 92 93###----------------------------------------------------------------### 94 95$prop = eval { FooServer->run(port => [2201, 2202])->{'server'} }; 96ok($prop, "Loaded server"); 97$prop ||= {}; 98is(scalar(@{ $prop->{'port'} }), 2, "Had 1 configured ports"); 99is($prop->{'port'}->[0], 2201, "Right port"); 100is($prop->{'port'}->[1], 2202, "Right port"); 101 102###----------------------------------------------------------------### 103 104$prop = eval { FooServer->run({port => 2201})->{'server'} }; 105ok($prop, "Loaded server"); 106$prop ||= {}; 107is(scalar(@{ $prop->{'port'} }), 1, "Had 1 configured ports"); 108is($prop->{'port'}->[0], 2201, "Right port"); 109 110###----------------------------------------------------------------### 111 112$prop = eval { FooServer->new(port => 2201)->run->{'server'} }; 113ok($prop, "Loaded server"); 114$prop ||= {}; 115is(scalar(@{ $prop->{'port'} }), 1, "Had 1 configured ports"); 116is($prop->{'port'}->[0], 2201, "Right port"); 117 118###----------------------------------------------------------------### 119 120$prop = eval { FooServer->new({port => 2201})->run->{'server'} }; 121ok($prop, "Loaded server"); 122$prop ||= {}; 123is(scalar(@{ $prop->{'port'} }), 1, "Had 1 configured ports"); 124is($prop->{'port'}->[0], 2201, "Right port"); 125 126###----------------------------------------------------------------### 127 128$prop = eval { local @ARGV = ('--port', '2201'); FooServer->run->{'server'} }; 129ok($prop, "Loaded server"); 130$prop ||= {}; 131is(scalar(@{ $prop->{'port'} }), 1, "Had 1 configured ports"); 132is($prop->{'port'}->[0], 2201, "Right port"); 133 134###----------------------------------------------------------------### 135 136$prop = eval { local @ARGV = ('--port', '2201', '--port=2202'); FooServer->run->{'server'} }; 137ok($prop, "Loaded server"); 138$prop ||= {}; 139is(scalar(@{ $prop->{'port'} }), 2, "Had 1 configured ports"); 140is($prop->{'port'}->[0], 2201, "Right port"); 141is($prop->{'port'}->[1], 2202, "Right port"); 142 143###----------------------------------------------------------------### 144 145$prop = eval { FooServer->run(conf_file => __FILE__.'.conf')->{'server'} }; 146ok($prop, "Loaded server"); 147$prop ||= {}; 148is(scalar(@{ $prop->{'port'} }), 3, "Had 1 configured ports"); 149is($prop->{'port'}->[0], 5401, "Right port"); 150is($prop->{'port'}->[1], 5402, "Right port"); 151is($prop->{'port'}->[2], 5403, "Right port"); 152is($prop->{'user'}, 'foo', "Right user"); 153 154###----------------------------------------------------------------### 155 156$prop = eval { local @ARGV = ('--user=cmdline'); FooServer->run(conf_file => __FILE__.'.conf', user => 'runargs')->{'server'} }; 157ok($prop, "Loaded server"); 158$prop ||= {}; 159is($prop->{'user'}, 'cmdline', "Right user \"$prop->{'user'}\""); 160 161###----------------------------------------------------------------### 162 163$prop = eval { FooServer->run(conf_file => __FILE__.'.conf', user => 'runargs')->{'server'} }; 164ok($prop, "Loaded server"); 165$prop ||= {}; 166is($prop->{'user'}, 'runargs', "Right user \"$prop->{'user'}\""); 167 168###----------------------------------------------------------------### 169 170$prop = eval { FooServer->run(my_option => 'wow')->{'server'} }; 171ok($prop, "Loaded server"); 172$prop ||= {}; 173is($prop->{'my_option'}, 'wow', 'Could use custom options'); 174 175###----------------------------------------------------------------### 176 177$prop = eval { FooServer->run(an_arrayref_item => 'wow')->{'server'} }; 178ok($prop, "Loaded server"); 179$prop ||= {}; 180is(scalar(@{ $prop->{'an_arrayref_item'} }), 1, "Had 1 configured custom array option"); 181is($prop->{'an_arrayref_item'}->[0], 'wow', "Right value"); 182 183###----------------------------------------------------------------### 184 185$prop = eval { FooServer->run(conf_file => __FILE__.'.conf', user => 'runargs')->{'server'} }; 186ok($prop, "Loaded server"); 187$prop ||= {}; 188is($prop->{'my_option'}, 'bar', "Right my_option \"$prop->{'my_option'}\""); 189is(scalar(@{ $prop->{'an_arrayref_item'} }), 3, "Had 3 configured custom array option"); 190is($prop->{'an_arrayref_item'}->[0], 'one', "Right value"); 191is($prop->{'an_arrayref_item'}->[1], 'three', "Right value"); 192is($prop->{'an_arrayref_item'}->[2], 'two', "Right value"); 193 194###----------------------------------------------------------------### 195 196$prop = eval { local @ARGV = ('--group=cmdline'); FooServer->run(conf_file => __FILE__.'.conf', group => 'runargs')->{'server'} }; 197ok($prop, "Loaded server"); 198$prop ||= {}; 199is($prop->{'group'}, 'cmdline', "Right group \"$prop->{'group'}\""); 200 201###----------------------------------------------------------------### 202 203$prop = eval { FooServer->run(conf_file => __FILE__.'.conf', group => 'runargs')->{'server'} }; 204ok($prop, "Loaded server"); 205$prop ||= {}; 206is($prop->{'group'}, 'runargs', "Right group \"$prop->{'group'}\""); 207 208###----------------------------------------------------------------### 209 210$prop = eval { FooServer->run(conf_file => __FILE__.'.conf')->{'server'} }; 211ok($prop, "Loaded server"); 212$prop ||= {}; 213is($prop->{'group'}, 'confgroup', "Right group \"$prop->{'group'}\""); 214 215###----------------------------------------------------------------### 216 217$prop = eval { FooServer->run->{'server'} }; 218ok($prop, "Loaded server"); 219$prop ||= {}; 220is($prop->{'group'}, 'defaultgroup', "Right group \"$prop->{'group'}\""); 221is(scalar(@{ $prop->{'allow'} }), 2, "Defaults for allow are set also"); 222 223###----------------------------------------------------------------### 224 225{ 226 package BarServer; 227 @BarServer::ISA = qw(FooServer); 228 sub default_values { 229 return { 230 conf_file => __FILE__.'.conf' 231 }; 232 } 233} 234 235$prop = eval { BarServer->run->{'server'} }; 236$prop ||= {}; 237is($prop->{'group'}, 'confgroup', "Right group \"$prop->{'group'}\""); 238 239###----------------------------------------------------------------### 240 241$prop = eval { FooServer->new({ 242 conf_file => __FILE__.'.conf', # arguments passed to new win 243})->run({ 244 conf_file => 'somefile_that_doesnot_exist', 245})->{'server'} }; 246$prop ||= {}; 247is($prop->{'group'}, 'confgroup', "Right group \"$prop->{'group'}\""); 248 249 250 251###----------------------------------------------------------------### 252 253if (!$ENV{'TEST_LOG4PERL'}) { 254 SKIP: { skip("TEST_LOG4PERL not set - skipping Log::Log4perl tests", 7) }; 255} elsif (!eval { require Log::Log4perl; require File::Temp }) { 256 SKIP: { skip("Log::Log4perl not installed: $@", 7) }; 257} else { 258 259 $prop = eval { FooServer->run( 260 log_file => "Log::Log4perl" 261 ) }; 262 like("$@", qr/Must specify a log4perl_conf file/, "Got error due to missing log4perl_conf"); 263 264 my ($log_fh, $log4perl_file) = File::Temp::tempfile(SUFFIX => '.log', UNLINK => 1); 265 unlink $log4perl_file; 266 267 my $conf = << "EOF"; 268log4perl.logger.tester = WARN, FileAppndr1 269 270log4perl.appender.FileAppndr1 = Log::Log4perl::Appender::File 271log4perl.appender.FileAppndr1.filename = ${log4perl_file} 272log4perl.appender.FileAppndr1.layout = Log::Log4perl::Layout::SimpleLayout 273EOF 274 275 my ($conf_fh, $conf_file) = File::Temp::tempfile(SUFFIX => '.log4perl', UNLINK => 1); 276 print $conf_fh $conf; 277 close $conf_fh; 278 279 # This log file is same as specified in Options.t.log4perl 280 open my $old_stdout, ">&", STDOUT; # save this off because setting a log_file is going to force close STDIN and STDOUT 281 $prop = eval { FooServer->run( 282 log_file => "Log::Log4perl", 283 log4perl_conf => $conf_file, 284 log4perl_logger => "tester", 285 )->{'server'} }; 286 my $err = "$@"; 287 open STDOUT, ">&", $old_stdout; # restore it 288 289 # There was a test for a bad log4perl_conf file, but log4perl only allows you to initialise once 290 # so subsequent initialisations always had the bad filename 291 #like( $@, qr/Cannot open config file '.*?'/, "Got error due to missing log4perl_conf file" ); 292 ok(!$err, "No Log4perl errors"); 293 is(ref($prop->{'log_function'}), "CODE", "Log4perl initialised with function created"); 294 ok(-e $log4perl_file, "Log file $log4perl_file found"); 295 ok(! -s $log4perl_file, "Log file is 0 bytes"); 296 297 $prop->{'log_function'}->(1, "A test message"); 298 ok(-s $log4perl_file, "Log file now has data"); 299 300 open my $fh, '<', $log4perl_file; 301 my $data = <$fh>; 302 is($data, "ERROR - A test message\n", "Got expected log message"); 303} 304