2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.mielecloud.internal.webservice.sse;
15 import static org.junit.jupiter.api.Assertions.*;
16 import static org.mockito.Mockito.*;
18 import java.util.Random;
20 import org.eclipse.jdt.annotation.NonNullByDefault;
21 import org.junit.jupiter.api.Test;
24 * @author Björn Lange - Initial contribution
27 public class ExponentialBackoffWithJitterTest {
28 private static final long RETRY_INTERVAL = 2;
29 private static final long ALTERNATIVE_RETRY_INTERVAL = 50;
30 private static final long MINIMUM_WAIT_TIME = 1;
31 private static final long ALTERNATIVE_MINIMUM_WAIT_TIME = 2;
32 private static final long MAXIMUM_WAIT_TIME = 100;
33 private static final long ALTERNATIVE_MAXIMUM_WAIT_TIME = 150;
36 public void whenMinimumWaitTimeIsSmallerThanZeroThenAnIllegalArgumentExceptionIsThrown() {
38 assertThrows(IllegalArgumentException.class, () -> {
39 new ExponentialBackoffWithJitter(-MINIMUM_WAIT_TIME, MAXIMUM_WAIT_TIME, RETRY_INTERVAL);
44 public void whenMaximumWaitTimeIsSmallerThanZeroThenAnIllegalArgumentExceptionIsThrown() {
46 assertThrows(IllegalArgumentException.class, () -> {
47 new ExponentialBackoffWithJitter(MINIMUM_WAIT_TIME, -MAXIMUM_WAIT_TIME, RETRY_INTERVAL);
52 public void whenRetryIntervalIsSmallerThanZeroThenAnIllegalArgumentExceptionIsThrown() {
54 assertThrows(IllegalArgumentException.class, () -> {
55 new ExponentialBackoffWithJitter(MINIMUM_WAIT_TIME, MAXIMUM_WAIT_TIME, -RETRY_INTERVAL);
60 public void whenMinimumWaitTimeIsLargerThanMaximumWaitTimeThenAnIllegalArgumentExceptionIsThrown() {
62 assertThrows(IllegalArgumentException.class, () -> {
63 new ExponentialBackoffWithJitter(MAXIMUM_WAIT_TIME, MINIMUM_WAIT_TIME, RETRY_INTERVAL);
68 public void whenRetryIntervalIsLargerThanMaximumWaitTimeThenAnIllegalArgumentExceptionIsThrown() {
70 assertThrows(IllegalArgumentException.class, () -> {
71 new ExponentialBackoffWithJitter(MINIMUM_WAIT_TIME, RETRY_INTERVAL, MAXIMUM_WAIT_TIME);
76 public void whenTheNumberOfFailedAttemptsIsNegativeThenZeroIsAssumedInstead() {
78 Random random = mock(Random.class, withSettings().withoutAnnotations());
79 when(random.nextLong()).thenReturn(RETRY_INTERVAL);
81 ExponentialBackoffWithJitter backoffStrategy = new ExponentialBackoffWithJitter(MINIMUM_WAIT_TIME,
82 MAXIMUM_WAIT_TIME, RETRY_INTERVAL, random);
85 long result = backoffStrategy.getSecondsUntilRetry(-10);
88 assertEquals(MINIMUM_WAIT_TIME + RETRY_INTERVAL, result);
92 public void whenThereIsNoFailedAttemptThenTheMaximalResultIsMinimumWaitTimePlusRetryInterval() {
94 Random random = mock(Random.class, withSettings().withoutAnnotations());
95 when(random.nextLong()).thenReturn(RETRY_INTERVAL);
97 ExponentialBackoffWithJitter backoffStrategy = new ExponentialBackoffWithJitter(MINIMUM_WAIT_TIME,
98 MAXIMUM_WAIT_TIME, RETRY_INTERVAL, random);
101 long result = backoffStrategy.getSecondsUntilRetry(0);
104 assertEquals(MINIMUM_WAIT_TIME + RETRY_INTERVAL, result);
108 public void whenThereIsOneFailedAttemptThenTheMaximalResultIsMinimumWaitTimePlusTwiceTheRetryInterval() {
110 Random random = mock(Random.class, withSettings().withoutAnnotations());
111 when(random.nextLong()).thenReturn(RETRY_INTERVAL * 2);
113 ExponentialBackoffWithJitter backoffStrategy = new ExponentialBackoffWithJitter(MINIMUM_WAIT_TIME,
114 MAXIMUM_WAIT_TIME, RETRY_INTERVAL, random);
117 long result = backoffStrategy.getSecondsUntilRetry(1);
120 assertEquals(MINIMUM_WAIT_TIME + RETRY_INTERVAL * 2, result);
124 public void whenThereAreTwoFailedAttemptsThenTheMaximalResultIsMinimumWaitTimePlusFourTimesTheRetryInterval() {
126 Random random = mock(Random.class, withSettings().withoutAnnotations());
127 when(random.nextLong()).thenReturn(RETRY_INTERVAL * 4);
129 ExponentialBackoffWithJitter backoffStrategy = new ExponentialBackoffWithJitter(MINIMUM_WAIT_TIME,
130 MAXIMUM_WAIT_TIME, RETRY_INTERVAL, random);
133 long result = backoffStrategy.getSecondsUntilRetry(2);
136 assertEquals(MINIMUM_WAIT_TIME + RETRY_INTERVAL * 4, result);
140 public void whenThereAreTwoFailedAttemptsThenTheMinimalResultIsTheMinimumWaitTime() {
142 Random random = mock(Random.class, withSettings().withoutAnnotations());
143 when(random.nextLong()).thenReturn(0L);
145 ExponentialBackoffWithJitter backoffStrategy = new ExponentialBackoffWithJitter(MINIMUM_WAIT_TIME,
146 MAXIMUM_WAIT_TIME, RETRY_INTERVAL, random);
149 long result = backoffStrategy.getSecondsUntilRetry(2);
152 assertEquals(MINIMUM_WAIT_TIME, result);
156 public void whenTheDrawnRandomValueIsNegativeThenItIsProjectedToAPositiveValue() {
158 Random random = mock(Random.class, withSettings().withoutAnnotations());
159 when(random.nextLong()).thenReturn(-RETRY_INTERVAL * 4 - 1);
161 ExponentialBackoffWithJitter backoffStrategy = new ExponentialBackoffWithJitter(MINIMUM_WAIT_TIME,
162 MAXIMUM_WAIT_TIME, RETRY_INTERVAL, random);
165 long result = backoffStrategy.getSecondsUntilRetry(2);
168 assertEquals(MINIMUM_WAIT_TIME, result);
172 public void whenTheResultWouldBeLargerThanTheMaximumThenItIsCappedToTheMaximum() {
174 Random random = mock(Random.class, withSettings().withoutAnnotations());
175 when(random.nextLong()).thenReturn(MAXIMUM_WAIT_TIME - ALTERNATIVE_MINIMUM_WAIT_TIME);
177 ExponentialBackoffWithJitter backoffStrategy = new ExponentialBackoffWithJitter(ALTERNATIVE_MINIMUM_WAIT_TIME,
178 MAXIMUM_WAIT_TIME, ALTERNATIVE_RETRY_INTERVAL, random);
181 long result = backoffStrategy.getSecondsUntilRetry(2);
184 assertEquals(MAXIMUM_WAIT_TIME, result);
188 public void whenTheResultWouldBeLargerThanTheAlternativeMaximumThenItIsCappedToTheAlternativeMaximum() {
190 Random random = mock(Random.class, withSettings().withoutAnnotations());
191 when(random.nextLong()).thenReturn(ALTERNATIVE_MAXIMUM_WAIT_TIME - ALTERNATIVE_MINIMUM_WAIT_TIME);
193 ExponentialBackoffWithJitter backoffStrategy = new ExponentialBackoffWithJitter(ALTERNATIVE_MINIMUM_WAIT_TIME,
194 ALTERNATIVE_MAXIMUM_WAIT_TIME, ALTERNATIVE_RETRY_INTERVAL, random);
197 long result = backoffStrategy.getSecondsUntilRetry(2);
200 assertEquals(ALTERNATIVE_MAXIMUM_WAIT_TIME, result);