lanti
lanti

Reputation: 549

Test Mojo - Premature connection close

I am testing my app using this code:

use Carp; use Carp::Heavy;
use Mojo::Base -strict;

use Test::More;
use Test::Mojo;

use FindBin;
require "$FindBin::Bin/../script/MyApp";
my $t = Test::Mojo->new( 'MyDb' );
$t->ua->max_redirects(10);
$t->ua->inactivity_timeout(3600);
$t->ua->connect_timeout(3600);

$t->get_ok('/int/ap/profit/2015-01-01/2015-03-31/overview')
  ->status_is(200)
  ->text_is('html body h3' => 'Überblick')
  ->text_is('tr:nth-child(2) td:nth-child(8)' => '2.000,00')
  ->text_is('tr:nth-child(5) td:nth-child(8)' => '4.000,00')
;

done_testing();

This test fails with Premature connection close. Nevertheless runnning the same request on morbo returns the expected html-code to the browser. It seems as if $t->ua->inactivity_timeout(3600); does not have any effect here.

Upvotes: 2

Views: 1279

Answers (2)

arhak
arhak

Reputation: 2542

based on @Logioniz answer and gist here is a fork of his MWE

use Mojo::Base -strict;

use Mojo::IOLoop;
use Mojolicious::Lite;
use Test::More;
use Test::Mojo;

get '/delayed' => sub {
  my $c = shift->render_later;
  $c->inactivity_timeout(5);
  Mojo::IOLoop->timer(3 => sub {
    $c->render(json => {result => 'ok'});
  });
};

get '/premature' => sub {
  my $c = shift;
  #$c->render(text => 'To be continued...', status => 206);
  $c->tx->res->headers->connection('close');
  $c->rendered(123);
};

my $t = Test::Mojo->new;

subtest 'enough timeout' => sub {
  $t->ua->inactivity_timeout(5);
  $t->get_ok('/delayed')
    ->status_is(200)
    ->json_is('/result' => 'ok')
  ;
};

subtest 'not enough timeout' => sub {
  $t->ua->inactivity_timeout(1);
  $t->get_fail('/delayed')
    ->status_isnt(200)
    ->content_is('', 'no content')
  ;
};

subtest 'sudden close' => sub {
  $t->ua->inactivity_timeout(5);
  $t->ua->max_connections(0);
  $t->get_fail('/premature')
    ->status_isnt(200)
    ->content_is('', 'no content')
  ;
};

done_testing();

package Test::Mojo;

use Test::More;

sub get_fail {
  my ($self, $uri) = @_;
  TODO: {
    local $TODO = 'get_fail';
    return $self->get_ok($uri);
  }
}

the corresponding output is:

# Subtest: enough timeout
    ok 1 - GET /delayed
    ok 2 - 200 OK
    ok 3 - exact match for JSON Pointer "/result"
    1..3
ok 1 - enough timeout
# Subtest: not enough timeout
    # Inactivity timeout
    not ok 1 - GET /delayed # TODO get_fail
    #   Failed (TODO) test 'GET /delayed'
    #   at D:/TMP-aux/MSP-reports2/1-fork-quick.pl line 60.
    ok 2 - not 200 OK
    ok 3 - no content
    1..3
ok 2 - not enough timeout
# Subtest: sudden close
    # Premature connection close
    not ok 1 - GET /premature # TODO get_fail
    #   Failed (TODO) test 'GET /premature'
    #   at D:/TMP-aux/MSP-reports2/1-fork-quick.pl line 60.
    ok 2 - not 200 OK
    ok 3 - no content
    1..3
ok 3 - sudden close
1..3

Upvotes: 0

Logioniz
Logioniz

Reputation: 891

Long operation require inactivity_timeout on client side and server side. Also if you write non-blocking code you must have render_later.

One day I needed option max_connections, but I can not remember why. So, after this day i always add max_connections(0) to my test :)

See, example here.

When you post your question you should write simple mojolicious lite example which have all logic which have error. So, now you show right test code and ask why it not working without main logic :) It's very strangely. Nobody will answer you or coming up with possible events when you have specific.

Upvotes: 3

Related Questions