use unified reader for test discovery data

This commit is contained in:
Dmitry Batkovich
2018-02-16 15:19:58 +03:00
parent 0a26b30c82
commit 2c1521770b
5 changed files with 130 additions and 167 deletions
@@ -1,56 +0,0 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.execution.testDiscovery;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.rt.coverage.data.SocketTestDataReader;
import com.intellij.util.containers.MultiMap;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.annotations.NotNull;
class IdeaSocketTestDiscoveryDataReader extends SocketTestDataReader {
private static final Logger LOG = Logger.getInstance(IdeaSocketTestDiscoveryDataReader.class);
@NotNull
private final TIntObjectHashMap<String> myTestExecutionNameEnumerator;
//test data
private String myTestName;
private final MultiMap<String, String> myUsedMethods = new MultiMap<>();
IdeaSocketTestDiscoveryDataReader(@NotNull TIntObjectHashMap<String> testExecutionNameEnumerator) {
myTestExecutionNameEnumerator = testExecutionNameEnumerator;
}
@NotNull
String getTestName() {
return myTestName;
}
@NotNull
MultiMap<String, String> getUsedMethods() {
return myUsedMethods;
}
@Override
protected void processTestName(int testClassId, int testMethodId) {
myTestName = myTestExecutionNameEnumerator.get(testClassId) + "-" + myTestExecutionNameEnumerator.get(testMethodId);
}
@Override
protected void processEnumeratedName(int id, String name) {
String previousName = myTestExecutionNameEnumerator.put(id, name);
LOG.assertTrue(previousName == null || previousName.equals(name));
}
@Override
protected void processUsedMethod(int classInternalId, int methodInternalId) {
String className = myTestExecutionNameEnumerator.get(classInternalId);
String methodName = myTestExecutionNameEnumerator.get(methodInternalId);
if (className == null || methodName == null) {
LOG.error("Inconsistent state");
return;
}
myUsedMethods.putValue(className, methodName);
}
}
@@ -0,0 +1,117 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.execution.testDiscovery;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.rt.coverage.data.api.TestDiscoveryProtocolReader;
import com.intellij.util.containers.MultiMap;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
class IdeaTestDiscoveryProtocolReader implements TestDiscoveryProtocolReader, TestDiscoveryProtocolReader.NameEnumeratorReader {
private static final Logger LOG = Logger.getInstance(IdeaTestDiscoveryProtocolReader.class);
@NotNull
private final TIntObjectHashMap<String> myTestExecutionNameEnumerator = new TIntObjectHashMap<>();
@NotNull
private final TestDiscoveryIndex myIndex;
private final String myModuleName;
private final String myFrameworkPrefix;
IdeaTestDiscoveryProtocolReader(@NotNull TestDiscoveryIndex index,
@Nullable String moduleName,
@NotNull String frameworkPrefix) {
myIndex = index;
myModuleName = moduleName;
myFrameworkPrefix = frameworkPrefix;
}
@Override
public void testDiscoveryDataProcessingStarted(int version) {
}
@Override
public void testDiscoveryDataProcessingFinished() {
}
@Override
public MetadataReader createMetadataReader() {
return new MetadataReader() {
@Override
public void processMetadataEntry(String s, String s1) {
// do nothing
}
};
}
@Override
public NameEnumeratorReader createNameEnumeratorReader() {
return this;
}
@Override
public TestDataReader createTestDataReader(int testClassId, int testMethodId) {
return new TestDataReader() {
private final String myTestName = myTestExecutionNameEnumerator.get(testClassId) + "-" + myTestExecutionNameEnumerator.get(testMethodId);
private final MultiMap<String, String> myUsedMethods = new MultiMap<>();
private int myCurrentClassId;
@Override
public void classProcessingStarted(int classId) {
myCurrentClassId = classId;
}
@Override
public void processUsedMethod(int methodId) {
String className = myTestExecutionNameEnumerator.get(myCurrentClassId);
String methodName = myTestExecutionNameEnumerator.get(methodId);
if (className == null || methodName == null) {
LOG.error("Inconsistent state");
return;
}
myUsedMethods.putValue(className, methodName);
}
@Override
public void classProcessingFinished(int classId) {
myCurrentClassId = -1;
}
@Override
public void testDataProcessed() {
try {
myIndex.updateFromData(myTestName, myUsedMethods, myModuleName, myFrameworkPrefix);
}
catch (IOException e) {
LOG.error(e);
}
}
};
}
@Override
public void debug(String message) {
LOG.debug(message);
}
@Override
public void error(String message) {
LOG.error(message);
}
@Override
public void error(Exception exception) {
LOG.error(exception);
}
@Override
public void enumerate(String name, int id) {
String previousName = myTestExecutionNameEnumerator.put(id, name);
LOG.assertTrue(previousName == null || previousName.equals(name));
}
}
@@ -1,57 +0,0 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.execution.testDiscovery;
import com.intellij.rt.coverage.data.SingleTrFileReader;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.io.IOException;
class IdeaTrFileTestDataReader extends SingleTrFileReader {
private String myCurrentClassName;
private MultiMap<String, String> myUsedMethods = new MultiMap<>();
private final TestDiscoveryIndex myIndex;
private final String myModuleName;
private final String myFrameworkPrefix;
public IdeaTrFileTestDataReader(@NotNull File file,
@NotNull TestDiscoveryIndex index,
@NotNull String moduleName,
@NotNull String frameworkPrefix) {
super(file);
myIndex = index;
myModuleName = moduleName;
myFrameworkPrefix = frameworkPrefix;
}
@Override
protected void testProcessingFinished(String testName) {
// flush
try {
int separatorIndex = testName.lastIndexOf('.');
testName = testName.substring(0, separatorIndex) + "-" + testName.substring(separatorIndex + 1);
myIndex.updateFromData(testName, myUsedMethods, myModuleName, myFrameworkPrefix);
}
catch (IOException e) {
throw new RuntimeException(e);
}
myUsedMethods.clear();
}
@Override
protected void classProcessingFinished(String className) {
myCurrentClassName = null;
}
@Override
protected void processMethodName(String methodName) {
myUsedMethods.putValue(myCurrentClassName, methodName);
}
@Override
protected void classProcessingStarted(String className) {
myCurrentClassName = className;
}
}
@@ -4,15 +4,12 @@ package com.intellij.execution.testDiscovery;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.rt.coverage.data.SocketTestDataReader;
import com.intellij.rt.coverage.data.SocketTestDiscoveryProtocolDataListener;
import com.intellij.rt.coverage.data.TestDiscoveryProtocolDataListener;
import com.intellij.rt.coverage.data.api.TestDiscoveryProtocolUtil;
import com.intellij.util.TimeoutUtil;
import gnu.trove.TIntObjectHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
@@ -26,7 +23,6 @@ public class TestDiscoveryDataSocketListener {
private final ServerSocket myServer;
private final int myPort;
private final TestDiscoveryIndex myTestDiscoveryIndex;
private final TIntObjectHashMap<String> myTestExecutionNameEnumerator = new TIntObjectHashMap<>();
private volatile boolean myCloseForcibly;
private volatile boolean myStarted;
@@ -60,10 +56,19 @@ public class TestDiscoveryDataSocketListener {
}
try {
listenForFinishedTests(socket);
InputStream testDataStream = socket.getInputStream();
IdeaTestDiscoveryProtocolReader protocolReader = new IdeaTestDiscoveryProtocolReader(myTestDiscoveryIndex, myModuleName, myFrameworkPrefix);
TestDiscoveryProtocolUtil.readSequentially(testDataStream, protocolReader);
}
catch (IOException e) {
LOG.error(e);
} finally {
try {
socket.close();
}
catch (IOException e) {
LOG.error(e);
}
}
});
@@ -72,53 +77,6 @@ public class TestDiscoveryDataSocketListener {
}
}
private void listenForFinishedTests(@NotNull Socket socket) throws IOException {
InputStream testDataStream = socket.getInputStream();
while (true) {
byte msgType = (byte)testDataStream.read();
switch (msgType) {
case TestDiscoveryProtocolDataListener.START_MARKER:
int version = testDataStream.read();
LOG.assertTrue(version == SocketTestDiscoveryProtocolDataListener.VERSION);
LOG.debug("test discovery started");
break;
case TestDiscoveryProtocolDataListener.FINISH_MARKER:
LOG.debug("test discovery finished");
socket.close();
myServer.close();
return;
case TestDiscoveryProtocolDataListener.NAMES_DICTIONARY_PART_MARKER:
LOG.info("name enumerator part received");
SocketTestDataReader.readDictionary(new DataInputStream(testDataStream), new SocketTestDataReader() {
@Override
protected void processTestName(int testClassId, int testMethodId) {
throw new UnsupportedOperationException();
}
@Override
protected void processUsedMethod(int classId, int methodId) {
throw new UnsupportedOperationException();
}
@Override
protected void processEnumeratedName(int id, String name) {
String previousName = myTestExecutionNameEnumerator.put(id, name);
LOG.assertTrue(previousName == null || name.equals(previousName));
}
});
break;
case TestDiscoveryProtocolDataListener.TEST_FINISHED_MARKER:
LOG.info("test data received");
IdeaSocketTestDiscoveryDataReader reader = new IdeaSocketTestDiscoveryDataReader(myTestExecutionNameEnumerator);
SocketTestDataReader.readTestData(new DataInputStream(testDataStream), reader);
myTestDiscoveryIndex.updateFromData(reader.getTestName(), reader.getUsedMethods(), myModuleName, myFrameworkPrefix);
break;
}
}
}
public int getPort() {
return myPort;
}
@@ -24,6 +24,7 @@ import com.intellij.openapi.util.registry.Registry;
import com.intellij.rt.coverage.data.SingleTrFileDiscoveryProtocolDataListener;
import com.intellij.rt.coverage.data.SocketTestDiscoveryProtocolDataListener;
import com.intellij.rt.coverage.data.TestDiscoveryProjectData;
import com.intellij.rt.coverage.data.api.TestDiscoveryProtocolUtil;
import com.intellij.rt.coverage.main.CoveragePremain;
import com.intellij.util.Alarm;
import com.intellij.util.PathUtil;
@@ -157,7 +158,7 @@ public class TestDiscoveryExtension extends RunConfigurationExtension {
final File tracesFile = new File(tracesFilePath);
synchronized (ourTracesLock) {
try {
new IdeaTrFileTestDataReader(tracesFile, discoveryIndex, moduleName, frameworkPrefix).read();
TestDiscoveryProtocolUtil.readFile(tracesFile, new IdeaTestDiscoveryProtocolReader(discoveryIndex, moduleName, frameworkPrefix));
}
catch (IOException e) {
LOG.error("Can not load " + tracesFilePath, e);