Algorithm-Backoff-RetryTimeouts

 view release on metacpan or  search on metacpan

t/basic.t  view on Meta::CPAN

#!perl

use strict;
use warnings;

use Test::More 0.98;
use List::Util qw< min max sum >;

use Algorithm::Backoff::RetryTimeouts;

my $rt;
my $time  = 0;
my $sqrt2 = sqrt(2);

subtest "Base defaults" => sub {
    $rt = Algorithm::Backoff::RetryTimeouts->new(
        # for the unit tests
        _start_timestamp      => 0,
        jitter_factor         => 0,
        timeout_jitter_factor => 0,
    );

    $time = 0;
    is($rt->timeout, 25, 'Initial timeout: 25');

    # 1: one second attempt
    test_attempt(
        attempt_time   => 1,
        expected_delay => $sqrt2 - 1,  # sqrt(2)^1 - 1
    );

    # 2: instant failure
    test_attempt(
        attempt_time   => 0,
        expected_delay => 2,  # sqrt(2)^2
    );

    # 3: full timeout
    test_attempt(
        attempt_time   => $rt->timeout,
        expected_delay => 0,
    );

    # 4: one second attempt
    test_attempt(
        attempt_time   => 1,
        expected_delay => 3,  # sqrt(2)^4 - 1
    );

    # 5: full timeout (with min_adjust_timeout trigger)
    test_attempt(
        expected_delay   => 0,
        expected_timeout => 5,
    );

    # 6: full timeout (with remaining time max delay check)
    test_attempt(
        expected_delay   => 2.323,  # 50% of the remaining time
        expected_timeout => 5,
    );

    # 7: final attempt
    test_attempt(
        expected_delay   => -1,
        expected_timeout => 5
    );
};

subtest "attr: adjust_timeout_factor" => sub {
    $rt = Algorithm::Backoff::RetryTimeouts->new(
        adjust_timeout_factor => 0.25,

        # for the unit tests
        _start_timestamp      => 0,
        jitter_factor         => 0,
        timeout_jitter_factor => 0,
    );

    $time = 0;
    is($rt->timeout, 12.5, 'Initial timeout: 12.5');

    # 1: one second attempt
    test_attempt(
        attempt_time   => 1,
        expected_delay => $sqrt2 - 1,  # sqrt(2)^1 - 1
    );

    # 2: instant failure
    test_attempt(
        attempt_time   => 0,
        expected_delay => 2,  # sqrt(2)^2
    );

    # 3: full timeout
    test_attempt(
        expected_delay => 0,
    );

    # 4: one second attempt
    test_attempt(
        attempt_time   => 1,
        expected_delay => 3,  # sqrt(2)^4 - 1
    );

    # 5: full timeout
    test_attempt(
        expected_delay => 0,
    );

    # 6: full timeout (with min_adjust_timeout trigger)
    note "Prev Timeout: ".round($rt->timeout);
    test_attempt(
        expected_delay   => 2.199,  # sqrt(2)^6 = 8 - 5.801 (prev timeout)
        expected_timeout => 5,
    );

    # 7: full timeout
    test_attempt(
        expected_delay   => 6.314,  # sqrt(2)^7 - 5
        expected_timeout => 5,
    );

    # 8: final attempt
    test_attempt(
        expected_delay   => -1,
        expected_timeout => 5,
    );
};

subtest "attr: min_adjust_timeout" => sub {
    $rt = Algorithm::Backoff::RetryTimeouts->new(
        adjust_timeout_factor => 0.75,  # just to make this faster
        min_adjust_timeout    => 0,

        # for the unit tests
        _start_timestamp      => 0,
        jitter_factor         => 0,
        timeout_jitter_factor => 0,
    );

    $time = 0;
    is($rt->timeout, 37.5, 'Initial timeout: 37.5');

    # 1: full timeout
    test_attempt(
        expected_delay => 0,
    );

    # 2: full timeout
    test_attempt(
        expected_delay => 0,
    );

    # NOTE: The rest of these are so close to the edge of max_actual_duration that they
    # consistently hit the remaining time max delay check.

    # 3-7: full timeouts
    test_attempt(
        expected_delay => 0.195,



( run in 0.784 second using v1.01-cache-2.11-cpan-39bf76dae61 )