blob: 6c4eecd4abcb03347ce8be7d31e1198482d11a48 [file] [log] [blame]
/*
* Copyright (c) 2015, 2020 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// 05/11/2015-2.7 Tomas Kraus
// - Initial API and implementation.
package org.eclipse.persistence.testing.tests.jpa;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.persistence.exceptions.ServerPlatformException;
import org.eclipse.persistence.internal.jpa.IsolatedHashMap;
import org.eclipse.persistence.logging.SessionLog;
import org.eclipse.persistence.platform.server.ServerPlatform;
import org.eclipse.persistence.platform.server.ServerPlatformUtils;
import org.eclipse.persistence.sessions.factories.SessionManager;
import org.eclipse.persistence.testing.framework.junit.JUnitTestCase;
import junit.framework.Test;
import junit.framework.TestSuite;
/**
* Tests partition isolated {@link HashMap}.
*/
public class IsolatedHashMapTest extends JUnitTestCase {
/** Session name and partition ID separator. */
private static final char SEPARATOR = '$';
/** Default short enough partition ID when server does not support partitions.*/
private static final String DEFAULT_PARTITION_ID = "0";
/** Tested map shall be stared trough whole JVM to run test against the same map for all configured partitions. */
private static final Map<String, String> map = IsolatedHashMap.newMap();
/** Detected server platform. */
private static final ServerPlatform serverPlatform;
/** Does platform support partitions? */
private static final boolean supportPartitions;
/** Session name templates used to generate session names in the tests. */
private static final String[] sessionNameTemplates = {
"", "0", "mySession", "EclipseLink"
};
/** Class initialization code. */
static {
String platformClass = ServerPlatformUtils.detectServerPlatform(null);
ServerPlatform sp = null;
try {
sp = platformClass != null
? ServerPlatformUtils.createServerPlatform(null, platformClass, SessionManager.class.getClassLoader())
: null;
} catch (ServerPlatformException e) {
}
serverPlatform = sp;
// False value also handles case when serverPlatform is null to avoid
// NPE.
supportPartitions = serverPlatform != null ? serverPlatform.usesPartitions() : false;
}
/**
* Creates jUnit test suite for partition isolated {@link HashMap} tests.
* @return new jUnit test suite containing all the tests.
*/
public static Test suite() {
TestSuite suite = new TestSuite();
suite.setName("IsolatedHashMapTest");
suite.addTest(new IsolatedHashMapTest("testIsolationInRealContext"));
return suite;
}
/**
* Initialize session names in current partition context.
* Test initialization helper.
* @param partitionId Current partition ID. Shall not be {@code null}.
*/
private static String[] initSessionNames(final String partitionId) {
final int count = sessionNameTemplates.length;
final String[] sessionNames = new String[count];
int maxLength = 0;
// Calculate StringBuilder internal storage size to avoid resizing.
for (int i = 0; i < count; i++) {
final int sessionNameTemplateLength = sessionNameTemplates[i].length();
if (sessionNameTemplateLength > maxLength) {
maxLength = sessionNameTemplateLength;
}
}
maxLength += 1 + partitionId.length();
final StringBuilder sb = new StringBuilder(maxLength);
for (int i = 0; i < count; i++) {
if (i > 0) {
sb.delete(0, sb.length() - 1);
}
sb.append(sessionNameTemplates[i]);
sb.append(SEPARATOR);
sb.append(partitionId);
sessionNames[i] = sb.toString();
}
return sessionNames;
}
/**
* Creates an instance of partition isolated {@link HashMap} test.
*/
public IsolatedHashMapTest() {
super();
}
/**
* Creates an instance of partition isolated {@link HashMap} test.
* @param name jUnit test name.
*/
public IsolatedHashMapTest(final String name) {
super(name);
}
/**
* Do partition isolation check in current partition context.
* @param partitionId Current partition ID that should be visible in {@code map}.
*/
private static void doIsolationCheck(final Map<String, String> map, final String partitionId, final SessionLog log) {
final String[] sessionNames = initSessionNames(partitionId);
final Set<String> namesSet = new HashSet<>(sessionNames.length);
log.log(SessionLog.INFO, " Partition ID: " + partitionId);
for (String sessionName : sessionNames) {
log.log(SessionLog.INFO, " Adding session name: " + sessionName);
map.put(sessionName, sessionName);
namesSet.add(sessionName);
}
// Map shall contain session names in current partition context only.
final int mapSize = map.size();
log.log(SessionLog.INFO, " Checking map size: session names count = "
+ sessionNames.length + ", map size = " + mapSize );
assertEquals("Map size does not match session names count.", sessionNames.length, mapSize);
// Verify individual session names.
for (String sessionName : map.keySet()) {
log.log(SessionLog.INFO, " Getting and checking session name: " + sessionName);
assertTrue("Session name " + sessionName + "was not stored in current partition context.",
namesSet.contains(sessionName));
}
}
/**
* Test partition isolation in real context with real {@link ServerPlatform}.
*/
public void testIsolationInRealContext() {
final SessionLog log = getServerSession().getSessionLog();
log.log(SessionLog.INFO, "IsolatedHashMapTest.testIsolationInRealContext()");
doIsolationCheck(map, supportPartitions ? serverPlatform.getPartitionID() : DEFAULT_PARTITION_ID, log);
}
}