Description: | In Model.java:49, the synchronized map returned by suite.getResults()
is iterated over in an unsynchronized manner, but according to the
Oracle Java 7 API specification,
this is not thread-safe and can lead to non-deterministic behavior.
This pull request adds a fix by synchronizing the iteration. |
Code with Misuse: |
class Model {
private void init() {
int testCounter = 0;
for (ISuite suite : m_suites) {
List<ITestResult> passed = Lists.newArrayList();
List<ITestResult> failed = Lists.newArrayList();
List<ITestResult> skipped = Lists.newArrayList();
for (ISuiteResult sr : suite.getResults().values()) {
ITestContext context = sr.getTestContext();
m_testTags.put(context.getName(), "test-" + testCounter++);
failed.addAll(context.getFailedTests().getAllResults());
skipped.addAll(context.getSkippedTests().getAllResults());
passed.addAll(context.getPassedTests().getAllResults());
IResultMap[] map = new IResultMap[] {
context.getFailedTests(),
context.getSkippedTests(),
context.getPassedTests()
};
for (IResultMap m : map) {
for (ITestResult tr : m.getAllResults()) {
m_testResultMap.put(tr, getTestResultName(tr));
}
}
}
// Process them in the order passed, skipped and failed, so that the failed
// icon overrides all the others and the skipped icon overrides passed.
// Passed
{
ResultsByClass rbc = new ResultsByClass();
for (ITestResult tr : passed) {
rbc.addResult(tr.getTestClass().getRealClass(), tr);
updateGroups(suite, tr);
}
m_passedResultsByClass.put(suite, rbc);
}
// Skipped
{
ResultsByClass rbc = new ResultsByClass();
for (ITestResult tr : skipped) {
m_statusBySuiteName.put(suite.getName(), "skipped");
rbc.addResult(tr.getTestClass().getRealClass(), tr);
updateGroups(suite, tr);
}
m_skippedResultsByClass.put(suite, rbc);
}
// Failed
{
ResultsByClass rbc = new ResultsByClass();
for (ITestResult tr : failed) {
m_statusBySuiteName.put(suite.getName(), "failed");
rbc.addResult(tr.getTestClass().getRealClass(), tr);
m_allFailedResults.add(tr);
updateGroups(suite, tr);
}
m_failedResultsByClass.put(suite, rbc);
}
m_model.putAll(suite, failed);
m_model.putAll(suite, skipped);
m_model.putAll(suite, passed);
}
}
}
|