1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.http.impl.client.cache.ehcache;
28
29 import static org.mockito.Matchers.isA;
30 import static org.mockito.Matchers.same;
31 import static org.mockito.Mockito.mock;
32 import static org.mockito.Mockito.times;
33 import static org.mockito.Mockito.verify;
34 import static org.mockito.Mockito.when;
35
36 import java.io.IOException;
37 import java.io.InputStream;
38 import java.io.OutputStream;
39
40 import junit.framework.TestCase;
41 import net.sf.ehcache.Ehcache;
42 import net.sf.ehcache.Element;
43
44 import org.apache.http.client.cache.HttpCacheEntry;
45 import org.apache.http.client.cache.HttpCacheEntrySerializer;
46 import org.apache.http.client.cache.HttpCacheUpdateCallback;
47 import org.apache.http.client.cache.HttpCacheUpdateException;
48 import org.apache.http.impl.client.cache.CacheConfig;
49 import org.apache.http.impl.client.cache.HttpTestUtils;
50 import org.junit.Test;
51
52 @SuppressWarnings("boxing")
53 public class TestEhcacheHttpCacheStorage extends TestCase {
54
55 private Ehcache mockCache;
56 private EhcacheHttpCacheStorage impl;
57 private HttpCacheEntrySerializer mockSerializer;
58
59 @Override
60 public void setUp() {
61 mockCache = mock(Ehcache.class);
62 final CacheConfig config = CacheConfig.custom().setMaxUpdateRetries(1).build();
63 mockSerializer = mock(HttpCacheEntrySerializer.class);
64 impl = new EhcacheHttpCacheStorage(mockCache, config, mockSerializer);
65 }
66
67 @Test
68 public void testCachePut() throws IOException {
69 final String key = "foo";
70 final HttpCacheEntry value = HttpTestUtils.makeCacheEntry();
71
72 final Element e = new Element(key, new byte[]{});
73
74 impl.putEntry(key, value);
75
76 verify(mockSerializer).writeTo(same(value), isA(OutputStream.class));
77 verify(mockCache).put(e);
78 }
79
80 @Test
81 public void testCacheGetNullEntry() throws IOException {
82 final String key = "foo";
83
84 when(mockCache.get(key)).thenReturn(null);
85
86 final HttpCacheEntry resultingEntry = impl.getEntry(key);
87
88 verify(mockCache).get(key);
89
90 assertNull(resultingEntry);
91 }
92
93 @Test
94 public void testCacheGet() throws IOException {
95 final String key = "foo";
96 final HttpCacheEntry cachedValue = HttpTestUtils.makeCacheEntry();
97
98 final Element element = new Element(key, new byte[]{});
99
100 when(mockCache.get(key))
101 .thenReturn(element);
102 when(mockSerializer.readFrom(isA(InputStream.class)))
103 .thenReturn(cachedValue);
104
105 final HttpCacheEntry resultingEntry = impl.getEntry(key);
106
107 verify(mockCache).get(key);
108 verify(mockSerializer).readFrom(isA(InputStream.class));
109
110 assertSame(cachedValue, resultingEntry);
111 }
112
113 @Test
114 public void testCacheRemove() {
115 final String key = "foo";
116
117 when(mockCache.remove(key)).thenReturn(true);
118
119 impl.removeEntry(key);
120 verify(mockCache).remove(key);
121 }
122
123 @Test
124 public void testCacheUpdateNullEntry() throws IOException, HttpCacheUpdateException {
125 final String key = "foo";
126 final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry();
127
128 final Element element = new Element(key, new byte[]{});
129
130 final HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback(){
131 @Override
132 public HttpCacheEntry update(final HttpCacheEntry old){
133 assertNull(old);
134 return updatedValue;
135 }
136 };
137
138
139 when(mockCache.get(key)).thenReturn(null);
140
141
142 mockSerializer.writeTo(same(updatedValue), isA(OutputStream.class));
143
144 impl.updateEntry(key, callback);
145
146 verify(mockCache).get(key);
147 verify(mockSerializer).writeTo(same(updatedValue), isA(OutputStream.class));
148 verify(mockCache).put(element);
149 }
150
151 @Test
152 public void testCacheUpdate() throws IOException, HttpCacheUpdateException {
153 final String key = "foo";
154 final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry();
155 final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry();
156
157 final Element existingElement = new Element(key, new byte[]{});
158
159 final HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback(){
160 @Override
161 public HttpCacheEntry update(final HttpCacheEntry old){
162 assertEquals(existingValue, old);
163 return updatedValue;
164 }
165 };
166
167
168 when(mockCache.get(key)).thenReturn(existingElement);
169 when(mockSerializer.readFrom(isA(InputStream.class))).thenReturn(existingValue);
170
171
172 mockSerializer.writeTo(same(updatedValue), isA(OutputStream.class));
173 when(mockCache.replace(same(existingElement), isA(Element.class))).thenReturn(true);
174
175 impl.updateEntry(key, callback);
176
177 verify(mockCache).get(key);
178 verify(mockSerializer).readFrom(isA(InputStream.class));
179 verify(mockSerializer).writeTo(same(updatedValue), isA(OutputStream.class));
180 verify(mockCache).replace(same(existingElement), isA(Element.class));
181 }
182
183 @Test
184 public void testSingleCacheUpdateRetry() throws IOException, HttpCacheUpdateException {
185 final String key = "foo";
186 final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry();
187 final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry();
188
189 final Element existingElement = new Element(key, new byte[]{});
190
191 final HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback(){
192 @Override
193 public HttpCacheEntry update(final HttpCacheEntry old){
194 assertEquals(existingValue, old);
195 return updatedValue;
196 }
197 };
198
199
200 when(mockCache.get(key)).thenReturn(existingElement);
201 when(mockSerializer.readFrom(isA(InputStream.class))).thenReturn(existingValue);
202
203
204 when(mockCache.replace(same(existingElement), isA(Element.class))).thenReturn(false).thenReturn(true);
205
206 impl.updateEntry(key, callback);
207
208 verify(mockCache, times(2)).get(key);
209 verify(mockSerializer, times(2)).readFrom(isA(InputStream.class));
210 verify(mockSerializer, times(2)).writeTo(same(updatedValue), isA(OutputStream.class));
211 verify(mockCache, times(2)).replace(same(existingElement), isA(Element.class));
212 }
213
214 @Test
215 public void testCacheUpdateFail() throws IOException {
216 final String key = "foo";
217 final HttpCacheEntry existingValue = HttpTestUtils.makeCacheEntry();
218 final HttpCacheEntry updatedValue = HttpTestUtils.makeCacheEntry();
219
220 final Element existingElement = new Element(key, new byte[]{});
221
222 final HttpCacheUpdateCallback callback = new HttpCacheUpdateCallback(){
223 @Override
224 public HttpCacheEntry update(final HttpCacheEntry old){
225 assertEquals(existingValue, old);
226 return updatedValue;
227 }
228 };
229
230
231 when(mockCache.get(key)).thenReturn(existingElement);
232 when(mockSerializer.readFrom(isA(InputStream.class))).thenReturn(existingValue);
233
234
235 when(mockCache.replace(same(existingElement), isA(Element.class))).thenReturn(false);
236
237 try{
238 impl.updateEntry(key, callback);
239 fail("Expected HttpCacheUpdateException");
240 } catch (final HttpCacheUpdateException e) { }
241
242 verify(mockCache, times(2)).get(key);
243 verify(mockSerializer, times(2)).readFrom(isA(InputStream.class));
244 verify(mockSerializer, times(2)).writeTo(same(updatedValue), isA(OutputStream.class));
245 verify(mockCache, times(2)).replace(same(existingElement), isA(Element.class));
246 }
247 }