SOLR-1835: run the core tests in parallel... not perfect but a start

git-svn-id: https://svn.apache.org/repos/asf/lucene/solr/branches/newtrunk@926470 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Muir 2010-03-23 06:02:05 +00:00
parent 8ae0689e89
commit 03345e1482
5 changed files with 284 additions and 7 deletions

View File

@ -375,8 +375,51 @@
description="Runs the core unit tests." description="Runs the core unit tests."
depends="test-core, test-contrib" /> depends="test-core, test-contrib" />
<target name="junit" depends="compileTests,dist-contrib"> <condition property="runsequential">
<isset property="testcase"/>
</condition>
<target name="junit" depends="compileTests,dist-contrib,junit-sequential,junit-parallel"/>
<target name="junit-sequential" if="runsequential">
<junit-macro/>
</target>
<target name="junit-parallel" unless="runsequential">
<parallel threadsPerProcessor="2">
<junit-macro pattern="S"/>
<junit-macro pattern="D"/>
<junit-macro pattern="A"/>
<junit-macro pattern="B"/>
<junit-macro pattern="C"/>
<junit-macro pattern="E"/>
<junit-macro pattern="F"/>
<junit-macro pattern="G"/>
<junit-macro pattern="H"/>
<junit-macro pattern="I"/>
<junit-macro pattern="J"/>
<junit-macro pattern="K"/>
<junit-macro pattern="L"/>
<junit-macro pattern="M"/>
<junit-macro pattern="N"/>
<junit-macro pattern="O"/>
<junit-macro pattern="P"/>
<junit-macro pattern="Q"/>
<junit-macro pattern="R"/>
<junit-macro pattern="T"/>
<junit-macro pattern="U"/>
<junit-macro pattern="V"/>
<junit-macro pattern="W"/>
<junit-macro pattern="X"/>
<junit-macro pattern="Y"/>
<junit-macro pattern="Z"/>
</parallel>
</target>
<macrodef name="junit-macro">
<attribute name="pattern" default=""/>
<sequential>
<!-- no description so it doesn't show up in -projecthelp --> <!-- no description so it doesn't show up in -projecthelp -->
<mkdir dir="${junit.output.dir}"/> <mkdir dir="${junit.output.dir}"/>
<condition property="runall"> <condition property="runall">
@ -404,17 +447,17 @@
<jvmarg line="${dir.prop}"/> <jvmarg line="${dir.prop}"/>
<jvmarg line="${args}"/> <jvmarg line="${args}"/>
<formatter type="brief" usefile="false" if="junit.details"/> <formatter classname="${junit.details.formatter}" usefile="false" if="junit.details"/>
<classpath refid="test.run.classpath"/> <classpath refid="test.run.classpath"/>
<formatter type="${junit.formatter}"/> <formatter type="${junit.formatter}"/>
<batchtest fork="yes" todir="${junit.output.dir}" if="runall"> <batchtest fork="yes" todir="${junit.output.dir}" if="runall">
<fileset dir="src/test" includes="${junit.includes}"/> <fileset dir="src/test" includes="**/Test@{pattern}*.java,**/@{pattern}*Test.java"/>
</batchtest> </batchtest>
<batchtest fork="yes" todir="${junit.output.dir}" if="testpackage"> <batchtest fork="yes" todir="${junit.output.dir}" if="testpackage">
<fileset dir="src/test" includes="**/${testpackage}/**/Test*.java,**/${testpackage}/**/*Test.java"/> <fileset dir="src/test" includes="**/${testpackage}/**/Test@{pattern}*.java,**/${testpackage}/**/@{pattern}*Test.java"/>
</batchtest> </batchtest>
<batchtest fork="yes" todir="${junit.output.dir}" if="testpackageroot"> <batchtest fork="yes" todir="${junit.output.dir}" if="testpackageroot">
<fileset dir="src/test" includes="**/${testpackageroot}/Test*.java,**/${testpackageroot}/*Test.java"/> <fileset dir="src/test" includes="**/${testpackageroot}/Test@{pattern}*.java,**/${testpackageroot}/@{pattern}*Test.java"/>
</batchtest> </batchtest>
<batchtest fork="yes" todir="${junit.output.dir}" if="testcase"> <batchtest fork="yes" todir="${junit.output.dir}" if="testcase">
<fileset dir="src/test" includes="**/${testcase}.java"/> <fileset dir="src/test" includes="**/${testcase}.java"/>
@ -422,7 +465,9 @@
</junit> </junit>
<fail if="tests.failed">Tests failed!</fail> <fail if="tests.failed">Tests failed!</fail>
</target> </sequential>
</macrodef>
<target name="test-reports" <target name="test-reports"
description="Generates HTML test reports."> description="Generates HTML test reports.">
@ -509,6 +554,7 @@
<exclude name="junit-*.jar" /> <exclude name="junit-*.jar" />
<exclude name="*.txt" /> <exclude name="*.txt" />
<exclude name="*.template" /> <exclude name="*.template" />
<exclude name="apache-ant-*.jar" />
</lib> </lib>
<lib dir="lucene-libs"/> <lib dir="lucene-libs"/>

View File

@ -103,6 +103,7 @@
<property name="junit.output.dir" location="${common-solr.dir}/${dest}/test-results"/> <property name="junit.output.dir" location="${common-solr.dir}/${dest}/test-results"/>
<property name="junit.reports" location="${common-solr.dir}/${dest}/test-results/reports"/> <property name="junit.reports" location="${common-solr.dir}/${dest}/test-results/reports"/>
<property name="junit.formatter" value="plain"/> <property name="junit.formatter" value="plain"/>
<property name="junit.details.formatter" value="org.apache.solr.SolrJUnitResultFormatter"/>
<!-- Maven properties --> <!-- Maven properties -->
<property name="maven.build.dir" value="${basedir}/build/maven"/> <property name="maven.build.dir" value="${basedir}/build/maven"/>

