<commit_before>package com.evanlennick.retry4j;

import com.evanlennick.retry4j.exception.CallFailureException;
import com.evanlennick.retry4j.exception.UnexpectedCallFailureException;
import org.testng.annotations.Test;

import java.util.concurrent.Callable;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.within;

public class RetryExecutorTest {

    @Test(expectedExceptions = {CallFailureException.class})
    public void verifyReturningFalseFromCallFails() throws Exception {
        Callable<Boolean> callable = () -> false;

        RetryConfig retryConfig = new RetryConfigBuilder()
                .withMaxNumberOfTries(5)
                .withDelayBetweenTries(0)
                .withFixedBackoff()
                .build();

        new RetryExecutor(retryConfig).execute(callable);
    }

    @Test
    public void verifyReturningTrueFromCallSucceeds() throws Exception {
        Callable<Boolean> callable = () -> true;

        RetryConfig retryConfig = new RetryConfigBuilder()
                .withMaxNumberOfTries(5)
                .withDelayBetweenTries(0)
                .withFixedBackoff()
                .build();

        RetryResults results = new RetryExecutor(retryConfig).execute(callable);
        assertThat(results.isSucceeded());
    }

    @Test(expectedExceptions = {CallFailureException.class})
    public void verifyExceptionFromCallThrowsCallFailureException() throws Exception {
        Callable<Boolean> callable = () -> {
            throw new RuntimeException();
        };

        RetryConfig retryConfig = new RetryConfigBuilder()
                .retryOnAnyException()
                .withMaxNumberOfTries(1)
                .withDelayBetweenTries(0)
                .withFixedBackoff()
                .build();

        new RetryExecutor(retryConfig).execute(callable);
    }

    @Test(expectedExceptions = {CallFailureException.class})
    public void verifySpecificExceptionFromCallThrowsCallFailureException() throws Exception {
        Callable<Boolean> callable = () -> {
            throw new IllegalArgumentException();
        };

        RetryConfig retryConfig = new RetryConfigBuilder()
                .retryOnSpecificExceptions(IllegalArgumentException.class)
                .withMaxNumberOfTries(1)
                .withDelayBetweenTries(0)
                .withFixedBackoff()
                .build();

        new RetryExecutor(retryConfig).execute(callable);
    }

    @Test(expectedExceptions = {UnexpectedCallFailureException.class})
    public void verifyUnspecifiedExceptionCausesUnexpectedCallFailureException() throws Exception {
        Callable<Boolean> callable = () -> {
            throw new IllegalArgumentException();
        };

        RetryConfig retryConfig = new RetryConfigBuilder()
                .retryOnSpecificExceptions(UnsupportedOperationException.class)
                .withMaxNumberOfTries(1)
                .withDelayBetweenTries(0)
                .withFixedBackoff()
                .build();

        new RetryExecutor(retryConfig).execute(callable);
    }

    @Test
    public void verifyFixedBackoffTiming() throws Exception {
        Callable<Boolean> callable = () -> false;

        RetryConfig retryConfig = new RetryConfigBuilder()
                .withMaxNumberOfTries(3)
                .withDelayBetweenTries(100L)
                .withFixedBackoff()
                .build();

        long start = System.currentTimeMillis();

        try {
            new RetryExecutor(retryConfig).execute(callable);
        } catch (CallFailureException | UnexpectedCallFailureException e) {
        }

        long end = System.currentTimeMillis();
        long elapsed = end - start;

        assertThat(elapsed).isCloseTo(300, within(25L));
    }

    @Test
    public void verifyExponentialBackoffTiming() throws Exception {
        Callable<Boolean> callable = () -> false;

        RetryConfig retryConfig = new RetryConfigBuilder()
                .withMaxNumberOfTries(5)
                .withDelayBetweenTries(20L)
                .withExponentialBackoff()
                .build();

        long start = System.currentTimeMillis();

        try {
            new RetryExecutor(retryConfig).execute(callable);
        } catch (CallFailureException | UnexpectedCallFailureException e) {
        }

        long end = System.currentTimeMillis();
        long elapsed = end - start;

        assertThat(elapsed).isCloseTo(290, within(25L));
    }

