diff options
| author | Murilo Ijanc <[email protected]> | 2026-07-26 14:40:05 -0300 |
|---|---|---|
| committer | Murilo Ijanc <[email protected]> | 2026-07-26 14:40:05 -0300 |
| commit | 0bc578d6d334c7f1ccaf329cd61bb8bce76b7f59 (patch) | |
| tree | 86f73108f0432fd8330edcaab8b8ae7018322dee /t/04-retry.t | |
| download | perl-6661cb35162c38099b86f248b938f5e4d4d11515.tar.gz | |
Initial importv0.1.0
Diffstat (limited to 't/04-retry.t')
| -rw-r--r-- | t/04-retry.t | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/t/04-retry.t b/t/04-retry.t new file mode 100644 index 0000000..d304b5a --- /dev/null +++ b/t/04-retry.t @@ -0,0 +1,147 @@ +use strict; +use warnings; +use utf8; + +use FindBin (); +use lib "$FindBin::Bin/lib"; + +use Test::More; +use TestServer qw(se_address json new_client); + +use Cepis; +use Time::HiRes (); + +{ + my $server = TestServer->new( + routes => { + '/01001000' => [ + [ 500, json( { erro => 'interno' } ), {} ], + [ 200, json( se_address() ), {} ], + ] + } + ); + my $client = new_client($server); + + is( $client->lookup('01001000')->localidade, 'São Paulo', 'a retry recovers' ); + is( $server->count('/01001000'), 2, 'it took two attempts' ); + $server->stop; +} + +{ + my $server = TestServer->new( + routes => { '/01001000' => [ 503, json( { erro => 'interno' } ), {} ] } ); + my $client = new_client($server); + + my $ok = eval { $client->lookup('01001000'); 1 }; + ok( !$ok, 'exhausting the attempts throws' ); + isa_ok( $@, 'Cepis::Error::ServerError' ); + is( $@->status, 503, 'the status of the last attempt is exposed' ); + is( $server->count('/01001000'), 3, 'three attempts by default' ); + $server->stop; +} + +{ + my $server = TestServer->new( routes => { '/01001000' => [ 500, '{}', {} ] } ); + my $client = new_client( $server, max_attempts => 1 ); + + my $ok = eval { $client->lookup('01001000'); 1 }; + ok( !$ok, 'max_attempts of 1 still throws' ); + is( $server->count('/01001000'), 1, 'and disables retrying' ); + $server->stop; +} + +{ + my $server = TestServer->new( + routes => { '/01001000' => [ 429, '{}', { 'Retry-After' => '7' } ] } ); + my $client = new_client($server); + + my $ok = eval { $client->lookup('01001000'); 1 }; + ok( !$ok, 'a 429 throws' ); + isa_ok( $@, 'Cepis::Error::RateLimited' ); + cmp_ok( abs( $@->retry_after - 7 ), '<', 1e-9, 'Retry-After in seconds is read' ); + $server->stop; +} + +{ + my @day = qw(Sun Mon Tue Wed Thu Fri Sat); + my @month = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); + my @t = gmtime( time + 4 ); + my $date = sprintf '%s, %02d %s %04d %02d:%02d:%02d GMT', $day[ $t[6] ], $t[3], + $month[ $t[4] ], $t[5] + 1900, $t[2], $t[1], $t[0]; + + my $server = TestServer->new( + routes => { '/01001000' => [ 429, '{}', { 'Retry-After' => $date } ] } ); + my $client = new_client($server); + + my $ok = eval { $client->lookup('01001000'); 1 }; + ok( !$ok, 'a 429 with an HTTP date throws' ); + isa_ok( $@, 'Cepis::Error::RateLimited' ); + cmp_ok( $@->retry_after, '>', 0, 'the date form is parsed too' ); + cmp_ok( $@->retry_after, '<=', 5, 'and lands where it should' ); + $server->stop; +} + +{ + my $server = TestServer->new( + routes => { '/01001000' => [ 429, '{}', { 'Retry-After' => '3600' } ] } ); + my $client = new_client($server); + + my $started = Time::HiRes::time(); + my $ok = eval { $client->lookup('01001000'); 1 }; + ok( !$ok, 'an absurd Retry-After still throws' ); + cmp_ok( Time::HiRes::time() - $started, '<', 5, 'and is capped by backoff_max' ); + $server->stop; +} + +{ + my $client = Cepis::Client->new( + base_url => 'http://127.0.0.1:1', + max_attempts => 2, + backoff_base => 0.001, + backoff_max => 0.01, + timeout => 1.0, + ); + + my $ok = eval { $client->lookup('01001000'); 1 }; + ok( !$ok, 'nothing listening throws' ); + isa_ok( $@, 'Cepis::Error::Network' ); + like( "$@", qr/127\.0\.0\.1:1/, 'the message names the URL' ); +} + +{ + my $server = TestServer->new( routes => { '/01001000' => [ 500, '{}', {} ] } ); + my $client = new_client( + $server, + max_attempts => 50, + backoff_base => 0.05, + backoff_max => 0.05, + total_timeout => 0.3, + ); + + my $started = Time::HiRes::time(); + my $ok = eval { $client->lookup('01001000'); 1 }; + ok( !$ok, 'the call still throws' ); + isa_ok( $@, 'Cepis::Error::ServerError' ); + cmp_ok( Time::HiRes::time() - $started, '<', 3, 'total_timeout bounds the whole call' ); + cmp_ok( $server->count('/01001000'), '<', 50, 'and cuts the attempts short' ); + $server->stop; +} + +{ + my $server = TestServer->new( + routes => { + '/01001000' => [ + [ 502, '{}', {} ], + [ 504, '{}', {} ], + [ 200, json( se_address() ), {} ], + ] + } + ); + my $client = new_client($server); + + is( $client->lookup('01001000')->uf, 'SP', '502 and 504 are retried too' ); + is( $server->count('/01001000'), 3, 'across three attempts' ); + $server->stop; +} + +done_testing(); |