1 package net.sf.ehcache.store;
2
3 import net.sf.ehcache.Cache;
4 import net.sf.ehcache.CacheManager;
5 import net.sf.ehcache.Element;
6 import net.sf.ehcache.Status;
7 import net.sf.ehcache.config.CacheConfiguration;
8 import net.sf.ehcache.config.Configuration;
9 import net.sf.ehcache.config.MemoryUnit;
10 import net.sf.ehcache.util.RetryAssert;
11 import org.hamcrest.core.Is;
12 import org.junit.After;
13 import org.junit.Before;
14 import org.junit.Test;
15
16 import java.util.concurrent.Callable;
17
18 import static java.util.concurrent.TimeUnit.SECONDS;
19 import static org.hamcrest.CoreMatchers.is;
20 import static org.junit.Assert.assertThat;
21
22 /***
23 * @author Alex Snaps
24 */
25 public class DiskStoreBootstrapCacheLoaderFactoryTest {
26
27 private static final int ELEMENTS_ON_DISK = 500;
28 private static final int LOADER_DELAY = 500;
29 private CacheManager manager;
30 private Cache cacheElementCountBound;
31 private Cache cacheSizeBound;
32 private DiskStoreBootstrapCacheLoader cacheElementCountBoundBootstrapCacheLoader;
33 private DiskStoreBootstrapCacheLoader cacheSizeBoundBootstrapCacheLoader;
34
35 public void setUp(CacheUT cut) {
36 initCacheManager(cut);
37 switch (cut) {
38 case elementBased:
39 cacheElementCountBound.removeAll();
40 populateCache(cacheElementCountBound);
41 break;
42 case sizeBased:
43 cacheSizeBound.removeAll();
44 populateCache(cacheSizeBound);
45 break;
46 }
47 }
48
49 private void populateCache(final Cache cache) {
50 for (int i = 0; i < ELEMENTS_ON_DISK; i++) {
51 cache.put(new Element(i, "Some value for key " + i));
52 }
53 }
54
55 @Test
56 public void testLoadsFromDiskWithMaxElementsInMemorySet() throws InterruptedException {
57 setUp(CacheUT.elementBased);
58 int waitCycles = 0;
59 while (cacheElementCountBound.getDiskStoreSize() != ELEMENTS_ON_DISK && waitCycles < 15) {
60 System.err.println("Not all entries have been spooled to disk, waiting a bit ... ");
61 Thread.sleep(250);
62 waitCycles++;
63 }
64 waitForBootstrapLoader(cacheElementCountBoundBootstrapCacheLoader);
65 RetryAssert.assertBy(10, SECONDS, new Callable<Integer>() {
66 public Integer call() throws Exception {
67 return cacheElementCountBound.getDiskStoreSize();
68 }
69 }, Is.is(ELEMENTS_ON_DISK));
70 assertThat(cacheElementCountBound.getMemoryStoreSize(), is(100L));
71 manager.shutdown();
72 initCacheManager(CacheUT.elementBased);
73 RetryAssert.assertBy(10, SECONDS, new Callable<Integer>() {
74 public Integer call() throws Exception {
75 return cacheElementCountBound.getDiskStoreSize();
76 }
77 }, Is.is(ELEMENTS_ON_DISK));
78 assertThat(cacheElementCountBound.getMemoryStoreSize(), is(0L));
79 waitForBootstrapLoader(cacheElementCountBoundBootstrapCacheLoader);
80 RetryAssert.assertBy(10, SECONDS, new Callable<Integer>() {
81 public Integer call() throws Exception {
82 return cacheElementCountBound.getDiskStoreSize();
83 }
84 }, Is.is(ELEMENTS_ON_DISK));
85 assertThat(cacheElementCountBound.getMemoryStoreSize(), is(100L));
86 assertThat(cacheElementCountBoundBootstrapCacheLoader.getLoadedElements(), is(100));
87 }
88
89 @Test
90 public void testLoadsFromDiskWithMaxBytesOnHeapSet() throws InterruptedException {
91 setUp(CacheUT.sizeBased);
92 int waitCycles = 0;
93 while (cacheSizeBound.getDiskStoreSize() != ELEMENTS_ON_DISK && waitCycles < 15) {
94 System.err.println("Not all entries have been spooled to disk, waiting a bit ... " + cacheSizeBound.getDiskStoreSize() + " in");
95 Thread.sleep(250);
96 waitCycles++;
97 }
98 waitForBootstrapLoader(cacheSizeBoundBootstrapCacheLoader);
99 RetryAssert.assertBy(10, SECONDS, new Callable<Integer>() {
100 public Integer call() throws Exception {
101 return cacheSizeBound.getDiskStoreSize();
102 }
103 }, Is.is(ELEMENTS_ON_DISK));
104 assertThat(cacheSizeBound.getLiveCacheStatistics().getLocalHeapSizeInBytes() <= MemoryUnit.KILOBYTES.toBytes(220), is(true));
105 manager.shutdown();
106 initCacheManager(CacheUT.sizeBased);
107 RetryAssert.assertBy(10, SECONDS, new Callable<Integer>() {
108 public Integer call() throws Exception {
109 return cacheSizeBound.getDiskStoreSize();
110 }
111 }, Is.is(ELEMENTS_ON_DISK));
112 assertThat(cacheSizeBound.getMemoryStoreSize(), is(0L));
113 waitForBootstrapLoader(cacheSizeBoundBootstrapCacheLoader);
114 RetryAssert.assertBy(10, SECONDS, new Callable<Integer>() {
115 public Integer call() throws Exception {
116 return cacheSizeBound.getDiskStoreSize();
117 }
118 }, Is.is(ELEMENTS_ON_DISK));
119 assertThat(cacheSizeBound.getLiveCacheStatistics().getLocalHeapSizeInBytes() <= MemoryUnit.KILOBYTES.toBytes(220), is(true));
120 }
121
122 private int waitForBootstrapLoader(DiskStoreBootstrapCacheLoader bootstrapCacheLoader) throws InterruptedException {
123 while (!bootstrapCacheLoader.isDoneLoading()) {
124 System.err.println("Waiting for the loader to be done... Loaded " + bootstrapCacheLoader.getLoadedElements()
125 + " elements so far");
126 Thread.sleep(LOADER_DELAY);
127 }
128 return bootstrapCacheLoader.getLoadedElements();
129 }
130
131 private void initCacheManager(CacheUT cut) {
132 manager = new CacheManager(new Configuration());
133 switch (cut) {
134 case elementBased:
135 cacheElementCountBoundBootstrapCacheLoader = new DiskStoreBootstrapCacheLoader(LOADER_DELAY);
136 cacheElementCountBound = new Cache(new CacheConfiguration("maxElementsInMemory", 100)
137 .eternal(true)
138 .diskPersistent(true)
139 .overflowToDisk(true)
140 .diskStorePath("caches/DiskPersistent")
141 .maxEntriesLocalDisk(ELEMENTS_ON_DISK), null, cacheElementCountBoundBootstrapCacheLoader);
142 manager.addCache(cacheElementCountBound);
143 break;
144 case sizeBased:
145 cacheSizeBoundBootstrapCacheLoader = new DiskStoreBootstrapCacheLoader(LOADER_DELAY);
146 cacheSizeBound = new Cache(new CacheConfiguration("maxOnHeap", 0)
147 .eternal(true)
148 .diskPersistent(true)
149 .overflowToDisk(true)
150 .maxBytesLocalHeap(220, MemoryUnit.KILOBYTES)
151 .maxBytesLocalDisk(300, MemoryUnit.MEGABYTES)
152 .diskStorePath("caches/DiskPersistentSize")
153 .maxEntriesLocalDisk(ELEMENTS_ON_DISK), null, cacheSizeBoundBootstrapCacheLoader);
154 manager.addCache(cacheSizeBound);
155 cacheSizeBound.setSampledStatisticsEnabled(true);
156 break;
157 }
158 }
159
160 @After
161 public void shutdown() {
162 if (manager != null && manager.getStatus() == Status.STATUS_ALIVE) {
163 manager.shutdown();
164 }
165 }
166
167 private static enum CacheUT {
168 elementBased, sizeBased
169 }
170 }