mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
sm junit: parallel execution for tests (IDEA-148602)
This commit is contained in:
+63
-3
@@ -367,7 +367,9 @@ public class JUnitTreeByDescriptionHierarchyTest {
|
||||
sender.testRunStarted(testA);
|
||||
final Exception exception = new Exception();
|
||||
exception.setStackTrace(new StackTraceElement[0]);
|
||||
sender.testStarted(testA);
|
||||
sender.testAssumptionFailure(new Failure(testA, exception));
|
||||
sender.testFinished(testA);
|
||||
sender.testRunFinished(new Result());
|
||||
|
||||
Assert.assertEquals("output: " + buf, "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
|
||||
@@ -404,7 +406,9 @@ public class JUnitTreeByDescriptionHierarchyTest {
|
||||
sender.testRunStarted(testA);
|
||||
final Exception exception = new Exception();
|
||||
exception.setStackTrace(new StackTraceElement[0]);
|
||||
sender.testStarted(testA);
|
||||
sender.testFailure(new Failure(testA, exception));
|
||||
sender.testFinished(testA);
|
||||
sender.testRunFinished(new Result());
|
||||
|
||||
Assert.assertEquals("output: " + buf, "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
|
||||
@@ -422,7 +426,52 @@ public class JUnitTreeByDescriptionHierarchyTest {
|
||||
"##teamcity[testFinished name='TestA.testName']\n" +
|
||||
"##teamcity[testSuiteFinished name='TestA']\n", StringUtil.convertLineSeparators(buf.toString()));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testParallelExecution() throws Exception {
|
||||
final Description root = Description.createSuiteDescription("root");
|
||||
Description testA = Description.createTestDescription("TestA", "test1");
|
||||
root.addChild(testA);
|
||||
|
||||
Description testB = Description.createTestDescription("TestB", "test2");
|
||||
root.addChild(testB);
|
||||
|
||||
final StringBuffer buf = new StringBuffer();
|
||||
final JUnit4TestListener sender = createListener(buf);
|
||||
sender.sendTree(root);
|
||||
|
||||
Assert.assertEquals("output: " + buf, "##teamcity[enteredTheMatrix]\n" +
|
||||
"##teamcity[suiteTreeNode name='TestA.test1' locationHint='java:test://TestA.test1']\n" +
|
||||
"##teamcity[suiteTreeNode name='TestB.test2' locationHint='java:test://TestB.test2']\n" +
|
||||
"##teamcity[treeEnded]\n", StringUtil.convertLineSeparators(buf.toString()));
|
||||
|
||||
buf.setLength(0);
|
||||
|
||||
sender.testRunStarted(root);
|
||||
sender.testStarted(testA);
|
||||
|
||||
sender.testStarted(testB);
|
||||
sender.testFinished(testB);
|
||||
|
||||
final Exception exception = new Exception();
|
||||
exception.setStackTrace(new StackTraceElement[0]);
|
||||
sender.testFailure(new Failure(testA, exception));
|
||||
sender.testFinished(testA);
|
||||
sender.testRunFinished(new Result());
|
||||
|
||||
Assert.assertEquals("output: " + buf, "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
|
||||
"\n" +
|
||||
"##teamcity[testStarted name='TestA.test1' locationHint='java:test://TestA.test1']\n" +
|
||||
"\n" +
|
||||
"##teamcity[testFailed name='TestA.test1' details='java.lang.Exception|n' error='true' message='']\n" +
|
||||
"\n" +
|
||||
"##teamcity[testFinished name='TestA.test1']\n" +
|
||||
"\n" +
|
||||
"##teamcity[testStarted name='TestB.test2' locationHint='java:test://TestB.test2']\n" +
|
||||
"\n" +
|
||||
"##teamcity[testFinished name='TestB.test2']\n", StringUtil.convertLineSeparators(buf.toString()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTearDownClassFailure() throws Exception {
|
||||
final Description root = Description.createSuiteDescription("root");
|
||||
@@ -448,7 +497,9 @@ public class JUnitTreeByDescriptionHierarchyTest {
|
||||
exception.setStackTrace(new StackTraceElement[0]);
|
||||
sender.testStarted(testName);
|
||||
sender.testFinished(testName);
|
||||
sender.testStarted(testA);
|
||||
sender.testFailure(new Failure(testA, exception));
|
||||
sender.testFinished(testA);
|
||||
sender.testRunFinished(new Result());
|
||||
|
||||
Assert.assertEquals("output: " + buf, "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
|
||||
@@ -492,7 +543,9 @@ public class JUnitTreeByDescriptionHierarchyTest {
|
||||
sender.testRunStarted(testA);
|
||||
final Exception exception = new Exception();
|
||||
exception.setStackTrace(new StackTraceElement[0]);
|
||||
sender.testStarted(testA);
|
||||
sender.testAssumptionFailure(new Failure(testA, exception));
|
||||
sender.testFinished(testA);
|
||||
sender.testRunFinished(new Result());
|
||||
|
||||
Assert.assertEquals("output: " + buf, "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
|
||||
@@ -508,14 +561,21 @@ public class JUnitTreeByDescriptionHierarchyTest {
|
||||
"##teamcity[testSuiteFinished name='TestA']\n", StringUtil.convertLineSeparators(buf.toString()));
|
||||
buf.setLength(0);
|
||||
|
||||
//testStarted and testFinished are called by the framework
|
||||
sender.testRunStarted(testA);
|
||||
sender.testStarted(testName);
|
||||
sender.testAssumptionFailure(new Failure(testName, exception));
|
||||
sender.testFinished(testName);
|
||||
sender.testRunFinished(new Result());
|
||||
|
||||
Assert.assertEquals("output: " + buf, "##teamcity[rootName name = 'root' location = 'java:suite://root']\n" +
|
||||
"##teamcity[testSuiteStarted name='TestA']\n" +
|
||||
"\n" +
|
||||
"##teamcity[testIgnored name='TestA.testName' details='java.lang.Exception|n' error='true' message='']\n", StringUtil.convertLineSeparators(buf.toString()));
|
||||
"##teamcity[testStarted name='TestA.testName' locationHint='java:test://TestA.testName']\n" +
|
||||
"\n" +
|
||||
"##teamcity[testIgnored name='TestA.testName' details='java.lang.Exception|n' error='true' message='']\n" +
|
||||
"\n" +
|
||||
"##teamcity[testFinished name='TestA.testName']\n" +
|
||||
"##teamcity[testSuiteFinished name='TestA']\n", StringUtil.convertLineSeparators(buf.toString()));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,10 @@ public class JUnit4TestListener extends RunListener {
|
||||
private long myCurrentTestStart;
|
||||
private int myFinishedCount = 0;
|
||||
|
||||
private Description myCurrentTest;
|
||||
private Map myWaitingQueue = new LinkedHashMap();
|
||||
|
||||
|
||||
public JUnit4TestListener() {
|
||||
this(System.out);
|
||||
}
|
||||
@@ -77,7 +81,8 @@ public class JUnit4TestListener extends RunListener {
|
||||
}
|
||||
}
|
||||
|
||||
public void testRunFinished(Result result) throws Exception {
|
||||
public void testRunFinished(Result result) {
|
||||
dumpQueue();
|
||||
for (int i = myStartedSuites.size() - 1; i>= 0; i--) {
|
||||
Object parent = JUnit4ReflectionUtil.getClassName((Description)myStartedSuites.get(i));
|
||||
myPrintStream.println("##teamcity[testSuiteFinished name=\'" + escapeName(getShortName((String)parent)) + "\']");
|
||||
@@ -85,7 +90,14 @@ public class JUnit4TestListener extends RunListener {
|
||||
myStartedSuites.clear();
|
||||
}
|
||||
|
||||
public void testStarted(Description description) throws Exception {
|
||||
public void testStarted(Description description) {
|
||||
if (myCurrentTest != null) {
|
||||
myWaitingQueue.put(description, new TestEvent());
|
||||
return;
|
||||
}
|
||||
|
||||
myCurrentTest = description;
|
||||
|
||||
final String classFQN = JUnit4ReflectionUtil.getClassName(description);
|
||||
|
||||
final List parents = (List)myParents.get(description);
|
||||
@@ -148,7 +160,32 @@ public class JUnit4TestListener extends RunListener {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public void testFinished(Description description) throws Exception {
|
||||
public void testFinished(Description description) {
|
||||
if (startedInParallel(description)) {
|
||||
TestEvent testEvent = (TestEvent)myWaitingQueue.get(description);
|
||||
testEvent.setFinished(true);
|
||||
return;
|
||||
}
|
||||
testFinishedNoDumping(description);
|
||||
|
||||
dumpQueue();
|
||||
}
|
||||
|
||||
/**
|
||||
* <code>myCurrentTest == null</code> means that initially started test was already finished but no new test were started:
|
||||
* test1 started | myCurrentTest == test1
|
||||
* test2 started | myWaitingQueue contains test2
|
||||
* test1 finished | myCurrentTest == null
|
||||
* test2 finished | testEvent from myWaitingQueue is marked as finished. Next dumping would dump test2 started/test2 finished
|
||||
*
|
||||
* <code>myCurrentTest.equals(description)</code> means that finish/failure/ignore event was fired against last started test
|
||||
* if in the previous example test2 finishes before test1, then myCurrentTest != description, testEvent in myWaitingQueue needs to be updated
|
||||
*/
|
||||
private boolean startedInParallel(Description description) {
|
||||
return myCurrentTest == null || !myCurrentTest.equals(description);
|
||||
}
|
||||
|
||||
private void testFinishedNoDumping(Description description) {
|
||||
final String methodName = getFullMethodName(description);
|
||||
if (methodName != null) {
|
||||
myFinishedCount++;
|
||||
@@ -156,16 +193,27 @@ public class JUnit4TestListener extends RunListener {
|
||||
myPrintStream.println("\n##teamcity[testFinished name=\'" + escapeName(methodName) +
|
||||
(duration > 0 ? "\' duration=\'" + Long.toString(duration) : "") + "\']");
|
||||
}
|
||||
myCurrentTest = null;
|
||||
}
|
||||
|
||||
public void testFailure(Failure failure) throws Exception {
|
||||
testFailure(failure, failure.getDescription(), MapSerializerUtil.TEST_FAILED, true);
|
||||
public void testFailure(Failure failure) {
|
||||
testFailure(failure, failure.getDescription(), MapSerializerUtil.TEST_FAILED);
|
||||
}
|
||||
|
||||
private void testFailure(Failure failure, Description description, String messageName, boolean local) throws Exception {
|
||||
private void testFailure(Failure failure, Description description, String messageName) {
|
||||
final boolean isIgnored = MapSerializerUtil.TEST_IGNORED.equals(messageName);
|
||||
if (startedInParallel(description)) {
|
||||
TestEvent testEvent = (TestEvent)myWaitingQueue.get(description);
|
||||
if (testEvent == null) {
|
||||
testEvent = new TestEvent();
|
||||
myWaitingQueue.put(description, testEvent);
|
||||
}
|
||||
testEvent.setIgnored(isIgnored);
|
||||
testEvent.setFailure(failure);
|
||||
return;
|
||||
}
|
||||
String methodName = getFullMethodName(description);
|
||||
if (methodName == null) { //class setUp/tearDown failed
|
||||
final boolean isIgnored = MapSerializerUtil.TEST_IGNORED.equals(messageName);
|
||||
if (!isIgnored) {
|
||||
methodName = "Class Configuration";
|
||||
myPrintStream.println("##teamcity[testStarted name=\'" + escapeName(methodName) + "\' " + getClassLocation(JUnit4ReflectionUtil.getClassName(description))+ " ]");
|
||||
@@ -176,14 +224,15 @@ public class JUnit4TestListener extends RunListener {
|
||||
if (myFinishedCount == 0) {
|
||||
//only setup failures
|
||||
for (Iterator iterator = description.getChildren().iterator(); iterator.hasNext(); ) {
|
||||
testFailure(isIgnored ? failure : null, (Description)iterator.next(), MapSerializerUtil.TEST_IGNORED, false);
|
||||
Description next = (Description)iterator.next();
|
||||
testStarted(next);
|
||||
testFailure(isIgnored ? failure : null, next, MapSerializerUtil.TEST_IGNORED);
|
||||
testFinished(next);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!local) testStarted(description);
|
||||
testFailure(failure, messageName, methodName);
|
||||
if (!local) testFinished(description);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,11 +267,7 @@ public class JUnit4TestListener extends RunListener {
|
||||
}
|
||||
|
||||
public void testAssumptionFailure(Failure failure) {
|
||||
final Description description = failure.getDescription();
|
||||
try {
|
||||
testFailure(failure, description, MapSerializerUtil.TEST_IGNORED, true);
|
||||
}
|
||||
catch (Exception ignore) {}
|
||||
testFailure(failure, failure.getDescription(), MapSerializerUtil.TEST_IGNORED);
|
||||
}
|
||||
|
||||
private String getFullMethodName(Description description) {
|
||||
@@ -246,7 +291,7 @@ public class JUnit4TestListener extends RunListener {
|
||||
return methodName;
|
||||
}
|
||||
|
||||
public synchronized void testIgnored(Description description) throws Exception {
|
||||
public void testIgnored(Description description) {
|
||||
final String methodName = getFullMethodName(description);
|
||||
if (methodName == null) {
|
||||
for (Iterator iterator = description.getChildren().iterator(); iterator.hasNext(); ) {
|
||||
@@ -259,7 +304,7 @@ public class JUnit4TestListener extends RunListener {
|
||||
}
|
||||
}
|
||||
|
||||
private void testIgnored(Description description, String methodName) throws Exception {
|
||||
private void testIgnored(Description description, String methodName) {
|
||||
testStarted(description);
|
||||
Map attrs = new HashMap();
|
||||
try {
|
||||
@@ -275,10 +320,89 @@ public class JUnit4TestListener extends RunListener {
|
||||
//junit < 4.4
|
||||
}
|
||||
attrs.put("name", methodName);
|
||||
myPrintStream.println(MapSerializerUtil.asString(MapSerializerUtil.TEST_IGNORED, attrs));
|
||||
|
||||
if (startedInParallel(description)) {
|
||||
TestEvent testEvent = (TestEvent)myWaitingQueue.get(description);
|
||||
if (testEvent == null) {
|
||||
testEvent = new TestEvent();
|
||||
myWaitingQueue.put(description, testEvent);
|
||||
}
|
||||
testEvent.setIgnored(true);
|
||||
testEvent.setAttrs(attrs);
|
||||
}
|
||||
else {
|
||||
myPrintStream.println(MapSerializerUtil.asString(MapSerializerUtil.TEST_IGNORED, attrs));
|
||||
}
|
||||
testFinished(description);
|
||||
}
|
||||
|
||||
private void dumpQueue() {
|
||||
for (Iterator iterator = myWaitingQueue.keySet().iterator(); iterator.hasNext(); ) {
|
||||
Description description = (Description)iterator.next();
|
||||
TestEvent testEvent = (TestEvent)myWaitingQueue.get(description);
|
||||
if (testEvent != null && testEvent.isFinished()) {
|
||||
iterator.remove();
|
||||
|
||||
testStarted(description);
|
||||
|
||||
Failure failure = testEvent.getFailure();
|
||||
if (testEvent.isIgnored()) {
|
||||
Map attrs = testEvent.getAttrs();
|
||||
if (attrs == null) {
|
||||
testFailure(failure, description, MapSerializerUtil.TEST_IGNORED);
|
||||
}
|
||||
else {
|
||||
myPrintStream.println(MapSerializerUtil.asString(MapSerializerUtil.TEST_IGNORED, attrs));
|
||||
}
|
||||
}
|
||||
else if (failure != null) {
|
||||
testFailure(failure);
|
||||
}
|
||||
|
||||
testFinishedNoDumping(description);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestEvent {
|
||||
private Failure myFailure;
|
||||
private boolean myIgnored;
|
||||
private boolean myFinished;
|
||||
private Map myAttrs;
|
||||
|
||||
public Failure getFailure() {
|
||||
return myFailure;
|
||||
}
|
||||
|
||||
public boolean isIgnored() {
|
||||
return myIgnored;
|
||||
}
|
||||
|
||||
public boolean isFinished() {
|
||||
return myFinished;
|
||||
}
|
||||
|
||||
public void setFinished(boolean finished) {
|
||||
myFinished = finished;
|
||||
}
|
||||
|
||||
public void setFailure(Failure failure) {
|
||||
myFailure = failure;
|
||||
}
|
||||
|
||||
public void setIgnored(boolean ignored) {
|
||||
myIgnored = ignored;
|
||||
}
|
||||
|
||||
public void setAttrs(Map attrs) {
|
||||
myAttrs = attrs;
|
||||
}
|
||||
|
||||
public Map getAttrs() {
|
||||
return myAttrs;
|
||||
}
|
||||
}
|
||||
|
||||
private void sendTree(Description description, Description parent, List currentParents) {
|
||||
List pParents = new ArrayList(3);
|
||||
pParents.addAll(currentParents);
|
||||
|
||||
Reference in New Issue
Block a user