File: retry-on-error.t

package info (click to toggle)
libtwitter-api-perl 1.0006-1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 424 kB
  • sloc: perl: 2,868; makefile: 7
file content (117 lines) | stat: -rw-r--r-- 3,697 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!perl
use 5.14.1;
use warnings;
use HTTP::Response;
use Ref::Util qw/is_ref/;
use Test::Fatal;
use Test::Spec;

use Twitter::API;

sub new_client {
    my $response = shift;

    my $user_agent = mock();
    $user_agent->stubs(request => sub {
        like $_[1]->headers->header('authorization'), qr/^OAuth\s/, 'The Authorization header should start with OAuth';

        my ( $code, $reason ) = is_ref($$response[0])
            ? @{ shift @$response // [ 999 => 'off the end' ] }
            : @{ $response };
        HTTP::Response->new($code, $reason);
    });

    return Twitter::API->new_with_traits(
        traits              => 'RetryOnError',
        consumer_key        => 'key',
        consumer_secret     => 'secret',
        access_token        => 'token',
        access_token_secret => 'token-secret',
        user_agent          => $user_agent,
        @_
    );
}

describe RetryOnError => sub {
    it 'dies after 5 retries' => sub {
        my $client = new_client([ 503 => 'Temporarily Unavailable' ]);
        my $retry = mock();
        $retry->expects('ping')->exactly(5);
        $client->retry_delay_code(sub { $retry->ping });
        like exception {
            $client->get('foo');
        }, qr/Temporarily Unavailable/;
    };
    it 'dies immediately on 404' => sub {
        my $client = new_client([ 404 => 'Not Found' ]);
        my $retry = mock();
        $retry->expects('ping')->exactly(0);
        $client->retry_delay_code(sub { $retry->ping });
        like exception {
            $client->get('foo');
        }, qr/Not Found/;
    };
    it 'dies no first perm error' => sub {
        my $client = new_client([
            [ 500 => 'Internal Server Error'   ],
            [ 503 => 'Temporarily Unavailable' ],
            [ 403 => 'Forbidden'               ],
        ]);
        my $retry = mock();
        $retry->expects('ping')->exactly(2);
        $client->retry_delay_code(sub { $retry->ping });
        like exception {
            $client->get('foo');
        }, qr/Forbidden/;
    };
    it 'succeeds after retry' => sub {
        my $client = new_client([
            [ 500 => 'Internal Server Error'   ],
            [ 503 => 'Temporarily Unavailable' ],
            [ 200 => 'OK'                      ],
        ]);
        my $retry = mock();
        $retry->expects('ping')->exactly(2);
        $client->retry_delay_code(sub { $retry->ping });
        is exception {
            $client->get('foo');
        }, undef;
    };
    it 'succeeds immediately on 200' => sub {
        my $client = new_client([ 200 => 'OK' ]);
        my $retry = mock();
        $retry->expects('ping')->exactly(0);
        $client->retry_delay_code(sub { $retry->ping });
        is exception {
            $client->get('foo');
        }, undef;
    };
    it 'has expected initial delay' => sub {
        my $client = new_client([
            [ 500 => 'Internal Server Error'   ],
            [ 200 => 'OK'                      ],
        ]);
        my $retry = mock();
        $retry->expects('ping')->with(0.25);
        $client->retry_delay_code(sub { $retry->ping(@_) });
        is exception {
            $client->get('foo');
        }, undef;
    };
    it 'delay doubles' => sub {
        my $client = new_client([
            [ 500 => 'Internal Server Error'   ],
            [ 500 => 'Internal Server Error'   ],
            [ 200 => 'OK'                      ],
        ]);
        my $expected_delay = 0.25;
        $client->retry_delay_code(sub {
            my $delay = shift;
            is $delay, $expected_delay;
            $expected_delay *= 2;
        });
        is exception { $client->get('foo') }, undef;
    };
};

runtests;