View Javadoc
1   package com.atlassian.cache.ehcache;
2   
3   import com.atlassian.cache.CacheLoader;
4   import net.sf.ehcache.Cache;
5   import net.sf.ehcache.CacheManager;
6   import net.sf.ehcache.Element;
7   import net.sf.ehcache.config.CacheConfiguration;
8   import net.sf.ehcache.config.Configuration;
9   import net.sf.ehcache.config.MemoryUnit;
10  import org.junit.After;
11  import org.junit.Before;
12  import org.junit.Test;
13  
14  import javax.annotation.Nonnull;
15  
16  import java.util.concurrent.CountDownLatch;
17  import java.util.concurrent.ExecutionException;
18  import java.util.concurrent.ExecutorService;
19  import java.util.concurrent.Executors;
20  import java.util.concurrent.Future;
21  
22  import static org.junit.Assert.*;
23  
24  public class SynchronizedLoadingCacheDecoratorTest {
25  
26      private LoadingCache<Object, Object> testedLoadingCache;
27      private SynchronizedLoadingCacheDecorator testedSynchronizedLoadingCacheDecorator;
28      private CountDownLatch loadCountDownLatch;
29      private CountDownLatch testCountDownLatch;
30      private CacheManager cacheManager;
31  
32      private ExecutorService executorService = Executors.newCachedThreadPool();
33  
34      @Before
35      public void setup() {
36          loadCountDownLatch = new CountDownLatch(1);
37          testCountDownLatch = new CountDownLatch(1);
38  
39          cacheManager = new CacheManager(new Configuration().name(SynchronizedLoadingCacheDecorator.class.getName()));
40          cacheManager.addCache(new Cache(new CacheConfiguration().name("tested").maxBytesLocalHeap(10, MemoryUnit.MEGABYTES)));
41          testedSynchronizedLoadingCacheDecorator = new SynchronizedLoadingCacheDecorator(cacheManager.getCache("tested"));
42          testedLoadingCache = new LoadingCache<>(
43                  testedSynchronizedLoadingCacheDecorator,
44                  new CacheLoader<Object, Object>() {
45                      @Nonnull
46                      @Override
47                      public Object load(@Nonnull final Object key) {
48                          testCountDownLatch.countDown();
49                          try {
50                              loadCountDownLatch.await();
51                          } catch (InterruptedException e) {
52                              throw new RuntimeException(e);
53                          }
54                          return key;
55                      }
56                  }
57          );
58      }
59  
60      @After
61      public void destroy() {
62          cacheManager.shutdown();
63      }
64  
65      @Test
66      public void shouldReturnProperlyLoadedValue() throws ExecutionException, InterruptedException {
67          assertEquals(0, testedLoadingCache.getKeys().size());
68  
69          loadCountDownLatch.countDown();
70          Object key = new Object();
71          Future<Element> future = executorService.submit(() -> testedLoadingCache.get(key));
72  
73          Element element = future.get();
74          assertEquals(key, element.getObjectValue());
75          assertEquals(key, element.getObjectKey());
76          assertEquals(1, testedLoadingCache.getKeys().size());
77      }
78  
79      @Test
80      public void shouldNotStoreRemovedValueWhileLoading() throws ExecutionException, InterruptedException {
81          assertEquals(0, testedLoadingCache.getKeys().size());
82  
83          Object key = new Object();
84          Future<Element> future = executorService.submit(() -> testedLoadingCache.get(key));
85  
86          testCountDownLatch.await();
87          testedSynchronizedLoadingCacheDecorator.remove(key);
88          loadCountDownLatch.countDown();
89  
90          Element element = future.get();
91          assertEquals(key, element.getObjectValue());
92          assertEquals(key, element.getObjectKey());
93          assertEquals(0, testedLoadingCache.getKeys().size());
94      }
95  
96      @Test
97      public void shouldNotStoreAfterRemoveAllWhileLoading() throws ExecutionException, InterruptedException {
98          assertEquals(0, testedLoadingCache.getKeys().size());
99  
100         Object key = new Object();
101         Future<Element> future = executorService.submit(() -> testedLoadingCache.get(key));
102 
103         testCountDownLatch.await();
104         testedSynchronizedLoadingCacheDecorator.removeAll();
105         loadCountDownLatch.countDown();
106 
107         Element element = future.get();
108         assertEquals(key, element.getObjectValue());
109         assertEquals(key, element.getObjectKey());
110         assertEquals(0, testedLoadingCache.getKeys().size());
111     }
112 }