| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.catalina.session; |
| |
| import java.util.concurrent.atomic.AtomicInteger; |
| |
| import jakarta.servlet.http.HttpServletRequest; |
| import jakarta.servlet.http.HttpSessionEvent; |
| import jakarta.servlet.http.HttpSessionListener; |
| |
| import org.junit.Assert; |
| import org.junit.Test; |
| |
| import org.apache.catalina.Context; |
| import org.apache.catalina.Host; |
| import org.apache.catalina.Manager; |
| import org.apache.catalina.Session; |
| import org.apache.catalina.Store; |
| import org.apache.catalina.connector.Connector; |
| import org.apache.catalina.connector.Request; |
| import org.apache.catalina.connector.RequestFacade; |
| import org.apache.tomcat.unittest.TesterContext; |
| import org.apache.tomcat.unittest.TesterHost; |
| import org.easymock.EasyMock; |
| import org.easymock.IAnswer; |
| |
| public class TestPersistentManager { |
| |
| @Test |
| public void testMinIdleSwap() throws Exception { |
| PersistentManager manager = new PersistentManager(); |
| manager.setStore(new TesterStore()); |
| |
| Host host = new TesterHost(); |
| Context context = new TesterContext(); |
| context.setParent(host); |
| |
| manager.setContext(context); |
| |
| manager.setMaxActiveSessions(2); |
| manager.setMinIdleSwap(0); |
| |
| manager.start(); |
| |
| // Create the maximum number of sessions |
| manager.createSession(null); |
| manager.createSession(null); |
| |
| // Given the minIdleSwap settings, this should swap one out to get below |
| // the limit |
| manager.processPersistenceChecks(); |
| Assert.assertEquals(1, manager.getActiveSessions()); |
| Assert.assertEquals(2, manager.getActiveSessionsFull()); |
| |
| manager.createSession(null); |
| Assert.assertEquals(2, manager.getActiveSessions()); |
| Assert.assertEquals(3, manager.getActiveSessionsFull()); |
| } |
| |
| @Test |
| public void testBug62175() throws Exception { |
| PersistentManager manager = new PersistentManager(); |
| AtomicInteger sessionExpireCounter = new AtomicInteger(); |
| |
| Store mockStore = EasyMock.createNiceMock(Store.class); |
| EasyMock.expect(mockStore.load(EasyMock.anyString())).andAnswer(new IAnswer<Session>() { |
| |
| @Override |
| public Session answer() throws Throwable { |
| return timedOutSession(manager, sessionExpireCounter); |
| } |
| }).anyTimes(); |
| |
| EasyMock.replay(mockStore); |
| |
| manager.setStore(mockStore); |
| |
| Host host = new TesterHost(); |
| |
| RequestCachingSessionListener requestCachingSessionListener = new RequestCachingSessionListener(); |
| |
| Context context = new TesterContext() { |
| |
| @Override |
| public Object[] getApplicationLifecycleListeners() { |
| return new Object[] { requestCachingSessionListener }; |
| } |
| |
| @Override |
| public Manager getManager() { |
| return manager; |
| } |
| }; |
| context.setParent(host); |
| |
| Connector connector = EasyMock.createNiceMock(Connector.class); |
| EasyMock.replay(connector); |
| Request req = new Request(connector, null) { |
| @Override |
| public Context getContext() { |
| return context; |
| } |
| }; |
| req.setRequestedSessionId("invalidSession"); |
| HttpServletRequest request = new RequestFacade(req); |
| requestCachingSessionListener.request = request; |
| |
| manager.setContext(context); |
| |
| manager.start(); |
| |
| Assert.assertNull(request.getSession(false)); |
| Assert.assertEquals(1, sessionExpireCounter.get()); |
| |
| } |
| |
| private static class RequestCachingSessionListener implements HttpSessionListener { |
| |
| private HttpServletRequest request; |
| |
| @Override |
| public void sessionDestroyed(HttpSessionEvent se) { |
| request.getSession(false); |
| } |
| } |
| |
| private StandardSession timedOutSession(PersistentManager manager, AtomicInteger counter) { |
| StandardSession timedOutSession = new StandardSession(manager) { |
| private static final long serialVersionUID = -5910605558747844210L; |
| |
| @Override |
| public void expire() { |
| counter.incrementAndGet(); |
| super.expire(); |
| } |
| }; |
| timedOutSession.isValid = true; |
| timedOutSession.expiring = false; |
| timedOutSession.maxInactiveInterval = 1; |
| timedOutSession.lastAccessedTime = 0; |
| timedOutSession.id = "invalidSession"; |
| return timedOutSession; |
| } |
| } |
| |