diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2014-07-16 12:10:13 +0200 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2014-07-16 12:10:27 +0200 |
commit | 9fea95aa451ac0bdca470ff30c8826815feee8fd (patch) | |
tree | 11d7e00123cedbe26944d52c626c80dd32c18d9f /server/sonar-server | |
parent | 3425d861e177847b96ce989fd519b07b192b4fd3 (diff) | |
download | sonarqube-9fea95aa451ac0bdca470ff30c8826815feee8fd.tar.gz sonarqube-9fea95aa451ac0bdca470ff30c8826815feee8fd.zip |
SONAR-5338 Read test info from the test_data measure
Diffstat (limited to 'server/sonar-server')
6 files changed, 177 insertions, 13 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MeasureDao.java b/server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MeasureDao.java index 7fbed57dc0f..80b279ec1cb 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MeasureDao.java +++ b/server/sonar-server/src/main/java/org/sonar/server/measure/persistence/MeasureDao.java @@ -69,6 +69,10 @@ public class MeasureDao extends BaseDao<MeasureMapper, MeasureDto, MeasureKey> i return dtos; } + public MeasureDto findByComponentKeyAndMetricKey(String componentKey, String metricKey, DbSession session) { + return session.getMapper(MeasureMapper.class).selectByComponentAndMetric(componentKey, metricKey); + } + @Override protected MeasureDto doInsert(DbSession session, MeasureDto item) { throw notImplemented(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/test/ws/TestsShowAction.java b/server/sonar-server/src/main/java/org/sonar/server/test/ws/TestsShowAction.java index 581dad7a90b..117a3b25c54 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/test/ws/TestsShowAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/test/ws/TestsShowAction.java @@ -21,6 +21,10 @@ package org.sonar.server.test.ws; import com.google.common.io.Resources; +import org.codehaus.staxmate.SMInputFactory; +import org.codehaus.staxmate.in.SMHierarchicCursor; +import org.codehaus.staxmate.in.SMInputCursor; +import org.sonar.api.measures.CoreMetrics; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.RequestHandler; import org.sonar.api.server.ws.Response; @@ -30,15 +34,27 @@ import org.sonar.api.test.TestCase; import org.sonar.api.utils.text.JsonWriter; import org.sonar.api.web.UserRole; import org.sonar.core.component.SnapshotPerspectives; +import org.sonar.core.measure.db.MeasureDto; +import org.sonar.core.persistence.DbSession; +import org.sonar.core.persistence.MyBatis; +import org.sonar.server.db.DbClient; import org.sonar.server.user.UserSession; +import javax.annotation.CheckForNull; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; + +import java.io.StringReader; + public class TestsShowAction implements RequestHandler { private static final String KEY = "key"; + private final DbClient dbClient; private final SnapshotPerspectives snapshotPerspectives; - public TestsShowAction(SnapshotPerspectives snapshotPerspectives) { + public TestsShowAction(DbClient dbClient, SnapshotPerspectives snapshotPerspectives) { + this.dbClient = dbClient; this.snapshotPerspectives = snapshotPerspectives; } @@ -61,15 +77,20 @@ public class TestsShowAction implements RequestHandler { String fileKey = request.mandatoryParam(KEY); UserSession.get().checkComponentPermission(UserRole.CODEVIEWER, fileKey); - MutableTestPlan testPlan = snapshotPerspectives.as(MutableTestPlan.class, fileKey); + String testData = findTestData(fileKey); JsonWriter json = response.newJsonWriter().beginObject(); - if (testPlan != null) { - writeTests(testPlan, json); + if (testData != null) { + writeFromTestData(testData, json); + } else { + MutableTestPlan testPlan = snapshotPerspectives.as(MutableTestPlan.class, fileKey); + if (testPlan != null) { + writeFromTestable(testPlan, json); + } } json.endObject().close(); } - private void writeTests(MutableTestPlan testPlan, JsonWriter json) { + private void writeFromTestable(MutableTestPlan testPlan, JsonWriter json) { json.name("tests").beginArray(); for (TestCase testCase : testPlan.testCases()) { json.beginObject(); @@ -84,4 +105,60 @@ public class TestsShowAction implements RequestHandler { json.endArray(); } + private void writeFromTestData(String data, JsonWriter json) { + SMInputFactory inputFactory = initStax(); + try { + SMHierarchicCursor root = inputFactory.rootElementCursor(new StringReader(data)); + root.advance(); // tests-details + SMInputCursor cursor = root.childElementCursor(); + json.name("tests").beginArray(); + while (cursor.getNext() != null) { + json.beginObject(); + + json.prop("name", cursor.getAttrValue("name")); + json.prop("status", cursor.getAttrValue("status").toUpperCase()); + json.prop("durationInMs", cursor.getAttrValue("time")); + + SMInputCursor errorCursor = cursor.childElementCursor(); + if (errorCursor.getNext() != null) { + json.prop("message", errorCursor.getAttrValue("message")); + + SMInputCursor stackTraceCursor = cursor.childElementCursor(); + if (stackTraceCursor.getNext() != null) { +// json.prop("stackTrace", stackTraceCursor.getAttrValue("")); + } + } + + json.endObject(); + } + json.endArray(); + } catch (XMLStreamException e) { + throw new IllegalStateException("XML is not valid: " + e.getMessage(), e); + } + } + + @CheckForNull + private String findTestData(String fileKey) { + DbSession session = dbClient.openSession(false); + try { + MeasureDto testData = dbClient.measureDao().findByComponentKeyAndMetricKey(fileKey, CoreMetrics.TEST_DATA_KEY, session); + if (testData != null) { + return testData.getData(); + } + } finally { + MyBatis.closeQuietly(session); + } + return null; + } + + private SMInputFactory initStax() { + XMLInputFactory xmlFactory = XMLInputFactory.newInstance(); + xmlFactory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE); + xmlFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.FALSE); + // just so it won't try to load DTD in if there's DOCTYPE + xmlFactory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE); + xmlFactory.setProperty(XMLInputFactory.IS_VALIDATING, Boolean.FALSE); + return new SMInputFactory(xmlFactory); + } + } diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/persistence/MeasureDaoTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/persistence/MeasureDaoTest.java index 15afbb3bdad..a93f066059d 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/measure/persistence/MeasureDaoTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/measure/persistence/MeasureDaoTest.java @@ -101,6 +101,23 @@ public class MeasureDaoTest extends AbstractDaoTestCase { } @Test + public void find_by_component_key_and_metric() throws Exception { + setupData("shared"); + + MeasureDto result = dao.findByComponentKeyAndMetricKey("org.struts:struts-core:src/org/struts/RequestContext.java", "ncloc", session); + assertThat(result.getId()).isEqualTo(22); + assertThat(result.getValue()).isEqualTo(10d); + assertThat(result.getKey()).isEqualTo(MeasureKey.of("org.struts:struts-core:src/org/struts/RequestContext.java", "ncloc")); + assertThat(result.getVariation(1)).isEqualTo(1d); + assertThat(result.getVariation(2)).isEqualTo(2d); + assertThat(result.getVariation(3)).isEqualTo(3d); + assertThat(result.getVariation(4)).isEqualTo(4d); + assertThat(result.getVariation(5)).isEqualTo(-5d); + + assertThat(dao.findByComponentKeyAndMetricKey("org.struts:struts-core:src/org/struts/RequestContext.java", "unknown", session)).isNull(); + } + + @Test public void exists_by_key() throws Exception { setupData("shared"); diff --git a/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsShowActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsShowActionTest.java index 80e9617d6ca..07f9be4ab61 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsShowActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsShowActionTest.java @@ -21,6 +21,7 @@ package org.sonar.server.test.ws; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -30,6 +31,11 @@ import org.sonar.api.test.MutableTestPlan; import org.sonar.api.test.TestCase; import org.sonar.api.web.UserRole; import org.sonar.core.component.SnapshotPerspectives; +import org.sonar.core.measure.db.MeasureDto; +import org.sonar.core.measure.db.MeasureKey; +import org.sonar.core.persistence.DbSession; +import org.sonar.server.db.DbClient; +import org.sonar.server.measure.persistence.MeasureDao; import org.sonar.server.user.MockUserSession; import org.sonar.server.ws.WsTester; @@ -45,28 +51,41 @@ public class TestsShowActionTest { static final String TEST_PLAN_KEY = "src/test/java/org/foo/BarTest.java"; @Mock + DbSession session; + + @Mock + MeasureDao measureDao; + + @Mock MutableTestPlan testPlan; + @Mock + SnapshotPerspectives snapshotPerspectives; + WsTester tester; @Before public void setUp() throws Exception { - SnapshotPerspectives snapshotPerspectives = mock(SnapshotPerspectives.class); - when(snapshotPerspectives.as(MutableTestPlan.class, TEST_PLAN_KEY)).thenReturn(testPlan); - tester = new WsTester(new TestsWs(new TestsShowAction(snapshotPerspectives), mock(TestsTestCasesAction.class), mock(TestsCoveredFilesAction.class))); + DbClient dbClient = mock(DbClient.class); + when(dbClient.openSession(false)).thenReturn(session); + when(dbClient.measureDao()).thenReturn(measureDao); + + tester = new WsTester(new TestsWs(new TestsShowAction(dbClient, snapshotPerspectives), mock(TestsTestCasesAction.class), mock(TestsCoveredFilesAction.class))); } @Test public void show() throws Exception { MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, "SonarQube", TEST_PLAN_KEY); + when(snapshotPerspectives.as(MutableTestPlan.class, TEST_PLAN_KEY)).thenReturn(testPlan); + MutableTestCase testCase1 = testCase("test1", TestCase.Status.OK, 10L, 32, null, null); MutableTestCase testCase2 = testCase("test2", TestCase.Status.ERROR, 97L, 21, "expected:<true> but was:<false>", "java.lang.AssertionError: expected:<true> but was:<false>\n\t" + - "at org.junit.Assert.fail(Assert.java:91)\n\t" + - "at org.junit.Assert.failNotEquals(Assert.java:645)\n\t" + - "at org.junit.Assert.assertEquals(Assert.java:126)\n\t" + - "at org.junit.Assert.assertEquals(Assert.java:145)\n"); + "at org.junit.Assert.fail(Assert.java:91)\n\t" + + "at org.junit.Assert.failNotEquals(Assert.java:645)\n\t" + + "at org.junit.Assert.assertEquals(Assert.java:126)\n\t" + + "at org.junit.Assert.assertEquals(Assert.java:145)\n"); when(testPlan.testCases()).thenReturn(newArrayList(testCase1, testCase2)); WsTester.TestRequest request = tester.newGetRequest("api/tests", "show").setParam("key", TEST_PLAN_KEY); @@ -74,6 +93,34 @@ public class TestsShowActionTest { request.execute().assertJson(getClass(), "show.json"); } + @Test + @Ignore + public void show_from_test_data() throws Exception { + MockUserSession.set().addComponentPermission(UserRole.CODEVIEWER, "SonarQube", TEST_PLAN_KEY); + + when(measureDao.findByComponentKeyAndMetricKey(TEST_PLAN_KEY, "test_data", session)).thenReturn(MeasureDto.createFor(MeasureKey.of(TEST_PLAN_KEY, "test_data")) + .setTextValue("<tests-details>" + + "<testcase status=\"ok\" time=\"10\" name=\"test1\"/>" + + "<testcase status=\"error\" time=\"97\" name=\"test2\">" + + "<error message=\"expected:<true> but was:<false>\">" + + "<![CDATA[" + + "java.lang.AssertionError: expected:<true> but was:<false>\n\t" + + "at org.junit.Assert.fail(Assert.java:91)\n\t" + + "at org.junit.Assert.failNotEquals(Assert.java:645)\n\t" + + "at org.junit.Assert.assertEquals(Assert.java:126)\n\t" + + "at org.junit.Assert.assertEquals(Assert.java:145)\n" + + "]]>" + + "</error>" + + "</testcase>" + + "</tests-details>")); + + // TODO failure + + WsTester.TestRequest request = tester.newGetRequest("api/tests", "show").setParam("key", TEST_PLAN_KEY); + + request.execute().assertJson(getClass(), "show_from_test_data.json"); + } + private MutableTestCase testCase(String name, TestCase.Status status, Long durationInMs, int coveredLines, @Nullable String message, @Nullable String stackTrace) { MutableTestCase testCase = mock(MutableTestCase.class); when(testCase.name()).thenReturn(name); diff --git a/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsWsTest.java index 5dd2c4f185f..50290be7023 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/test/ws/TestsWsTest.java @@ -24,6 +24,7 @@ import org.junit.Before; import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.core.component.SnapshotPerspectives; +import org.sonar.server.db.DbClient; import org.sonar.server.ws.WsTester; import static org.fest.assertions.Assertions.assertThat; @@ -36,7 +37,7 @@ public class TestsWsTest { @Before public void setUp() throws Exception { SnapshotPerspectives snapshotPerspectives = mock(SnapshotPerspectives.class); - WsTester tester = new WsTester(new TestsWs(new TestsShowAction(snapshotPerspectives), new TestsTestCasesAction(snapshotPerspectives), new TestsCoveredFilesAction(snapshotPerspectives))); + WsTester tester = new WsTester(new TestsWs(new TestsShowAction(mock(DbClient.class), snapshotPerspectives), new TestsTestCasesAction(snapshotPerspectives), new TestsCoveredFilesAction(snapshotPerspectives))); controller = tester.controller("api/tests"); } diff --git a/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsShowActionTest/show_from_test_data.json b/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsShowActionTest/show_from_test_data.json new file mode 100644 index 00000000000..f8832a0f01f --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/test/ws/TestsShowActionTest/show_from_test_data.json @@ -0,0 +1,18 @@ +{ +"tests": [ + { + "name": "test1", + "status": "OK", + "durationInMs": 10, + "coveredLines": 32 + }, + { + "name": "test2", + "status": "ERROR", + "durationInMs": 97, + "coveredLines": 21, + "message": "expected:<true> but was:<false>", + "stackTrace" : "java.lang.AssertionError: expected:<true> but was:<false>\n\tat org.junit.Assert.fail(Assert.java:91)\n\tat org.junit.Assert.failNotEquals(Assert.java:645)\n\tat org.junit.Assert.assertEquals(Assert.java:126)\n\tat org.junit.Assert.assertEquals(Assert.java:145)\n" + } + ] +} |