View Javadoc
1   /*
2    * Copyright (c) 2012-2024, jcabi.com
3    * All rights reserved.
4    *
5    * Redistribution and use in source and binary forms, with or without
6    * modification, are permitted provided that the following conditions
7    * are met: 1) Redistributions of source code must retain the above
8    * copyright notice, this list of conditions and the following
9    * disclaimer. 2) Redistributions in binary form must reproduce the above
10   * copyright notice, this list of conditions and the following
11   * disclaimer in the documentation and/or other materials provided
12   * with the distribution. 3) Neither the name of the jcabi.com nor
13   * the names of its contributors may be used to endorse or promote
14   * products derived from this software without specific prior written
15   * permission.
16   *
17   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18   * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
19   * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
20   * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21   * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
22   * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23   * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24   * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26   * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28   * OF THE POSSIBILITY OF SUCH DAMAGE.
29   */
30  package com.jcabi.aspects.aj;
31  
32  import com.jcabi.aspects.RetryOnFailure;
33  import java.util.concurrent.Callable;
34  import java.util.concurrent.atomic.AtomicInteger;
35  import org.hamcrest.MatcherAssert;
36  import org.hamcrest.Matchers;
37  import org.junit.jupiter.api.Assertions;
38  import org.junit.jupiter.api.Test;
39  
40  /**
41   * Tests for {@link Repeater}.
42   *
43   * @since 0.1.10
44   */
45  final class RepeaterTest {
46  
47      @Test
48      void retriesAfterFailure() {
49          final AtomicInteger calls = new AtomicInteger(0);
50          MatcherAssert.assertThat(
51              new Callable<Boolean>() {
52                  @Override
53                  @RetryOnFailure(verbose = false)
54                  public Boolean call() {
55                      if (calls.get() < 3 - 1) {
56                          calls.incrementAndGet();
57                          throw new IllegalStateException();
58                      }
59                      return true;
60                  }
61              } .call(),
62              Matchers.equalTo(true)
63          );
64          MatcherAssert.assertThat(calls.get(), Matchers.equalTo(3 - 1));
65      }
66  
67      @Test
68      void stopsRetryingAfterNumberOfAttempts() {
69          final AtomicInteger calls = new AtomicInteger(0);
70          Assertions.assertThrows(
71              IllegalStateException.class,
72              () -> new Callable<Boolean>() {
73                  @Override
74                  @RetryOnFailure(verbose = false)
75                  public Boolean call() {
76                      if (calls.get() < 3) {
77                          calls.incrementAndGet();
78                          throw new IllegalStateException();
79                      }
80                      return true;
81                  }
82              } .call()
83          );
84      }
85  
86      @Test
87      void onlyRetryExceptionsWhichAreSpecified() {
88          final AtomicInteger calls = new AtomicInteger(0);
89          MatcherAssert.assertThat(
90              new Callable<Boolean>() {
91                  @Override
92                  @RetryOnFailure(
93                      types = ArrayIndexOutOfBoundsException.class,
94                      verbose = false
95                  )
96                  public Boolean call() {
97                      if (calls.get() < 3 - 1) {
98                          calls.incrementAndGet();
99                          throw new ArrayIndexOutOfBoundsException();
100                     }
101                     return true;
102                 }
103             } .call(),
104             Matchers.equalTo(true)
105         );
106         MatcherAssert.assertThat(calls.get(), Matchers.equalTo(3 - 1));
107     }
108 
109     @Test
110     void throwExceptionsWhichAreNotSpecifiedAsRetry() {
111         final AtomicInteger calls = new AtomicInteger(0);
112         try {
113             Assertions.assertThrows(
114                 ArrayIndexOutOfBoundsException.class,
115                 () -> new Callable<Boolean>() {
116                     @Override
117                     @RetryOnFailure(types = IllegalArgumentException.class, verbose = false)
118                     public Boolean call() {
119                         if (calls.get() < 3 - 1) {
120                             calls.incrementAndGet();
121                             throw new ArrayIndexOutOfBoundsException();
122                         }
123                         return true;
124                     }
125                 } .call()
126             );
127         } finally {
128             MatcherAssert.assertThat(calls.get(), Matchers.equalTo(1));
129         }
130     }
131 
132     @Test
133     void retryExceptionsWhichAreSubTypesOfTheExceptionsSpecified() {
134         final AtomicInteger calls = new AtomicInteger(0);
135         MatcherAssert.assertThat(
136             new Callable<Boolean>() {
137                 @Override
138                 @RetryOnFailure(verbose = false, types = IndexOutOfBoundsException.class)
139                 public Boolean call() {
140                     if (calls.get() < 3 - 1) {
141                         calls.incrementAndGet();
142                         throw new ArrayIndexOutOfBoundsException();
143                     }
144                     return true;
145                 }
146             } .call(),
147             Matchers.equalTo(true)
148         );
149         MatcherAssert.assertThat(calls.get(), Matchers.equalTo(3 - 1));
150     }
151 }