View Javadoc

1   package com.atlassian.vcache.internal.core.service;
2   
3   import com.atlassian.utt.concurrency.Barrier;
4   import com.atlassian.vcache.VCacheException;
5   import com.google.common.base.Throwables;
6   import org.junit.Test;
7   
8   import java.time.Duration;
9   import java.util.concurrent.CompletableFuture;
10  
11  import static com.atlassian.vcache.internal.test.CompletionStageSuccessful.successfulWith;
12  import static com.atlassian.vcache.internal.test.TestUtils.runAndWaitForStart;
13  import static org.hamcrest.Matchers.instanceOf;
14  import static org.hamcrest.Matchers.is;
15  import static org.junit.Assert.assertThat;
16  import static org.junit.Assert.fail;
17  
18  public class VCacheLockTest {
19  
20      @Test
21      public void timeout() {
22          // T1: get the lock and await signal
23          // T2: attempt to get the lock
24          // Confirm T2 times out
25  
26          final Barrier blockedInSupplier = new Barrier();
27          final Barrier resumeInSupplier = new Barrier();
28          final VCacheLock lock = new VCacheLock("noname", Duration.ofMillis(100));
29  
30          final CompletableFuture<String> t1Result =
31                  runAndWaitForStart(() -> lock.withLock(() -> {
32                      blockedInSupplier.signal();
33                      resumeInSupplier.await();
34                      return "T1";
35                  }));
36  
37          blockedInSupplier.await();
38          final CompletableFuture<String> t2Result =
39                  runAndWaitForStart(() -> lock.withLock(() -> "T2"));
40  
41          // Wait for the result from T2 to ensure it has run to completion.
42          try {
43              t2Result.join();
44              fail("Expected to get an error");
45          } catch (Exception e) {
46              final Throwable reasonEx = Throwables.getRootCause(e);
47              assertThat(reasonEx, instanceOf(VCacheException.class));
48              assertThat(reasonEx.getMessage(), is("Timed out waiting for lock on cache: noname"));
49          }
50  
51          resumeInSupplier.signal(); //Wait until T2 completed before resuming.
52  
53          assertThat(t1Result, successfulWith(is("T1")));
54      }
55  }