blob: dc22c42872115d7c002e826734ae4bc8738bcdac [file] [log] [blame]
/*
* Copyright (c) 1998, 2021 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:
// Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.tests.identitymaps;
import java.util.Iterator;
import java.util.Map;
import java.util.Vector;
import org.eclipse.persistence.internal.identitymaps.CacheKey;
import org.eclipse.persistence.internal.identitymaps.WeakIdentityMap;
import org.eclipse.persistence.queries.InsertObjectQuery;
import org.eclipse.persistence.testing.models.employee.domain.Employee;
import org.eclipse.persistence.testing.framework.*;
//bug4649617 Test if there is any memory leak in InsertObjectQuery with WeakIdentityMap.
public class InsertWeakIdentityMapTest extends TestCase {
protected Class originalIdentityMapClass;
protected int originalIdentityMapSize;
protected int identityMapSize = 10;
public InsertWeakIdentityMapTest() {
setDescription("Test if there is any memory leak in InsertObjectQuery with WeakIdentityMap.");
}
protected WeakIdentityMap getIdentityMap() {
return (WeakIdentityMap)getAbstractSession().getIdentityMapAccessorInstance().getIdentityMap(Employee.class);
}
@Override
public void reset() {
getSession().getDescriptor(Employee.class).setIdentityMapClass(originalIdentityMapClass);
getSession().getDescriptor(Employee.class).setIdentityMapSize(originalIdentityMapSize);
getSession().getIdentityMapAccessor().initializeIdentityMaps();
}
@Override
public void setup() {
originalIdentityMapClass = getSession().getDescriptor(Employee.class).getIdentityMapClass();
originalIdentityMapSize = getSession().getDescriptor(Employee.class).getIdentityMapSize();
getSession().getDescriptor(Employee.class).setIdentityMapClass(WeakIdentityMap.class);
getSession().getDescriptor(Employee.class).setIdentityMapSize(identityMapSize);
getSession().getIdentityMapAccessor().initializeIdentityMaps();
}
@Override
public void test() {
for (int index = 0; index < (identityMapSize * 2); index++) {
Employee obj = new Employee();
InsertObjectQuery query = new InsertObjectQuery(obj);
getAbstractSession().beginTransaction();
getSession().executeQuery(query);
getAbstractSession().rollbackTransaction();
System.gc();
}
System.gc();
}
@Override
public void verify() {
// Force full GC.
for (int loops = 0; loops < 10; loops++) {
// The jdk1.2.0 on the Testing machine treats the weak reference as a softweak reference so we must waste memory
Vector vector = new Vector(50000);
for (int i = 0; i < 50000; i++) {
vector.add(new java.math.BigDecimal(i));
}
// Force garbage collection, which should clear the cache.
System.gc();
System.runFinalization();
}
// Check to see if maximum size was maintained. The maximum size is identityMapSize + 2, because System.gc()
//inside the for block does not garbage collect the object just inserted, also in put(CacheKey) method of WeakIdentityMap
//it checks if (getCleanupCount() > getMaxSize()) instead of =, which adds one more.
int maxSize = identityMapSize + 2;
if (getIdentityMap().getSize() > maxSize) {
throw new TestErrorException("Weak identity map " + getIdentityMap() + " contains " +
getIdentityMap().getSize() + " objects. " +
"The specified maximum size for this cache was " + maxSize + ".");
}
// Check that all the CacheReferences (WeakCacheReferences) are null, since
// they all should have been garbage collected.
Map<Object, CacheKey> cache = getIdentityMap().getCacheKeys();
for (Iterator<CacheKey> iterator = cache.values().iterator(); iterator.hasNext(); ) {
CacheKey key = iterator.next();
if (key.getObject() != null) {
throw new TestErrorException("A WeakCacheKey with a non-empty WeakReference was found. The garbage collection did not clear the cache as expected.");
}
}
}
}