1 package net.sf.ehcache.store;
2
3 import net.sf.ehcache.Cache;
4 import net.sf.ehcache.Element;
5 import net.sf.ehcache.config.CacheConfiguration;
6 import net.sf.ehcache.transaction.manager.TransactionManagerLookup;
7 import net.sf.ehcache.transaction.xa.EhcacheXAStoreImpl;
8 import org.junit.Before;
9 import org.junit.Ignore;
10 import org.junit.Test;
11 import org.mockito.invocation.InvocationOnMock;
12 import org.mockito.stubbing.Answer;
13
14 import javax.transaction.RollbackException;
15 import javax.transaction.SystemException;
16 import javax.transaction.Transaction;
17 import javax.transaction.TransactionManager;
18 import javax.transaction.xa.XAException;
19 import javax.transaction.xa.XAResource;
20 import javax.transaction.xa.Xid;
21 import java.util.ArrayList;
22
23 import static org.hamcrest.CoreMatchers.*;
24 import static org.junit.Assert.assertThat;
25 import static org.mockito.Matchers.anyObject;
26 import static org.mockito.Mockito.mock;
27 import static org.mockito.Mockito.when;
28
29 /***
30 * @author Alex Snaps
31 */
32 public class XaIsolationTransactionalStoreTest {
33
34 private static final String KEY = "KEY";
35 private static final String OTHER_KEY = "OTHER";
36
37 private Store store;
38 private Store underlyingStore;
39 private Store oldVersionStore;
40
41
42 private boolean keyInStore = false;
43
44 @Before
45 public void setupMockedStore()
46 throws SystemException, RollbackException {
47
48 underlyingStore = mock(Store.class);
49 oldVersionStore = mock(Store.class);
50 final Xid xid = mock(Xid.class);
51 Transaction tx = mock(Transaction.class);
52
53 when(tx.enlistResource((XAResource) anyObject())).thenAnswer(new Answer() {
54 public Object answer(InvocationOnMock invocation) {
55 XAResource xaResource = (XAResource) invocation.getArguments()[0];
56 try {
57 xaResource.start(xid, XAResource.TMNOFLAGS);
58 } catch (XAException e) {
59 throw new RuntimeException(e);
60 }
61 return true;
62 }
63 });
64
65
66 TransactionManager tm = mock(TransactionManager.class);
67 when(tm.getTransaction()).thenReturn(tx);
68 TransactionManagerLookup transactionManagerLookup = mock(TransactionManagerLookup.class);
69 when(transactionManagerLookup.getTransactionManager()).thenReturn(tm);
70
71 CacheConfiguration cacheConfiguration = mock(CacheConfiguration.class);
72 when(cacheConfiguration.clone()).thenReturn(cacheConfiguration);
73 when(cacheConfiguration.getCacheEventListenerConfigurations()).thenReturn(new ArrayList());
74 when(cacheConfiguration.getElementValueComparatorConfiguration()).thenReturn(CacheConfiguration.DEFAULT_ELEMENT_VALUE_COMPARATOR_CONFIGURATION);
75 Cache cache = new Cache(cacheConfiguration);
76
77 EhcacheXAStoreImpl xaStore = new EhcacheXAStoreImpl(underlyingStore, oldVersionStore, false);
78 when(underlyingStore.isCacheCoherent()).thenReturn(true);
79 when(underlyingStore.getKeys()).thenAnswer(new Answer<Object>() {
80 public Object answer(InvocationOnMock invocationOnMock)
81 throws Throwable {
82 if (keyInStore) {
83 return new Object[]{KEY};
84 }
85 return new Object[0];
86 }
87 });
88 when(underlyingStore.containsKey(KEY)).thenAnswer(new Answer<Object>() {
89 public Object answer(InvocationOnMock invocationOnMock)
90 throws Throwable {
91 return keyInStore;
92 }
93 });
94 when(underlyingStore.containsKey(OTHER_KEY)).thenAnswer(new Answer<Object>() {
95 public Object answer(InvocationOnMock invocationOnMock)
96 throws Throwable {
97 return false;
98 }
99 });
100 store = new XATransactionalStore(cache, xaStore, transactionManagerLookup, transactionManagerLookup.getTransactionManager());
101 }
102
103 @Test
104 public void testIsolationNoKey() {
105 Element element = new Element(KEY, "VALUE");
106 assertThat(store.get(element.getKey()), nullValue());
107 assertThat(store.getSize(), is(0));
108 assertThat(store.getTerracottaClusteredSize(), is(0));
109 assertThat(store.containsKey(KEY), is(false));
110 store.put(element);
111 assertThat(store.get(element.getKey()), sameInstance(element));
112 assertThat(store.getSize(), is(1));
113 assertThat(store.getTerracottaClusteredSize(), is(1));
114 assertThat(store.containsKey(KEY), is(true));
115 assertThat(store.remove(element.getKey()), sameInstance(element));
116 assertThat(store.getSize(), is(0));
117 assertThat(store.containsKey(KEY), is(false));
118 assertThat(store.get(element.getKey()), nullValue());
119 assertThat(store.remove(element.getKey()), nullValue());
120 assertThat(store.getSize(), is(0));
121 assertThat(store.getTerracottaClusteredSize(), is(0));
122 store.put(element);
123 store.put(element);
124 assertThat(store.get(element.getKey()), sameInstance(element));
125 assertThat(store.getSize(), is(1));
126 assertThat(store.getTerracottaClusteredSize(), is(1));
127 assertThat(store.containsKey(KEY), is(true));
128 assertThat(store.remove(KEY), sameInstance(element));
129 assertThat(store.remove(KEY), nullValue());
130 store.remove(KEY);
131 assertThat(store.getSize(), is(0));
132 assertThat(store.getTerracottaClusteredSize(), is(0));
133 assertThat(store.get(element.getKey()), nullValue());
134
135 assertThat(store.containsKey(KEY), is(false));
136 }
137
138 @Test
139 @Ignore
140 public void testIsolationWithKey() {
141 Element element = new Element(KEY, "VALUE");
142 putInStore(element);
143
144 assertThat(store.get(element.getKey()), sameInstance(element));
145 assertThat(store.getSize(), is(1));
146 assertThat(store.getTerracottaClusteredSize(), is(1));
147 assertThat(store.getKeys().size(), is(1));
148 assertThat(store.containsKey(KEY), is(true));
149 Element newElement = new Element(element.getKey(), "NEW_VALUE");
150 store.put(newElement);
151 assertThat(store.get(element.getKey()), sameInstance(newElement));
152 assertThat(store.getSize(), is(1));
153 assertThat(store.getTerracottaClusteredSize(), is(1));
154 assertThat(store.getKeys().size(), is(1));
155 assertThat(store.containsKey(KEY), is(true));
156 assertThat(store.remove(element.getKey()), sameInstance(newElement));
157 assertThat(store.getSize(), is(0));
158 assertThat(store.getTerracottaClusteredSize(), is(0));
159 assertThat(store.getKeys().size(), is(0));
160 assertThat(store.get(element.getKey()), nullValue());
161 assertThat(store.remove(element.getKey()), nullValue());
162 assertThat(store.getSize(), is(0));
163 assertThat(store.getTerracottaClusteredSize(), is(0));
164 assertThat(store.getKeys().size(), is(0));
165 assertThat(store.containsKey(KEY), is(false));
166 store.put(newElement);
167 store.put(newElement);
168 assertThat(store.get(element.getKey()), sameInstance(newElement));
169 assertThat(store.getSize(), is(1));
170 assertThat(store.getTerracottaClusteredSize(), is(1));
171 assertThat(store.getKeys().size(), is(1));
172 assertThat(store.containsKey(KEY), is(true));
173 assertThat(store.remove(KEY), sameInstance(newElement));
174 assertThat(store.remove(KEY), nullValue());
175 assertThat(store.getSize(), is(0));
176 assertThat(store.getTerracottaClusteredSize(), is(0));
177 assertThat(store.getKeys().size(), is(0));
178 assertThat(store.get(element.getKey()), nullValue());
179 assertThat(store.containsKey(KEY), is(false));
180 }
181
182 @Test
183 @Ignore
184 public void testIsolationWithOtherKey() {
185 Element element = new Element(KEY, "VALUE");
186 putInStore(element);
187
188 assertThat(store.get(element.getKey()), sameInstance(element));
189 assertThat(store.getSize(), is(1));
190 assertThat(store.getTerracottaClusteredSize(), is(1));
191 assertThat(store.getKeys().size(), is(1));
192 assertThat(store.containsKey(KEY), is(true));
193 assertThat(store.containsKey(OTHER_KEY), is(false));
194 Element newElement = new Element(OTHER_KEY, "NEW_VALUE");
195 store.put(newElement);
196 assertThat(store.get(element.getKey()), sameInstance(element));
197 assertThat(store.get(KEY), sameInstance(element));
198 assertThat(store.get(OTHER_KEY), sameInstance(newElement));
199 assertThat(store.getSize(), is(2));
200 assertThat(store.getTerracottaClusteredSize(), is(2));
201 assertThat(store.getKeys().size(), is(2));
202 assertThat(store.containsKey(element.getKey()), is(true));
203 assertThat(store.containsKey(KEY), is(true));
204 assertThat(store.remove(OTHER_KEY), sameInstance(newElement));
205 assertThat(store.getSize(), is(1));
206 assertThat(store.getTerracottaClusteredSize(), is(1));
207 assertThat(store.getKeys().size(), is(1));
208 assertThat(store.get(OTHER_KEY), nullValue());
209 assertThat(store.get(KEY), sameInstance(element));
210 assertThat(store.remove(OTHER_KEY), nullValue());
211 assertThat(store.getSize(), is(1));
212 assertThat(store.getTerracottaClusteredSize(), is(1));
213 assertThat(store.getKeys().size(), is(1));
214 assertThat(store.containsKey(OTHER_KEY), is(false));
215 assertThat(store.containsKey(KEY), is(true));
216 store.put(newElement);
217 store.put(newElement);
218 assertThat(store.get(OTHER_KEY), sameInstance(newElement));
219 assertThat(store.getSize(), is(2));
220 assertThat(store.getTerracottaClusteredSize(), is(2));
221 assertThat(store.getKeys().size(), is(2));
222 assertThat(store.containsKey(KEY), is(true));
223 assertThat(store.containsKey(OTHER_KEY), is(true));
224 assertThat(store.remove(OTHER_KEY), sameInstance(newElement));
225 assertThat(store.remove(OTHER_KEY), nullValue());
226 assertThat(store.remove(KEY), sameInstance(element));
227 assertThat(store.remove(KEY), nullValue());
228 assertThat(store.getSize(), is(0));
229 assertThat(store.getTerracottaClusteredSize(), is(0));
230 assertThat(store.getKeys().size(), is(0));
231 assertThat(store.get(OTHER_KEY), nullValue());
232 assertThat(store.get(KEY), nullValue());
233 assertThat(store.containsKey(OTHER_KEY), is(false));
234 assertThat(store.containsKey(KEY), is(false));
235 }
236
237 private void putInStore(final Element element) {
238 when(oldVersionStore.get(element.getKey())).thenReturn(element);
239 when(oldVersionStore.getQuiet(element.getKey())).thenReturn(element);
240
241 when(underlyingStore.getSize()).thenReturn(1);
242 when(underlyingStore.getTerracottaClusteredSize()).thenReturn(1);
243 keyInStore = true;
244 }
245
246 }