]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9616 Add bugs, vulnerabilities and code smells in branches list
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Fri, 11 Aug 2017 16:51:38 +0000 (18:51 +0200)
committerJanos Gyerik <janos.gyerik@sonarsource.com>
Tue, 12 Sep 2017 08:59:56 +0000 (10:59 +0200)
server/sonar-server/src/main/java/org/sonar/server/projectbranch/ws/ListAction.java
server/sonar-server/src/test/java/org/sonar/server/projectbranch/ws/ListActionTest.java
sonar-ws/src/main/protobuf/ws-projectbranches.proto

index fd34266be0a216b00a03053582feb9b861f5a92d..77f54fd78b8bd4ac4882ecd3d2b14baef6488b8d 100644 (file)
@@ -40,6 +40,7 @@ import org.sonar.db.metric.MetricDto;
 import org.sonar.server.user.UserSession;
 import org.sonar.server.ws.WsUtils;
 import org.sonarqube.ws.WsBranches;
+import org.sonarqube.ws.WsBranches.Branch.Status;
 
 import static com.google.common.base.Preconditions.checkState;
 import static java.util.Arrays.asList;
@@ -51,6 +52,8 @@ import static org.sonar.core.util.Protobuf.setNullable;
 import static org.sonar.core.util.stream.MoreCollectors.index;
 import static org.sonar.core.util.stream.MoreCollectors.toList;
 import static org.sonar.core.util.stream.MoreCollectors.uniqueIndex;
+import static org.sonar.db.component.BranchType.LONG;
+import static org.sonar.db.component.BranchType.SHORT;
 import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001;
 import static org.sonarqube.ws.client.projectbranches.ProjectBranchesParameters.ACTION_LIST;
 import static org.sonarqube.ws.client.projectbranches.ProjectBranchesParameters.PARAM_PROJECT;
@@ -94,7 +97,7 @@ public class ListAction implements BranchWsAction {
         throw new IllegalArgumentException("Invalid project key");
       }
 
-      List<MetricDto> metrics = dbClient.metricDao().selectByKeys(dbSession, asList(ALERT_STATUS_KEY));
+      List<MetricDto> metrics = dbClient.metricDao().selectByKeys(dbSession, asList(ALERT_STATUS_KEY, BUGS_KEY, VULNERABILITIES_KEY, CODE_SMELLS_KEY));
       Map<Integer, MetricDto> metricsById = metrics.stream().collect(uniqueIndex(MetricDto::getId));
       Map<String, Integer> metricIdsByKey = metrics.stream().collect(uniqueIndex(MetricDto::getKey, MetricDto::getId));
 
@@ -127,9 +130,30 @@ public class ListAction implements BranchWsAction {
       setNullable(mergeBranch.getKey(), builder::setMergeBranch);
     }
 
-    int qualityGateStatusMetricId = metricIdsByKey.get(ALERT_STATUS_KEY);
-    measuresByComponentUuids.get(branch.getUuid()).stream().filter(m -> m.getMetricId() == qualityGateStatusMetricId).findAny()
-      .ifPresent(measure -> builder.setStatus(WsBranches.Branch.Status.newBuilder().setQualityGateStatus(measure.getData())));
+    Status.Builder statusBuilder = Status.newBuilder();
+    Collection<MeasureDto> componentMeasures = measuresByComponentUuids.get(branch.getUuid());
+    if (branch.getBranchType().equals(LONG)) {
+      int qualityGateStatusMetricId = metricIdsByKey.get(ALERT_STATUS_KEY);
+      componentMeasures.stream().filter(m -> m.getMetricId() == qualityGateStatusMetricId).findAny()
+        .ifPresent(measure -> statusBuilder.setQualityGateStatus(measure.getData()));
+    }
+
+    if (branch.getBranchType().equals(SHORT)) {
+      int bugsMetricId = metricIdsByKey.get(BUGS_KEY);
+      componentMeasures.stream().filter(m -> m.getMetricId() == bugsMetricId).findAny()
+        .ifPresent(measure -> statusBuilder.setBugs(measure.getValue().intValue()));
+
+      int vulnerabilitiesMetricId = metricIdsByKey.get(VULNERABILITIES_KEY);
+      componentMeasures.stream().filter(m -> m.getMetricId() == vulnerabilitiesMetricId).findAny()
+        .ifPresent(measure -> statusBuilder.setVulnerabilities(measure.getValue().intValue()));
+
+      int codeSmellMetricId = metricIdsByKey.get(CODE_SMELLS_KEY);
+      componentMeasures.stream().filter(m -> m.getMetricId() == codeSmellMetricId).findAny()
+        .ifPresent(measure -> statusBuilder.setCodeSmells(measure.getValue().intValue()));
+    }
+
+    builder.setStatus(statusBuilder);
     builder.build();
   }
+
 }
index 17fb1a8c086c63147078d7bf2ac5b83fd76d7427..46c8415b6ceefe6588f5544f332cd13825d1be47 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.server.projectbranch.ws;
 
