stress tests workloads reduced to speedup community tests

This commit is contained in:
Alexey Kudravtsev
2018-08-01 16:36:19 +03:00
parent 4b38facc17
commit aa9efdf94c
4 changed files with 38 additions and 61 deletions
@@ -333,7 +333,7 @@ public class PsiDocumentManagerImplTest extends PlatformTestCase {
assertEquals(StdFileTypes.JAVA.getLanguage(), file.getLanguage());
for (int i = 0; i < 300; i++) {
for (int i = 0; i < 30; i++) {
assertTrue("Still not committed: " + document, getPsiDocumentManager().isCommitted(document));
WriteCommandAction.runWriteCommandAction(null, () -> {
document.insertString(0, "/**/");
@@ -903,7 +903,7 @@ public class PsiDocumentManagerImplTest extends PlatformTestCase {
final Document document = getDocument(psiFile);
Random random = new Random();
for (int i=0; i<1000;i++) {
for (int i=0; i<100;i++) {
ApplicationManager.getApplication().runWriteAction(() -> {
@Language(value = "JAVA", prefix = "class c {", suffix = "}")
String body = "@NotNull\n" +
@@ -15,9 +15,13 @@
*/
package com.intellij.util.concurrency;
import com.intellij.diagnostic.ThreadDumper;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.EmptyRunnable;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.IntIntFunction;
import com.intellij.util.TimeoutUtil;
import com.intellij.util.TripleFunction;
import junit.framework.TestCase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.ide.PooledThreadExecutor;
@@ -27,6 +31,7 @@ import java.util.Random;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
public class BoundedScheduledExecutorTest extends TestCase {
private static final Logger LOG = Logger.getInstance(BoundedScheduledExecutorTest.class);
@@ -131,27 +136,39 @@ public class BoundedScheduledExecutorTest extends TestCase {
assertTrue(executor.awaitTermination(100, TimeUnit.SECONDS));
}
public void testStressWhenSomeTasksCallOtherTasksGet() throws ExecutionException, InterruptedException {
ExecutorService backendExecutor = AppExecutorUtil.getAppExecutorService();
for (int maxSimultaneousTasks = 1; maxSimultaneousTasks<20; maxSimultaneousTasks++) {
public void testStressWhenSomeTasksCallOtherTasksGet() throws Exception {
doTestBoundedExecutor(
getName(),
(backendExecutor, maxSimultaneousTasks) -> createBoundedScheduledExecutor(backendExecutor, maxSimultaneousTasks),
maxSimultaneousTasks -> 1000,
(executor, runnable, i)-> ((BoundedScheduledExecutorService)executor).schedule(runnable, i % 10, TimeUnit.MILLISECONDS));
}
static void doTestBoundedExecutor(String testName,
BiFunction<ExecutorService, Integer, ? extends ExecutorService> executorCreator,
IntIntFunction numberOfFuturesComputer,
TripleFunction<ExecutorService, Runnable, Integer, Future<?>> executorScheduler) throws Exception {
ExecutorService backendExecutor = Executors.newCachedThreadPool(ConcurrencyUtil.newNamedThreadFactory(testName));
for (int maxSimultaneousTasks = 1; maxSimultaneousTasks < 20; maxSimultaneousTasks++) {
LOG.debug("maxSimultaneousTasks = " + maxSimultaneousTasks);
BoundedScheduledExecutorService executor = createBoundedScheduledExecutor(backendExecutor, maxSimultaneousTasks);
ExecutorService executor = executorCreator.apply(backendExecutor, maxSimultaneousTasks);
AtomicInteger running = new AtomicInteger();
AtomicInteger maxThreads = new AtomicInteger();
AtomicInteger availableThreads = new AtomicInteger(maxSimultaneousTasks); // to avoid deadlocks when trying to wait inside the pool thread
AtomicInteger availableThreads =
new AtomicInteger(maxSimultaneousTasks); // to avoid deadlocks when trying to wait inside the pool thread
try {
int N = 1000;
int N = numberOfFuturesComputer.fun(maxSimultaneousTasks);
Future[] futures = new Future[N];
Random random = new Random();
for (int i = 0; i < N; i++) {
final int finalI = i;
final int finalMaxSimultaneousTasks = maxSimultaneousTasks;
futures[i] = executor.schedule(() -> {
int maxDelayMs = Math.min(5, maxSimultaneousTasks);
Runnable runnable = () -> {
maxThreads.accumulateAndGet(running.incrementAndGet(), Math::max);
try {
int r = random.nextInt(finalMaxSimultaneousTasks);
int r = random.nextInt(maxDelayMs);
int prev = finalI - r;
if (prev < finalI && prev >= 0) {
if (availableThreads.decrementAndGet() > 0) {
@@ -169,7 +186,8 @@ public class BoundedScheduledExecutorTest extends TestCase {
finally {
running.decrementAndGet();
}
}, i % 10, TimeUnit.MILLISECONDS);
};
futures[i] = executorScheduler.fun(executor, runnable, i);
}
for (Future future : futures) {
future.get();
@@ -177,10 +195,10 @@ public class BoundedScheduledExecutorTest extends TestCase {
}
finally {
executor.shutdownNow();
assertTrue(executor.awaitTermination(100, TimeUnit.SECONDS));
if (!executor.awaitTermination(100, TimeUnit.SECONDS)) fail(ThreadDumper.dumpThreadsToString());
}
assertTrue("Max threads was: "+maxThreads+" but bound was: "+maxSimultaneousTasks, maxThreads.get() <= maxSimultaneousTasks);
assertTrue("Max threads was: " + maxThreads + " but bound was: " + maxSimultaneousTasks, maxThreads.get() <= maxSimultaneousTasks);
}
}
@@ -150,51 +150,13 @@ public class BoundedTaskExecutorTest extends TestCase {
if (!backendExecutor.awaitTermination(100, TimeUnit.SECONDS)) fail(ThreadDumper.dumpThreadsToString());
}
public void testStressWhenSomeTasksCallOtherTasksGet() throws InterruptedException {
ExecutorService backendExecutor = Executors.newCachedThreadPool(ConcurrencyUtil.newNamedThreadFactory(getName()));
for (int maxSimultaneousTasks = 1; maxSimultaneousTasks<20; maxSimultaneousTasks++) {
ExecutorService executor = AppExecutorUtil.createBoundedApplicationPoolExecutor(getName(), backendExecutor, maxSimultaneousTasks);
AtomicInteger running = new AtomicInteger();
AtomicInteger maxThreads = new AtomicInteger();
public void testStressWhenSomeTasksCallOtherTasksGet() throws Exception {
BoundedScheduledExecutorTest.doTestBoundedExecutor(
getName(),
(backendExecutor, maxSimultaneousTasks) -> AppExecutorUtil.createBoundedApplicationPoolExecutor(getName(), backendExecutor, maxSimultaneousTasks),
maxSimultaneousTasks -> 3000,
(executor, runnable, i)-> executor.submit(runnable));
int N = 5000;
Future[] futures = new Future[N];
Random random = new Random();
for (int i = 0; i < N; i++) {
final int finalI = i;
final int finalMaxSimultaneousTasks = maxSimultaneousTasks;
futures[i] = executor.submit(() -> {
maxThreads.accumulateAndGet(running.incrementAndGet(), Math::max);
try {
int r = random.nextInt(finalMaxSimultaneousTasks);
int prev = finalI - r;
if (prev < finalI && prev >= 0) {
try {
futures[prev].get();
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
TimeoutUtil.sleep(r);
}
finally {
running.decrementAndGet();
}
});
}
executor.shutdown();
if (!executor.awaitTermination(100, TimeUnit.SECONDS)) fail(ThreadDumper.dumpThreadsToString());
for (Future future : futures) {
assertTrue(future.isDone());
}
assertTrue("Max threads was: "+maxThreads+" but bound was: "+maxSimultaneousTasks, maxThreads.get() <= maxSimultaneousTasks);
}
backendExecutor.shutdownNow();
if (!backendExecutor.awaitTermination(100, TimeUnit.SECONDS)) fail(ThreadDumper.dumpThreadsToString());
}
public void testSequentialSubmitsMustExecuteSequentially() throws ExecutionException, InterruptedException {
@@ -166,7 +166,6 @@ public class ContainerUtilCollectionsTest {
assertNull(map.get(strong));
GCUtil.tryGcSoftlyReachableObjects();
System.gc();
}
while (map.size() != 0);
assertTrue(map.isEmpty());
@@ -192,7 +191,6 @@ public class ContainerUtilCollectionsTest {
assertEquals(0, map.get(strong));
GCUtil.tryGcSoftlyReachableObjects();
System.gc();
}
while (map.size() != 0);
assertTrue(map.isEmpty());
@@ -218,7 +216,6 @@ public class ContainerUtilCollectionsTest {
assertNull(map.get(RANDOM_INT));
GCUtil.tryGcSoftlyReachableObjects();
System.gc();
}
while (map.size() != 0);
assertTrue(map.isEmpty());