View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  
23  package org.hipparchus;
24  
25  import org.junit.runners.BlockJUnit4ClassRunner;
26  import org.junit.runners.model.FrameworkMethod;
27  import org.junit.runners.model.InitializationError;
28  import org.junit.runners.model.Statement;
29  
30  
31  /**
32   * A test runner that retries tests when assertions fail.
33   */
34  public class RetryRunner extends BlockJUnit4ClassRunner {
35      /**
36       * Simple constructor.
37       *
38       * @param testClass Class to test.
39       * @throws InitializationError if default runner cannot be built.
40       */
41      public RetryRunner(final Class<?> testClass)
42          throws InitializationError {
43          super(testClass);
44      }
45  
46      @Override
47      public Statement methodInvoker(final FrameworkMethod method,
48                                     Object test) {
49          final Statement singleTryStatement = super.methodInvoker(method, test);
50          return new Statement() {
51              /**
52               * Evaluate the statement.
53               * We attempt several runs for the test, at most MAX_ATTEMPTS.
54               * if one attempt succeeds, we succeed, if all attempts fail, we
55               * fail with the reason corresponding to the last attempt
56               */
57              @Override
58              public void evaluate() throws Throwable {
59                  Throwable failureReason = null;
60  
61                  final Retry retry = method.getAnnotation(Retry.class);
62                  if (retry == null) {
63                      // Do a single test run attempt.
64                      singleTryStatement.evaluate();
65                  } else {
66                      final int numRetries = retry.value();
67  
68                      for (int i = 0; i < numRetries; ++i) {
69                          try {
70                              // Do a single test run attempt.
71                              singleTryStatement.evaluate();
72                              // Attempt succeeded, stop evaluation here.
73                              return;
74                          } catch (Throwable t) {
75                              // Attempt failed, store the reason.
76                              failureReason = t;
77                          }
78                      }
79  
80                      // All attempts failed.
81                      throw failureReason;
82                  }
83              }
84          };
85      }
86  }