use the new session manager interface
[java-idp.git] / tests / edu / internet2 / middleware / shibboleth / common / provider / CacheTests.java
1 /*
2  * Copyright [2005] [University Corporation for Advanced Internet Development, Inc.]
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package edu.internet2.middleware.shibboleth.common.provider;
18
19 import java.util.List;
20
21 import javax.crypto.SecretKey;
22 import javax.crypto.spec.SecretKeySpec;
23 import javax.servlet.http.Cookie;
24
25 import junit.framework.TestCase;
26
27 import org.apache.log4j.BasicConfigurator;
28 import org.apache.log4j.Level;
29 import org.apache.log4j.Logger;
30
31 import com.mockrunner.mock.web.MockHttpServletRequest;
32 import com.mockrunner.mock.web.MockHttpServletResponse;
33 import com.mockrunner.mock.web.WebMockObjectFactory;
34
35 import edu.internet2.middleware.shibboleth.common.Cache;
36 import edu.internet2.middleware.shibboleth.common.CacheException;
37 import edu.internet2.middleware.shibboleth.common.CredentialsTests;
38
39 public class CacheTests extends TestCase {
40
41         private static Logger log = Logger.getLogger(CacheTests.class.getName());
42         private WebMockObjectFactory factory = new WebMockObjectFactory();
43         private MockHttpServletResponse response = factory.getMockResponse();
44         private MockHttpServletRequest request = factory.getMockRequest();
45
46         private String cipherAlgorithm = "DESede/CBC/PKCS5Padding";
47         private String macAlgorithm = "HmacSHA1";
48
49         byte[] defaultKey = new byte[]{(byte) 0xC7, (byte) 0x49, (byte) 0x80, (byte) 0xD3, (byte) 0x02, (byte) 0x4A,
50                         (byte) 0x61, (byte) 0xEF, (byte) 0x25, (byte) 0x5D, (byte) 0xE3, (byte) 0x2F, (byte) 0x57, (byte) 0x51,
51                         (byte) 0x20, (byte) 0x15, (byte) 0xC7, (byte) 0x49, (byte) 0x80, (byte) 0xD3, (byte) 0x02, (byte) 0x4A,
52                         (byte) 0x61, (byte) 0xEF};
53
54         public CacheTests(String name) {
55
56                 super(name);
57                 BasicConfigurator.resetConfiguration();
58                 BasicConfigurator.configure();
59                 Logger.getRootLogger().setLevel(Level.OFF);
60         }
61
62         public static void main(String[] args) {
63
64                 junit.textui.TestRunner.run(CredentialsTests.class);
65                 BasicConfigurator.configure();
66                 Logger.getRootLogger().setLevel(Level.OFF);
67         }
68
69         /**
70          * @see junit.framework.TestCase#setUp()
71          */
72         protected void setUp() throws Exception {
73
74                 super.setUp();
75                 request.resetAll();
76                 response.resetAll();
77         }
78
79         public void testServletSessionCache() {
80
81                 try {
82                         // Startup the cache
83                         Cache cache = new ServletSessionCache("foobar", request);
84
85                         // Make sure the cache starts clean
86                         assertNull("Cache contained errant record.", cache.retrieve("foo"));
87
88                         // Store and retrieve
89                         cache.store("foo", "bar", 99999);
90                         assertTrue("Cache expected to contain record.", cache.contains("foo"));
91                         assertEquals("Cache expected to contain record.", "bar", cache.retrieve("foo"));
92
93                         // Make sure expiration works
94                         cache.store("bar", "foo", 1);
95                         try {
96                                 Thread.sleep(2000);
97                         } catch (InterruptedException e) {
98                                 // Who cares
99                         }
100                         assertFalse("Cache expected to expire record.", cache.contains("bar"));
101                         assertEquals("Cache expected to expire record.", null, cache.retrieve("bar"));
102
103                 } catch (CacheException e) {
104                         fail("Error exercising cache: " + e);
105                 }
106         }
107
108         public void testMemoryCache() {
109
110                 try {
111                         // Startup the cache
112                         Cache cache = new MemoryCache("foobar");
113
114                         // Make sure the cache starts clean
115                         assertNull("Cache contained errant record.", cache.retrieve("foo"));
116
117                         // Store and retrieve
118                         cache.store("foo", "bar", 99999);
119                         assertTrue("Cache expected to contain record.", cache.contains("foo"));
120                         assertEquals("Cache expected to contain record.", "bar", cache.retrieve("foo"));
121
122                         // Make sure expiration works
123                         cache.store("bar", "foo", 1);
124                         try {
125                                 Thread.sleep(2000);
126                         } catch (InterruptedException e) {
127                                 // Who cares
128                         }
129                         assertFalse("Cache expected to expire record.", cache.contains("bar"));
130                         assertEquals("Cache expected to expire record.", null, cache.retrieve("bar"));
131
132                 } catch (CacheException e) {
133                         fail("Error exercising cache: " + e);
134                 }
135         }
136
137         public void testCookieCacheBasic() {
138
139                 try {
140
141                         SecretKey secret = new SecretKeySpec(defaultKey, "DESede");
142
143                         // Startup the cache
144                         CookieCache cache = new CookieCache("foobar", secret, cipherAlgorithm, macAlgorithm, request, response);
145
146                         // Make sure the cache starts clean
147                         assertNull("Cache contained errant record.", cache.retrieve("foo"));
148
149                         // Store and retrieve
150                         cache.store("foo", "bar", 99999);
151                         assertTrue("Cache expected to contain record.", cache.contains("foo"));
152                         assertEquals("Cache expected to contain record.", "bar", cache.retrieve("foo"));
153
154                         // Make sure expiration works
155                         cache.store("expr1", "foo", 1); // check immediate
156                         cache.store("expr2", "foo", 1); // check after round trip
157
158                         try {
159                                 Thread.sleep(2000);
160                         } catch (InterruptedException e) {
161                                 // Who cares
162                         }
163                         assertFalse("Cache expected to expire record.", cache.contains("expr1"));
164                         assertEquals("Cache expected to expire record.", null, cache.retrieve("expr1"));
165
166                         // Write cache to cookies
167                         cache.postProcessing();
168                         request.resetAll();
169
170                         // Round trip testing
171                         // Add cookies from previous query response to the new request.. to simulate a browser interaction
172                         List<Cookie> cookies = (List<Cookie>) response.getCookies();
173                         for (Cookie cookie : cookies) {
174                                 log.debug("Cookie Name: " + cookie.getName());
175                                 log.debug("Cookie Value: " + cookie.getValue());
176                                 request.addCookie(cookie);
177                         }
178
179                         response.resetAll();
180
181                         cache = new CookieCache("foobar", secret, cipherAlgorithm, macAlgorithm, request, response);
182
183                         // Test round-tripped entry
184                         assertTrue("Cache expected to contain record.", cache.contains("foo"));
185                         assertEquals("Cache expected to contain record.", "bar", cache.retrieve("foo"));
186
187                         // Test round-tripped expired entry
188                         assertFalse("Cache expected to expire record.", cache.contains("expr2"));
189                         assertEquals("Cache expected to expire record.", null, cache.retrieve("expr2"));
190
191                 } catch (CacheException e) {
192                         fail("Error exercising cache: " + e);
193                 }
194         }
195
196         public void testCookieCacheLargeDataSet() {
197
198                 try {
199
200                         SecretKey secret = new SecretKeySpec(defaultKey, "DESede");
201
202                         // Round trip with a large data set
203                         CookieCache cache = new CookieCache("foobar", secret, cipherAlgorithm, macAlgorithm, request, response);
204                         for (int i = 0; i < 5000; i++) {
205                                 cache.store(new Integer(i).toString(), "Walter", 99999);
206                         }
207
208                         cache.postProcessing();
209                         request.resetAll();
210
211                         List<Cookie> cookies = (List<Cookie>) response.getCookies();
212                         for (Cookie cookie : cookies) {
213                                 log.debug("Cookie Name: " + cookie.getName());
214                                 log.debug("Cookie Value: " + cookie.getValue());
215                                 request.addCookie(cookie);
216                         }
217
218                         response.resetAll();
219
220                         cache = new CookieCache("foobar", secret, cipherAlgorithm, macAlgorithm, request, response);
221                         assertEquals("Cache expected to contain record.", "Walter", cache.retrieve(new Integer(1).toString()));
222
223                 } catch (CacheException e) {
224                         fail("Error exercising cache: " + e);
225                 }
226         }
227
228         public void testCookieCacheStaleCookieCleanup() {
229
230                 try {
231
232                         SecretKey secret = new SecretKeySpec(defaultKey, "DESede");
233
234                         // Round trip with a large data set
235                         CookieCache cache = new CookieCache("foobar", secret, cipherAlgorithm, macAlgorithm, request, response);
236                         for (int i = 0; i < 5000; i++) {
237                                 cache.store(new Integer(i).toString(), "Walter", 99999);
238                         }
239
240                         cache.postProcessing();
241                         request.resetAll();
242
243                         List<Cookie> cookies = (List<Cookie>) response.getCookies();
244                         for (Cookie cookie : cookies) {
245                                 log.debug("Cookie Name: " + cookie.getName());
246                                 log.debug("Cookie Value: " + cookie.getValue());
247                                 log.debug("Cookie Max Age: " + cookie.getMaxAge());
248                                 request.addCookie(cookie);
249                         }
250
251                         response.resetAll();
252                         cache = new CookieCache("foobar", secret, cipherAlgorithm, macAlgorithm, request, response);
253
254                         // OK, delete a bunch of entries and make sure this is reflected in the cookies
255                         for (int i = 0; i < 4999; i++) {
256                                 cache.remove(new Integer(i).toString());
257                         }
258
259                         cache.postProcessing();
260                         request.resetAll();
261
262                         cookies = (List<Cookie>) response.getCookies();
263                         for (Cookie cookie : cookies) {
264                                 log.debug("Cookie Name: " + cookie.getName());
265                                 log.debug("Cookie Value: " + cookie.getValue());
266                                 log.debug("Cookie Max Age: " + cookie.getMaxAge());
267                                 request.addCookie(cookie);
268                                 if (!cookie.getName().equals("IDP_CACHE:foobar:1")) {
269                                         assertTrue("Cookie not properly expired.", cookie.getMaxAge() == 0);
270                                 }
271                         }
272
273                 } catch (CacheException e) {
274                         fail("Error exercising cache: " + e);
275                 }
276         }
277
278 }