• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.car.test.mocks;
18 
19 import static com.google.common.truth.Truth.assertThat;
20 import static com.google.common.truth.Truth.assertWithMessage;
21 
22 import static org.junit.Assert.assertThrows;
23 import static org.mockito.ArgumentMatchers.any;
24 import static org.mockito.ArgumentMatchers.anyLong;
25 import static org.mockito.Mockito.verify;
26 import static org.mockito.Mockito.when;
27 
28 import android.util.Log;
29 
30 import org.junit.Test;
31 import org.junit.runner.RunWith;
32 import org.mockito.Mock;
33 import org.mockito.junit.MockitoJUnitRunner;
34 
35 import java.util.concurrent.CountDownLatch;
36 import java.util.concurrent.ExecutionException;
37 import java.util.concurrent.Future;
38 import java.util.concurrent.Semaphore;
39 import java.util.concurrent.TimeUnit;
40 import java.util.concurrent.TimeoutException;
41 
42 @RunWith(MockitoJUnitRunner.class)
43 public final class JavaMockitoHelperTest {
44 
45     private static final String TAG = JavaMockitoHelperTest.class.getSimpleName();
46 
47     // Make sure TIMEOUT_MS is at least 1s, but not same as ASYNC_TIMEOUT_MS
48     private static final long TIMEOUT_MS = Math.max(1_000L, JavaMockitoHelper.ASYNC_TIMEOUT_MS) + 1;
49 
50     private static final String DEFAULT_TIMEOUT_MSG = JavaMockitoHelper.ASYNC_TIMEOUT_MS + "ms";
51     private static final String CUSTOM_TIMEOUT_MSG = TIMEOUT_MS + "ms";
52 
53     @Mock
54     private Future<String> mFuture;
55 
56     @Test
testAwait_Semaphore()57     public void testAwait_Semaphore() throws Exception {
58         Semaphore semaphore = new Semaphore(1);
59 
60         JavaMockitoHelper.await(semaphore, TIMEOUT_MS);
61 
62         assertThat(semaphore.availablePermits()).isEqualTo(0);
63     }
64 
65     @Test
testAwait_CountDownLatch()66     public void testAwait_CountDownLatch() throws Exception {
67         CountDownLatch latch = new CountDownLatch(1);
68         new Thread(() -> latch.countDown(), "testAwait_CountDownLatch").start();
69 
70         JavaMockitoHelper.await(latch, TIMEOUT_MS);
71 
72         assertThat(latch.getCount()).isEqualTo(0);
73     }
74 
75     @Test
testSilentAwait_notCalled()76     public void testSilentAwait_notCalled() {
77         CountDownLatch latch = new CountDownLatch(1);
78 
79         assertThat(JavaMockitoHelper.silentAwait(latch, 5L)).isFalse();
80         assertThat(latch.getCount()).isEqualTo(1);
81     }
82 
83     @Test
testSilentAwait_called()84     public void testSilentAwait_called() {
85         CountDownLatch latch = new CountDownLatch(1);
86         new Thread(() -> latch.countDown(), "testSilentAwait_called").start();
87 
88         assertThat(JavaMockitoHelper.silentAwait(latch, TIMEOUT_MS)).isTrue();
89         assertThat(latch.getCount()).isEqualTo(0);
90     }
91 
92     @Test
testGetResult_nullFuture()93     public void testGetResult_nullFuture() throws Exception {
94         assertThrows(NullPointerException.class, ()->JavaMockitoHelper.getResult(null, "D'OH!"));
95     }
96 
97     @Test
testGetResult_nullMessageFormat()98     public void testGetResult_nullMessageFormat() throws Exception {
99         assertThrows(NullPointerException.class, ()->JavaMockitoHelper.getResult(mFuture, null));
100     }
101 
102     @Test
testGetResult_ok()103     public void testGetResult_ok() throws Exception {
104         when(mFuture.get(anyLong(), any())).thenReturn("done");
105 
106         assertThat(JavaMockitoHelper.getResult(mFuture, "I am number %d!", 4)).isEqualTo("done");
107     }
108 
109     @Test
testGetResult_timeoutException()110     public void testGetResult_timeoutException() throws Exception {
111         TimeoutException cause = new TimeoutException("D'OH!");
112         when(mFuture.get(anyLong(), any())).thenThrow(cause);
113 
114         IllegalStateException exception = assertThrows(IllegalStateException.class,
115                 () -> JavaMockitoHelper.getResult(mFuture, "I am number %d!", 4));
116 
117         assertThat(exception).hasCauseThat().isSameInstanceAs(cause);
118         assertThat(exception).hasMessageThat().contains("I am number 4!");
119         assertThat(exception).hasMessageThat().contains(DEFAULT_TIMEOUT_MSG);
120     }
121 
122     @Test
testGetResult_executionException()123     public void testGetResult_executionException() throws Exception {
124         ExecutionException cause = new ExecutionException(new Exception("Double D'OH!"));
125         when(mFuture.get(anyLong(), any())).thenThrow(cause);
126 
127         IllegalStateException exception = assertThrows(IllegalStateException.class,
128                 () -> JavaMockitoHelper.getResult(mFuture, "I am number %d!", 4));
129 
130         assertThat(exception).hasCauseThat().isSameInstanceAs(cause);
131         assertThat(exception).hasMessageThat().contains("I am number 4!");
132     }
133 
134     @Test
testGetResult_interruptedException()135     public void testGetResult_interruptedException() throws Exception {
136         InterruptedException cause = new InterruptedException("D'OH!");
137         when(mFuture.get(anyLong(), any())).thenThrow(cause);
138         Thread thread = getCurrentThreadIninterrupted();
139 
140         IllegalStateException exception = assertThrows(IllegalStateException.class,
141                 () -> JavaMockitoHelper.getResult(mFuture, "I am number %d!", 4));
142 
143         assertThat(exception).hasCauseThat().isSameInstanceAs(cause);
144         assertThat(exception).hasMessageThat().contains("I am number 4!");
145         assertWithMessage("thread %s interrupted ", thread).that(thread.isInterrupted()).isTrue();
146     }
147 
148     @Test
testGetResult_withCustomTimeout_nullFuture()149     public void testGetResult_withCustomTimeout_nullFuture() throws Exception {
150         assertThrows(NullPointerException.class,
151                 () -> JavaMockitoHelper.getResult(null, TIMEOUT_MS, "D'OH!"));
152     }
153 
154     @Test
testGetResult_withCustomTimeout_nullMessageFormat()155     public void testGetResult_withCustomTimeout_nullMessageFormat() throws Exception {
156         assertThrows(NullPointerException.class,
157                 () -> JavaMockitoHelper.getResult(mFuture, TIMEOUT_MS, null));
158     }
159 
160     @Test
testGetResult_withCustomTimeout_ok()161     public void testGetResult_withCustomTimeout_ok() throws Exception {
162         when(mFuture.get(anyLong(), any(TimeUnit.class))).thenReturn("done");
163 
164         assertThat(JavaMockitoHelper.getResult(mFuture, TIMEOUT_MS, "I am number %d!", 4))
165                 .isEqualTo("done");
166         verify(mFuture).get(TIMEOUT_MS, TimeUnit.MILLISECONDS);
167     }
168 
169 
170     @Test
testGetResult_withCustomTimeout_timeoutException()171     public void testGetResult_withCustomTimeout_timeoutException() throws Exception {
172         TimeoutException cause = new TimeoutException("D'OH!");
173         when(mFuture.get(anyLong(), any())).thenThrow(cause);
174 
175         IllegalStateException exception = assertThrows(IllegalStateException.class,
176                 () -> JavaMockitoHelper.getResult(mFuture, TIMEOUT_MS, "I am number %d!", 4));
177 
178         assertThat(exception).hasCauseThat().isSameInstanceAs(cause);
179         assertThat(exception).hasMessageThat().contains("I am number 4!");
180         assertThat(exception).hasMessageThat().contains(CUSTOM_TIMEOUT_MSG);
181     }
182 
183     @Test
testGetResult_withCustomTimeout_executionException()184     public void testGetResult_withCustomTimeout_executionException() throws Exception {
185         ExecutionException cause = new ExecutionException(new Exception("Double D'OH!"));
186         when(mFuture.get(anyLong(), any())).thenThrow(cause);
187 
188         IllegalStateException exception = assertThrows(IllegalStateException.class,
189                 () -> JavaMockitoHelper.getResult(mFuture, TIMEOUT_MS, "I am number %d!", 4));
190 
191         assertThat(exception).hasCauseThat().isSameInstanceAs(cause);
192         assertThat(exception).hasMessageThat().contains("I am number 4!");
193     }
194 
195     @Test
testGetResult_withCustomTimeout_interruptedException()196     public void testGetResult_withCustomTimeout_interruptedException() throws Exception {
197         InterruptedException cause = new InterruptedException("D'OH!");
198         when(mFuture.get(anyLong(), any())).thenThrow(cause);
199         Thread thread = getCurrentThreadIninterrupted();
200 
201         IllegalStateException exception = assertThrows(IllegalStateException.class,
202                 () -> JavaMockitoHelper.getResult(mFuture, TIMEOUT_MS, "I am number %d!", 4));
203 
204         assertThat(exception).hasCauseThat().isSameInstanceAs(cause);
205         assertThat(exception).hasMessageThat().contains("I am number 4!");
206         assertWithMessage("thread %s interrupted ", thread).that(thread.isInterrupted()).isTrue();
207     }
208 
getCurrentThreadIninterrupted()209     private Thread getCurrentThreadIninterrupted() {
210         Thread thread = Thread.currentThread();
211         if (Thread.interrupted()) {
212             Log.w(TAG, "Thread " + thread + " was not interrupted");
213             // call to interrupted() interrupts it, so check again...
214             if (!thread.isInterrupted()) {
215                 throw new IllegalStateException("Could not reset interrupted state of  " + thread);
216             }
217         }
218         return thread;
219     }
220 }
221