|
10 | 10 | import io.temporal.common.interceptors.ActivityClientCallsInterceptor; |
11 | 11 | import io.temporal.common.interceptors.ActivityClientCallsInterceptor.*; |
12 | 12 | import java.util.concurrent.CompletableFuture; |
| 13 | +import java.util.concurrent.TimeUnit; |
13 | 14 | import org.junit.Before; |
14 | 15 | import org.junit.Test; |
15 | 16 |
|
@@ -151,6 +152,57 @@ public void testFromUntypedGetResultAsyncNoArg() throws Exception { |
151 | 152 | assertEquals("async-typed", future.get()); |
152 | 153 | } |
153 | 154 |
|
| 155 | + @Test |
| 156 | + @SuppressWarnings("unchecked") |
| 157 | + public void testGetResultAsyncCachesNoTimeoutFuture() throws Exception { |
| 158 | + GetActivityResultOutput<String> output = mock(GetActivityResultOutput.class); |
| 159 | + when(output.getResult()).thenReturn("cached-result"); |
| 160 | + when(interceptor.getActivityResultAsync(any(GetActivityResultInput.class))) |
| 161 | + .thenReturn(CompletableFuture.completedFuture(output)); |
| 162 | + |
| 163 | + UntypedActivityHandle handle = new ActivityHandleImpl("id", "run", interceptor); |
| 164 | + CompletableFuture<String> first = handle.getResultAsync(String.class); |
| 165 | + CompletableFuture<String> second = handle.getResultAsync(String.class); |
| 166 | + |
| 167 | + assertSame(first, second); |
| 168 | + verify(interceptor, times(1)).getActivityResultAsync(any(GetActivityResultInput.class)); |
| 169 | + } |
| 170 | + |
| 171 | + @Test |
| 172 | + @SuppressWarnings("unchecked") |
| 173 | + public void testGetResultAsyncTimeoutReusesCompletedCache() throws Exception { |
| 174 | + GetActivityResultOutput<String> output = mock(GetActivityResultOutput.class); |
| 175 | + when(output.getResult()).thenReturn("done"); |
| 176 | + when(interceptor.getActivityResultAsync(any(GetActivityResultInput.class))) |
| 177 | + .thenReturn(CompletableFuture.completedFuture(output)); |
| 178 | + |
| 179 | + UntypedActivityHandle handle = new ActivityHandleImpl("id", "run", interceptor); |
| 180 | + // Warm the cache with a no-timeout call |
| 181 | + handle.getResultAsync(String.class).get(); |
| 182 | + // Timeout call should reuse the completed cache, not start a new poll |
| 183 | + CompletableFuture<String> timed = handle.getResultAsync(5, TimeUnit.SECONDS, String.class); |
| 184 | + assertEquals("done", timed.get()); |
| 185 | + |
| 186 | + verify(interceptor, times(1)).getActivityResultAsync(any(GetActivityResultInput.class)); |
| 187 | + } |
| 188 | + |
| 189 | + @Test |
| 190 | + @SuppressWarnings("unchecked") |
| 191 | + public void testGetResultAsyncTimeoutSuccessPopulatesCache() throws Exception { |
| 192 | + GetActivityResultOutput<String> output = mock(GetActivityResultOutput.class); |
| 193 | + when(output.getResult()).thenReturn("timed-result"); |
| 194 | + when(interceptor.getActivityResultAsync(any(GetActivityResultInput.class))) |
| 195 | + .thenReturn(CompletableFuture.completedFuture(output)); |
| 196 | + |
| 197 | + UntypedActivityHandle handle = new ActivityHandleImpl("id", "run", interceptor); |
| 198 | + // First call: timed — succeeds, should populate cache |
| 199 | + handle.getResultAsync(5, TimeUnit.SECONDS, String.class).get(); |
| 200 | + // Second call: no-timeout — should reuse the cache, not issue a second poll |
| 201 | + handle.getResultAsync(String.class).get(); |
| 202 | + |
| 203 | + verify(interceptor, times(1)).getActivityResultAsync(any(GetActivityResultInput.class)); |
| 204 | + } |
| 205 | + |
154 | 206 | @Test |
155 | 207 | @SuppressWarnings("unchecked") |
156 | 208 | public void testGetResultAsyncWrapsActivityFailedExceptionInRuntimeException() throws Exception { |
|
0 commit comments