test discovery: process collected traces during test run

This commit is contained in:
Anna Kozlova
2015-07-21 08:51:18 +02:00
parent af596a12d5
commit 16994effc3
4 changed files with 85 additions and 24 deletions
@@ -117,11 +117,15 @@ public abstract class JavaTestFrameworkRunnableState<T extends ModuleBasedConfig
final OSProcessHandler handler = createHandler(executor);
consoleView.attachToProcess(handler);
final AbstractTestProxy root = viewer.getRoot();
if (root instanceof TestProxyRoot) {
((TestProxyRoot)root).setHandler(handler);
}
handler.addProcessListener(new ProcessAdapter() {
@Override
public void startNotified(ProcessEvent event) {
if (getConfiguration().isSaveOutputToFile()) {
viewer.getRoot().setOutputFilePath(getConfiguration().getOutputFilePath());
root.setOutputFilePath(getConfiguration().getOutputFilePath());
}
}
@@ -129,7 +133,7 @@ public abstract class JavaTestFrameworkRunnableState<T extends ModuleBasedConfig
public void processTerminated(ProcessEvent event) {
Runnable runnable = new Runnable() {
public void run() {
viewer.getRoot().flush();
root.flush();
deleteTempFiles();
clear();
}
@@ -21,18 +21,22 @@ import com.intellij.execution.TestDiscoveryListener;
import com.intellij.execution.configurations.JavaParameters;
import com.intellij.execution.configurations.RunConfigurationBase;
import com.intellij.execution.configurations.RunnerSettings;
import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.testframework.sm.runner.SMTRunnerEventsAdapter;
import com.intellij.execution.testframework.sm.runner.SMTRunnerEventsListener;
import com.intellij.execution.testframework.sm.runner.SMTestProxy;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.util.Alarm;
import com.intellij.util.PathUtil;
import com.intellij.util.messages.MessageBusConnection;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -66,30 +70,35 @@ public class TestDiscoveryExtension extends RunConfigurationExtension {
@NotNull final ProcessHandler handler,
@Nullable RunnerSettings runnerSettings) {
if (runnerSettings == null && isApplicableFor(configuration)) {
handler.addProcessListener(new ProcessAdapter() {
final Alarm processTracesAlarm = new Alarm(Alarm.ThreadToUse.POOLED_THREAD, null);
final MessageBusConnection connection = configuration.getProject().getMessageBus().connect();
connection.subscribe(SMTRunnerEventsListener.TEST_STATUS, new SMTRunnerEventsAdapter() {
@Override
public void processTerminated(ProcessEvent event) {
final String tracesDirectory = getTracesDirectory(configuration);
final TestDiscoveryIndex coverageIndex = TestDiscoveryIndex.getInstance(configuration.getProject());
final File[] testMethodTraces = new File(tracesDirectory).listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".tr");
}
});
if (testMethodTraces != null) {
for (File testMethodTrace : testMethodTraces) {
try {
coverageIndex.updateFromTestTrace(testMethodTrace);
FileUtil.delete(testMethodTrace);
public void onTestFinished(@NotNull SMTestProxy test) {
final SMTestProxy.SMRootTestProxy root = test.getRoot();
if ((root == null || root.getHandler() == handler) && processTracesAlarm.getActiveRequestCount() == 0) {
processTracesAlarm.addRequest(new Runnable() {
@Override
public void run() {
processAvailableTraces(configuration);
}
catch (IOException e) {
LOG.error("Can not load " + testMethodTrace, e);
}, 200);
}
}
@Override
public void onTestingFinished(@NotNull SMTestProxy.SMRootTestProxy testsRoot) {
if (testsRoot.getHandler() == handler) {
processTracesAlarm.cancelAllRequests();
processTracesAlarm.addRequest(new Runnable() {
@Override
public void run() {
processAvailableTraces(configuration);
Disposer.dispose(processTracesAlarm);
}
}
}, 0);
connection.disconnect();
}
handler.removeProcessListener(this);
}
});
}
@@ -133,4 +142,29 @@ public class TestDiscoveryExtension extends RunConfigurationExtension {
public static String baseTestDiscoveryPathForProject(Project project) {
return PathManager.getSystemPath() + File.separator + "testDiscovery" + File.separator + project.getName() + "." + project.getLocationHash();
}
private static final Object ourTracesLock = new Object();
private static void processAvailableTraces(RunConfigurationBase configuration) {
final String tracesDirectory = getTracesDirectory(configuration);
final TestDiscoveryIndex coverageIndex = TestDiscoveryIndex.getInstance(configuration.getProject());
synchronized (ourTracesLock) {
final File[] testMethodTraces = new File(tracesDirectory).listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".tr");
}
});
if (testMethodTraces != null) {
for (File testMethodTrace : testMethodTraces) {
try {
coverageIndex.updateFromTestTrace(testMethodTrace);
FileUtil.delete(testMethodTrace);
}
catch (IOException e) {
LOG.error("Can not load " + testMethodTrace, e);
}
}
}
}
}
}
@@ -16,6 +16,7 @@
package com.intellij.execution.testframework.sm.runner;
import com.intellij.execution.Location;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.testframework.*;
import com.intellij.execution.testframework.sm.SMStacktraceParser;
import com.intellij.execution.testframework.sm.SMStacktraceParserEx;
@@ -785,6 +786,14 @@ public class SMTestProxy extends AbstractTestProxy {
containerSuite.invalidateCachedDurationForContainerSuites();
}
}
public SMRootTestProxy getRoot() {
SMTestProxy parent = getParent();
while (parent != null && !(parent instanceof SMRootTestProxy)) {
parent = parent.getParent();
}
return parent instanceof SMRootTestProxy ? (SMRootTestProxy)parent : null;
}
public static class SMRootTestProxy extends SMTestProxy implements TestProxyRoot {
private boolean myTestsReporterAttached; // false by default
@@ -792,6 +801,7 @@ public class SMTestProxy extends AbstractTestProxy {
private String myPresentation;
private String myComment;
private String myRootLocationUrl;
private ProcessHandler myHandler;
public SMRootTestProxy() {
super("[root]", true, null);
@@ -832,6 +842,15 @@ public class SMTestProxy extends AbstractTestProxy {
return myRootLocationUrl;
}
public ProcessHandler getHandler() {
return myHandler;
}
@Override
public void setHandler(ProcessHandler handler) {
myHandler = handler;
}
@Nullable
@Override
public Location getLocation(@NotNull Project project, @NotNull GlobalSearchScope searchScope) {
@@ -15,10 +15,14 @@
*/
package com.intellij.execution.testframework;
import com.intellij.execution.process.ProcessHandler;
public interface TestProxyRoot {
String getPresentation();
String getComment();
String getRootLocation();
void setHandler(ProcessHandler handler);
}