1 package net.sf.ehcache.store.disk;
2
3 import junit.framework.Assert;
4
5 import net.sf.ehcache.Cache;
6 import net.sf.ehcache.CacheException;
7 import net.sf.ehcache.CacheManager;
8 import net.sf.ehcache.Ehcache;
9 import net.sf.ehcache.Element;
10 import net.sf.ehcache.config.CacheConfiguration;
11 import net.sf.ehcache.config.Configuration;
12 import net.sf.ehcache.event.CacheEventListener;
13 import net.sf.ehcache.pool.impl.UnboundedPool;
14 import net.sf.ehcache.store.DiskBackedMemoryStore;
15 import net.sf.ehcache.store.MemoryOnlyStore;
16 import net.sf.ehcache.store.Store;
17 import net.sf.ehcache.util.RetryAssert;
18 import org.hamcrest.core.Is;
19 import org.junit.Before;
20 import org.junit.Test;
21
22 import java.util.concurrent.Callable;
23 import java.util.concurrent.atomic.AtomicLong;
24
25 import static java.util.concurrent.TimeUnit.SECONDS;
26 import static org.junit.Assert.assertEquals;
27 import static org.junit.Assert.assertNotSame;
28 import static org.junit.Assert.assertNull;
29 import static org.junit.Assert.assertTrue;
30 import static org.junit.Assert.fail;
31
32 /***
33 * @author Alex Snaps
34 * @author Ludovic Orban
35 */
36 public class DiskStoreTest {
37
38 private static final String KEY = "KEY";
39
40 private Store store;
41 private Store xaStore;
42
43 private Cache cache;
44 private Cache xaCache;
45
46 @Before
47 public void init() {
48 cache = new Cache(new CacheConfiguration("SomeCache", 1000).overflowToDisk(true).diskPersistent(true));
49 store = DiskBackedMemoryStore.create(cache, System.getProperty("java.io.tmpdir"), new UnboundedPool(), new UnboundedPool());
50 xaCache = new Cache(new CacheConfiguration("SomeXaCache", 1000).transactionalMode("xa_strict"));
51 xaStore = MemoryOnlyStore.create(xaCache, new UnboundedPool());
52 }
53
54 @Test
55 public void testPersistenceWithPinnedElements() {
56 final Element[] lastEvicted = new Element[1];
57
58 cache.getCacheEventNotificationService().registerListener(new CacheEventListener() {
59 @Override
60 public Object clone() throws CloneNotSupportedException {
61 return super.clone();
62 }
63 public void notifyElementRemoved(Ehcache cache, Element element) throws CacheException {
64 }
65 public void notifyElementPut(Ehcache cache, Element element) throws CacheException {
66 }
67 public void notifyElementUpdated(Ehcache cache, Element element) throws CacheException {
68 }
69 public void notifyElementExpired(Ehcache cache, Element element) {
70 }
71 public void notifyElementEvicted(Ehcache cache, Element element) {
72 lastEvicted[0] = element;
73 }
74 public void notifyRemoveAll(Ehcache cache) {
75 }
76 public void dispose() {
77 }
78 });
79
80 store.put(new Element(1, "one"));
81 Element element2 = new Element(2, new Object());
82 element2.setPinned(true);
83 store.put(element2);
84 store.dispose();
85
86 assertNull("element should not have been evicted: " + lastEvicted[0], lastEvicted[0]);
87
88 store = DiskStore.create(new Cache(new CacheConfiguration("SomeCache", 1000).overflowToDisk(true)
89 .diskPersistent(true)), System.getProperty("java.io.tmpdir"), new UnboundedPool(), new UnboundedPool());
90 assertEquals("one", store.get(1).getObjectValue());
91 assertNull(store.get(2));
92 }
93
94 @Test
95 public void testDiskStoreSize() throws Exception {
96 CacheManager cm = new CacheManager(
97 new Configuration()
98 .cache(new CacheConfiguration("aCache", 10000)
99 .overflowToDisk(true)
100 .eternal(false)
101 .timeToLiveSeconds(1000)
102 .timeToLiveSeconds(360)
103 )
104 );
105 final Cache cache = cm.getCache("aCache");
106
107
108 cache.put(new Element(-1, -1));
109 assertEquals(-1, cache.get(-1).getValue());
110 cache.remove(-1);
111 assertEquals(null, cache.get(-1));
112
113 cache.put(new Element(-2, -2));
114 assertEquals(-2, cache.get(-2).getValue());
115 cache.remove(-2);
116 assertEquals(null, cache.get(-2));
117
118 assertEquals(0, cache.getDiskStoreSize());
119
120 for (int i = 0; i < 10010; i++) {
121 cache.put(new Element(i, i));
122 }
123
124 Thread.sleep(3000);
125
126 RetryAssert.assertBy(1, SECONDS, new Callable<Integer>() {
127 public Integer call() throws Exception {
128 return cache.getDiskStoreSize();
129 }
130 }, Is.is(10010));
131
132 cm.shutdown();
133 }
134
135 @Test
136 public void testSupportsCopyOnRead() {
137 Element element = new Element(KEY, "Some String", 1);
138 xaStore.put(element);
139 Element copy = xaStore.get(KEY);
140 Assert.assertNotNull(copy);
141 assertNotSame(copy, xaStore.get(KEY));
142 Assert.assertEquals("Some String", copy.getValue());
143 Assert.assertEquals(copy.getValue(), xaStore.get(KEY).getValue());
144 assertNotSame(copy.getValue(), xaStore.get(KEY).getValue());
145 }
146
147 @Test
148 public void testSupportsCopyOnWrite() {
149
150 AtomicLong atomicLong = new AtomicLong(0);
151
152 Element element = new Element(KEY, atomicLong, 1);
153 atomicLong.getAndIncrement();
154 xaStore.put(element);
155
156 atomicLong.getAndIncrement();
157 element.setVersion(2);
158
159 Assert.assertEquals(1, ((AtomicLong)xaStore.get(KEY).getValue()).get());
160 Assert.assertEquals(1, xaStore.get(KEY).getVersion());
161
162 xaStore.put(new Element(KEY, atomicLong, 1));
163 Assert.assertEquals(2, ((AtomicLong)xaStore.get(KEY).getValue()).get());
164 atomicLong.getAndIncrement();
165
166 Assert.assertEquals(2, ((AtomicLong)xaStore.get(KEY).getValue()).get());
167 Assert.assertEquals(1, xaStore.get(KEY).getVersion());
168 }
169
170 @Test
171 public void testThrowsExceptionOnNonSerializableValue() {
172 try {
173 xaStore.put(new Element(KEY, new Object()));
174 fail("Should have thrown an Exception");
175 } catch (Exception e) {
176 e.printStackTrace();
177 assertTrue("Expected " + CacheException.class.getName() + ", but was " + e.getClass().getName(), e instanceof CacheException);
178 }
179 assertNull(xaStore.get(KEY));
180 }
181
182 }