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); } }
}
|