+import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
@@ -35,13 +36,18 @@ import org.sonar.server.exceptions.NotFoundException;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.ws.WsActionTester;
 import org.sonarqube.ws.MediaTypes;
+import org.sonarqube.ws.WsBranches;
 import org.sonarqube.ws.WsBranches.Branch;
 import org.sonarqube.ws.WsBranches.ListWsResponse;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.tuple;
 import static org.sonar.api.measures.CoreMetrics.ALERT_STATUS_KEY;
+import static org.sonar.api.measures.CoreMetrics.BUGS_KEY;
+import static org.sonar.api.measures.CoreMetrics.CODE_SMELLS_KEY;
+import static org.sonar.api.measures.CoreMetrics.VULNERABILITIES_KEY;
 import static org.sonar.test.JsonAssert.assertJson;
+import static org.sonarqube.ws.WsBranches.Branch.Status;
 
 public class ListActionTest {
 
@@ -54,8 +60,21 @@ public class ListActionTest {
   @Rule
   public UserSessionRule userSession = UserSessionRule.standalone();
 
+  private MetricDto qualityGateStatus;
+  private MetricDto bugs;
+  private MetricDto vulnerabilities;
+  private MetricDto codeSmells;
+
   public WsActionTester tester = new WsActionTester(new ListAction(db.getDbClient(), userSession));
 
+  @Before
+  public void setUp() throws Exception {
+    qualityGateStatus = db.measures().insertMetric(m -> m.setKey(ALERT_STATUS_KEY));
+    bugs = db.measures().insertMetric(m -> m.setKey(BUGS_KEY));
+    vulnerabilities = db.measures().insertMetric(m -> m.setKey(VULNERABILITIES_KEY));
+    codeSmells = db.measures().insertMetric(m -> m.setKey(CODE_SMELLS_KEY));
+  }
+
   @Test
   public void test_definition() {
     WebService.Action definition = tester.getDef();
@@ -173,7 +192,6 @@ public class ListActionTest {
     userSession.logIn().addProjectPermission(UserRole.USER, project);
     ComponentDto branch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.LONG));
     SnapshotDto branchAnalysis = db.components().insertSnapshot(branch);
-    MetricDto qualityGateStatus = db.measures().insertMetric(m -> m.setKey(ALERT_STATUS_KEY));
     db.measures().insertMeasure(branch, branchAnalysis, qualityGateStatus, m -> m.setData("OK"));
 
     ListWsResponse response = tester.newRequest()
@@ -185,6 +203,30 @@ public class ListActionTest {
       .containsExactlyInAnyOrder(tuple(false, ""), tuple(true, "OK"));
   }
 
+  @Test
+  public void bugs_vulnerabilities_and_code_smells_on_short_living_branch() {
+    ComponentDto project = db.components().insertMainBranch();
+    userSession.logIn().addProjectPermission(UserRole.USER, project);
+    ComponentDto longLivingBranch = db.components().insertProjectBranch(project, b -> b.setBranchType(BranchType.LONG));
+    ComponentDto shortLivingBranch = db.components().insertProjectBranch(project,
+      b -> b.setBranchType(BranchType.SHORT).setMergeBranchUuid(longLivingBranch.uuid()));
+    SnapshotDto branchAnalysis = db.components().insertSnapshot(shortLivingBranch);
+    db.measures().insertMeasure(shortLivingBranch, branchAnalysis, bugs, m -> m.setValue(1d));
+    db.measures().insertMeasure(shortLivingBranch, branchAnalysis, vulnerabilities, m -> m.setValue(2d));
+    db.measures().insertMeasure(shortLivingBranch, branchAnalysis, codeSmells, m -> m.setValue(3d));
+
+    ListWsResponse response = tester.newRequest()
+      .setParam("project", project.getKey())
+      .executeProtobuf(ListWsResponse.class);
+
+    assertThat(response.getBranchesList().stream().map(WsBranches.Branch::getStatus))
+      .extracting(Status::hasBugs, Status::getBugs, Status::hasVulnerabilities, Status::getVulnerabilities, Status::hasCodeSmells, Status::getCodeSmells)
+      .containsExactlyInAnyOrder(
+        tuple(false, 0, false, 0, false, 0),
+        tuple(false, 0, false, 0, false, 0),
+        tuple(true, 1, true, 2, true, 3));
+  }
+
   @Test
   public void test_example() {
     ComponentDto project = db.components().insertPrivateProject();
index 3b32bc08fb882845c6d48a8ad1ab075a0e15adb4..915e983e788e61c9e005dce79a86975afe3ce40a 100644 (file)
@@ -43,9 +43,9 @@ message Branch {
     // Quality gate status is only present for long living branch
     optional string qualityGateStatus = 1;
     // Merge bugs, vulnerabilities and codeSmell are only present for short living branch
-    optional string bugs = 2;
-    optional string vulnerabilities = 3;
-    optional string codeSmell = 4;
+    optional int32 bugs = 2;
+    optional int32 vulnerabilities = 3;
+    optional int32 codeSmells = 4;
   }
 
   enum BranchType {