View Javadoc

1   package com.atlassian.vcache.internal.test;
2   
3   import java.util.Map;
4   import java.util.Optional;
5   import java.util.concurrent.CompletableFuture;
6   import javax.annotation.Nonnull;
7   
8   import com.atlassian.vcache.DirectExternalCache;
9   import com.atlassian.vcache.PutPolicy;
10  import com.atlassian.vcache.TransactionalExternalCache;
11  
12  import com.google.common.collect.Maps;
13  import org.junit.Rule;
14  import org.junit.Test;
15  import org.slf4j.Logger;
16  import org.slf4j.LoggerFactory;
17  
18  import static com.atlassian.vcache.internal.test.CompletableFutureSuccessful.successful;
19  import static com.atlassian.vcache.internal.test.CompletableFutureSuccessful.successfulWith;
20  import static org.hamcrest.MatcherAssert.assertThat;
21  import static org.hamcrest.Matchers.containsInAnyOrder;
22  import static org.hamcrest.Matchers.is;
23  
24  /**
25   * Base test class for the {@link com.atlassian.vcache.TransactionalExternalCache}.
26   */
27  public abstract class AbstractTransactionalExternalCacheIT
28  {
29      protected static final String CACHE_NAME = "fragileSting";
30      private static final Logger log = LoggerFactory.getLogger(AbstractStableReadExternalCacheIT.class);
31  
32      @Rule
33      public LoggingTestWatcher watcher = new LoggingTestWatcher(log);
34  
35      @Nonnull
36      protected abstract TransactionalExternalCache<String> cache();
37      @Nonnull
38      protected abstract DirectExternalCache<String> directCache();
39      protected abstract void directCacheRefresh();
40      protected abstract void cacheTransactionSync();
41  
42      @Test
43      public void put_get_sync_successful()
44      {
45          cache().put("claira", "dancing", PutPolicy.PUT_ALWAYS);
46  
47          final CompletableFuture<Optional<String>> get1 = cache().get("claira");
48  
49          assertThat(get1, successfulWith(is(Optional.of("dancing"))));
50  
51          // Now use the directCache to verify no data has been written
52          directCacheRefresh();
53          final CompletableFuture<Optional<String>> get2 = directCache().get("claira");
54  
55          assertThat(get2, successfulWith(is(Optional.empty())));
56  
57          // Now sync the changes
58          cacheTransactionSync();
59  
60          // And check the changes are now visible
61          directCacheRefresh();
62          final CompletableFuture<Optional<String>> get3 = directCache().get("claira");
63  
64          assertThat(get3, successfulWith(is(Optional.of("dancing"))));
65      }
66  
67      @Test
68      public void put_get_sync_unsuccessful() throws Exception
69      {
70          cache().put("claira", "dancing", PutPolicy.ADD_ONLY); // Must be ADD_ONLY
71  
72          final CompletableFuture<Optional<String>> get1 = cache().get("claira");
73  
74          assertThat(get1, successfulWith(is(Optional.of("dancing"))));
75  
76          // Now use the directCache to verify no data has been written
77          directCacheRefresh();
78          final CompletableFuture<Optional<String>> get2 = directCache().get("claira");
79  
80          assertThat(get2, successfulWith(is(Optional.empty())));
81  
82          // Now add values to the backing cache using the directCache
83          final CompletableFuture<Map<String, String>> get3 =
84                  directCache().getBulk(keys -> Maps.asMap(keys, k -> k + "-1"), "claira", "josephine");
85  
86          assertThat(get3, successful());
87          assertThat(get3.get().keySet(), containsInAnyOrder("claira", "josephine"));
88          assertThat(get3.get().values(), containsInAnyOrder("claira-1", "josephine-1"));
89  
90          // Now sync the changes
91          cacheTransactionSync();
92  
93          // And check the cache is empty
94          directCacheRefresh();
95          final CompletableFuture<Map<String, Optional<String>>> get4 = directCache().getBulk("claira", "josephine");
96  
97          assertThat(get4, successful());
98          assertThat(get4.get().keySet(), containsInAnyOrder("claira", "josephine"));
99          assertThat(get4.get().values(), containsInAnyOrder(Optional.empty(), Optional.empty()));
100     }
101 
102     @Test
103     public void getBulk_getBulkFunction_directPut_sync() throws Exception
104     {
105         final CompletableFuture<Boolean> put1 = directCache().put("claira", "dancing", PutPolicy.PUT_ALWAYS);
106 
107         assertThat(put1, successful());
108 
109         final CompletableFuture<Map<String, Optional<String>>> get1 = cache().getBulk("claira", "josephine");
110 
111         assertThat(get1, successful());
112         assertThat(get1.get().keySet(), containsInAnyOrder("claira", "josephine"));
113         assertThat(get1.get().values(), containsInAnyOrder(Optional.of("dancing"), Optional.empty()));
114 
115         final CompletableFuture<Map<String, String>> get2 =
116                 cache().getBulk(keys -> Maps.asMap(keys, k -> "football"), "claira", "josephine");
117 
118         assertThat(get2, successful());
119         assertThat(get2.get().keySet(), containsInAnyOrder("claira", "josephine"));
120         assertThat(get2.get().values(), containsInAnyOrder("dancing", "football"));
121 
122         // Now add an entry to the backend cache for "josephine" and verify one does not exist yet
123         directCacheRefresh();
124         final CompletableFuture<Boolean> put2 = directCache().put("josephine", "soccer", PutPolicy.ADD_ONLY);
125 
126         assertThat(put2, successfulWith(is(true)));
127 
128         cacheTransactionSync();
129 
130         // Now verify nothing in the cache, due to panic when added josephine
131         directCacheRefresh();
132         final CompletableFuture<Map<String, Optional<String>>> get3 = directCache().getBulk("claira", "josephine");
133 
134         assertThat(get3, successful());
135         assertThat(get3.get().keySet(), containsInAnyOrder("claira", "josephine"));
136         assertThat(get3.get().values(), containsInAnyOrder(Optional.empty(), Optional.empty()));
137     }
138 
139     @Test
140     public void put_get_remove_get()
141     {
142         cache().put("nirvana", "shotgun", PutPolicy.PUT_ALWAYS);
143 
144         final CompletableFuture<Optional<String>> get1 = cache().get("nirvana");
145 
146         assertThat(get1, successfulWith(is(Optional.of("shotgun"))));
147 
148         cache().remove("a", "b", "nirvana");
149 
150         final CompletableFuture<Optional<String>> get2 = cache().get("nirvana");
151 
152         assertThat(get2, successfulWith(is(Optional.empty())));
153     }
154 
155     @Test
156     public void getSupplier_removeAll_get()
157     {
158         final CompletableFuture<String> get1 = cache().get("vienna", () -> "sandwiches");
159 
160         assertThat(get1, successfulWith(is("sandwiches")));
161 
162         cache().removeAll();
163 
164         final CompletableFuture<Optional<String>> get2 = cache().get("vienna");
165 
166         assertThat(get2, successfulWith(is(Optional.empty())));
167     }
168 }