blob: e13114d0ef046d3e5acac0394d6f0f3ac569fdba [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.clientserver;
import org.eclipse.persistence.testing.framework.*;
import org.eclipse.persistence.sessions.*;
import org.eclipse.persistence.exceptions.*;
import org.eclipse.persistence.sessions.DatabaseLogin;
@SuppressWarnings("deprecation")
public class ConcurrentTestWithReadLocks extends org.eclipse.persistence.testing.framework.AutoVerifyTestCase {
public static int numThreads = 8;
public boolean isCheckerThread;
public static Server server;
public static boolean execute = true;
public static Thread[] threadList = new Thread[numThreads];
public static long[] timeList = new long[numThreads];
public static long runTime;
public int index;
public ConcurrentTestWithReadLocks(long runtime) {
setDescription("Test Simulates a highly concurrent situation with ReadLocks");
ConcurrentTestWithReadLocks.runTime = runtime;
}
protected ConcurrentTestWithReadLocks(boolean checkerThread, int index) {
this.isCheckerThread = checkerThread;
this.index = index;
}
@Override
public void reset() {
ConcurrentTestWithReadLocks.execute = false;
for (int count = 0; count < numThreads; ++count) {
try {
ConcurrentTestWithReadLocks.threadList[count].join();
} catch (InterruptedException ex) {
throw new TestProblemException("Test thread was interrupted. Test failed to run properly");
}
}
ConcurrentTestWithReadLocks.server.logout();
}
@Override
public void setup() {
ConcurrentTestWithReadLocks.execute = true;
try {
getSession().getLog().write("WARNING, some tests may take 3 minutes or more");
getSession().getLog().flush();
} catch (java.io.IOException e) {
}
try {
DatabaseLogin login = (DatabaseLogin)getSession().getLogin().clone();
ConcurrentTestWithReadLocks.server = new Server(login, numThreads, numThreads + 2);
ConcurrentTestWithReadLocks.server.serverSession.setSessionLog(getSession().getSessionLog());
ConcurrentTestWithReadLocks.server.login();
ConcurrentTestWithReadLocks.server.copyDescriptors(getSession());
} catch (ValidationException ex) {
this.verify();
}
for (int count = 0; count < numThreads; ++count) {
ConcurrentTestWithReadLocks.threadList[count] = new Thread(new ConcurrentTestWithReadLocks(false, count).runnable());
ConcurrentTestWithReadLocks.timeList[count] = System.currentTimeMillis();
}
}
@Override
public void test() {
for (int count = 0; count < numThreads; ++count) {
ConcurrentTestWithReadLocks.threadList[count].start();
}
Thread checker = new Thread(new ConcurrentTestWithReadLocks(true, -1).runnable());
checker.start();
try {
checker.join();
} catch (InterruptedException ex) {
throw new TestProblemException("Test thread was interrupted. Test failed to run properly");
}
}
@Override
public void verify() {
if (!execute) {
for (int count = 0; count < numThreads; ++count) {
threadList[count].stop();
}
getSession().getIdentityMapAccessor().initializeAllIdentityMaps();
throw new TestErrorException("This test caused a deadlock in TopLink. see bug 3049635");
}
}
public Runnable runnable() {
return new Runnable() {
// This section represents the executing threads
// If the type is set to checker then this set the thread
// to watch the other threads for deadlock. If none occurs then
// the test will time out.
@Override
public void run() {
if (org.eclipse.persistence.testing.tests.clientserver.ConcurrentTestWithReadLocks.this.isCheckerThread) {
watchOtherThreads();
} else {
executeUntilStopped();
}
}
};
}
public void watchOtherThreads() {
long startTime = System.currentTimeMillis();
while (((System.currentTimeMillis() - startTime) < (runTime + 30000)) && ConcurrentTestWithReadLocks.execute) {
for (int localIdex = 0; localIdex < numThreads; ++localIdex) {
if ((System.currentTimeMillis() - ConcurrentTestWithReadLocks.timeList[localIdex]) > 30000) {
execute = false;
break;
}
}
try {
Thread.sleep(30000);
} catch (InterruptedException ex) {
throw new TestProblemException("Test thread was interrupted. Test failed to run properly");
}
}
}
public void executeUntilStopped() {
Session session = ConcurrentTestWithReadLocks.server.serverSession.acquireClientSession();
DeadLockEmployee employee = (DeadLockEmployee)session.readObject(DeadLockEmployee.class);
// session.release();
while (ConcurrentTestWithReadLocks.execute) {
// session = this.server.serverSession.acquireClientSession();
ConcurrentTestWithReadLocks.timeList[this.index] = System.currentTimeMillis();
/* Aquire Unit Of Work */
UnitOfWork uow = session.acquireUnitOfWork();
/* Register */
DeadLockEmployee workingEmp = (DeadLockEmployee)uow.registerObject(employee);
/* make an Refresh */
uow.refreshObject(workingEmp);
uow.commit();
}
}
}