• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.adservices.exceptions;
18 
19 import static android.adservices.exceptions.AdServicesNetworkException.ERROR_TOO_MANY_REQUESTS;
20 import static android.adservices.exceptions.RetryableAdServicesNetworkException.INVALID_ERROR_CODE_MESSAGE;
21 import static android.adservices.exceptions.RetryableAdServicesNetworkException.INVALID_RETRY_AFTER_MESSAGE;
22 
23 import static com.google.common.truth.Truth.assertThat;
24 
25 import static org.junit.Assert.assertThrows;
26 
27 import static java.util.Locale.ENGLISH;
28 
29 import com.android.adservices.common.AdServicesUnitTestCase;
30 
31 import org.junit.Test;
32 
33 import java.time.Duration;
34 import java.time.temporal.ChronoUnit;
35 
36 // TODO(b/278016822): Move to CTS tests once public APIs are unhidden
37 public class RetryableAdServicesNetworkExceptionTest extends AdServicesUnitTestCase {
38     private static final int VALID_ERROR_CODE = ERROR_TOO_MANY_REQUESTS;
39     private static final int INVALID_ERROR_CODE = 1000;
40     private static final Duration VALID_RETRY_AFTER = Duration.of(1000, ChronoUnit.MILLIS);
41     private static final Duration UNSET_RETRY_AFTER = Duration.ZERO;
42     private static final Duration NEGATIVE_RETRY_AFTER = Duration.of(-1, ChronoUnit.MILLIS);
43     private static final long MIN_RETRY_AFTER_DURATION_MS = 30 * 1000;
44     private static final long MAX_RETRY_AFTER_DURATION_MS = 90 * 1000;
45 
46     @Test
testExceptionWithErrorCodeAndRetryAfter_valid()47     public void testExceptionWithErrorCodeAndRetryAfter_valid() {
48         RetryableAdServicesNetworkException exception =
49                 new RetryableAdServicesNetworkException(VALID_ERROR_CODE, VALID_RETRY_AFTER);
50 
51         expect.that(exception.getErrorCode()).isEqualTo(VALID_ERROR_CODE);
52         expect.that(exception.getRetryAfter()).isEqualTo(VALID_RETRY_AFTER);
53         expect.that(exception).hasMessageThat().isNull();
54         expect.that(exception.toString())
55                 .isEqualTo(
56                         getHumanReadableRetryableNetworkException(
57                                 VALID_ERROR_CODE, VALID_RETRY_AFTER));
58     }
59 
60     @Test
testExceptionWithErrorCodeAndRetryAfter_errorCodeInvalid()61     public void testExceptionWithErrorCodeAndRetryAfter_errorCodeInvalid() {
62         Exception exception =
63                 assertThrows(
64                         IllegalArgumentException.class,
65                         () ->
66                                 new RetryableAdServicesNetworkException(
67                                         INVALID_ERROR_CODE, VALID_RETRY_AFTER));
68         assertThat(exception).hasMessageThat().isEqualTo(INVALID_ERROR_CODE_MESSAGE);
69     }
70 
71     @Test
testExceptionWithErrorCodeAndRetryAfter_retryAfterUnset()72     public void testExceptionWithErrorCodeAndRetryAfter_retryAfterUnset() {
73         Exception exception =
74                 assertThrows(
75                         IllegalArgumentException.class,
76                         () ->
77                                 new RetryableAdServicesNetworkException(
78                                         VALID_ERROR_CODE, UNSET_RETRY_AFTER));
79         assertThat(exception).hasMessageThat().isEqualTo(INVALID_RETRY_AFTER_MESSAGE);
80     }
81 
82     @Test
testExceptionWithErrorCodeAndRetryAfter_retryAfterNegative()83     public void testExceptionWithErrorCodeAndRetryAfter_retryAfterNegative() {
84         Exception exception =
85                 assertThrows(
86                         IllegalArgumentException.class,
87                         () ->
88                                 new RetryableAdServicesNetworkException(
89                                         VALID_ERROR_CODE, NEGATIVE_RETRY_AFTER));
90         assertThat(exception).hasMessageThat().isEqualTo(INVALID_RETRY_AFTER_MESSAGE);
91     }
92 
93     @Test
testSetRetryAfterToValidDurationStaysSame()94     public void testSetRetryAfterToValidDurationStaysSame() {
95         long validMs = 60 * 1000;
96         RetryableAdServicesNetworkException exception =
97                 new RetryableAdServicesNetworkException(
98                         VALID_ERROR_CODE, Duration.ofMillis(validMs));
99 
100         exception.setRetryAfterToValidDuration(
101                 MIN_RETRY_AFTER_DURATION_MS, MAX_RETRY_AFTER_DURATION_MS);
102         assertThat(exception.getRetryAfter().toMillis()).isEqualTo(validMs);
103     }
104 
105     @Test
testSetRetryAfterToValidDurationGetsCappedToDefault()106     public void testSetRetryAfterToValidDurationGetsCappedToDefault() {
107         long tooSmallMs = 20 * 1000;
108         RetryableAdServicesNetworkException exception =
109                 new RetryableAdServicesNetworkException(
110                         VALID_ERROR_CODE, Duration.ofMillis(tooSmallMs));
111 
112         exception.setRetryAfterToValidDuration(
113                 MIN_RETRY_AFTER_DURATION_MS, MAX_RETRY_AFTER_DURATION_MS);
114         assertThat(exception.getRetryAfter().toMillis()).isEqualTo(MIN_RETRY_AFTER_DURATION_MS);
115     }
116 
117     @Test
testSetRetryAfterToValidDurationGetsCappedToMax()118     public void testSetRetryAfterToValidDurationGetsCappedToMax() {
119         long tooBigSecondsMs = 100 * 1000;
120         RetryableAdServicesNetworkException exception =
121                 new RetryableAdServicesNetworkException(
122                         VALID_ERROR_CODE, Duration.ofMillis(tooBigSecondsMs));
123 
124         exception.setRetryAfterToValidDuration(
125                 MIN_RETRY_AFTER_DURATION_MS, MAX_RETRY_AFTER_DURATION_MS);
126         assertThat(exception.getRetryAfter().toMillis()).isEqualTo(MAX_RETRY_AFTER_DURATION_MS);
127     }
128 
getHumanReadableRetryableNetworkException(int errorCode, Duration retryAfter)129     private String getHumanReadableRetryableNetworkException(int errorCode, Duration retryAfter) {
130         return String.format(
131                 ENGLISH,
132                 "%s: {Error code: %s, Retry after: %sms}",
133                 RetryableAdServicesNetworkException.class.getCanonicalName(),
134                 errorCode,
135                 retryAfter.toMillis());
136     }
137 }
138