How to diagnose forked jcstress execution problems?
Jerzy Krolak
j.krolak at gmail.com
Thu Mar 23 19:19:29 UTC 2017
> Please resend both patches, I need them on mailing list record.
Here's all three patches. I've improved the 'error reporting' part - a new
test case added.
A note about the 'windows-grouping-character' - I'm not 100% sure if
jcstress code is the right place for this kind of fix. Any thoughts?
Thanks,
Jerzy
-------------- next part --------------
diff -r 9f21d933addf jcstress-core/src/main/java/org/openjdk/jcstress/EmbeddedExecutor.java
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/EmbeddedExecutor.java Fri Mar 17 11:23:01 2017 +0100
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/EmbeddedExecutor.java Wed Mar 22 22:21:18 2017 +0100
@@ -37,6 +37,8 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
+import static org.openjdk.jcstress.util.StringUtils.getStacktrace;
+
public class EmbeddedExecutor {
private final ExecutorService pool;
@@ -80,11 +82,11 @@
o.run();
} catch (ClassFormatError | NoClassDefFoundError | NoSuchMethodError | NoSuchFieldError e) {
TestResult result = new TestResult(config, Status.API_MISMATCH, 0);
- result.addAuxData(e.getMessage());
+ result.addAuxData(getStacktrace(e));
sink.add(result);
} catch (Throwable ex) {
TestResult result = new TestResult(config, Status.TEST_ERROR, 0);
- result.addAuxData(ex.getMessage());
+ result.addAuxData(getStacktrace(ex));
sink.add(result);
} finally {
if (onFinish != null) {
diff -r 9f21d933addf jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Runner.java
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Runner.java Fri Mar 17 11:23:01 2017 +0100
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/runners/Runner.java Wed Mar 22 22:21:18 2017 +0100
@@ -30,8 +30,6 @@
import org.openjdk.jcstress.util.Counter;
import org.openjdk.jcstress.vm.WhiteBoxSupport;
-import java.io.PrintWriter;
-import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -41,6 +39,8 @@
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
+import static org.openjdk.jcstress.util.StringUtils.getStacktrace;
+
/**
* Basic runner for concurrency tests.
*
@@ -107,11 +107,7 @@
protected void dumpFailure(int iteration, Status status, String message, Throwable aux) {
messages.add(message);
TestResult result = prepareResult(iteration, status);
- StringWriter sw = new StringWriter();
- PrintWriter pw = new PrintWriter(sw);
- aux.printStackTrace(pw);
- pw.close();
- result.addAuxData(sw.toString());
+ result.addAuxData(getStacktrace(aux));
collector.add(result);
}
diff -r 9f21d933addf jcstress-core/src/main/java/org/openjdk/jcstress/util/StringUtils.java
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/util/StringUtils.java Fri Mar 17 11:23:01 2017 +0100
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/util/StringUtils.java Wed Mar 22 22:21:18 2017 +0100
@@ -24,8 +24,9 @@
*/
package org.openjdk.jcstress.util;
+import java.io.PrintWriter;
+import java.io.StringWriter;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.List;
@@ -101,4 +102,20 @@
}
return sb.toString();
}
+
+ public static String getStacktrace(Throwable throwable) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ throwable.printStackTrace(pw);
+ pw.close();
+ return sw.toString();
+ }
+
+ public static String getFirstLine(String actual) {
+ int endLine = actual.indexOf("\n");
+ if (endLine > 0) {
+ return actual.substring(0, endLine).trim();
+ }
+ return actual;
+ }
}
diff -r 9f21d933addf jcstress-core/src/test/java/org/openjdk/jcstress/EmbeddedExecutorTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jcstress-core/src/test/java/org/openjdk/jcstress/EmbeddedExecutorTest.java Wed Mar 22 22:21:18 2017 +0100
@@ -0,0 +1,42 @@
+package org.openjdk.jcstress;
+
+import junit.framework.Assert;
+import org.junit.Test;
+import org.openjdk.jcstress.infra.Status;
+import org.openjdk.jcstress.infra.TestInfo;
+import org.openjdk.jcstress.infra.collectors.InProcessCollector;
+import org.openjdk.jcstress.infra.collectors.TestResult;
+import org.openjdk.jcstress.infra.runners.TestConfig;
+
+import java.util.Collections;
+
+import static org.openjdk.jcstress.util.StringUtils.getFirstLine;
+
+public class EmbeddedExecutorTest {
+
+ private InProcessCollector sink = new InProcessCollector();
+
+ private EmbeddedExecutor embeddedExecutor = new EmbeddedExecutor(sink);
+
+ @Test
+ public void testReportTestError() {
+ TestConfig config = createSimpleConfigFor("my.missing.ClassName");
+ embeddedExecutor.run(config);
+
+ Assert.assertEquals("Should get exactly one test result", 1, sink.getTestResults().size());
+
+ TestResult testResult = sink.getTestResults().iterator().next();
+ Assert.assertEquals("Should report a test error", Status.TEST_ERROR, testResult.status());
+
+ String errorMessage = testResult.getAuxData().get(0);
+ Assert.assertEquals("Should report the test error reason", "java.lang.ClassNotFoundException: my.missing.ClassName",
+ getFirstLine(errorMessage));
+ }
+
+ private TestConfig createSimpleConfigFor(String runnerClassName) {
+ Options opts = new Options(new String[]{});
+ TestInfo info = new TestInfo("", runnerClassName, "", 4, false);
+ return new TestConfig(opts, info, TestConfig.RunMode.FORKED, 1, Collections.emptyList());
+ }
+
+}
\ No newline at end of file
diff -r 9f21d933addf jcstress-core/src/test/java/org/openjdk/jcstress/util/StringUtilsTest.java
--- a/jcstress-core/src/test/java/org/openjdk/jcstress/util/StringUtilsTest.java Fri Mar 17 11:23:01 2017 +0100
+++ b/jcstress-core/src/test/java/org/openjdk/jcstress/util/StringUtilsTest.java Wed Mar 22 22:21:18 2017 +0100
@@ -15,4 +15,18 @@
Assert.assertEquals("...", StringUtils.cutoff(s, 3));
}
+ @Test
+ public void testGetStacktrace() {
+ String actual = StringUtils.getStacktrace(new NullPointerException("my message"));
+ String firstLine = StringUtils.getFirstLine(actual);
+
+ Assert.assertEquals("java.lang.NullPointerException: my message", firstLine);
+ }
+
+ @Test
+ public void testGetFirstLine() {
+ Assert.assertEquals("First line", StringUtils.getFirstLine("First line"));
+ Assert.assertEquals("First line", StringUtils.getFirstLine("First line\nsecond line"));
+ }
+
}
-------------- next part --------------
diff -r b64aaf61b6be jcstress-core/src/main/java/org/openjdk/jcstress/infra/grading/ReportUtils.java
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/grading/ReportUtils.java Wed Mar 08 20:52:43 2017 +0100
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/grading/ReportUtils.java Mon Mar 13 22:01:58 2017 +0100
@@ -146,7 +146,7 @@
pw.printf("%" + idLen + "s %" + occLen +"s %" + expectLen + "s %-" + descLen + "s%n", "Observed state", "Occurrences", "Expectation", "Interpretation");
for (GradingResult gradeRes : r.grading().gradingResults) {
- pw.printf("%" + idLen + "s %," + occLen + "d %" + expectLen + "s %-" + descLen + "s%n",
+ pw.printf(Locale.US, "%" + idLen + "s %," + occLen + "d %" + expectLen + "s %-" + descLen + "s%n",
StringUtils.cutoff(gradeRes.id, idLen),
gradeRes.count,
gradeRes.expect,
-------------- next part --------------
diff -r b64aaf61b6be jcstress-core/src/main/java/org/openjdk/jcstress/Options.java
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/Options.java Wed Mar 08 20:52:43 2017 +0100
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/Options.java Mon Mar 13 21:42:59 2017 +0100
@@ -262,12 +262,12 @@
public void printSettingsOn(PrintStream out) {
out.printf(" Hardware threads in use/available: %d/%d, %s%n", getUserCPUs(), getSystemCPUs(), getSpinStyle());
- out.printf(" Test preset mode: \"%s\"\n", mode);
- out.printf(" Writing the test results to \"%s\"\n", resultFile);
- out.printf(" Parsing results to \"%s\"\n", resultDir);
- out.printf(" Running each test matching \"%s\" for %d forks, %d iterations, %d ms each\n", getTestFilter(), getForks(), getIterations(), getTime());
- out.printf(" Each JVM would execute at most %d tests in the row.\n", getBatchSize());
- out.printf(" Solo stride size will be autobalanced within [%d, %d] elements, but taking no more than %d Mb.\n", getMinStride(), getMaxStride(), getMaxFootprintMb());
+ out.printf(" Test preset mode: \"%s\"%n", mode);
+ out.printf(" Writing the test results to \"%s\"%n", resultFile);
+ out.printf(" Parsing results to \"%s\"%n", resultDir);
+ out.printf(" Running each test matching \"%s\" for %d forks, %d iterations, %d ms each%n", getTestFilter(), getForks(), getIterations(), getTime());
+ out.printf(" Each JVM would execute at most %d tests in the row.%n", getBatchSize());
+ out.printf(" Solo stride size will be autobalanced within [%d, %d] elements, but taking no more than %d Mb.%n", getMinStride(), getMaxStride(), getMaxFootprintMb());
out.println();
}
diff -r b64aaf61b6be jcstress-core/src/main/java/org/openjdk/jcstress/infra/grading/ConsoleReportPrinter.java
--- a/jcstress-core/src/main/java/org/openjdk/jcstress/infra/grading/ConsoleReportPrinter.java Wed Mar 08 20:52:43 2017 +0100
+++ b/jcstress-core/src/main/java/org/openjdk/jcstress/infra/grading/ConsoleReportPrinter.java Mon Mar 13 21:42:59 2017 +0100
@@ -123,7 +123,7 @@
private void printLine(TestResult r) {
String label = ReportUtils.statusToLabel(r);
output.printf("\r%" + progressLen + "s\r", "");
- output.printf("%10s %s\n", "[" + label + "]", StringUtils.chunkName(r.getName()));
+ output.printf("%10s %s%n", "[" + label + "]", StringUtils.chunkName(r.getName()));
}
private void printProgress() {
More information about the jcstress-dev
mailing list