View File

@ -0,0 +1,2 @@
AnyObjectId[704717779f6d0d7eb026dc7af78a35e51adeec8b] was removed in git history.
Apache SVN contains full history.

View File

@ -0,0 +1,2 @@
AnyObjectId[063cce4f940033fa6e33d3e590cf6f5051129295] was removed in git history.
Apache SVN contains full history.

View File

@ -0,0 +1,226 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.solr;
import java.io.IOException;
import java.io.OutputStream;
import java.text.NumberFormat;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import org.apache.tools.ant.taskdefs.optional.junit.JUnitResultFormatter;
import org.apache.tools.ant.taskdefs.optional.junit.JUnitTest;
import org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.StringUtils;
/**
* Just like BriefJUnitResultFormatter "brief" bundled with ant,
* except all formatted text is buffered until the test suite is finished.
* At this point, the output is written at once in synchronized fashion.
* This way tests can run in parallel without interleaving output.
*/
public class SolrJUnitResultFormatter implements JUnitResultFormatter {
private static final double ONE_SECOND = 1000.0;
/** Where to write the log to. */
private OutputStream out;
/** Formatter for timings. */
private NumberFormat numberFormat = NumberFormat.getInstance();
/** Output suite has written to System.out */
private String systemOutput = null;
/** Output suite has written to System.err */
private String systemError = null;
/** Buffer output until the end of the test */
private StringBuilder sb;
/** Constructor for SolrJUnitResultFormatter. */
public SolrJUnitResultFormatter() {
sb = new StringBuilder();
}
/**
* Sets the stream the formatter is supposed to write its results to.
* @param out the output stream to write to
*/
public void setOutput(OutputStream out) {
this.out = out;
}
/**
* @see JUnitResultFormatter#setSystemOutput(String)
*/
/** {@inheritDoc}. */
public void setSystemOutput(String out) {
systemOutput = out;
}
/**
* @see JUnitResultFormatter#setSystemError(String)
*/
/** {@inheritDoc}. */
public void setSystemError(String err) {
systemError = err;
}
/**
* The whole testsuite started.
* @param suite the test suite
*/
public synchronized void startTestSuite(JUnitTest suite) {
if (out == null) {
return; // Quick return - no output do nothing.
}
sb.setLength(0);
sb.append("Testsuite: ");
sb.append(suite.getName());
sb.append(StringUtils.LINE_SEP);
}
/**
* The whole testsuite ended.
* @param suite the test suite
*/
public synchronized void endTestSuite(JUnitTest suite) {
sb.append("Tests run: ");
sb.append(suite.runCount());
sb.append(", Failures: ");
sb.append(suite.failureCount());
sb.append(", Errors: ");
sb.append(suite.errorCount());
sb.append(", Time elapsed: ");
sb.append(numberFormat.format(suite.getRunTime() / ONE_SECOND));
sb.append(" sec");
sb.append(StringUtils.LINE_SEP);
sb.append(StringUtils.LINE_SEP);
// append the err and output streams to the log
if (systemOutput != null && systemOutput.length() > 0) {
sb.append("------------- Standard Output ---------------")
.append(StringUtils.LINE_SEP)
.append(systemOutput)
.append("------------- ---------------- ---------------")
.append(StringUtils.LINE_SEP);
}
if (systemError != null && systemError.length() > 0) {
sb.append("------------- Standard Error -----------------")
.append(StringUtils.LINE_SEP)
.append(systemError)
.append("------------- ---------------- ---------------")
.append(StringUtils.LINE_SEP);
}
if (out != null) {
try {
out.write(sb.toString().getBytes());
out.flush();
} catch (IOException e) {
throw new RuntimeException("unable to write results", e);
} finally {
if (out != System.out && out != System.err) {
FileUtils.close(out);
}
}
}
}
/**
* A test started.
* @param test a test
*/
public void startTest(Test test) {
}
/**
* A test ended.
* @param test a test
*/
public void endTest(Test test) {
}
/**
* Interface TestListener for JUnit &lt;= 3.4.
*
* <p>A Test failed.
* @param test a test
* @param t the exception thrown by the test
*/
public void addFailure(Test test, Throwable t) {
formatError("\tFAILED", test, t);
}
/**
* Interface TestListener for JUnit &gt; 3.4.
*
* <p>A Test failed.
* @param test a test
* @param t the assertion failed by the test
*/
public void addFailure(Test test, AssertionFailedError t) {
addFailure(test, (Throwable) t);
}
/**
* A test caused an error.
* @param test a test
* @param error the error thrown by the test
*/
public void addError(Test test, Throwable error) {
formatError("\tCaused an ERROR", test, error);
}
/**
* Format the test for printing..
* @param test a test
* @return the formatted testname
*/
protected String formatTest(Test test) {
if (test == null) {
return "Null Test: ";
} else {
return "Testcase: " + test.toString() + ":";
}
}
/**
* Format an error and print it.
* @param type the type of error
* @param test the test that failed
* @param error the exception that the test threw
*/
protected synchronized void formatError(String type, Test test,
Throwable error) {
if (test != null) {
endTest(test);
}
sb.append(formatTest(test) + type);
sb.append(error.getMessage());
String strace = JUnitTestRunner.getFilteredTrace(error);
sb.append(strace);
sb.append(StringUtils.LINE_SEP);
}
}