TPSGI.t 3.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. use strict;
  2. use warnings;
  3. use Test2::V0;
  4. use Test2::Plugin::NoWarnings;
  5. use Cwd qw{abs_path};
  6. use File::Temp qw{tempdir};
  7. use File::Basename qw{dirname};
  8. use Test::MockModule;
  9. use lib dirname( abs_path(__FILE__) ) . '/../lib';
  10. use TPSGI;
  11. # Every line the log gets, so a test can ask whether the reason for a 500 is
  12. # among them.
  13. package Test::Logger::Capture {
  14. use parent qw{Log::Dispatch::Output};
  15. our @lines;
  16. sub new {
  17. my ( $class, %p ) = @_;
  18. my $self = bless {}, $class;
  19. $self->_basic_init( name => 'capture', min_level => $p{min_level} );
  20. return $self;
  21. }
  22. sub log_message {
  23. my ( $self, %p ) = @_;
  24. push( @lines, $p{message} );
  25. return;
  26. }
  27. }
  28. $INC{'Test/Logger/Capture.pm'} = __FILE__;
  29. my $dir = tempdir( CLEANUP => 1 );
  30. my %options = (
  31. log_name => "$dir/tpsgi.log",
  32. log_dir => $dir,
  33. verbose => 0,
  34. loggers => ['Test::Logger::Capture'],
  35. );
  36. sub fake_env {
  37. open( my $errors, '>', \my $written ) or die "Cannot open a scalar: $!";
  38. return ( { 'psgi.errors' => $errors }, \$written );
  39. }
  40. # TPSGI builds its log once per process, so this has to run before anything
  41. # else here builds it: a logger that will not load is only a failure the first
  42. # time.
  43. subtest 'cannot_start, when building the log is what failed' => sub {
  44. my ( $env, $written ) = fake_env();
  45. my $res;
  46. ok( lives { $res = TPSGI::cannot_start( "Could not load Bogus.pm!\n", $env, %options, loggers => ['Bogus::Logger::That::Is::Not'] ) },
  47. 'a logger that will not load does not turn the 500 into an exception' )
  48. or note $@;
  49. is( $res->[0], 500, 'it still answers 500' );
  50. like( $$written, qr/Could not load Bogus\.pm/, 'and psgi.errors still gets the reason' );
  51. };
  52. subtest 'cannot_start' => sub {
  53. local @Test::Logger::Capture::lines;
  54. my ( $env, $written ) = fake_env();
  55. my $res = TPSGI::cannot_start( "Could not load Bogus.pm!\nCan't locate Bogus/Dep.pm in \@INC\n", $env, %options );
  56. is( $res->[0], 500, 'answers 500' );
  57. like( $$written, qr/Can't locate Bogus\/Dep\.pm/, 'psgi.errors gets the whole reason' );
  58. like( \@Test::Logger::Capture::lines, bag { item qr/Could not start: Could not load Bogus\.pm!\nCan't locate/; etc() }, 'and so does the log' );
  59. ok( lives { TPSGI::cannot_start( "no env\n", undef, %options ) }, 'a missing env is not a second failure' ) or note $@;
  60. };
  61. subtest 'app, when the request dies' => sub {
  62. local @Test::Logger::Capture::lines;
  63. my ( $env, $written ) = fake_env();
  64. my $mock = Test::MockModule->new( 'TPSGI', no_auto => 1 );
  65. $mock->redefine( _app => sub { die "Can't locate Bogus/Dep.pm in \@INC\n" } );
  66. my $tpsgi = bless( { %options, ip => '0.0.0.0' }, 'TPSGI' );
  67. my $res = $tpsgi->app($env);
  68. is( $res->[0], 500, 'answers 500' );
  69. like( $$written, qr/Can't locate Bogus\/Dep\.pm/, 'psgi.errors gets the reason' );
  70. like( \@Test::Logger::Capture::lines, bag { item qr/Request failed: Can't locate Bogus\/Dep\.pm/; etc() }, 'and so does the log, not just that a 500 happened' );
  71. };
  72. done_testing();