View Javadoc

1   package com.atlassian.vcache.internal.test;
2   
3   import com.atlassian.utt.concurrency.Barrier;
4   import com.atlassian.vcache.JvmCache;
5   import com.atlassian.vcache.JvmCacheSettings;
6   import com.atlassian.vcache.JvmCacheSettingsBuilder;
7   import com.atlassian.vcache.VCache;
8   import org.junit.Test;
9   
10  import java.time.Duration;
11  import java.util.Arrays;
12  import java.util.concurrent.CompletableFuture;
13  
14  import static com.atlassian.vcache.internal.test.CompletionStageSuccessful.successfulWith;
15  import static com.atlassian.vcache.internal.test.TestUtils.runAndWaitForStart;
16  import static org.hamcrest.Matchers.containsInAnyOrder;
17  import static org.hamcrest.Matchers.is;
18  import static org.junit.Assert.assertThat;
19  
20  /**
21   * Base test class for the {@link JvmCache}.
22   */
23  public abstract class AbstractJvmCacheTest extends AbstractLocalCacheOperationsTest {
24      protected abstract <K, V> JvmCache<K, V> createCache(String name, JvmCacheSettings settings, Duration lockTimeout);
25  
26      @Override
27      protected final <K, V> JvmCache<K, V> createCache(String name, Duration lockTimeout) {
28          return createCache(name, new JvmCacheSettingsBuilder().build(), lockTimeout);
29      }
30  
31      @Override
32      protected final <K, V> JvmCache<K, V> createCache(String name) {
33          final JvmCacheSettings settings = new JvmCacheSettingsBuilder().maxEntries(3).defaultTtl(Duration.ofSeconds(10)).build();
34          return createCache(name, settings, Duration.ofSeconds(10));
35      }
36  
37      @Test
38      public void testGetName() throws Exception {
39          final VCache namedCache = createCache("jvmcache");
40          assertThat(namedCache.getName(), is("jvmcache"));
41      }
42  
43      @SuppressWarnings("unchecked")
44      @Test
45      public void testKeys() {
46          final JvmCache<String, String> mycache = createCache("ignored");
47  
48          assertThat(mycache.getKeys(), containsInAnyOrder());
49  
50          mycache.put("k1", "v1");
51  
52          assertThat(mycache.getKeys(), containsInAnyOrder("k1"));
53  
54          mycache.put("k2", "v2");
55  
56          assertThat(mycache.getKeys(), containsInAnyOrder("k1", "k2"));
57      }
58  
59      @Test
60      public void testSize() {
61          final JvmCache<String, String> mycache = createCache("ignored");
62  
63          assertThat(mycache.getKeys().size(), is(0));
64  
65          mycache.put("k1", "v1");
66  
67          assertThat(mycache.getKeys().size(), is(1));
68  
69          mycache.put("k2", "v2");
70  
71          assertThat(mycache.getKeys().size(), is(2));
72  
73          mycache.put("k3", "v3");
74  
75          assertThat(mycache.getKeys().size(), is(3));
76  
77          mycache.put("k4", "v4");
78  
79          assertThat(mycache.getKeys().size(), is(3));
80  
81          Arrays.asList("k1", "k2", "k3", "k4").forEach(mycache::remove);
82  
83          assertThat(mycache.getKeys().size(), is(0));
84      }
85  
86      @Test
87      public void get_remove_concurrently() {
88          // T1: get with supplier and await signal
89          // T2: remove()
90          // T1: signalled, supplier returns "T1"
91          // Confirm T1 return "T1"
92  
93          final Barrier blockedInSupplier = new Barrier();
94          final Barrier resumeInSupplier = new Barrier();
95          final JvmCache<String, String> cache = createCache("getremove");
96  
97  
98          final CompletableFuture<String> t1Result =
99                  runAndWaitForStart(() -> cache.get("alive", () -> {
100                     blockedInSupplier.signal();
101                     resumeInSupplier.await();
102                     return "T1";
103                 }));
104 
105         blockedInSupplier.await();
106         final CompletableFuture<String> t2Result =
107                 runAndWaitForStart(() -> {
108                     cache.remove("alive");
109                     return "" + cache.get("alive").isPresent();
110                 });
111 
112         // Wait for the result from T2 to ensure it has run to completion.
113         assertThat(t2Result, successfulWith(is("false")));
114 
115         resumeInSupplier.signal(); // Wait until T2 cache.get calls join
116 
117         assertThat(t1Result, successfulWith(is("T1")));
118     }
119 }