    @Test
    public void verifyResultsArePopulatedOnSuccessfulCall() throws Exception {
        Callable<Boolean> callable = () -> true;

        RetryConfig retryConfig = new RetryConfigBuilder()
                .withMaxNumberOfTries(5)
                .withDelayBetweenTries(0)
                .withFixedBackoff()
                .build();
<commit_msg>added test for fibonacci backoff<commit_after>package com.evanlennick.retry4j;

import com.evanlennick.retry4j.exception.CallFailureException;
import com.evanlennick.retry4j.exception.UnexpectedCallFailureException;
import org.testng.annotations.Test;

import java.util.concurrent.Callable;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.within;

public class RetryExecutorTest {

    @Test(expectedExceptions = {CallFailureException.class})
    public void verifyReturningFalseFromCallFails() throws Exception {
        Callable<Boolean> callable = () -> false;

        RetryConfig retryConfig = new RetryConfigBuilder()
                .withMaxNumberOfTries(5)
                .withDelayBetweenTries(0)
                .withFixedBackoff()
                .build();

        new RetryExecutor(retryConfig).execute(callable);
    }

    @Test
    public void verifyReturningTrueFromCallSucceeds() throws Exception {
        Callable<Boolean> callable = () -> true;

        RetryConfig retryConfig = new RetryConfigBuilder()
                .withMaxNumberOfTries(5)
                .withDelayBetweenTries(0)
                .withFixedBackoff()
                .build();

        RetryResults results = new RetryExecutor(retryConfig).execute(callable);
        assertThat(results.isSucceeded());
    }

    @Test(expectedExceptions = {CallFailureException.class})
    public void verifyExceptionFromCallThrowsCallFailureException() throws Exception {
        Callable<Boolean> callable = () -> {
            throw new RuntimeException();
        };

        RetryConfig retryConfig = new RetryConfigBuilder()
                .retryOnAnyException()
                .withMaxNumberOfTries(1)
                .withDelayBetweenTries(0)
                .withFixedBackoff()
                .build();

        new RetryExecutor(retryConfig).execute(callable);
    }

    @Test(expectedExceptions = {CallFailureException.class})
    public void verifySpecificExceptionFromCallThrowsCallFailureException() throws Exception {
        Callable<Boolean> callable = () -> {
            throw new IllegalArgumentException();
        };

        RetryConfig retryConfig = new RetryConfigBuilder()
                .retryOnSpecificExceptions(IllegalArgumentException.class)
                .withMaxNumberOfTries(1)
                .withDelayBetweenTries(0)
                .withFixedBackoff()
                .build();

        new RetryExecutor(retryConfig).execute(callable);
    }

    @Test(expectedExceptions = {UnexpectedCallFailureException.class})
    public void verifyUnspecifiedExceptionCausesUnexpectedCallFailureException() throws Exception {
        Callable<Boolean> callable = () -> {
            throw new IllegalArgumentException();
        };

        RetryConfig retryConfig = new RetryConfigBuilder()
                .retryOnSpecificExceptions(UnsupportedOperationException.class)
                .withMaxNumberOfTries(1)
                .withDelayBetweenTries(0)
                .withFixedBackoff()
                .build();

        new RetryExecutor(retryConfig).execute(callable);
    }

    @Test
    public void verifyBackoffTiming_fixed() throws Exception {
        Callable<Boolean> callable = () -> false;

        RetryConfig retryConfig = new RetryConfigBuilder()
                .withMaxNumberOfTries(3)
                .withDelayBetweenTries(100L)
                .withFixedBackoff()
                .build();

        long start = System.currentTimeMillis();

        try {
            new RetryExecutor(retryConfig).execute(callable);
        } catch (CallFailureException | UnexpectedCallFailureException e) {
        }

        long end = System.currentTimeMillis();
        long elapsed = end - start;

        assertThat(elapsed).isCloseTo(300, within(25L));
    }

    @Test
    public void verifyBackoffTiming_exponential() throws Exception {
        Callable<Boolean> callable = () -> false;

        RetryConfig retryConfig = new RetryConfigBuilder()
                .withMaxNumberOfTries(5)
                .withDelayBetweenTries(20L)
                .withExponentialBackoff()
                .build();

        long start = System.currentTimeMillis();

        try {
            new RetryExecutor(retryConfig).execute(callable);
        } catch (CallFailureException | UnexpectedCallFailureException e) {
        }

        long end = System.currentTimeMillis();
        long elapsed = end - start;

        assertThat(elapsed).isCloseTo(290, within(25L));
    }

    @Test
    public void verifyBackoffTiming_fibonacci() throws Exception {
        Callable<Boolean> callable = () -> false;

        RetryConfig retryConfig = new RetryConfigBuilder()
                .withMaxNumberOfTries(5)
                .withDelayBetweenTries(10L)
                .withFibonacciBackoff()
                .build();

        long start = System.currentTimeMillis();

        try {
            new RetryExecutor(retryConfig).execute(callable);
        } catch (CallFailureException | UnexpectedCallFailureException e) {
        }

        long end = System.currentTimeMillis();
        long elapsed = end - start;

        assertThat(elapsed).isCloseTo(70, within(25L));
    }

    @Test
    public void verifyResultsArePopulatedOnSuccessfulCall() throws Exception {
        Callable<Boolean> callable = () -> true;

        RetryConfig retryConfig = new RetryConfigBuilder()
                .withMaxNumberOfTries(5)
                .withDelayBetweenTries(0)
                .withFixedBackoff()
                .build();

{'fraction_non_alphanumeric': 0.08734709480122324, 'fraction_numerical': 0.006785168195718654, 'mean_word_length': 2.3541666666666665, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6645725', 'n_tokens_mistral': 2810, 'n_tokens_neox': 2665, 'n_words': 478}