blob: 2bea8de354efc72c71d3c7f51ac3c5cbe27062e4 [file] [log] [blame]
/*
* 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.geode.modules.session.catalina;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.HashSet;
import java.util.Set;
import javax.servlet.http.HttpSession;
import org.junit.Before;
import org.junit.Test;
import org.apache.geode.cache.Cache;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionFactory;
import org.apache.geode.cache.RegionShortcut;
import org.apache.geode.cache.execute.FunctionException;
import org.apache.geode.cache.execute.ResultCollector;
import org.apache.geode.modules.session.catalina.callback.SessionExpirationCacheListener;
import org.apache.geode.modules.util.RegionConfiguration;
import org.apache.geode.modules.util.SessionCustomExpiry;
import org.apache.geode.modules.util.TouchPartitionedRegionEntriesFunction;
import org.apache.geode.modules.util.TouchReplicatedRegionEntriesFunction;
public class PeerToPeerSessionCacheJUnitTest extends AbstractSessionCacheJUnitTest {
private String localRegionName = sessionRegionName + "_local";
@SuppressWarnings("unchecked")
private RegionFactory<String, HttpSession> regionFactory = mock(RegionFactory.class);
@SuppressWarnings("unchecked")
private Region<String, HttpSession> localRegion = mock(Region.class);
private Cache cache = mock(Cache.class);
@Before
public void setUp() {
sessionCache = spy(new PeerToPeerSessionCache(sessionManager, cache));
doReturn(sessionRegion).when((PeerToPeerSessionCache) sessionCache)
.createRegionUsingHelper(any(RegionConfiguration.class));
doReturn(true).when((PeerToPeerSessionCache) sessionCache)
.isFunctionRegistered(any(String.class));
when(sessionManager.getRegionName()).thenReturn(sessionRegionName);
when(sessionManager.getRegionAttributesId()).thenReturn(RegionShortcut.PARTITION.toString());
when(sessionManager.getLogger()).thenReturn(logger);
when(sessionManager.getEnableLocalCache()).thenReturn(true);
when(sessionManager.getMaxInactiveInterval())
.thenReturn(RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL);
when(sessionRegion.getName()).thenReturn(sessionRegionName);
doReturn(regionFactory).when(cache).createRegionFactory(RegionShortcut.LOCAL_HEAP_LRU);
when(regionFactory.create(localRegionName)).thenReturn(localRegion);
when(cache.getDistributedSystem()).thenReturn(distributedSystem);
}
@Test
public void initializeSessionCacheSucceeds() {
sessionCache.initialize();
verify(cache).createRegionFactory(RegionShortcut.LOCAL_HEAP_LRU);
verify(regionFactory).create(localRegionName);
verify((PeerToPeerSessionCache) sessionCache)
.createRegionUsingHelper(any(RegionConfiguration.class));
verify(regionFactory, times(0)).setStatisticsEnabled(true);
verify(regionFactory, times(0)).setCustomEntryIdleTimeout(any(SessionCustomExpiry.class));
verify(regionFactory, times(0)).addCacheListener(any(SessionExpirationCacheListener.class));
}
@Test
public void functionRegistrationDoesNotThrowException() {
doReturn(false).when((PeerToPeerSessionCache) sessionCache)
.isFunctionRegistered(any(String.class));
sessionCache.initialize();
verify((PeerToPeerSessionCache) sessionCache).registerFunctionWithFunctionService(any(
TouchPartitionedRegionEntriesFunction.class));
verify((PeerToPeerSessionCache) sessionCache).registerFunctionWithFunctionService(any(
TouchReplicatedRegionEntriesFunction.class));
}
@Test
public void initializeSessionCacheSucceedsWhenSessionRegionAlreadyExists() {
doReturn(sessionRegion).when(cache).getRegion(sessionRegionName);
doNothing().when((PeerToPeerSessionCache) sessionCache)
.validateRegionUsingRegionhelper(any(RegionConfiguration.class), any(Region.class));
sessionCache.initialize();
verify((PeerToPeerSessionCache) sessionCache, times(0))
.createRegionUsingHelper(any(RegionConfiguration.class));
}
@Test
public void nonDefaultMaxTimeoutIntervalSetsExpirationDetails() {
// Setting the mocked return value of getMaxInactiveInterval to something distinctly not equal
// to the default
when(sessionManager.getMaxInactiveInterval())
.thenReturn(RegionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL + 1);
sessionCache.initialize();
verify(regionFactory).setStatisticsEnabled(true);
verify(regionFactory).setCustomEntryIdleTimeout(any(SessionCustomExpiry.class));
verify(regionFactory).addCacheListener(any(SessionExpirationCacheListener.class));
}
@Test
public void initializeSessionCacheSucceedsWhenLocalRegionAlreadyExists() {
doReturn(localRegion).when(cache).getRegion(localRegionName);
sessionCache.initialize();
verify(regionFactory, times(0)).create(any(String.class));
}
@Test
public void operationRegionIsCorrectlySetWhenEnableLocalCachingIsFalse() {
when(sessionManager.getEnableLocalCache()).thenReturn(false);
sessionCache.initialize();
verify(cache, times(0)).getRegion(localRegionName);
assertThat(sessionCache.sessionRegion).isEqualTo(sessionCache.operatingRegion);
}
@Test
public void touchSessionsWithPartitionedRegionSucceeds() {
Set<String> sessionIds = new HashSet<>();
ResultCollector collector = mock(ResultCollector.class);
when(sessionManager.getRegionAttributesId()).thenReturn(RegionShortcut.PARTITION.toString());
doReturn(emptyExecution).when((PeerToPeerSessionCache) sessionCache)
.getExecutionForFunctionOnRegionWithFilter(sessionIds);
when(emptyExecution.execute(TouchPartitionedRegionEntriesFunction.ID)).thenReturn(collector);
sessionCache.touchSessions(sessionIds);
verify(emptyExecution).execute(TouchPartitionedRegionEntriesFunction.ID);
verify(collector).getResult();
}
@Test
public void touchSessionsWithReplicatedRegionSucceeds() {
// Need to invoke this to set the session region
sessionCache.initialize();
Set<String> sessionIds = new HashSet<>();
ResultCollector collector = mock(ResultCollector.class);
when(sessionManager.getRegionAttributesId()).thenReturn(RegionShortcut.REPLICATE.toString());
doReturn(emptyExecution).when((PeerToPeerSessionCache) sessionCache)
.getExecutionForFunctionOnMembersWithArguments(any(Object[].class));
when(emptyExecution.execute(TouchReplicatedRegionEntriesFunction.ID)).thenReturn(collector);
sessionCache.touchSessions(sessionIds);
verify(emptyExecution).execute(TouchReplicatedRegionEntriesFunction.ID);
verify(collector).getResult();
}
@Test
public void touchSessionsCatchesThrownException() {
Set<String> sessionIds = new HashSet<>();
ResultCollector collector = mock(ResultCollector.class);
FunctionException exception = new FunctionException();
when(sessionManager.getRegionAttributesId()).thenReturn(RegionShortcut.PARTITION.toString());
doReturn(emptyExecution).when((PeerToPeerSessionCache) sessionCache)
.getExecutionForFunctionOnRegionWithFilter(sessionIds);
when(emptyExecution.execute(TouchPartitionedRegionEntriesFunction.ID)).thenReturn(collector);
doThrow(exception).when(collector).getResult();
sessionCache.touchSessions(sessionIds);
verify(logger).warn("Caught unexpected exception:", exception);
}
}